Commit Graph

63 Commits

Author SHA1 Message Date
Reto Buerki
28b5e67a8c Update or add hw_x86_64 copyright headers 2015-03-27 11:53:32 +01:00
Reto Buerki
69a58c4bd5 hw_x86_64: Set EFLAGS IF, IOPL bits in Cpu::init_thread
Enable interrupts for all threads, set I/O privilege level (IOPL) to 3
for core threads to allow UART access.
2015-03-27 11:53:32 +01:00
Adrian-Ken Rueegsegger
7ce8464b3a hw_x86_64: Enable FPU support
* Enable the use of the FXSAVE and FXRSTOR instructions, see Intel SDM
  Vol. 3C, section 2.5.
* The state of the x87 floating point unit (FPU) is loaded and saved on
  demand.
* Make the cr0 control register accessible in the Cpu class. This is in
  preparation of the upcoming FPU management.
* Access to the FPU is disabled by setting the Task Switch flag in the cr0
  register.
* Access to the FPU is enabled by clearing the Task Switch flag in the cr0
  register.
* Implement FPU initialization
* Add is_fpu_enabled helper function
* Add pointer to CPU lazy state to CPU class
* Init FPU when finishing kernel initialization
* Add function to retry FPU instruction:
    Similar to the ARM mechanism to retry undefined instructions, implement a
    function for retrying an FPU instruction. If a floating-point instruction
    causes an #NM exception due to the FPU being disabled, it can be retried
    after the correct FPU state is restored, saving the current state and
    enabling the FPU in the process.
* Disable FPU when switching to different user context:
    This enables lazy save/restore of the FPU since trying to execute a
    floating point instruction when the FPU is disabled will cause a #NM
    exception.
* Declare constant for #NM exception
* Retry FPU instruction on #NM exception
* Assure alignment of FXSAVE area:
    The FXSAVE area is 512-byte memory region that must be 16-byte aligned. As
    it turns out the alignment attribute is not honored in all cases so add a
    workaround to assure the alignment constraint is met by manually rounding
    the start of the FXSAVE area to the next 16-byte boundary if necessary.
2015-03-27 11:53:31 +01:00
Reto Buerki
4e259f7b1e hw_x86_64: Implement LAPIC-based kernel timer
The LAPIC timer is programmed in one-shot mode with vector 32
(Board::TIMER_VECTOR_KERNEL). The timer frequency is measured using PIT
channel 2 as reference (50ms delay).

Disable PIT timer channel 0 since BIOS programs it to fire periodically.
This avoids potential spurious timer interrupts.
2015-03-27 11:53:31 +01:00
Reto Buerki
a21959fc26 hw_x86_64: Implement APIC-based PIC driver
The implementation initializes the Local APIC (LAPIC) of CPU 0 in xapic
mode (mmio register access) and uses the I/O APIC to remap, mask and
unmask hardware IRQs. The remapping offset of IRQs is 48.

Also initialize the legacy PIC and mask all interrupts in order to
disable it.

For more information about LAPIC and I/O APIC see Intel SDM Vol. 3A,
chapter 10 and the Intel 82093AA I/O Advanced Programmable Interrupt
Controller (IOAPIC) specification

Set bit 9 in the RFLAGS register of user CPU context to enable
interrupts on kernel- to usermode switch.
2015-03-27 11:53:31 +01:00
Reto Buerki
cf100f96af hw_x86_64: Add x86-specific board.h file
The file specifies constants for the LAPIC, I/O APIC MMIO regions plus
the interrupt remapping offset and timer vectors.
2015-03-27 11:53:30 +01:00
Reto Buerki
b75b1902f2 hw_x86_64: Provide inb and outb functions for port I/O
The port_io.h file provides the inb and outb functions to perform port
I/O operations.
2015-03-27 11:53:30 +01:00
Reto Buerki
1b3871a3f0 hw_x86_64: Move exception_entry to 0xffff0000
The location in memory is arbitrary but we use the same address as the
ARM architecture. Adjust references to virtual addresses in the mode
transition pages to cope with 64-bit values.
2015-03-27 11:53:30 +01:00
Reto Buerki
d553d38ecf hw_x86_64: Model cr2 register in CPU state
Make the cr2 control register accessible in the Cpu class. The register
is needed to retrieve the linear address that caused a page fault.
2015-03-27 11:53:29 +01:00
Reto Buerki
9c44d32dd9 hw_x86_64: Add virt_base paramater to Tss::setup function
The stack pointers (RSP) for privilege levels 0-2 must be setup using an
address in the mtc region to make stack switching work for non-core
threads.
2015-03-27 11:53:27 +01:00
Reto Buerki
a5efe04656 hw_x86_64: Add virt_base paramater to Idt::setup function
Use parameter instead of class member variable because it would get
stored into the mtc region otherwise. In a further iteration only the
actual IDT should be saved into the mtc, not the complete class
instance. Currently the class instance size is equal to the IDT table
size.
2015-03-27 11:53:27 +01:00
Reto Buerki
1102b2b562 hw_x86_64: Calculate limit using _mt_gdt_end in Gdt::load 2015-03-27 11:53:27 +01:00
Reto Buerki
6f5ea78a51 hw_x86_64: Prefix gdt labels with _mt
Streamline the naming by prepending the _mt prefix to the gdt labels.
2015-03-27 11:53:26 +01:00
Reto Buerki
69e820e4e3 hw_x86_64: Reload GDTR in Genode::Cpu::init_thread
The GDT reload must happen after the page tables mapping the mtc region
is active, that's why it cannot be done in the Genode::Cpu ctor.
2015-03-27 11:53:26 +01:00
Reto Buerki
968ab15bbb hw_x86_64: Add Genode::Gdt class
The class provides the load() function which reloads the GDTR with the
GDT address in the mtc region. This is needed to make the segments
accessible to non-core threads.

Make the _gdt_start label global to use it in the call to
_virt_mtc_addr().
2015-03-27 11:53:26 +01:00
Reto Buerki
251b270e4b hw_x86_64: Factor out _virt_mtc_addr to mtc_util.h header 2015-03-27 11:53:26 +01:00
Reto Buerki
cfe89996e8 hw_x86_64: Factor out pseudo descriptor class to own header 2015-03-27 11:53:26 +01:00
Reto Buerki
00921e4a5c hw_x86_64: Create Tss instance in mtc region
Use the _mt_tss label and the placement new operator to create the
Tss class instance in the mtc region. Update the hard-coded
TSS base address to use the virtual mtc address.
2015-03-27 11:53:25 +01:00
Reto Buerki
34a25d3160 hw_x86_64: Make Tss member functions non-static
Add appropriate Tss object to Genode::Cpu class.
2015-03-27 11:53:25 +01:00
Reto Buerki
bf5118fe54 hw_x86_64: Make _virt_idt_addr member more generic
Add label argument to function and rename it to _virt_mtc_addr. It can
be used to retrieve the virtual mtc address of any given label.
2015-03-27 11:53:25 +01:00
Reto Buerki
9c2d071654 hw_x86_64: Add virt_base argument to Idt::load
The argument specifies the virtual base address of the mode transition
pages.
2015-03-27 11:53:24 +01:00
Reto Buerki
ecaad9ecce hw_x86_64: Add private _virt_idt_address member to Idt class
This function calculates the address of the IDT for a given virtual
mode transition base address.
2015-03-27 11:53:24 +01:00
Reto Buerki
89add00518 hw_x86_64: Create Idt instance in mtc region
Use the _mt_idt label and the placement new operator to create the Idt
instance in the mtc region.
2015-03-27 11:53:24 +01:00
Reto Buerki
d8a10448bb hw_x86_64: Make Idt member functions non-static
Add appropriate Idt object to Genode::Cpu class. Update the hard-coded
TSS base address.
2015-03-27 11:53:24 +01:00
Reto Buerki
d1a4eaed0d hw_x86_64: Add fake Timer::ms_to_tics implementation
This makes the scheduler happy and it starts scheduling threads.
2015-03-27 11:53:23 +01:00
Adrian-Ken Rueegsegger
9f825ffb17 hw_x86_64: Setup and load Task State Segment 2015-03-27 11:53:23 +01:00
Adrian-Ken Rueegsegger
2af5aaa54d hw_x86_64: Add Tss class
The class Genode::Tss represents a 64-bit Task State Segment (TSS) as
specified by Intel SDM Vol. 3A, section 7.7.

The setup function sets the stack pointers for privilege levels 0-2 to
the kernel stack address. The load function loads the TSS segment
selector into the task register.
2015-03-27 11:53:23 +01:00
Adrian-Ken Rueegsegger
793b5264e3 hw_x86_64: Set dpl of syscall IDT entry to 3
Since this IDT entry is called from usermode the descriptor privilege
level must be 3.
2015-03-27 11:53:22 +01:00
Adrian-Ken Rueegsegger
ed06c46233 hw_x86_64: Specify user argument to register mapping
Implement user argument setter and getter support functions. The mapping of
the state registers corresponds to the system call parameter passing
convention.
2015-03-27 11:53:22 +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
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
Stefan Kalkowski
657646e76e hw: adjust core bootstrap to fit generic process
* Introduce hw-specific crt0 for core that calls e.g.: init_main_thread
* re-map core's main thread UTCB to fit the right context area location
* switch core's main thread's stack to fit the right context area location

Fix #1440
2015-03-19 08:57:19 +01:00
Reto Buerki
32521cfd71 hw: Declare mtc_size constant in arm/cpu_support.h
This constant specifies the size of the mode transition control region.
2015-03-13 12:17:28 +01:00
Stefan Kalkowski
7582396e9c hw_arndale: enable ARM virtualization extensions
* enables world-switch using ARM virtualization extensions
* split TrustZone and virtualization extensions hardly from platforms,
  where it is not used
* extend 'Vm_session' interface to enable configuration of guest-physical memory
* introduce VM destruction syscall
* add virtual machine monitor for hw_arndale that emulates a simplified version
  of ARM's Versatile Express Cortex A15 board for a Linux guest OS

Fixes #1405
2015-02-27 11:48:05 +01:00
Stefan Kalkowski
07c8d1652e hw_arndale: setup ARM hypervisor mode
To enable support of hardware virtualization for ARM on the Arndale board,
the cpu needs to be prepared to enter the non-secure mode, as long as it does
not already run in it. Therefore, especially the interrupt controller and
some TrustZone specific system registers need to be prepared. Moreover,
the exception vector for the hypervisor needs to be set up properly, before
booting normally in the supervisor mode of the non-secure world.

Ref #1405
2015-02-27 11:48:05 +01:00
Stefan Kalkowski
8e2b4d6f45 hw: extend kernel interrupt class
The generalization of interrupt objects in the kernel and the use of
C++ polymorphism instead of explicitely checking for special interrupts
within generic code (Cpu_job::_interrupt) enables the registration of
additional interrupts used by the kernel, which are needed for specific
aspects added to the kernel, like ARM hardware virtualization interrupts.

* Introduce generic base class for interrupt objects handled by the kernel
* Derive an interrupt class for those handled by the user-land
* Implement IPI-specific interrupt class
* Implement timer interrupts using the new generic base class

Ref #1405
2015-02-27 11:43:56 +01:00
Stefan Kalkowski
0836726df2 hw: use one IRQ for all cpus to send IPIs
Until now, one distinct software generated IRQ per cpu was used to
send signals between cpus. As ARM's GIC has 16 software generated
IRQs only, and they need to be partitioned between secure/non-secure
TrustZone world as well as virtual and non-virtual worlds, we should
save them.

Ref #1405
2015-02-27 11:43:56 +01:00
Stefan Kalkowski
a40932a324 hw: refactor irq controllers
* name irq controller memory mapped I/O regions consistently
  in board descriptions
* move irq controller and timer memory mapped I/O region descriptions
  from cpu class to board class
* eliminate artificial distinction between flavors of ARM's GIC
* factor cpu local initialization out of ARM's GIC interface description,
  which is needed if the GIC is initialized differently e.g. for TrustZone

Ref #1405
2015-02-27 11:43:56 +01:00
Martin Stein
3a40c27c26 hw_vea9x4: quickfix slow RAM access
Setting the ACTLR.SMP bit also without SMP support fastens RAM access
significantly. A proper solution would implement SMP support which must enable
the bit anyway.

Fixes #1353
2015-02-17 14:18:16 +01:00
Stefan Kalkowski
322be1b4fb hw: LPAE for Cortex a15 (fix #1387) 2015-02-16 13:40:37 +01:00
Stefan Kalkowski
21fd2fc582 hw: introduce ARM LPAE extension (ref #1387)
This patch adds support for the Large Physical Address Space Extension
for ARM v7.
2015-02-16 13:40:37 +01:00
Stefan Kalkowski
102444b82b hw: remove pointless, wasted memory in pd object
(ref #1387)
2015-02-16 13:40:37 +01:00
Martin Stein
5dea0b40aa hw: don't use ARM CPU-state stuff in generic code
Fixes #1404
2015-02-16 13:40:36 +01:00
Stefan Kalkowski
a3abf74d1e hw: remove code duplication related to Exynos5 SoC
Fixes #1396
2015-02-16 13:40:36 +01:00
Stefan Kalkowski
901bff813d imx31: remove platform completely (fix #1360) 2015-01-12 14:24:15 +01:00
Martin Stein
9a4a0448be hw vea9x4: remove trustzone support
When building Genode for VEA9X4 as micro-hypervisor protected by the ARM
TrustZone hardware we ran into limitations regarding our basic daily
testing routines. The most significant is that, when speaking about RAM
partitioning, the only available options are to configure the whole SRAM
to be secure and the whole DDR-RAM to be non-secure or vice versa. The
SRAM however provides only 32 MB which isn't enough for both a
representative non-secure guest OS or a secure Genode that is still
capable of passing our basic tests. This initiated our decision to
remove the VEA9X4 TrustZone-support.

Fixes #1351
2015-01-08 13:28:42 +01:00
Martin Stein
e63092f1dd hw & cortex_a9: fix scheduling-timer speed
The estimation of the input clock of the Cortex A9 Private Timer module
was pretty miserable at every Cortex A9 board.

Fixes #1341
2015-01-06 15:22:07 +01:00
Martin Stein
659f6ff5c8 hw_vea9x4: quickfix for missing SMP awareness
This fix configures TTBRs and translation-table descriptors as if we would use
SMP although we don't to circumvent problems with UP-configurations.
This fix should be superseded later by full SMP support for the VEA9X4.

ref #1312
2014-12-19 13:58:49 +01:00
Martin Stein
09e6c3457f hw_arndale: consider timer resets
On Arndale, the kernel timer resets to the initial value of the last
count-down and continues as soon as it reaches zero. We must check this
via the interrupt status when we read out the timer value and in case
return 0 instead of the real value.

fix #1299
2014-11-28 12:02:37 +01:00