mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
d4a3db22bd
commit
e3f82b09d7
@ -47,7 +47,6 @@ class Bootstrap::Platform
|
||||
Mmio_space const core_mmio;
|
||||
unsigned cpus { NR_OF_CPUS };
|
||||
::Board::Boot_info info { };
|
||||
::Board::Pic pic { };
|
||||
|
||||
Board();
|
||||
};
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
unsigned Bootstrap::Platform::enable_mmu()
|
||||
{
|
||||
::Board::Pic pic { };
|
||||
::Board::Cpu::Sctlr::init();
|
||||
::Board::Cpu::enable_mmu_and_caches((addr_t)core_pd->table_base);
|
||||
|
||||
|
@ -118,7 +118,7 @@ unsigned Bootstrap::Platform::enable_mmu()
|
||||
Actlr::disable_smp();
|
||||
|
||||
/* locally initialize interrupt controller */
|
||||
board.pic.init_cpu_local();
|
||||
::Board::Pic pic { };
|
||||
|
||||
Cpu::invalidate_data_cache();
|
||||
data_cache_invalidated.inc();
|
||||
|
@ -13,8 +13,41 @@
|
||||
|
||||
#include <board.h>
|
||||
|
||||
void Board::Pic::init_cpu_local()
|
||||
Hw::Gicv2::Gicv2()
|
||||
: _distr(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE),
|
||||
_cpui (Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE),
|
||||
_last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)),
|
||||
_max_irq(_distr.max_irq())
|
||||
{
|
||||
static bool distributor_initialized = false;
|
||||
|
||||
if (!distributor_initialized) {
|
||||
distributor_initialized = true;
|
||||
|
||||
/* disable device */
|
||||
_distr.write<Distributor::Ctlr>(0);
|
||||
|
||||
/* configure every shared peripheral interrupt */
|
||||
for (unsigned i = min_spi; i <= _max_irq; i++) {
|
||||
if (Board::NON_SECURE) {
|
||||
_distr.write<Distributor::Igroupr::Group_status>(1, i);
|
||||
}
|
||||
_distr.write<Distributor::Icfgr::Edge_triggered>(0, i);
|
||||
_distr.write<Distributor::Ipriorityr::Priority>(0, i);
|
||||
_distr.write<Distributor::Icenabler::Clear_enable>(1, i);
|
||||
}
|
||||
|
||||
/* enable device */
|
||||
Distributor::Ctlr::access_t v = 0;
|
||||
if (Board::NON_SECURE) {
|
||||
Distributor::Ctlr::Enable_grp0::set(v, 1);
|
||||
Distributor::Ctlr::Enable_grp1::set(v, 1);
|
||||
} else {
|
||||
Distributor::Ctlr::Enable::set(v, 1);
|
||||
}
|
||||
_distr.write<Distributor::Ctlr>(v);
|
||||
}
|
||||
|
||||
if (Board::NON_SECURE) {
|
||||
_cpui.write<Cpu_interface::Ctlr>(0);
|
||||
|
||||
@ -40,34 +73,3 @@ void Board::Pic::init_cpu_local()
|
||||
}
|
||||
_cpui.write<Cpu_interface::Ctlr>(v);
|
||||
}
|
||||
|
||||
|
||||
Hw::Gicv2::Gicv2()
|
||||
: _distr(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE),
|
||||
_cpui (Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE),
|
||||
_last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)),
|
||||
_max_irq(_distr.max_irq())
|
||||
{
|
||||
/* disable device */
|
||||
_distr.write<Distributor::Ctlr>(0);
|
||||
|
||||
/* configure every shared peripheral interrupt */
|
||||
for (unsigned i = min_spi; i <= _max_irq; i++) {
|
||||
if (Board::NON_SECURE) {
|
||||
_distr.write<Distributor::Igroupr::Group_status>(1, i);
|
||||
}
|
||||
_distr.write<Distributor::Icfgr::Edge_triggered>(0, i);
|
||||
_distr.write<Distributor::Ipriorityr::Priority>(0, i);
|
||||
_distr.write<Distributor::Icenabler::Clear_enable>(1, i);
|
||||
}
|
||||
|
||||
/* enable device */
|
||||
Distributor::Ctlr::access_t v = 0;
|
||||
if (Board::NON_SECURE) {
|
||||
Distributor::Ctlr::Enable_grp0::set(v, 1);
|
||||
Distributor::Ctlr::Enable_grp1::set(v, 1);
|
||||
} else {
|
||||
Distributor::Ctlr::Enable::set(v, 1);
|
||||
}
|
||||
_distr.write<Distributor::Ctlr>(v);
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* \brief Interrupt controller definitions for ARM
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2017-02-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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__BOOTSTRAP__SPEC__ARM__GICV2_H_
|
||||
#define _SRC__BOOTSTRAP__SPEC__ARM__GICV2_H_
|
||||
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board { struct Pic; }
|
||||
|
||||
struct Board::Pic : Hw::Gicv2
|
||||
{
|
||||
void init_cpu_local();
|
||||
};
|
||||
|
||||
#endif /* _SRC__BOOTSTRAP__SPEC__ARM__GICV2_H_ */
|
@ -15,6 +15,7 @@
|
||||
|
||||
using Board::Cpu;
|
||||
|
||||
extern "C" void * _crt0_enable_fpu;
|
||||
|
||||
static inline void prepare_non_secure_world()
|
||||
{
|
||||
@ -82,6 +83,12 @@ static inline void prepare_hypervisor()
|
||||
|
||||
unsigned Bootstrap::Platform::enable_mmu()
|
||||
{
|
||||
static volatile bool primary_cpu = true;
|
||||
bool primary = primary_cpu;
|
||||
if (primary) primary_cpu = false;
|
||||
|
||||
::Board::Pic pic __attribute__((unused)) {};
|
||||
|
||||
while (Cpu::current_privilege_level() > Cpu::Current_el::EL1) {
|
||||
if (Cpu::current_privilege_level() == Cpu::Current_el::EL3)
|
||||
prepare_non_secure_world();
|
||||
@ -89,6 +96,9 @@ unsigned Bootstrap::Platform::enable_mmu()
|
||||
prepare_hypervisor();
|
||||
}
|
||||
|
||||
/* primary cpu wakes up all others */
|
||||
if (primary && NR_OF_CPUS > 1) Cpu::wake_up_all_cpus(&_crt0_enable_fpu);
|
||||
|
||||
/* enable performance counter for user-land */
|
||||
Cpu::Pmuserenr_el0::write(0b1111);
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
#include <hw/spec/arm/arndale_board.h>
|
||||
#include <hw/spec/arm/lpae.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Arndale_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
static constexpr bool NON_SECURE = true;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,9 @@ unsigned Bootstrap::Platform::enable_mmu()
|
||||
using namespace ::Board;
|
||||
|
||||
static volatile bool primary_cpu = true;
|
||||
board.pic.init_cpu_local();
|
||||
|
||||
/* locally initialize interrupt controller */
|
||||
::Board::Pic pic { };
|
||||
|
||||
prepare_nonsecure_world();
|
||||
prepare_hypervisor((addr_t)core_pd->table_base);
|
||||
|
@ -18,11 +18,11 @@
|
||||
#include <spec/arm/cortex_a9_actlr.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Imx6q_sabrelite_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
struct L2_cache;
|
||||
|
||||
static constexpr bool NON_SECURE = false;
|
||||
|
@ -17,11 +17,11 @@
|
||||
#include <hw/spec/arm/imx7d_sabre_board.h>
|
||||
#include <hw/spec/arm/lpae.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Imx7d_sabre_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
static constexpr bool NON_SECURE = true;
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,9 @@ unsigned Bootstrap::Platform::enable_mmu()
|
||||
{
|
||||
static volatile bool primary_cpu = true;
|
||||
static unsigned long timer_freq = Cpu::Cntfrq::read();
|
||||
board.pic.init_cpu_local();
|
||||
|
||||
/* locally initialize interrupt controller */
|
||||
::Board::Pic pic { };
|
||||
|
||||
prepare_nonsecure_world(timer_freq);
|
||||
prepare_hypervisor((addr_t)core_pd->table_base);
|
||||
|
@ -24,4 +24,7 @@ Bootstrap::Platform::Board::Board()
|
||||
Memory_region { ::Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE,
|
||||
::Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE },
|
||||
Memory_region { ::Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE,
|
||||
::Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE }) {}
|
||||
::Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE })
|
||||
{
|
||||
::Board::Pic pic {};
|
||||
}
|
||||
|
@ -18,11 +18,11 @@
|
||||
#include <spec/arm/cortex_a9_actlr.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Nit6_solox_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
struct L2_cache;
|
||||
|
||||
static constexpr bool NON_SECURE = false;
|
||||
|
@ -17,10 +17,11 @@
|
||||
#include <hw/spec/arm/odroid_xu_board.h>
|
||||
#include <hw/spec/arm/lpae.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Odroid_xu_board;
|
||||
using Pic = Hw::Gicv2;
|
||||
static constexpr bool NON_SECURE = false;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,9 @@ Bootstrap::Platform::Board::Board()
|
||||
|
||||
unsigned Bootstrap::Platform::enable_mmu()
|
||||
{
|
||||
board.pic.init_cpu_local();
|
||||
/* locally initialize interrupt controller */
|
||||
::Board::Pic pic { };
|
||||
|
||||
Cpu::Sctlr::init();
|
||||
Cpu::Cpsr::init();
|
||||
Cpu::invalidate_data_cache();
|
||||
|
@ -17,11 +17,11 @@
|
||||
#include <hw/spec/arm/panda_board.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Panda_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
static constexpr bool NON_SECURE = false;
|
||||
|
||||
class L2_cache;
|
||||
|
@ -19,11 +19,13 @@
|
||||
#include <spec/arm/cortex_a9_actlr.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Pbxa9_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
|
||||
static constexpr bool NON_SECURE = false;
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,7 @@
|
||||
|
||||
#include <hw/spec/riscv/board.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Riscv_board;
|
||||
struct Pic {};
|
||||
}
|
||||
namespace Board { using namespace Hw::Riscv_board; }
|
||||
|
||||
template <typename E, unsigned B, unsigned S>
|
||||
void Sv39::Level_x_translation_table<E, B, S>::_translation_added(addr_t, size_t)
|
||||
|
@ -18,11 +18,7 @@
|
||||
#include <hw/spec/arm/page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Rpi_board;
|
||||
|
||||
struct Pic {};
|
||||
}
|
||||
namespace Board { using namespace Hw::Rpi_board; }
|
||||
|
||||
|
||||
constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
@ -20,8 +20,13 @@
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Rpi3_board;
|
||||
using Cpu = Hw::Arm_64_cpu;
|
||||
struct Pic {};
|
||||
|
||||
struct Cpu : Hw::Arm_64_cpu
|
||||
{
|
||||
static void wake_up_all_cpus(void*);
|
||||
};
|
||||
|
||||
struct Pic { }; /* dummy object */
|
||||
};
|
||||
|
||||
#endif /* _BOOTSTRAP__SPEC__RPI3__BOARD_H_ */
|
||||
|
@ -38,6 +38,8 @@ Bootstrap::Platform::Board::Board()
|
||||
Aipstz aipstz_1(AIPS_1_MMIO_BASE);
|
||||
Aipstz aipstz_2(AIPS_2_MMIO_BASE);
|
||||
|
||||
Pic pic {};
|
||||
|
||||
/* set monitor mode exception vector entry */
|
||||
Cpu::Mvbar::write(Hw::Mm::system_exception_vector().base);
|
||||
|
||||
|
@ -18,11 +18,13 @@
|
||||
#include <spec/arm/cortex_a9_actlr.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Wand_quad_board;
|
||||
|
||||
using Pic = Hw::Gicv2;
|
||||
|
||||
struct L2_cache;
|
||||
|
||||
static constexpr bool NON_SECURE = false;
|
||||
|
@ -22,7 +22,6 @@
|
||||
namespace Board {
|
||||
using namespace Hw::Pc_board;
|
||||
using Cpu = Hw::X86_64_cpu;
|
||||
struct Pic {};
|
||||
}
|
||||
|
||||
#endif /* _SRC__BOOTSTRAP__SPEC__X86_64__BOARD_H_ */
|
||||
|
@ -18,10 +18,11 @@
|
||||
#include <spec/arm/cortex_a9_actlr.h>
|
||||
#include <spec/arm/cortex_a9_page_table.h>
|
||||
#include <spec/arm/cpu.h>
|
||||
#include <spec/arm/gicv2.h>
|
||||
#include <hw/spec/arm/gicv2.h>
|
||||
|
||||
namespace Board {
|
||||
using namespace Hw::Zynq_qemu_board;
|
||||
using Pic = Hw::Gicv2;
|
||||
static constexpr bool NON_SECURE = false;
|
||||
}
|
||||
|
||||
|
@ -157,10 +157,10 @@ addr_t Cpu::stack_start() {
|
||||
return (addr_t)&kernel_stack + KERNEL_STACK_SIZE * (_id+1); }
|
||||
|
||||
|
||||
Cpu::Cpu(unsigned const id, Board::Pic & pic,
|
||||
Cpu::Cpu(unsigned const id,
|
||||
Inter_processor_work_list & global_work_list)
|
||||
:
|
||||
_id(id), _pic(pic), _timer(*this),
|
||||
_id(id), _timer(*this),
|
||||
_scheduler(&_idle, _quota(), _fill()), _idle(*this),
|
||||
_ipi_irq(*this),
|
||||
_global_work_list(global_work_list)
|
||||
@ -174,7 +174,7 @@ Cpu::Cpu(unsigned const id, Board::Pic & pic,
|
||||
bool Cpu_pool::initialize()
|
||||
{
|
||||
unsigned id = Cpu::executing_id();
|
||||
_cpus[id].construct(id, _pic, _global_work_list);
|
||||
_cpus[id].construct(id, _global_work_list);
|
||||
return --_initialized == 0;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
|
||||
|
||||
unsigned const _id;
|
||||
Board::Pic &_pic;
|
||||
Board::Pic _pic {};
|
||||
Timer _timer;
|
||||
Cpu_scheduler _scheduler;
|
||||
Idle_thread _idle;
|
||||
@ -132,7 +132,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
|
||||
/**
|
||||
* Construct object for CPU 'id'
|
||||
*/
|
||||
Cpu(unsigned const id, Board::Pic & pic,
|
||||
Cpu(unsigned const id,
|
||||
Inter_processor_work_list & global_work_list);
|
||||
|
||||
static inline unsigned primary_id() { return 0; }
|
||||
@ -191,7 +191,6 @@ class Kernel::Cpu_pool
|
||||
{
|
||||
private:
|
||||
|
||||
Board::Pic _pic {};
|
||||
Inter_processor_work_list _global_work_list {};
|
||||
unsigned _count;
|
||||
unsigned _initialized { _count };
|
||||
|
@ -105,8 +105,6 @@ class Kernel::Timer
|
||||
|
||||
unsigned interrupt_id() const;
|
||||
|
||||
static void init_cpu_local();
|
||||
|
||||
time_t time() const { return _time + _duration(); }
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,6 @@ class Board::Pic : Genode::Mmio
|
||||
|
||||
Pic();
|
||||
|
||||
void init_cpu_local();
|
||||
bool take_request(unsigned &irq);
|
||||
void finish_request() { }
|
||||
void mask();
|
||||
|
@ -17,11 +17,16 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static inline Genode::addr_t redistributor_addr()
|
||||
{
|
||||
return Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE
|
||||
+ (Cpu::executing_id() * 0x20000));
|
||||
};
|
||||
|
||||
Hw::Pic::Pic()
|
||||
: _distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)),
|
||||
_redistr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE)),
|
||||
_redistr_sgi(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE)
|
||||
+ Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE / 2),
|
||||
_redistr(redistributor_addr()),
|
||||
_redistr_sgi(redistributor_addr() + 0x10000),
|
||||
_max_irq(_distr.max_irq())
|
||||
{
|
||||
_redistributor_init();
|
||||
|
@ -22,8 +22,6 @@ void Kernel::Cpu::_arch_init()
|
||||
Idt::init();
|
||||
Tss::init();
|
||||
|
||||
Timer::init_cpu_local();
|
||||
|
||||
/* enable timer interrupt */
|
||||
_pic.store_apic_id(id());
|
||||
_pic.unmask(_timer.interrupt_id(), id());
|
||||
|
@ -56,9 +56,6 @@ Board::Timer::Timer(unsigned) : ticks_per_ms(sinfo()->get_tsc_khz()), start(0)
|
||||
}
|
||||
|
||||
|
||||
void Timer::init_cpu_local() { }
|
||||
|
||||
|
||||
unsigned Timer::interrupt_id() const {
|
||||
return Board::TIMER_VECTOR_KERNEL; }
|
||||
|
||||
|
@ -75,11 +75,7 @@ Board::Timer::Timer(unsigned)
|
||||
/* Calculate timer frequency */
|
||||
ticks_per_ms = pit_calc_timer_freq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Timer::init_cpu_local()
|
||||
{
|
||||
/**
|
||||
* Disable PIT timer channel. This is necessary since BIOS sets up
|
||||
* channel 0 to fire periodically.
|
||||
|
@ -168,9 +168,7 @@ class Hw::Gicv2
|
||||
Distributor _distr;
|
||||
Cpu_interface _cpui;
|
||||
Cpu_interface::Iar::access_t _last_iar;
|
||||
unsigned const _max_irq;
|
||||
|
||||
void _init();
|
||||
unsigned const _max_irq;
|
||||
|
||||
bool _valid(unsigned const irq_id) const { return irq_id <= _max_irq; }
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace Hw::Imx8q_evk_board {
|
||||
IRQ_CONTROLLER_DISTR_BASE = 0x38800000,
|
||||
IRQ_CONTROLLER_DISTR_SIZE = 0x10000,
|
||||
IRQ_CONTROLLER_REDIST_BASE = 0x38880000,
|
||||
IRQ_CONTROLLER_REDIST_SIZE = 0x20000, /* per core */
|
||||
IRQ_CONTROLLER_REDIST_SIZE = 0xc0000,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user