mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
hw: remove duplicated definition of x86 local APIC
Ref genodelabs/genode#5310
This commit is contained in:
parent
6889959f59
commit
7770285aed
@ -20,6 +20,7 @@
|
|||||||
#include <multiboot2.h>
|
#include <multiboot2.h>
|
||||||
|
|
||||||
#include <hw/spec/x86_64/acpi.h>
|
#include <hw/spec/x86_64/acpi.h>
|
||||||
|
#include <hw/spec/x86_64/apic.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -274,57 +275,28 @@ Bootstrap::Platform::Board::Board()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Lapic : Mmio<Hw::Cpu_memory_map::LAPIC_SIZE>
|
static inline
|
||||||
|
void ipi_to_all(Hw::Local_apic &lapic, unsigned const boot_frame,
|
||||||
|
Hw::Local_apic::Icr_low::Delivery_mode::Mode const mode)
|
||||||
{
|
{
|
||||||
struct Svr : Register<0x0f0, 32>
|
using Icr_low = Hw::Local_apic::Icr_low;
|
||||||
{
|
|
||||||
struct APIC_enable : Bitfield<8, 1> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Icr_low : Register<0x300, 32>
|
|
||||||
{
|
|
||||||
struct Vector : Bitfield< 0, 8> { };
|
|
||||||
struct Delivery_mode : Bitfield< 8, 3>
|
|
||||||
{
|
|
||||||
enum Mode { INIT = 5, SIPI = 6 };
|
|
||||||
};
|
|
||||||
struct Delivery_status : Bitfield<12, 1> { };
|
|
||||||
struct Level_assert : Bitfield<14, 1> { };
|
|
||||||
struct Dest_shorthand : Bitfield<18, 2>
|
|
||||||
{
|
|
||||||
enum { ALL_OTHERS = 3 };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Icr_high : Register<0x310, 32>
|
|
||||||
{
|
|
||||||
struct Destination : Bitfield<24, 8> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
Lapic(addr_t const addr) : Mmio({(char *)addr, Mmio::SIZE}) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static inline void ipi_to_all(Lapic &lapic, unsigned const boot_frame,
|
|
||||||
Lapic::Icr_low::Delivery_mode::Mode const mode)
|
|
||||||
{
|
|
||||||
/* wait until ready */
|
/* wait until ready */
|
||||||
while (lapic.read<Lapic::Icr_low::Delivery_status>())
|
while (lapic.read<Icr_low::Delivery_status>())
|
||||||
asm volatile ("pause":::"memory");
|
asm volatile ("pause":::"memory");
|
||||||
|
|
||||||
unsigned const apic_cpu_id = 0; /* unused for IPI to all */
|
unsigned const apic_cpu_id = 0; /* unused for IPI to all */
|
||||||
|
|
||||||
Lapic::Icr_low::access_t icr_low = 0;
|
Icr_low::access_t icr_low = 0;
|
||||||
|
Icr_low::Vector::set(icr_low, boot_frame);
|
||||||
Lapic::Icr_low::Vector::set(icr_low, boot_frame);
|
Icr_low::Delivery_mode::set(icr_low, mode);
|
||||||
Lapic::Icr_low::Delivery_mode::set(icr_low, mode);
|
Icr_low::Level_assert::set(icr_low);
|
||||||
Lapic::Icr_low::Level_assert::set(icr_low);
|
Icr_low::Level_assert::set(icr_low);
|
||||||
Lapic::Icr_low::Level_assert::set(icr_low);
|
Icr_low::Dest_shorthand::set(icr_low, Icr_low::Dest_shorthand::ALL_OTHERS);
|
||||||
Lapic::Icr_low::Dest_shorthand::set(icr_low, Lapic::Icr_low::Dest_shorthand::ALL_OTHERS);
|
|
||||||
|
|
||||||
/* program */
|
/* program */
|
||||||
lapic.write<Lapic::Icr_high::Destination>(apic_cpu_id);
|
lapic.write<Hw::Local_apic::Icr_high::Destination>(apic_cpu_id);
|
||||||
lapic.write<Lapic::Icr_low>(icr_low);
|
lapic.write<Icr_low>(icr_low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -356,11 +328,11 @@ unsigned Bootstrap::Platform::enable_mmu()
|
|||||||
Cpu::IA32_apic_base::Lapic::set(lapic_msr);
|
Cpu::IA32_apic_base::Lapic::set(lapic_msr);
|
||||||
Cpu::IA32_apic_base::write(lapic_msr);
|
Cpu::IA32_apic_base::write(lapic_msr);
|
||||||
|
|
||||||
Lapic lapic(board.core_mmio.virt_addr(Hw::Cpu_memory_map::lapic_phys_base()));
|
Hw::Local_apic lapic(board.core_mmio.virt_addr(Hw::Cpu_memory_map::lapic_phys_base()));
|
||||||
|
|
||||||
/* enable local APIC if required */
|
/* enable local APIC if required */
|
||||||
if (!lapic.read<Lapic::Svr::APIC_enable>())
|
if (!lapic.read<Hw::Local_apic::Svr::APIC_enable>())
|
||||||
lapic.write<Lapic::Svr::APIC_enable>(true);
|
lapic.write<Hw::Local_apic::Svr::APIC_enable>(true);
|
||||||
|
|
||||||
/* reset assembly counter (crt0.s) by last booted CPU, required for resume */
|
/* reset assembly counter (crt0.s) by last booted CPU, required for resume */
|
||||||
if (__cpus_booted >= board.cpus)
|
if (__cpus_booted >= board.cpus)
|
||||||
@ -377,12 +349,15 @@ unsigned Bootstrap::Platform::enable_mmu()
|
|||||||
/* BSP - we're primary CPU - wake now all other CPUs */
|
/* BSP - we're primary CPU - wake now all other CPUs */
|
||||||
|
|
||||||
/* see Intel Multiprocessor documentation - we need to do INIT-SIPI-SIPI */
|
/* see Intel Multiprocessor documentation - we need to do INIT-SIPI-SIPI */
|
||||||
ipi_to_all(lapic, 0 /* unused */, Lapic::Icr_low::Delivery_mode::INIT);
|
ipi_to_all(lapic, 0 /* unused */,
|
||||||
|
Hw::Local_apic::Icr_low::Delivery_mode::INIT);
|
||||||
/* wait 10 ms - debates ongoing whether this is still required */
|
/* wait 10 ms - debates ongoing whether this is still required */
|
||||||
ipi_to_all(lapic, AP_BOOT_CODE_PAGE >> 12, Lapic::Icr_low::Delivery_mode::SIPI);
|
ipi_to_all(lapic, AP_BOOT_CODE_PAGE >> 12,
|
||||||
|
Hw::Local_apic::Icr_low::Delivery_mode::SIPI);
|
||||||
/* wait 200 us - debates ongoing whether this is still required */
|
/* wait 200 us - debates ongoing whether this is still required */
|
||||||
/* debates ongoing whether the second SIPI is still required */
|
/* debates ongoing whether the second SIPI is still required */
|
||||||
ipi_to_all(lapic, AP_BOOT_CODE_PAGE >> 12, Lapic::Icr_low::Delivery_mode::SIPI);
|
ipi_to_all(lapic, AP_BOOT_CODE_PAGE >> 12,
|
||||||
|
Hw::Local_apic::Icr_low::Delivery_mode::SIPI);
|
||||||
|
|
||||||
return (unsigned)cpu_id;
|
return (unsigned)cpu_id;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ enum {
|
|||||||
Local_interrupt_controller::
|
Local_interrupt_controller::
|
||||||
Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl)
|
Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl)
|
||||||
:
|
:
|
||||||
Mmio { {(char *)Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()), Mmio::SIZE} },
|
Local_apic({Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base())}),
|
||||||
_global_irq_ctrl { global_irq_ctrl }
|
_global_irq_ctrl { global_irq_ctrl }
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
|
#include <hw/spec/x86_64/apic.h>
|
||||||
#include <hw/spec/x86_64/x86_64.h>
|
#include <hw/spec/x86_64/x86_64.h>
|
||||||
|
|
||||||
namespace Board {
|
namespace Board {
|
||||||
@ -148,43 +149,10 @@ class Board::Global_interrupt_controller : public Genode::Mmio<Hw::Cpu_memory_ma
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Board::Local_interrupt_controller : public Genode::Mmio<Hw::Cpu_memory_map::LAPIC_SIZE>
|
class Board::Local_interrupt_controller : private Hw::Local_apic
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*
|
|
||||||
* Registers
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Id : Register<0x020, 32> { };
|
|
||||||
struct EOI : Register<0x0b0, 32, true> { };
|
|
||||||
struct Svr : Register<0x0f0, 32>
|
|
||||||
{
|
|
||||||
struct APIC_enable : Bitfield<8, 1> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ISR register, see Intel SDM Vol. 3A, section 10.8.4.
|
|
||||||
*
|
|
||||||
* Each of the 8 32-bit ISR values is followed by 12 bytes of padding.
|
|
||||||
*/
|
|
||||||
struct Isr : Register_array<0x100, 32, 8 * 4, 32> { };
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt control register
|
|
||||||
*/
|
|
||||||
struct Icr_low : Register<0x300, 32, true>
|
|
||||||
{
|
|
||||||
struct Vector : Bitfield< 0, 8> { };
|
|
||||||
struct Delivery_status : Bitfield<12, 1> { };
|
|
||||||
struct Level_assert : Bitfield<14, 1> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Icr_high : Register<0x310, 32, true>
|
|
||||||
{
|
|
||||||
struct Destination : Bitfield<24, 8> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
Global_interrupt_controller &_global_irq_ctrl;
|
Global_interrupt_controller &_global_irq_ctrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
64
repos/base-hw/src/include/hw/spec/x86_64/apic.h
Normal file
64
repos/base-hw/src/include/hw/spec/x86_64/apic.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* \brief APIC definitions
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2024-04-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SRC__INCLUDE__HW__SPEC__X86_64__APIC_H_
|
||||||
|
#define _SRC__INCLUDE__HW__SPEC__X86_64__APIC_H_
|
||||||
|
|
||||||
|
namespace Hw { class Local_apic; }
|
||||||
|
|
||||||
|
#include <hw/spec/x86_64/x86_64.h>
|
||||||
|
|
||||||
|
struct Hw::Local_apic : Genode::Mmio<Hw::Cpu_memory_map::LAPIC_SIZE>
|
||||||
|
{
|
||||||
|
struct Id : Register<0x020, 32> { };
|
||||||
|
struct EOI : Register<0x0b0, 32, true> { };
|
||||||
|
struct Svr : Register<0x0f0, 32>
|
||||||
|
{
|
||||||
|
struct APIC_enable : Bitfield<8, 1> { };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR register, see Intel SDM Vol. 3A, section 10.8.4.
|
||||||
|
*
|
||||||
|
* Each of the 8 32-bit ISR values is followed by 12 bytes of padding.
|
||||||
|
*/
|
||||||
|
struct Isr : Register_array<0x100, 32, 8 * 4, 32> { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt control register
|
||||||
|
*/
|
||||||
|
struct Icr_low : Register<0x300, 32, true>
|
||||||
|
{
|
||||||
|
struct Vector : Bitfield< 0, 8> { };
|
||||||
|
struct Delivery_mode : Bitfield< 8, 3>
|
||||||
|
{
|
||||||
|
enum Mode { INIT = 5, SIPI = 6 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Delivery_status : Bitfield<12, 1> { };
|
||||||
|
struct Level_assert : Bitfield<14, 1> { };
|
||||||
|
struct Dest_shorthand : Bitfield<18, 2>
|
||||||
|
{
|
||||||
|
enum { ALL_OTHERS = 3 };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Icr_high : Register<0x310, 32, true>
|
||||||
|
{
|
||||||
|
struct Destination : Bitfield<24, 8> { };
|
||||||
|
};
|
||||||
|
|
||||||
|
Local_apic(addr_t const addr) : Mmio({(char*)addr, Mmio::SIZE}) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _SRC__INCLUDE__HW__SPEC__X86_64__APIC_H_ */
|
Loading…
Reference in New Issue
Block a user