Commit Graph

71 Commits

Author SHA1 Message Date
Stefan Kalkowski e61a3db30d hw: separate function declaration/implementation
Move kernel object functions from its headers to compilation units,
thereby reducing the kernel's text section, cache, and TLB footprint.

Fix #1492
2015-05-06 10:55:23 +02:00
Martin Stein c9272937e7 CPU session: apply quota via relative weightings
Physical CPU quota was previously given to a thread on construction only
by directly specifying a percentage of the quota of the according CPU
session. Now, a new thread is given a weighting that can be any value.
The physical counter-value of such a weighting depends on the weightings
of the other threads at the CPU session. Thus, the physical quota of all
threads of a CPU session must be updated when a weighting is added or
removed. This is each time the session creates or destroys a thread.

This commit also adapts the "cpu_quota" test in base-hw accordingly.

Ref #1464
2015-05-06 10:55:16 +02:00
Stefan Kalkowski b32af4e0a4 hw: directly reference kernel objects from core
Instead of handing over object ids to the kernel, which has to find them
in object pools then, core can simply use object pointers to reference
kernel objects.

Ref #1443
2015-04-17 16:13:20 +02:00
Stefan Kalkowski c850462f43 hw: replace kernel's object id allocators
Instead of having an ID allocator per object class use one global allocator for
all. Thereby artificial limitations for the different object types are
superfluent. Moreover, replace the base-hw specific id allocator implementation
with the generic Bit_allocator, which is also memory saving.

Ref #1443
2015-04-17 16:13:20 +02:00
Martin Stein 60e392f0c0 hw: support Wandboard Quad (i.MX6)
The port uses the Cortex-A9 private timer for the kernel and an EPIT as
user timer. It was successfully tested on the Wandboard Quad and the CuBox-i
with the signal test. It lacks L2-cache and Trustzone support by now.

Thanks to Praveen Srinivas (IIT Madras, India) and  Nikolay Golikov (Ksys Labs
LLC, Russia). This work is partially based on their contributions.

Fix #1467
2015-04-09 16:04:43 +02:00
Martin Stein 4f887448c3 hw & cortex_a9: clean-up board_support.h
Change class name according to our common naming scheme and remove unnecessary
'using' directive.

Ref #1467
2015-03-27 12:20:07 +01:00
Reto Buerki c82f5e9269 hw_x86_64: Do not mask edge-triggered interrupts
Do not mask edge-triggered interrupts to avoid losing them while masked,
see Intel 82093AA I/O Advanced Programmable Interrupt Controller
(IOAPIC) specification, section 3.4.2, "Interrupt Mask":

"When this bit is 1, the interrupt signal is masked. Edge-sensitive
interrupts signaled on a masked interrupt pin are ignored (i.e., not
delivered or held pending)"

Or to quote Linus Torvalds on the subject:

"Now, edge-triggered interrupts are a _lot_ harder to mask, because the
Intel APIC is an unbelievable piece of sh*t, and has the edge-detect
logic _before_ the mask logic, so if a edge happens _while_ the device
is masked, you'll never ever see the edge ever again (unmasking will not
cause a new edge, so you simply lost the interrupt)."

So when you "mask" an edge-triggered IRQ, you can't really mask it at
all, because if you did that, you'd lose it forever if the IRQ comes in
while you masked it. Instead, we're supposed to leave it active, and set
a flag, and IF the IRQ comes in, we just remember it, and mask it at
that point instead, and then on unmasking, we have to replay it by
sending a self-IPI." [1]

[1] - http://yarchive.net/comp/linux/edge_triggered_interrupts.html

Ref #1448
2015-03-27 11:53:34 +01:00
Martin Stein bfe1fac37c hw_x86_64: style fixes
Ref #1448
2015-03-27 11:53:34 +01:00
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