diff --git a/repos/base-hw/src/core/include/spec/x86/cpu.h b/repos/base-hw/src/core/include/spec/x86/cpu.h index 72f240909..51fc9ab8d 100644 --- a/repos/base-hw/src/core/include/spec/x86/cpu.h +++ b/repos/base-hw/src/core/include/spec/x86/cpu.h @@ -61,7 +61,7 @@ class Genode::Cpu _tss->setup(Cpu::exception_entry); } - static constexpr addr_t exception_entry = 0x0; /* XXX */ + static constexpr addr_t exception_entry = 0xffff0000; static constexpr addr_t mtc_size = 1 << 13; /** diff --git a/repos/base-hw/src/core/spec/x86_64/idt.cc b/repos/base-hw/src/core/spec/x86_64/idt.cc index ffffc8319..d2f117e54 100644 --- a/repos/base-hw/src/core/spec/x86_64/idt.cc +++ b/repos/base-hw/src/core/spec/x86_64/idt.cc @@ -11,18 +11,18 @@ using namespace Genode; void Idt::setup(addr_t const virt_base) { - int base = _virt_mtc_addr(virt_base, (addr_t)&_mt_isrs); + addr_t base = _virt_mtc_addr(virt_base, (addr_t)&_mt_isrs); + addr_t isr_addr; for (unsigned vec = 0; vec < SIZE_IDT; vec++) { /* ISRs are padded to 4 bytes */ - base = vec * 0xc; + isr_addr = base + vec * 0xc; - _table[vec].offset_15_00 = base & 0xffff; + _table[vec].offset_15_00 = isr_addr & 0xffff; _table[vec].segment_sel = 8; _table[vec].flags = 0x8e00; - /* Assume base to be below address 0x10000 */ - _table[vec].offset_31_16 = 0; - _table[vec].offset_63_32 = 0; + _table[vec].offset_31_16 = (isr_addr >> 16); + _table[vec].offset_63_32 = (isr_addr >> 32); } /* Set DPL of syscall entry to 3 */ diff --git a/repos/base-hw/src/core/spec/x86_64/mode_transition.s b/repos/base-hw/src/core/spec/x86_64/mode_transition.s index a10f1c8d5..6ec74eb67 100644 --- a/repos/base-hw/src/core/spec/x86_64/mode_transition.s +++ b/repos/base-hw/src/core/spec/x86_64/mode_transition.s @@ -29,12 +29,15 @@ .set TRAPNO_OFFSET, 19 * 8 .set CR3_OFFSET, 21 * 8 -/* tss segment limit */ +/* tss segment constants */ .set TSS_LIMIT, 0x68 +.set TSS_TYPE, 0x8900 /* mtc virt addresses */ -.set MT_BUFFER, _mt_buffer - _mt_begin -.set MT_MASTER, _mt_master_context_begin - _mt_begin +.set MT_BASE, 0xffff0000 +.set MT_BUFFER, MT_BASE + (_mt_buffer - _mt_begin) +.set MT_MASTER, MT_BASE + (_mt_master_context_begin - _mt_begin) +.set MT_TSS, MT_BASE + (_mt_tss - _mt_begin) .macro _isr_entry .align 4, 0x90 @@ -130,10 +133,10 @@ _mt_kernel_entry_pic: /* Copy client context RAX to buffer */ - mov %rax, MT_BUFFER + movabs %rax, MT_BUFFER /* Switch to kernel page tables */ - mov MT_MASTER+CR3_OFFSET, %rax + movabs MT_MASTER+CR3_OFFSET, %rax mov %rax, %cr3 /* Save information on interrupt stack frame in client context */ @@ -239,7 +242,7 @@ mov %rax, %cr3 /* Set stack back to mt buffer and restore client RAX */ - mov $MT_BUFFER, %rsp + movabs $MT_BUFFER, %rsp popq %rax iretq @@ -299,10 +302,10 @@ /* GDTE_LONG | GDTE_PRESENT | GDTE_TYPE_DATA_A | GDTE_TYPE_DATA_W | GDTE_NON_SYSTEM */ .long 0x20f300 /* Task segment descriptor */ - .long (_mt_tss - _mt_begin) << 16 | TSS_LIMIT + .long (MT_TSS & 0xffff) << 16 | TSS_LIMIT /* GDTE_PRESENT | GDTE_SYS_TSS */ - .long 0x8900 - .long 0 + .long ((MT_TSS >> 24) & 0xff) << 24 | ((MT_TSS >> 16) & 0xff) | TSS_TYPE + .long MT_TSS >> 32 .long 0 .global _mt_gdt_end _mt_gdt_end: