Commit Graph

171 Commits

Author SHA1 Message Date
Adrian-Ken Rueegsegger
172dec209b hw_x86_64: Restore registers to client context values
Set the stack pointer to the R8 field in the client context to enable
restoring registers by popping values of the stack.

After this step the only remaining registers that do not contain client
values are RAX, RSP and RIP.

Note that the client value of RAX is pop'd to the global buffer region as
the register will still be used by subsequent steps. It will be restored to
the value in the buffer area just prior to resuming client code execution.
2015-03-27 11:53:20 +01:00
Adrian-Ken Rueegsegger
60e799f7b4 hw_x86_64: Set segment registers prior to mode transition
The registers for the ds, es, fs and gs segments are hardcoded to GDT
index 4 with requested privilege level set to 3.
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
fe22858550 hw_x86_64: Adjust EFLAGS of prepared interrupt stack frame
Set I/O privilege level to 3 to allow core to perform port I/O from
userspace. Also make sure the IF flag is cleared for now until interrupt
handling is implemented.
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
40862a81eb hw_x86_64: Prepare interrupt stack frame in mode transition buffer
Setup an IA-32e interrupt stack frame in the mode transition buffer region.
It will be used to perform the mode switch to userspace using the iret
instruction.

For detailed information about the IA-32e interrupt stack frame refer to
Intel SDM Vol. 3A, figure 6-8.
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
4b7a5ced3b hw_x86_64: Declare CPU context offset constants
The constants specify offset values of CPU context member variables as
specified by Genode::Cpu_state [1] and Genode::Cpu::Context [2].

[1] - repos/base/include/x86_64/cpu/cpu_state.h
[2] - repos/base-hw/src/core/include/spec/x86/cpu.h
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
e3f10b5ce2 hw_x86_64: Reserve space for mode transition buffer
Since the buffer stores an IA-32e interrupt stack frame, its size must
be 6 * 8 bytes.
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
03929b3cc9 hw_x86_64: Add 64-bit user code and data segments to GDT
The new entries specify a 64-bit code segment with DPL 3 at index 3 and a
64-bit data segment with DPL 3 at index 4.

These segments are needed for transitioning to user mode.
2015-03-27 11:53:19 +01:00
Adrian-Ken Rueegsegger
51d515c77f hw_x86_64: Explicitly set up segment selectors during boot 2015-03-27 11:53:18 +01:00
Adrian-Ken Rueegsegger
65de09c7a6 hw_x86_64: Reserve space for client context pointer
A pointer to the client context is placed in the mt_client_context_ptr area.
It is used to pass the current client context to the lowlevel mode-switching
assembly code.
2015-03-27 11:53:18 +01:00
Adrian-Ken Rueegsegger
4417fe6201 hw_x86_64: Implementation of IA-32e paging
IA-32e paging translates 48-bit linear addresses to 52-bit physical
addresses. Translation structures are hierarchical and four levels deep.
The current implementation supports regular 4KB and 1 GB and 2 MB large
page mappings.

Memory typing is not yet implemented since the encoded type bits depend
on the active page attribute table (PAT)*.

For detailed information refer to Intel SDM Vol. 3A, section 4.5.

* The default PAT after power up does not allow the encoding of the
  write-combining memory type, see Intel SDM Vol. 3A, section 11.12.4.
* Add common IA-32e paging descriptor type:
    The type represents a table entry and encompasses all fields shared by
    paging structure entries of all four levels (PML4, PDPT, PD and PT).
* Simplify PT entry type by using common descriptor:
    Differing fields are the physical address, the global flag and the memory
    type flags.
* Simplify directory entry type by using common descriptor:
    Page directory entries (PDPT and PD) have an additional 'page size' field
    that specifies if the entry references a next level paging structure or
    represents a large page mapping.
* Simplify PML4 entry type by using common descriptor
    Top-level paging structure entries (PML4) do not have a 'pat' flag and the
    memory type is specified by the 'pwt' and 'pcd' fields only.
* Implement access right merging for directory paging entries
    The access rights for translations are determined by the U/S, R/W and XD
    flags. Paging structure entries that reference other tables must provide
    the superset of rights required for all entries of the referenced table.
    Thus merge access rights of new mappings into existing directory entries to
    grant additional rights if needed.
* Add cr3 register definition:
    The control register 3 is used to set the current page-directory base
    register.
* Add cr3 variable to x86_64 Cpu Context
    The variable designates the address of the top-level paging structure.
* Return current cr3 value as translation table base
* Set context cr3 value on translation table assignment
* Implement switch to virtual mode in kernel
    Activate translation table in init_virt_kernel function by updating the
    cr3 register.
* Ignore accessed and dirty flags when comparing existing table entries
    These flags can be set by the MMU and must be disregarded.
2015-03-27 11:53:18 +01:00
Reto Buerki
c7cadf52a6 hw_x86_64: setup ISR and IDT
* Add isr.s assembler file:
    The file declares an array of Interrupt Service Routines (ISR) to handle
    the exception vectors from 0 to 19, see Intel SDM Vol. 3A, section
    6.3.1.
* Add Idt class:
  * The class Genode::Idt represents an Interrupt Descriptor Table as
    specified by Intel SDM Vol. 3A, section 6.10.
  * The setup function initializes the IDT with 20 entries using the ISR
    array defined in the isr.s assembly file.
* Setup and load IDT in Genode::Cpu ctor:
    The Idt::setup function is only executed once on the BSP.
* Declare ISRs for interrupts 20-255
* Set IDT size to 256
2015-03-27 11:53:18 +01:00
Reto Buerki
6e0f1a4466 hw_x86_64: Adjust size of _mt_master_context
The CPU state in IA-32e mode consists of 20 64-bit registers.
2015-03-27 11:53:18 +01:00
Reto Buerki
0f624cdde7 hw_x86_64: Perform indirect long jump to 64-bit code 2015-03-27 11:53:18 +01:00
Reto Buerki
15d0e86592 hw_x86_64: Load Global Descriptor Table register 2015-03-27 11:53:17 +01:00
Reto Buerki
27191b17ce hw_x86_64: Declare Global Descriptor Table (GDT) in .data
The table specifies a 64-bit code segment descriptor at index 1, a
64-bit data segment descriptor at index 2 and a task segment descriptor
at index 3.
2015-03-27 11:53:17 +01:00
Reto Buerki
59bba7624f hw_x86_64: Set system control flags of cr0 register
Enable paging, write protection, caching and native FPU error reporting,
see Intel SDM Vol. 3A, section 2.5.
2015-03-27 11:53:17 +01:00
Reto Buerki
032fc3b190 hw_x86_64: Enable IA-32e mode and execute-disable
Set bits 8 (LME) and 11 (NXE) in the IA32_EFER MSR to enable IA-32e mode
and execute-disable.
2015-03-27 11:53:17 +01:00
Reto Buerki
d23cd7e5ff hw_x86_64: Load initial pagetable address into cr3 2015-03-27 11:53:17 +01:00
Reto Buerki
bafb893a70 hw_x86_64: Declare initial pagetables in .data segment
The table specifies the initial identity mapping for the memory region
from 2 MiB to 4 MiB using one 2 MiB mapping.
2015-03-27 11:53:17 +01:00
Reto Buerki
be430b9648 hw_x86_64: Enable Physical Address Extension (PAE)
This is a prerequisite for IA-32e mode.
2015-03-27 11:53:16 +01:00
Norman Feske
a974726e26 hw: skeleton for building on x86_64
This patch contains the initial code needed to build and bootstrap the
base-hw kernel on x86 64-bit platforms. It gets stuck earlier
because the binary contains 64-bit instructions, but it is started in
32-bit mode. The initial setup of page tables and switch to long mode is
still missing from the crt0 code.
2015-03-27 11:53:16 +01:00