parent
49bffbfe7e
commit
bfe1fac37c
|
@ -16,10 +16,15 @@
|
||||||
#ifndef _CPU_H_
|
#ifndef _CPU_H_
|
||||||
#define _CPU_H_
|
#define _CPU_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <util/register.h>
|
#include <util/register.h>
|
||||||
#include <unmanaged_singleton.h>
|
|
||||||
#include <kernel/interface_support.h>
|
#include <kernel/interface_support.h>
|
||||||
#include <cpu/cpu_state.h>
|
#include <cpu/cpu_state.h>
|
||||||
|
|
||||||
|
/* base includes */
|
||||||
|
#include <unmanaged_singleton.h>
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <idt.h>
|
#include <idt.h>
|
||||||
#include <tss.h>
|
#include <tss.h>
|
||||||
|
@ -65,14 +70,12 @@ class Genode::Cpu_lazy_state
|
||||||
/**
|
/**
|
||||||
* Load x87 FPU State from fxsave area.
|
* Load x87 FPU State from fxsave area.
|
||||||
*/
|
*/
|
||||||
inline void load() {
|
inline void load() { asm volatile ("fxrstor %0" : : "m" (*start)); }
|
||||||
asm volatile ("fxrstor %0" : : "m" (*start)); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save x87 FPU State to fxsave area.
|
* Save x87 FPU State to fxsave area.
|
||||||
*/
|
*/
|
||||||
inline void save() {
|
inline void save() { asm volatile ("fxsave %0" : "=m" (*start)); }
|
||||||
asm volatile ("fxsave %0" : "=m" (*start)); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -95,6 +98,7 @@ class Genode::Cpu
|
||||||
friend class Cpu_lazy_state;
|
friend class Cpu_lazy_state;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Idt *_idt;
|
Idt *_idt;
|
||||||
Tss *_tss;
|
Tss *_tss;
|
||||||
Cpu_lazy_state *_fpu_state;
|
Cpu_lazy_state *_fpu_state;
|
||||||
|
@ -138,22 +142,18 @@ class Genode::Cpu
|
||||||
/**
|
/**
|
||||||
* Enable FPU by clearing the TS flag in CR0.
|
* Enable FPU by clearing the TS flag in CR0.
|
||||||
*/
|
*/
|
||||||
static void _enable_fpu() {
|
static void _enable_fpu() { asm volatile ("clts"); }
|
||||||
asm volatile ("clts"); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize FPU without checking for pending unmasked floating-point
|
* Initialize FPU without checking for pending unmasked floating-point
|
||||||
* exceptions.
|
* exceptions.
|
||||||
*/
|
*/
|
||||||
static void _init_fpu() {
|
static void _init_fpu() { asm volatile ("fninit"); }
|
||||||
asm volatile ("fninit");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns True if the FPU is enabled.
|
* Returns True if the FPU is enabled.
|
||||||
*/
|
*/
|
||||||
static bool is_fpu_enabled() {
|
static bool is_fpu_enabled() { return !Cr0::Ts::get(Cr0::read()); }
|
||||||
return !Cr0::Ts::get(Cr0::read()); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -362,8 +362,7 @@ class Genode::Cpu
|
||||||
* Flush data-cache entries for virtual region ['base', 'base + size')
|
* Flush data-cache entries for virtual region ['base', 'base + size')
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
flush_data_caches_by_virt_region(addr_t base, size_t const size)
|
flush_data_caches_by_virt_region(addr_t base, size_t const size) { }
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bin instr.-cache entries for virtual region ['base', 'base + size')
|
* Bin instr.-cache entries for virtual region ['base', 'base + size')
|
||||||
|
@ -384,26 +383,22 @@ class Genode::Cpu
|
||||||
init_virt_kernel(addr_t const table, unsigned const process_id) {
|
init_virt_kernel(addr_t const table, unsigned const process_id) {
|
||||||
Cr3::write(Cr3::init(table)); }
|
Cr3::write(Cr3::init(table)); }
|
||||||
|
|
||||||
inline static void finish_init_phys_kernel() {
|
inline static void finish_init_phys_kernel() { _init_fpu(); }
|
||||||
_init_fpu(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure this module appropriately for the first kernel run
|
* Configure this module appropriately for the first kernel run
|
||||||
*/
|
*/
|
||||||
static void init_phys_kernel() {
|
static void init_phys_kernel() { Timer::disable_pit(); };
|
||||||
Timer::disable_pit(); };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish all previous data transfers
|
* Finish all previous data transfers
|
||||||
*/
|
*/
|
||||||
static void data_synchronization_barrier()
|
static void data_synchronization_barrier() { }
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable secondary CPUs with instr. pointer 'ip'
|
* Enable secondary CPUs with instr. pointer 'ip'
|
||||||
*/
|
*/
|
||||||
static void start_secondary_cpus(void * const ip)
|
static void start_secondary_cpus(void * const ip) { }
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for the next interrupt as cheap as possible
|
* Wait for the next interrupt as cheap as possible
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
.include "spec/x86/macros_support.s"
|
|
||||||
|
|
||||||
|
/***************************************************
|
||||||
|
** Constant values that are pretty commonly used **
|
||||||
|
***************************************************/
|
||||||
|
|
||||||
|
/* alignment constraints */
|
||||||
|
.set MIN_PAGE_SIZE_LOG2, 12
|
||||||
|
.set DATA_ACCESS_ALIGNM_LOG2, 2
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* \brief Macros that are used by multiple assembly files
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2014-01-13
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU General Public License version 2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************
|
|
||||||
** Constant values that are pretty commonly used **
|
|
||||||
***************************************************/
|
|
||||||
|
|
||||||
/* alignment constraints */
|
|
||||||
.set MIN_PAGE_SIZE_LOG2, 12
|
|
||||||
.set DATA_ACCESS_ALIGNM_LOG2, 2
|
|
|
@ -14,9 +14,12 @@
|
||||||
#ifndef _PIC_H_
|
#ifndef _PIC_H_
|
||||||
#define _PIC_H_
|
#define _PIC_H_
|
||||||
|
|
||||||
#include <board.h>
|
/* Genode includes */
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
|
#include <board.h>
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -153,8 +156,6 @@ class Genode::Pic : public Mmio
|
||||||
|
|
||||||
void finish_request();
|
void finish_request();
|
||||||
|
|
||||||
void mask() { }
|
|
||||||
|
|
||||||
void unmask(unsigned const i, unsigned);
|
void unmask(unsigned const i, unsigned);
|
||||||
|
|
||||||
void mask(unsigned const i);
|
void mask(unsigned const i);
|
||||||
|
@ -163,6 +164,7 @@ class Genode::Pic : public Mmio
|
||||||
* Dummies
|
* Dummies
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void mask() { }
|
||||||
void init_cpu_local() { }
|
void init_cpu_local() { }
|
||||||
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
||||||
void trigger_ip_interrupt(unsigned) { }
|
void trigger_ip_interrupt(unsigned) { }
|
||||||
|
|
|
@ -60,31 +60,29 @@ static void init_comport(Genode::uint16_t port, unsigned baud)
|
||||||
if (!port)
|
if (!port)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const unsigned
|
unsigned const ier = port + 1;
|
||||||
IER = port + 1,
|
unsigned const eir = port + 2;
|
||||||
EIR = port + 2,
|
unsigned const lcr = port + 3;
|
||||||
LCR = port + 3,
|
unsigned const mcr = port + 4;
|
||||||
MCR = port + 4,
|
unsigned const lsr = port + 5;
|
||||||
LSR = port + 5,
|
unsigned const msr = port + 6;
|
||||||
MSR = port + 6,
|
unsigned const dllo = port + 0;
|
||||||
DLLO = port + 0,
|
unsigned const dlhi = port + 1;
|
||||||
DLHI = port + 1;
|
|
||||||
|
|
||||||
outb(LCR, 0x80); /* select bank 1 */
|
outb(lcr, 0x80); /* select bank 1 */
|
||||||
// for (volatile int i = 10000000; i--; );
|
outb(dllo, (115200/baud) >> 0);
|
||||||
outb(DLLO, (115200/baud) >> 0);
|
outb(dlhi, (115200/baud) >> 8);
|
||||||
outb(DLHI, (115200/baud) >> 8);
|
outb(lcr, 0x03); /* set 8,n,1 */
|
||||||
outb(LCR, 0x03); /* set 8,N,1 */
|
outb(ier, 0x00); /* disable interrupts */
|
||||||
outb(IER, 0x00); /* disable interrupts */
|
outb(eir, 0x07); /* enable FIFOs */
|
||||||
outb(EIR, 0x07); /* enable FIFOs */
|
outb(mcr, 0x0b); /* force data terminal ready */
|
||||||
outb(MCR, 0x0b); /* force data terminal ready */
|
outb(ier, 0x01); /* enable rx interrupts */
|
||||||
outb(IER, 0x01); /* enable RX interrupts */
|
inb(ier);
|
||||||
inb(IER);
|
inb(eir);
|
||||||
inb(EIR);
|
inb(lcr);
|
||||||
inb(LCR);
|
inb(mcr);
|
||||||
inb(MCR);
|
inb(lsr);
|
||||||
inb(LSR);
|
inb(msr);
|
||||||
inb(MSR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,12 @@
|
||||||
#ifndef _TIMER_H_
|
#ifndef _TIMER_H_
|
||||||
#define _TIMER_H_
|
#define _TIMER_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
#include <base/stdint.h>
|
#include <base/stdint.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
#include <port_io.h>
|
#include <port_io.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
|
@ -58,7 +61,7 @@ class Genode::Timer : public Mmio
|
||||||
uint32_t _tics_per_ms = 0;
|
uint32_t _tics_per_ms = 0;
|
||||||
|
|
||||||
/* Measure LAPIC timer frequency using PIT channel 2 */
|
/* Measure LAPIC timer frequency using PIT channel 2 */
|
||||||
uint32_t pit_calc_timer_freq(void)
|
uint32_t _pit_calc_timer_freq(void)
|
||||||
{
|
{
|
||||||
uint32_t t_start, t_end;
|
uint32_t t_start, t_end;
|
||||||
|
|
||||||
|
@ -95,7 +98,7 @@ class Genode::Timer : public Mmio
|
||||||
write<Tmr_lvt::Timer_mode>(0);
|
write<Tmr_lvt::Timer_mode>(0);
|
||||||
|
|
||||||
/* Calculate timer frequency */
|
/* Calculate timer frequency */
|
||||||
_tics_per_ms = pit_calc_timer_freq();
|
_tics_per_ms = _pit_calc_timer_freq();
|
||||||
PINF("LAPIC: timer frequency %u kHz", _tics_per_ms);
|
PINF("LAPIC: timer frequency %u kHz", _tics_per_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#ifndef _GDT_H_
|
#ifndef _GDT_H_
|
||||||
#define _GDT_H_
|
#define _GDT_H_
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
#include <pseudo_descriptor.h>
|
#include <pseudo_descriptor.h>
|
||||||
#include <mtc_util.h>
|
#include <mtc_util.h>
|
||||||
|
|
||||||
|
@ -40,9 +41,10 @@ class Genode::Gdt
|
||||||
*/
|
*/
|
||||||
static void load(addr_t const virt_base)
|
static void load(addr_t const virt_base)
|
||||||
{
|
{
|
||||||
asm volatile ("lgdt %0" : : "m" (Pseudo_descriptor
|
addr_t const start = (addr_t)&_mt_gdt_start;
|
||||||
(_mt_gdt_end - _mt_gdt_start - 1,
|
uint16_t const limit = _mt_gdt_end - _mt_gdt_start - 1;
|
||||||
_virt_mtc_addr(virt_base, (addr_t)&_mt_gdt_start))));
|
uint64_t const base = _virt_mtc_addr(virt_base, start);
|
||||||
|
asm volatile ("lgdt %0" :: "m" (Pseudo_descriptor(limit, base)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace Genode
|
||||||
};
|
};
|
||||||
|
|
||||||
class Level_4_translation_table;
|
class Level_4_translation_table;
|
||||||
class PML4_table;
|
class Pml4_table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IA-32e page directory template.
|
* IA-32e page directory template.
|
||||||
|
@ -66,7 +66,7 @@ namespace Genode
|
||||||
Page_directory<Level_3_translation_table,
|
Page_directory<Level_3_translation_table,
|
||||||
SIZE_LOG2_1GB, SIZE_LOG2_512GB>;
|
SIZE_LOG2_1GB, SIZE_LOG2_512GB>;
|
||||||
|
|
||||||
using Translation_table = PML4_table;
|
using Translation_table = Pml4_table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IA-32e common descriptor.
|
* IA-32e common descriptor.
|
||||||
|
@ -152,34 +152,33 @@ class Genode::Level_4_translation_table
|
||||||
|
|
||||||
typename Descriptor::access_t _entries[MAX_ENTRIES];
|
typename Descriptor::access_t _entries[MAX_ENTRIES];
|
||||||
|
|
||||||
inline bool _aligned(addr_t const a, size_t const alignm_log2) {
|
|
||||||
return a == ((a >> alignm_log2) << alignm_log2); }
|
|
||||||
|
|
||||||
struct Insert_func
|
struct Insert_func
|
||||||
{
|
{
|
||||||
Page_flags const & flags;
|
Page_flags const & flags;
|
||||||
Page_slab * slab;
|
Page_slab * slab;
|
||||||
|
|
||||||
Insert_func(Page_flags const & flags,
|
Insert_func(Page_flags const & flags,
|
||||||
Page_slab * slab) : flags(flags), slab(slab) { }
|
Page_slab * slab) : flags(flags), slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
size_t const size,
|
||||||
size_t const size,
|
Descriptor::access_t &desc)
|
||||||
Descriptor::access_t &desc)
|
{
|
||||||
|
if ((vo & ~PAGE_MASK) || (pa & ~PAGE_MASK) ||
|
||||||
|
size < PAGE_SIZE)
|
||||||
{
|
{
|
||||||
if ((vo & ~PAGE_MASK) || (pa & ~PAGE_MASK) ||
|
throw Invalid_range();
|
||||||
size < PAGE_SIZE)
|
|
||||||
throw Invalid_range();
|
|
||||||
|
|
||||||
Descriptor::access_t table_entry =
|
|
||||||
Descriptor::create(flags, pa);
|
|
||||||
if (Descriptor::present(desc) &&
|
|
||||||
Descriptor::clear_mmu_flags(desc) != table_entry)
|
|
||||||
throw Double_insertion();
|
|
||||||
|
|
||||||
desc = table_entry;
|
|
||||||
}
|
}
|
||||||
|
Descriptor::access_t table_entry =
|
||||||
|
Descriptor::create(flags, pa);
|
||||||
|
|
||||||
|
if (Descriptor::present(desc) &&
|
||||||
|
Descriptor::clear_mmu_flags(desc) != table_entry)
|
||||||
|
{
|
||||||
|
throw Double_insertion();
|
||||||
|
}
|
||||||
|
desc = table_entry;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Remove_func
|
struct Remove_func
|
||||||
|
@ -188,11 +187,10 @@ class Genode::Level_4_translation_table
|
||||||
|
|
||||||
Remove_func(Page_slab * slab) : slab(slab) { }
|
Remove_func(Page_slab * slab) : slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
size_t const size,
|
||||||
size_t const size,
|
Descriptor::access_t &desc)
|
||||||
Descriptor::access_t &desc) {
|
{ desc = 0; }
|
||||||
desc = 0; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
|
@ -223,21 +221,16 @@ class Genode::Level_4_translation_table
|
||||||
* IA-32e page table (Level 4)
|
* IA-32e page table (Level 4)
|
||||||
*
|
*
|
||||||
* A page table consists of 512 entries that each maps a 4KB page
|
* A page table consists of 512 entries that each maps a 4KB page
|
||||||
* frame.
|
* frame. For further details refer to Intel SDM Vol. 3A, table 4-19.
|
||||||
* For further details refer to Intel SDM Vol. 3A, table 4-19.
|
|
||||||
*/
|
*/
|
||||||
Level_4_translation_table()
|
Level_4_translation_table()
|
||||||
{
|
{
|
||||||
if (!_aligned((addr_t)this, ALIGNM_LOG2))
|
if (!aligned(this, ALIGNM_LOG2)) throw Misaligned();
|
||||||
throw Misaligned();
|
|
||||||
|
|
||||||
memset(&_entries, 0, sizeof(_entries));
|
memset(&_entries, 0, sizeof(_entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns True if table does not contain any page mappings.
|
* Returns True if table does not contain any page mappings.
|
||||||
*
|
|
||||||
* \return false if an entry is present, True otherwise
|
|
||||||
*/
|
*/
|
||||||
bool empty()
|
bool empty()
|
||||||
{
|
{
|
||||||
|
@ -258,11 +251,8 @@ class Genode::Level_4_translation_table
|
||||||
* \param flags mapping flags
|
* \param flags mapping flags
|
||||||
* \param slab second level page slab allocator
|
* \param slab second level page slab allocator
|
||||||
*/
|
*/
|
||||||
void insert_translation(addr_t vo,
|
void insert_translation(addr_t vo, addr_t pa, size_t size,
|
||||||
addr_t pa,
|
Page_flags const & flags, Page_slab * slab)
|
||||||
size_t size,
|
|
||||||
Page_flags const & flags,
|
|
||||||
Page_slab * slab)
|
|
||||||
{
|
{
|
||||||
this->_range_op(vo, pa, size, Insert_func(flags, slab));
|
this->_range_op(vo, pa, size, Insert_func(flags, slab));
|
||||||
}
|
}
|
||||||
|
@ -359,16 +349,12 @@ class Genode::Page_directory
|
||||||
addr_t const pa)
|
addr_t const pa)
|
||||||
{
|
{
|
||||||
/* XXX: Set memory type depending on active PAT */
|
/* XXX: Set memory type depending on active PAT */
|
||||||
return Base::create(flags)
|
return Base::create(flags) | Pa::masked(pa);
|
||||||
| Pa::masked(pa);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typename Base_descriptor::access_t _entries[MAX_ENTRIES];
|
typename Base_descriptor::access_t _entries[MAX_ENTRIES];
|
||||||
|
|
||||||
inline bool _aligned(addr_t const a, size_t const alignm_log2) {
|
|
||||||
return a == ((a >> alignm_log2) << alignm_log2); }
|
|
||||||
|
|
||||||
struct Insert_func
|
struct Insert_func
|
||||||
{
|
{
|
||||||
Page_flags const & flags;
|
Page_flags const & flags;
|
||||||
|
@ -377,20 +363,22 @@ class Genode::Page_directory
|
||||||
Insert_func(Page_flags const & flags,
|
Insert_func(Page_flags const & flags,
|
||||||
Page_slab * slab) : flags(flags), slab(slab) { }
|
Page_slab * slab) : flags(flags), slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
|
||||||
size_t const size,
|
size_t const size,
|
||||||
typename Base_descriptor::access_t &desc)
|
typename Base_descriptor::access_t &desc)
|
||||||
{
|
{
|
||||||
/* can we insert a large page mapping? */
|
/* can we insert a large page mapping? */
|
||||||
if (!((vo & ~PAGE_MASK) || (pa & ~PAGE_MASK) ||
|
if (!((vo & ~PAGE_MASK) || (pa & ~PAGE_MASK) ||
|
||||||
size < PAGE_SIZE)) {
|
size < PAGE_SIZE))
|
||||||
|
{
|
||||||
typename Base_descriptor::access_t table_entry =
|
typename Base_descriptor::access_t table_entry =
|
||||||
Page_descriptor::create(flags, pa);
|
Page_descriptor::create(flags, pa);
|
||||||
|
|
||||||
if (Base_descriptor::present(desc) &&
|
if (Base_descriptor::present(desc) &&
|
||||||
Base_descriptor::clear_mmu_flags(desc) != table_entry)
|
Base_descriptor::clear_mmu_flags(desc) != table_entry)
|
||||||
|
{
|
||||||
throw Double_insertion();
|
throw Double_insertion();
|
||||||
|
}
|
||||||
|
|
||||||
desc = table_entry;
|
desc = table_entry;
|
||||||
return;
|
return;
|
||||||
|
@ -405,10 +393,10 @@ class Genode::Page_directory
|
||||||
/* create and link next level table */
|
/* create and link next level table */
|
||||||
table = new (slab) ENTRY();
|
table = new (slab) ENTRY();
|
||||||
ENTRY * phys_addr = (ENTRY*) slab->phys_addr(table);
|
ENTRY * phys_addr = (ENTRY*) slab->phys_addr(table);
|
||||||
|
addr_t const pa = (addr_t)(phys_addr ? phys_addr : table);
|
||||||
desc = (typename Base_descriptor::access_t)
|
desc = (typename Base_descriptor::access_t)
|
||||||
Table_descriptor::create(flags,
|
Table_descriptor::create(flags, pa);
|
||||||
(addr_t)(phys_addr ? phys_addr
|
|
||||||
: table));
|
|
||||||
} else if (Base_descriptor::maps_page(desc)) {
|
} else if (Base_descriptor::maps_page(desc)) {
|
||||||
throw Double_insertion();
|
throw Double_insertion();
|
||||||
} else {
|
} else {
|
||||||
|
@ -431,8 +419,7 @@ class Genode::Page_directory
|
||||||
|
|
||||||
Remove_func(Page_slab * slab) : slab(slab) { }
|
Remove_func(Page_slab * slab) : slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
|
||||||
size_t const size,
|
size_t const size,
|
||||||
typename Base_descriptor::access_t &desc)
|
typename Base_descriptor::access_t &desc)
|
||||||
{
|
{
|
||||||
|
@ -445,8 +432,8 @@ class Genode::Page_directory
|
||||||
Table_descriptor::Pa::masked(desc);
|
Table_descriptor::Pa::masked(desc);
|
||||||
ENTRY* table = (ENTRY*) slab->virt_addr(phys_addr);
|
ENTRY* table = (ENTRY*) slab->virt_addr(phys_addr);
|
||||||
table = table ? table : (ENTRY*)phys_addr;
|
table = table ? table : (ENTRY*)phys_addr;
|
||||||
table->remove_translation(vo - (vo & PAGE_MASK),
|
addr_t const table_vo = vo - (vo & PAGE_MASK);
|
||||||
size, slab);
|
table->remove_translation(table_vo, size, slab);
|
||||||
if (table->empty()) {
|
if (table->empty()) {
|
||||||
destroy(slab, table);
|
destroy(slab, table);
|
||||||
desc = 0;
|
desc = 0;
|
||||||
|
@ -460,7 +447,8 @@ class Genode::Page_directory
|
||||||
void _range_op(addr_t vo, addr_t pa, size_t size, FUNC &&func)
|
void _range_op(addr_t vo, addr_t pa, size_t size, FUNC &&func)
|
||||||
{
|
{
|
||||||
for (size_t i = vo >> PAGE_SIZE_LOG2; size > 0;
|
for (size_t i = vo >> PAGE_SIZE_LOG2; size > 0;
|
||||||
i = vo >> PAGE_SIZE_LOG2) {
|
i = vo >> PAGE_SIZE_LOG2)
|
||||||
|
{
|
||||||
addr_t end = (vo + PAGE_SIZE) & PAGE_MASK;
|
addr_t end = (vo + PAGE_SIZE) & PAGE_MASK;
|
||||||
size_t sz = min(size, end-vo);
|
size_t sz = min(size, end-vo);
|
||||||
|
|
||||||
|
@ -482,9 +470,7 @@ class Genode::Page_directory
|
||||||
|
|
||||||
Page_directory()
|
Page_directory()
|
||||||
{
|
{
|
||||||
if (!_aligned((addr_t)this, ALIGNM_LOG2))
|
if (!aligned(this, ALIGNM_LOG2)) throw Misaligned();
|
||||||
throw Misaligned();
|
|
||||||
|
|
||||||
memset(&_entries, 0, sizeof(_entries));
|
memset(&_entries, 0, sizeof(_entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,11 +498,8 @@ class Genode::Page_directory
|
||||||
* \param flags mapping flags
|
* \param flags mapping flags
|
||||||
* \param slab second level page slab allocator
|
* \param slab second level page slab allocator
|
||||||
*/
|
*/
|
||||||
void insert_translation(addr_t vo,
|
void insert_translation(addr_t vo, addr_t pa, size_t size,
|
||||||
addr_t pa,
|
Page_flags const & flags, Page_slab * slab)
|
||||||
size_t size,
|
|
||||||
Page_flags const & flags,
|
|
||||||
Page_slab * slab)
|
|
||||||
{
|
{
|
||||||
_range_op(vo, pa, size, Insert_func(flags, slab));
|
_range_op(vo, pa, size, Insert_func(flags, slab));
|
||||||
}
|
}
|
||||||
|
@ -535,7 +518,7 @@ class Genode::Page_directory
|
||||||
} __attribute__((aligned(1 << ALIGNM_LOG2)));
|
} __attribute__((aligned(1 << ALIGNM_LOG2)));
|
||||||
|
|
||||||
|
|
||||||
class Genode::PML4_table
|
class Genode::Pml4_table
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -556,16 +539,12 @@ class Genode::PML4_table
|
||||||
static access_t create(Page_flags const &flags, addr_t const pa)
|
static access_t create(Page_flags const &flags, addr_t const pa)
|
||||||
{
|
{
|
||||||
/* XXX: Set memory type depending on active PAT */
|
/* XXX: Set memory type depending on active PAT */
|
||||||
return Common_descriptor::create(flags)
|
return Common_descriptor::create(flags) | Pa::masked(pa);
|
||||||
| Pa::masked(pa);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typename Descriptor::access_t _entries[MAX_ENTRIES];
|
typename Descriptor::access_t _entries[MAX_ENTRIES];
|
||||||
|
|
||||||
inline bool _aligned(addr_t const a, size_t const alignm_log2) {
|
|
||||||
return a == ((a >> alignm_log2) << alignm_log2); }
|
|
||||||
|
|
||||||
using ENTRY = Level_2_translation_table;
|
using ENTRY = Level_2_translation_table;
|
||||||
|
|
||||||
struct Insert_func
|
struct Insert_func
|
||||||
|
@ -576,8 +555,7 @@ class Genode::PML4_table
|
||||||
Insert_func(Page_flags const & flags,
|
Insert_func(Page_flags const & flags,
|
||||||
Page_slab * slab) : flags(flags), slab(slab) { }
|
Page_slab * slab) : flags(flags), slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
|
||||||
size_t const size,
|
size_t const size,
|
||||||
Descriptor::access_t &desc)
|
Descriptor::access_t &desc)
|
||||||
{
|
{
|
||||||
|
@ -590,9 +568,8 @@ class Genode::PML4_table
|
||||||
/* create and link next level table */
|
/* create and link next level table */
|
||||||
table = new (slab) ENTRY();
|
table = new (slab) ENTRY();
|
||||||
ENTRY * phys_addr = (ENTRY*) slab->phys_addr(table);
|
ENTRY * phys_addr = (ENTRY*) slab->phys_addr(table);
|
||||||
desc = Descriptor::create(flags,
|
addr_t const pa = (addr_t)(phys_addr ? phys_addr : table);
|
||||||
(addr_t)(phys_addr ? phys_addr
|
desc = Descriptor::create(flags, pa);
|
||||||
: table));
|
|
||||||
} else {
|
} else {
|
||||||
Descriptor::merge_access_rights(desc, flags);
|
Descriptor::merge_access_rights(desc, flags);
|
||||||
ENTRY * phys_addr = (ENTRY*)
|
ENTRY * phys_addr = (ENTRY*)
|
||||||
|
@ -602,8 +579,8 @@ class Genode::PML4_table
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert translation */
|
/* insert translation */
|
||||||
table->insert_translation(vo - (vo & PAGE_MASK),
|
addr_t const table_vo = vo - (vo & PAGE_MASK);
|
||||||
pa, size, flags, slab);
|
table->insert_translation(table_vo, pa, size, flags, slab);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -613,8 +590,7 @@ class Genode::PML4_table
|
||||||
|
|
||||||
Remove_func(Page_slab * slab) : slab(slab) { }
|
Remove_func(Page_slab * slab) : slab(slab) { }
|
||||||
|
|
||||||
void operator () (addr_t const vo,
|
void operator () (addr_t const vo, addr_t const pa,
|
||||||
addr_t const pa,
|
|
||||||
size_t const size,
|
size_t const size,
|
||||||
Descriptor::access_t &desc)
|
Descriptor::access_t &desc)
|
||||||
{
|
{
|
||||||
|
@ -624,8 +600,8 @@ class Genode::PML4_table
|
||||||
Descriptor::Pa::masked(desc);
|
Descriptor::Pa::masked(desc);
|
||||||
ENTRY* table = (ENTRY*) slab->virt_addr(phys_addr);
|
ENTRY* table = (ENTRY*) slab->virt_addr(phys_addr);
|
||||||
table = table ? table : (ENTRY*)phys_addr;
|
table = table ? table : (ENTRY*)phys_addr;
|
||||||
table->remove_translation(vo - (vo & PAGE_MASK), size,
|
addr_t const table_vo = vo - (vo & PAGE_MASK);
|
||||||
slab);
|
table->remove_translation(table_vo, size, slab);
|
||||||
if (table->empty()) {
|
if (table->empty()) {
|
||||||
destroy(slab, table);
|
destroy(slab, table);
|
||||||
desc = 0;
|
desc = 0;
|
||||||
|
@ -658,11 +634,9 @@ class Genode::PML4_table
|
||||||
static constexpr size_t MIN_PAGE_SIZE_LOG2 = SIZE_LOG2_4KB;
|
static constexpr size_t MIN_PAGE_SIZE_LOG2 = SIZE_LOG2_4KB;
|
||||||
static constexpr size_t ALIGNM_LOG2 = SIZE_LOG2_4KB;
|
static constexpr size_t ALIGNM_LOG2 = SIZE_LOG2_4KB;
|
||||||
|
|
||||||
PML4_table()
|
Pml4_table()
|
||||||
{
|
{
|
||||||
if (!_aligned((addr_t)this, ALIGNM_LOG2))
|
if (!aligned(this, ALIGNM_LOG2)) throw Misaligned();
|
||||||
throw Misaligned();
|
|
||||||
|
|
||||||
memset(&_entries, 0, sizeof(_entries));
|
memset(&_entries, 0, sizeof(_entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,11 +664,8 @@ class Genode::PML4_table
|
||||||
* \param flags mapping flags
|
* \param flags mapping flags
|
||||||
* \param slab second level page slab allocator
|
* \param slab second level page slab allocator
|
||||||
*/
|
*/
|
||||||
void insert_translation(addr_t vo,
|
void insert_translation(addr_t vo, addr_t pa, size_t size,
|
||||||
addr_t pa,
|
Page_flags const & flags, Page_slab * slab)
|
||||||
size_t size,
|
|
||||||
Page_flags const & flags,
|
|
||||||
Page_slab * slab)
|
|
||||||
{
|
{
|
||||||
_range_op(vo, pa, size, Insert_func(flags, slab));
|
_range_op(vo, pa, size, Insert_func(flags, slab));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,30 +21,29 @@ Thread::Thread(unsigned const priority, unsigned const quota,
|
||||||
char const * const label)
|
char const * const label)
|
||||||
:
|
:
|
||||||
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
|
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
|
||||||
_utcb_phys(0), _signal_receiver(0), _label(label) {}
|
_utcb_phys(0), _signal_receiver(0), _label(label) { }
|
||||||
|
|
||||||
|
|
||||||
void Thread::exception(unsigned const cpu)
|
void Thread::exception(unsigned const cpu)
|
||||||
{
|
{
|
||||||
if (trapno == PAGE_FAULT) {
|
switch (trapno) {
|
||||||
|
case PAGE_FAULT:
|
||||||
_mmu_exception();
|
_mmu_exception();
|
||||||
return;
|
return;
|
||||||
} else if (trapno == NO_MATH_COPROC) {
|
case NO_MATH_COPROC:
|
||||||
if (_cpu->retry_fpu_instr(&_lazy_state)) { return; }
|
if (_cpu->retry_fpu_instr(&_lazy_state)) { return; }
|
||||||
PWRN("fpu error");
|
PWRN("%s -> %s: FPU error", pd_label(), label());
|
||||||
_stop();
|
_stop();
|
||||||
return;
|
return;
|
||||||
}
|
case SUPERVISOR_CALL:
|
||||||
if (trapno == SUPERVISOR_CALL) {
|
|
||||||
_call();
|
_call();
|
||||||
return;
|
return;
|
||||||
} else if (trapno >= INTERRUPTS_START && trapno <= INTERRUPTS_END) {
|
}
|
||||||
|
if (trapno >= INTERRUPTS_START && trapno <= INTERRUPTS_END) {
|
||||||
_interrupt(cpu);
|
_interrupt(cpu);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
PWRN("%s -> %s: triggered an unknown exception %lu with error code %lu",
|
|
||||||
pd_label(), label(), trapno, errcode);
|
|
||||||
_stop();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
PWRN("%s -> %s: triggered unknown exception %lu with error code %lu",
|
||||||
|
pd_label(), label(), trapno, errcode);
|
||||||
|
_stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
#include <pseudo_descriptor.h>
|
#include <pseudo_descriptor.h>
|
||||||
#include <mtc_util.h>
|
#include <mtc_util.h>
|
||||||
|
#include <idt.h>
|
||||||
#include "idt.h"
|
|
||||||
|
|
||||||
extern int _mt_idt;
|
extern int _mt_idt;
|
||||||
extern int _mt_isrs;
|
extern int _mt_isrs;
|
||||||
|
@ -46,6 +46,7 @@ void Idt::setup(addr_t const virt_base)
|
||||||
|
|
||||||
void Idt::load(addr_t const virt_base)
|
void Idt::load(addr_t const virt_base)
|
||||||
{
|
{
|
||||||
asm volatile ("lidt %0" : : "m" (Pseudo_descriptor (sizeof(_table) - 1,
|
uint16_t const limit = sizeof(_table) - 1;
|
||||||
_virt_mtc_addr(virt_base, (addr_t)&_mt_idt))));
|
uint64_t const base = _virt_mtc_addr(virt_base, (addr_t)&_mt_idt);
|
||||||
|
asm volatile ("lidt %0" : : "m" (Pseudo_descriptor(limit, base)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,30 +81,30 @@
|
||||||
*/
|
*/
|
||||||
.global _mt_isrs
|
.global _mt_isrs
|
||||||
_mt_isrs:
|
_mt_isrs:
|
||||||
_exception 0
|
_exception 0
|
||||||
_exception 1
|
_exception 1
|
||||||
_exception 2
|
_exception 2
|
||||||
_exception 3
|
_exception 3
|
||||||
_exception 4
|
_exception 4
|
||||||
_exception 5
|
_exception 5
|
||||||
_exception 6
|
_exception 6
|
||||||
_exception 7
|
_exception 7
|
||||||
_exception_with_code 8
|
_exception_with_code 8
|
||||||
_exception 9
|
_exception 9
|
||||||
_exception_with_code 10
|
_exception_with_code 10
|
||||||
_exception_with_code 11
|
_exception_with_code 11
|
||||||
_exception_with_code 12
|
_exception_with_code 12
|
||||||
_exception_with_code 13
|
_exception_with_code 13
|
||||||
_exception_with_code 14
|
_exception_with_code 14
|
||||||
_exception 15
|
_exception 15
|
||||||
_exception 16
|
_exception 16
|
||||||
_exception_with_code 17
|
_exception_with_code 17
|
||||||
_exception 18
|
_exception 18
|
||||||
_exception 19
|
_exception 19
|
||||||
|
|
||||||
.set vec, 20
|
.set vec, 20
|
||||||
.rept 236
|
.rept 236
|
||||||
_exception vec
|
_exception vec
|
||||||
.set vec, vec + 1
|
.set vec, vec + 1
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
#include <mtc_util.h>
|
#include <mtc_util.h>
|
||||||
|
#include <tss.h>
|
||||||
#include "tss.h"
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ extern int _mt_kernel_interrupt_stack;
|
||||||
|
|
||||||
void Tss::setup(addr_t const virt_base)
|
void Tss::setup(addr_t const virt_base)
|
||||||
{
|
{
|
||||||
addr_t const stack_addr = _virt_mtc_addr(virt_base,
|
addr_t const stack_addr =
|
||||||
(addr_t)&_mt_kernel_interrupt_stack);
|
_virt_mtc_addr(virt_base, (addr_t)&_mt_kernel_interrupt_stack);
|
||||||
|
|
||||||
this->rsp0 = stack_addr;
|
this->rsp0 = stack_addr;
|
||||||
this->rsp1 = stack_addr;
|
this->rsp1 = stack_addr;
|
||||||
|
|
Loading…
Reference in New Issue