hw: switch page-tables only when necessary

* Instead of always re-load page-tables when a thread context is switched
  only do this when another user PD's thread is the next target,
  core-threads are always executed within the last PD's page-table set
* remove the concept of the mode transition
* instead map the exception vector once in bootstrap code into kernel's
  memory segment
* when a new page directory is constructed for a user PD, copy over the
  top-level kernel segment entries on RISCV and X86, on ARM we use a designated
  page directory register for the kernel segment
* transfer the current CPU id from bootstrap to core/kernel in a register
  to ease first stack address calculation
* align cpu context member of threads and vms, because of x86 constraints
  regarding the stack-pointer loading
* introduce Align_at template for members with alignment constraints
* let the x86 hardware do part of the context saving in ISS, by passing
  the thread context into the TSS before leaving to user-land
* use one exception vector for all ARM platforms including Arm_v6

Fix #2091
This commit is contained in:
Stefan Kalkowski
2017-06-30 12:00:27 +02:00
committed by Christian Helmuth
parent ca60e24ad9
commit 4e97a6511b
97 changed files with 1162 additions and 1966 deletions

View File

@ -25,6 +25,6 @@ extern "C" void init() __attribute__ ((noreturn));
extern "C" void init()
{
Bootstrap::platform().enable_mmu();
Bootstrap::platform().start_core();
Bootstrap::Platform & p = Bootstrap::platform();
p.start_core(p.enable_mmu());
}

View File

@ -135,18 +135,24 @@ Mapping Platform::_load_elf()
core_pd->map_insert(m);
else
ret = m;
/* map start of the text segment as exception vector */
if (segment.flags().x && !segment.flags().w) {
Memory_region e = Hw::Mm::supervisor_exception_vector();
core_pd->map_insert(Mapping((addr_t)phys, e.base, e.size, flags));
}
};
core_elf.for_each_segment(lambda);
return ret;
}
void Platform::start_core()
void Platform::start_core(unsigned cpu_id)
{
typedef void (* Entry)();
typedef void (* Entry)(unsigned);
Entry __attribute__((noreturn)) const entry
= reinterpret_cast<Entry>(core_elf.entry());
entry();
entry(cpu_id);
}

View File

@ -135,8 +135,8 @@ class Bootstrap::Platform
Platform();
void enable_mmu();
void start_core() __attribute__((noreturn));
unsigned enable_mmu();
void start_core(unsigned) __attribute__((noreturn));
};
#endif /* _SRC__BOOTSTRAP__PLATFORM_H_ */

View File

@ -37,13 +37,20 @@ void Bootstrap::Cpu::enable_mmu_and_caches(Genode::addr_t table)
Dacr::write(Dacr::D0::bits(1));
Ttbr_64bit::access_t ttbr0 = Ttbr_64bit::Ba::masked(table);
Ttbr_64bit::access_t ttbr1 = Ttbr_64bit::Ba::masked(table);
Ttbr_64bit::Asid::set(ttbr0, 0);
Ttbr0_64bit::write(ttbr0);
Ttbr1_64bit::write(ttbr1);
Ttbcr::access_t ttbcr = 0;
Ttbcr::T0sz::set(ttbcr, 1);
Ttbcr::T1sz::set(ttbcr, 0);
Ttbcr::Irgn0::set(ttbcr, 1);
Ttbcr::Irgn1::set(ttbcr, 1);
Ttbcr::Orgn0::set(ttbcr, 1);
Ttbcr::Orgn1::set(ttbcr, 1);
Ttbcr::Sh0::set(ttbcr, 0b10);
Ttbcr::Sh1::set(ttbcr, 0b10);
Ttbcr::Eae::set(ttbcr, 1);
Ttbcr::write(ttbcr);

View File

@ -13,8 +13,10 @@
#include <platform.h>
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
Cpu::Sctlr::init();
Cpu::enable_mmu_and_caches((addr_t)core_pd->table_base);
return 0;
}

View File

@ -95,7 +95,7 @@ struct Scu : Genode::Mmio
*
* See ARM's Cortex-A9 MPCore TRM r2p0 in section 5.3.5 for more details
*/
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
using namespace Bootstrap;
@ -162,4 +162,6 @@ void Bootstrap::Platform::enable_mmu()
/* wait for other cores' coherency activation */
smp_coherency_enabled.wait_for(NR_OF_CPUS);
return Cpu::Mpidr::Aff_0::get(Cpu::Mpidr::read());
}

View File

@ -71,7 +71,7 @@ static inline void prepare_hypervisor(Genode::addr_t table)
using Cpu = Hw::Arm_cpu;
/* set hypervisor exception vector */
Cpu::Hvbar::write(0xfff00000); /* FIXME */
Cpu::Hvbar::write(Hw::Mm::hypervisor_exception_vector().base);
/* set hypervisor's translation table */
Cpu::Httbr_64bit::write(table);
@ -152,7 +152,7 @@ static inline void switch_to_supervisor_mode()
}
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
static volatile bool primary_cpu = true;
pic.init_cpu_local();
@ -173,6 +173,8 @@ void Bootstrap::Platform::enable_mmu()
}
cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base);
return Cpu::Mpidr::Aff_0::get(Cpu::Mpidr::read());
}

View File

@ -44,7 +44,7 @@ Bootstrap::Platform::Board::Board()
Aipstz aipstz_2(AIPS_2_MMIO_BASE);
/* set exception vector entry */
Cpu::Mvbar::write(0xfff00000);
Cpu::Mvbar::write(Hw::Mm::system_exception_vector().base);
/* enable coprocessor 10 + 11 access for TZ VMs */
Cpu::Nsacr::access_t v = 0;

View File

@ -23,11 +23,12 @@ Bootstrap::Platform::Board::Board()
Memory_region { UART_2_MMIO_BASE, UART_2_MMIO_SIZE }) { }
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
pic.init_cpu_local();
Cpu::Sctlr::init();
Cpu::Cpsr::init();
cpu.invalidate_data_cache();
cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base);
return 0;
}

View File

@ -20,8 +20,10 @@ Bootstrap::Platform::Board::Board()
: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE } ) {}
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
using Sptbr = Hw::Riscv_cpu::Sptbr;
Sptbr::write(Sptbr::Ppn::masked((addr_t)core_pd->table_base >> 12));
return 0;
}

View File

@ -35,7 +35,7 @@ Bootstrap::Platform::Board::Board()
USB_DWC_OTG_SIZE }) {}
void Bootstrap::Platform::enable_mmu()
unsigned Bootstrap::Platform::enable_mmu()
{
struct Sctlr : Cpu::Sctlr
{
@ -73,13 +73,14 @@ void Bootstrap::Platform::enable_mmu()
/* do not use domains, but permission bits in table */
Cpu::Dacr::write(Cpu::Dacr::D0::bits(1));
Cpu::Ttbcr::write(0);
Cpu::Ttbcr::write(1);
Genode::addr_t table = (Genode::addr_t)core_pd->table_base;
Cpu::Ttbr::access_t ttbr0 = Cpu::Ttbr::Ba::masked(table);
Cpu::Ttbr::Rgn::set(ttbr0, Cpu::Ttbr::CACHEABLE);
Cpu::Ttbr::C::set(ttbr0, 1);
Cpu::Ttbr0::write(ttbr0);
Cpu::Ttbr::access_t ttbr = Cpu::Ttbr::Ba::masked(table);
Cpu::Ttbr::Rgn::set(ttbr, Cpu::Ttbr::CACHEABLE);
Cpu::Ttbr::C::set(ttbr, 1);
Cpu::Ttbr0::write(ttbr);
Cpu::Ttbr1::write(ttbr);
sctlr = Cpu::Sctlr::read();
Cpu::Sctlr::C::set(sctlr, 1);
@ -89,4 +90,6 @@ void Bootstrap::Platform::enable_mmu()
/* invalidate branch predictor */
Cpu::Bpiall::write(0);
return 0;
}

View File

@ -38,8 +38,8 @@ Bootstrap::Platform::Board::Board()
Aipstz aipstz_1(AIPS_1_MMIO_BASE);
Aipstz aipstz_2(AIPS_2_MMIO_BASE);
/* set exception vector entry */
Cpu::Mvbar::write(0xfff00000); //FIXME
/* set monitor mode exception vector entry */
Cpu::Mvbar::write(Hw::Mm::system_exception_vector().base);
/* enable coprocessor 10 + 11 access for TZ VMs */
Cpu::Nsacr::access_t v = 0;

View File

@ -20,6 +20,8 @@
#include <hw/spec/x86_64/cpu.h>
#include <hw/spec/x86_64/x86_64.h>
void Hw::Pml4_table::_invalidate_range(addr_t vo, size_t size) {}
namespace Bootstrap {
struct Pic {};
using Cpu = Hw::X86_64_cpu;

View File

@ -82,9 +82,9 @@
movl %eax, %cr0
/* Set up GDT */
movl $_mt_gdt_ptr+2, %eax
movl $_mt_gdt_start, (%eax)
lgdt _mt_gdt_ptr
movl $__gdt_ptr+2, %eax
movl $__gdt_start, (%eax)
lgdt __gdt_ptr
/* Indirect long jump to 64-bit code */
ljmp $8, $_start64

View File

@ -100,8 +100,11 @@ Bootstrap::Platform::Board::Board()
}
void Bootstrap::Platform::enable_mmu() {
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base)); }
unsigned Bootstrap::Platform::enable_mmu()
{
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base));
return 0;
}
addr_t Bios_data_area::_mmio_base_virt() { return 0x1ff000; }

View File

@ -42,8 +42,11 @@ Bootstrap::Platform::Board::Board()
}
void Bootstrap::Platform::enable_mmu() {
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base)); }
unsigned Bootstrap::Platform::enable_mmu()
{
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base));
return 0;
}
Board::Serial::Serial(Genode::addr_t, Genode::size_t, unsigned baudrate)