mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 05:41:36 +00:00
parent
1cbd77c806
commit
87a6368ba1
@ -8,4 +8,6 @@ SRC_S += bootstrap/spec/arm_64/crt0.s
|
||||
|
||||
vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw
|
||||
|
||||
NR_OF_CPUS = 4
|
||||
|
||||
include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc
|
||||
|
@ -2,17 +2,17 @@ INC_DIR += $(REP_DIR)/src/core/spec/rpi3
|
||||
INC_DIR += $(REP_DIR)/src/core/spec/arm_v8
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += platform_services.cc
|
||||
SRC_CC += kernel/cpu_mp.cc
|
||||
SRC_CC += kernel/vm_thread_off.cc
|
||||
SRC_CC += kernel/cpu_up.cc
|
||||
SRC_CC += kernel/lock.cc
|
||||
SRC_CC += spec/arm_v8/cpu.cc
|
||||
SRC_CC += spec/arm_v8/kernel/thread.cc
|
||||
SRC_CC += spec/arm_v8/kernel/cpu.cc
|
||||
SRC_CC += spec/arm/platform_support.cc
|
||||
SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
SRC_CC += spec/arm/bcm2837_pic.cc
|
||||
SRC_CC += spec/arm/generic_timer.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
SRC_CC += spec/arm/kernel/lock.cc
|
||||
SRC_CC += spec/arm/platform_support.cc
|
||||
SRC_CC += spec/arm_v8/cpu.cc
|
||||
SRC_CC += spec/arm_v8/kernel/cpu.cc
|
||||
SRC_CC += spec/arm_v8/kernel/thread.cc
|
||||
|
||||
#add assembly sources
|
||||
SRC_S += spec/arm_v8/exception_vector.s
|
||||
@ -20,5 +20,7 @@ SRC_S += spec/arm_v8/crt0.s
|
||||
|
||||
vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw
|
||||
|
||||
NR_OF_CPUS = 4
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/core-hw.inc
|
||||
|
@ -23,7 +23,7 @@ namespace Board {
|
||||
|
||||
struct Cpu : Hw::Arm_64_cpu
|
||||
{
|
||||
static void wake_up_all_cpus(void*) {}
|
||||
static void wake_up_all_cpus(void*);
|
||||
};
|
||||
|
||||
struct Pic { }; /* dummy object */
|
||||
|
@ -26,3 +26,12 @@ Bootstrap::Platform::Board::Board()
|
||||
::Board::LOCAL_IRQ_CONTROLLER_SIZE },
|
||||
Memory_region { ::Board::IRQ_CONTROLLER_BASE,
|
||||
::Board::IRQ_CONTROLLER_SIZE }) {}
|
||||
|
||||
|
||||
extern unsigned int _crt0_qemu_start_secondary_cpus;
|
||||
|
||||
void Board::Cpu::wake_up_all_cpus(void *)
|
||||
{
|
||||
_crt0_qemu_start_secondary_cpus = 1;
|
||||
asm volatile("dsb #0; sev");
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
@ -21,41 +22,109 @@ Board::Pic::Pic()
|
||||
|
||||
bool Board::Pic::take_request(unsigned & irq)
|
||||
{
|
||||
Core0_irq_source::access_t src = read<Core0_irq_source>();
|
||||
unsigned cpu = Genode::Cpu::executing_id();
|
||||
Core_irq_source<0>::access_t src = 0;
|
||||
switch (cpu) {
|
||||
case 0: src = read<Core_irq_source<0>>(); break;
|
||||
case 1: src = read<Core_irq_source<1>>(); break;
|
||||
case 2: src = read<Core_irq_source<2>>(); break;
|
||||
case 3: src = read<Core_irq_source<3>>(); break;
|
||||
}
|
||||
|
||||
if ((1 << TIMER_IRQ) & src) {
|
||||
irq = TIMER_IRQ;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (0xf0 & src) {
|
||||
irq = IPI;
|
||||
switch (cpu) {
|
||||
case 0: write<Core_mailbox_clear<0>>(1); break;
|
||||
case 1: write<Core_mailbox_clear<1>>(1); break;
|
||||
case 2: write<Core_mailbox_clear<2>>(1); break;
|
||||
case 3: write<Core_mailbox_clear<3>>(1); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Board::Pic::mask() { }
|
||||
void Board::Pic::_timer_irq(unsigned cpu, bool enable)
|
||||
{
|
||||
unsigned v = enable ? 1 : 0;
|
||||
switch (cpu) {
|
||||
case 0:
|
||||
write<Core_timer_irq_control<0>::Cnt_p_ns_irq>(v);
|
||||
return;
|
||||
case 1:
|
||||
write<Core_timer_irq_control<1>::Cnt_p_ns_irq>(v);
|
||||
return;
|
||||
case 2:
|
||||
write<Core_timer_irq_control<2>::Cnt_p_ns_irq>(v);
|
||||
return;
|
||||
case 3:
|
||||
write<Core_timer_irq_control<3>::Cnt_p_ns_irq>(v);
|
||||
return;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Board::Pic::_ipi(unsigned cpu, bool enable)
|
||||
{
|
||||
unsigned v = enable ? 1 : 0;
|
||||
switch (cpu) {
|
||||
case 0:
|
||||
write<Core_mailbox_irq_control<0>>(v);
|
||||
return;
|
||||
case 1:
|
||||
write<Core_mailbox_irq_control<1>>(v);
|
||||
return;
|
||||
case 2:
|
||||
write<Core_mailbox_irq_control<2>>(v);
|
||||
return;
|
||||
case 3:
|
||||
write<Core_mailbox_irq_control<3>>(v);
|
||||
return;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Board::Pic::unmask(unsigned const i, unsigned cpu)
|
||||
{
|
||||
if (cpu > 0)
|
||||
Genode::raw("multi-core irq controller not implemented yet");
|
||||
|
||||
if (i == TIMER_IRQ) {
|
||||
write<Core0_timer_irq_control::Cnt_p_ns_irq>(1);
|
||||
return;
|
||||
switch (i) {
|
||||
case TIMER_IRQ: _timer_irq(cpu, true); return;
|
||||
case IPI: _ipi(cpu, true); return;
|
||||
}
|
||||
|
||||
Genode::raw("irq of peripherals != timer not implemented yet!");
|
||||
Genode::raw("irq of peripherals != timer not implemented yet! (irq=", i, ")");
|
||||
}
|
||||
|
||||
|
||||
void Board::Pic::mask(unsigned const i)
|
||||
{
|
||||
if (i == TIMER_IRQ) {
|
||||
write<Core0_timer_irq_control::Cnt_p_ns_irq>(0);
|
||||
return;
|
||||
unsigned cpu = Genode::Cpu::executing_id();
|
||||
switch (i) {
|
||||
case TIMER_IRQ: _timer_irq(cpu, false); return;
|
||||
case IPI: _ipi(cpu, false); return;
|
||||
}
|
||||
|
||||
Genode::raw("irq of peripherals != timer not implemented yet!");
|
||||
Genode::raw("irq of peripherals != timer not implemented yet! (irq=", i, ")");
|
||||
}
|
||||
|
||||
|
||||
void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { }
|
||||
|
||||
|
||||
void Board::Pic::send_ipi(unsigned cpu_target)
|
||||
{
|
||||
switch (cpu_target) {
|
||||
case 0: write<Core_mailbox_set<0>>(1); return;
|
||||
case 1: write<Core_mailbox_set<1>>(1); return;
|
||||
case 2: write<Core_mailbox_set<2>>(1); return;
|
||||
case 3: write<Core_mailbox_set<3>>(1); return;
|
||||
}
|
||||
}
|
||||
|
@ -23,31 +23,34 @@ class Board::Pic : Genode::Mmio
|
||||
public:
|
||||
|
||||
enum {
|
||||
IPI = 0,
|
||||
NR_OF_IRQ = 64,
|
||||
|
||||
/*
|
||||
* dummy IPI value on non-SMP platform,
|
||||
* only used in interrupt reservation within generic code
|
||||
*/
|
||||
IPI,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
|
||||
struct Core0_timer_irq_control : Register<0x40, 32>
|
||||
template <unsigned CPU_NUM>
|
||||
struct Core_timer_irq_control : Register<0x40+CPU_NUM*0x4, 32>
|
||||
{
|
||||
struct Cnt_p_ns_irq : Bitfield<1, 1> {};
|
||||
struct Cnt_p_ns_irq
|
||||
: Register<0x40+CPU_NUM*0x4, 32>::template Bitfield<1, 1> {};
|
||||
};
|
||||
|
||||
struct Core1_timer_irq_control : Register<0x44, 32> {};
|
||||
struct Core2_timer_irq_control : Register<0x48, 32> {};
|
||||
struct Core3_timer_irq_control : Register<0x4c, 32> {};
|
||||
template <unsigned CPU_NUM>
|
||||
struct Core_mailbox_irq_control : Register<0x50+CPU_NUM*0x4, 32> {};
|
||||
|
||||
struct Core0_irq_source : Register<0x60, 32> {};
|
||||
struct Core1_irq_source : Register<0x64, 32> {};
|
||||
struct Core2_irq_source : Register<0x68, 32> {};
|
||||
struct Core3_irq_source : Register<0x6c, 32> {};
|
||||
template <unsigned CPU_NUM>
|
||||
struct Core_irq_source : Register<0x60+CPU_NUM*0x4, 32> {};
|
||||
|
||||
template <unsigned CPU_NUM>
|
||||
struct Core_mailbox_set : Register<0x80+CPU_NUM*0x10, 32> {};
|
||||
|
||||
template <unsigned CPU_NUM>
|
||||
struct Core_mailbox_clear : Register<0xc0+CPU_NUM*0x10, 32> {};
|
||||
|
||||
void _ipi(unsigned cpu, bool enable);
|
||||
void _timer_irq(unsigned cpu, bool enable);
|
||||
|
||||
public:
|
||||
|
||||
@ -55,10 +58,10 @@ class Board::Pic : Genode::Mmio
|
||||
|
||||
bool take_request(unsigned &irq);
|
||||
void finish_request() { }
|
||||
void mask();
|
||||
void unmask(unsigned const i, unsigned);
|
||||
void mask(unsigned const i);
|
||||
void irq_mode(unsigned, unsigned, unsigned);
|
||||
void send_ipi(unsigned);
|
||||
|
||||
static constexpr bool fast_interrupts() { return false; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user