base-hw: enable SMP support for Zynq-7000 boards

Issue #2641
This commit is contained in:
Johannes Schlatow 2018-01-11 16:46:09 +01:00 committed by Norman Feske
parent abd536d5d3
commit bfe0031304
10 changed files with 40 additions and 9 deletions

View File

@ -5,8 +5,10 @@ SRC_S += bootstrap/spec/arm/crt0.s
SRC_CC += bootstrap/spec/arm/cpu.cc SRC_CC += bootstrap/spec/arm/cpu.cc
SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc
SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/arm/pic.cc
SRC_CC += bootstrap/spec/zynq_qemu/platform.cc SRC_CC += bootstrap/spec/zynq/platform.cc
SRC_CC += hw/spec/arm/arm_v7_cpu.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc
SRC_CC += hw/spec/32bit/memory_map.cc SRC_CC += hw/spec/32bit/memory_map.cc
NR_OF_CPUS = 1
include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc

View File

@ -28,6 +28,13 @@ struct Bootstrap::Actlr : Bootstrap::Cpu::Actlr
Smp::set(v, 1); Smp::set(v, 1);
write(v); write(v);
} }
static void disable_smp()
{
auto v = read();
Smp::set(v, 0);
write(v);
}
}; };
#endif /* _SRC__BOOTSTRAP__SPEC__ARM__CORTEX_A9_ACTLR_H_ */ #endif /* _SRC__BOOTSTRAP__SPEC__ARM__CORTEX_A9_ACTLR_H_ */

View File

@ -109,6 +109,7 @@ unsigned Bootstrap::Platform::enable_mmu()
Cpu::Sctlr::init(); Cpu::Sctlr::init();
Cpu::Cpsr::init(); Cpu::Cpsr::init();
Actlr::disable_smp();
/* locally initialize interrupt controller */ /* locally initialize interrupt controller */
pic.init_cpu_local(); pic.init_cpu_local();

View File

@ -28,7 +28,7 @@ void Bootstrap::Cpu::enable_mmu_and_caches(Genode::addr_t table)
Ttbr::access_t ttbr = Ttbr::Ba::masked(table); Ttbr::access_t ttbr = Ttbr::Ba::masked(table);
Ttbr::Rgn::set(ttbr, Ttbr::CACHEABLE); Ttbr::Rgn::set(ttbr, Ttbr::CACHEABLE);
if (Mpidr::read()) { /* check for SMP system */ if (Mpidr::Me::get(Mpidr::read())) { /* check for SMP system */
Ttbr::Irgn::set(ttbr, Ttbr::CACHEABLE); Ttbr::Irgn::set(ttbr, Ttbr::CACHEABLE);
Ttbr::S::set(ttbr, 1); Ttbr::S::set(ttbr, 1);
} else } else

View File

@ -44,6 +44,8 @@ struct Bootstrap::Actlr
{ {
static void enable_smp() { static void enable_smp() {
Hw::call_panda_firmware(Hw::CPU_ACTLR_SMP_BIT_RAISE, 0); } Hw::call_panda_firmware(Hw::CPU_ACTLR_SMP_BIT_RAISE, 0); }
static void disable_smp() { /* not implemented */ }
}; };

View File

@ -23,7 +23,7 @@ Bootstrap::Platform::Board::Board()
late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }), late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }),
core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE, core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE,
CORTEX_A9_PRIVATE_MEM_SIZE }, CORTEX_A9_PRIVATE_MEM_SIZE },
Memory_region { UART_0_MMIO_BASE, Memory_region { UART_BASE,
UART_SIZE }, UART_SIZE },
Memory_region { PL310_MMIO_BASE, Memory_region { PL310_MMIO_BASE,
PL310_MMIO_SIZE }) { } PL310_MMIO_SIZE }) { }
@ -31,3 +31,19 @@ Bootstrap::Platform::Board::Board()
bool Bootstrap::Cpu::errata(Bootstrap::Cpu::Errata) { bool Bootstrap::Cpu::errata(Bootstrap::Cpu::Errata) {
return false; } return false; }
void Bootstrap::Cpu::wake_up_all_cpus(void* ip) {
struct Wakeup_generator : Genode::Mmio
{
struct Core1_boot_addr : Register<0x0, 32> { };
Wakeup_generator(void * const ip) : Mmio(CORE1_ENTRY)
{
write<Core1_boot_addr>((addr_t)ip);
}
};
Wakeup_generator wgen(ip);
asm volatile("dsb\n"
"sev\n");
}

View File

@ -42,8 +42,6 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
*/ */
struct Ttbr0 : Hw::Arm_cpu::Ttbr0 struct Ttbr0 : Hw::Arm_cpu::Ttbr0
{ {
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
/** /**
* Return initialized value * Return initialized value
* *
@ -52,9 +50,9 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
static access_t init(addr_t const table) static access_t init(addr_t const table)
{ {
access_t v = Ttbr::Ba::masked((addr_t)table); access_t v = Ttbr::Ba::masked((addr_t)table);
Ttbr::Rgn::set(v, CACHEABLE); Ttbr::Rgn::set(v, Ttbr::CACHEABLE);
Ttbr::S::set(v, Board::SMP ? 1 : 0); Ttbr::S::set(v, Board::SMP ? 1 : 0);
if (Board::SMP) Ttbr::Irgn::set(v, CACHEABLE); if (Board::SMP) Ttbr::Irgn::set(v, Ttbr::CACHEABLE);
else Ttbr::C::set(v, 1); else Ttbr::C::set(v, 1);
return v; return v;
} }

View File

@ -33,6 +33,7 @@ struct Hw::Arm_cpu
/* Multiprocessor Affinity Register */ /* Multiprocessor Affinity Register */
ARM_CP15_REGISTER_32BIT(Mpidr, c0, c0, 0, 5, ARM_CP15_REGISTER_32BIT(Mpidr, c0, c0, 0, 5,
struct Aff_0 : Bitfield<0, 8> { }; /* affinity value 0 */ struct Aff_0 : Bitfield<0, 8> { }; /* affinity value 0 */
struct Me : Bitfield<31, 1> { }; /* multiprocessing extension */
); );
/* System Control Register */ /* System Control Register */
@ -90,7 +91,7 @@ struct Hw::Arm_cpu
*/ */
struct Ttbr : Genode::Register<32> struct Ttbr : Genode::Register<32>
{ {
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 }; enum Memory_region { CACHEABLE = 1 };
struct C : Bitfield<0,1> { }; /* inner cacheable */ struct C : Bitfield<0,1> { }; /* inner cacheable */
struct S : Bitfield<1,1> { }; /* shareable */ struct S : Bitfield<1,1> { }; /* shareable */

View File

@ -47,6 +47,9 @@ namespace Zynq {
CORTEX_A9_PRIVATE_MEM_BASE = 0xf8f00000, CORTEX_A9_PRIVATE_MEM_BASE = 0xf8f00000,
CORTEX_A9_PRIVATE_MEM_SIZE = 0x00002000, CORTEX_A9_PRIVATE_MEM_SIZE = 0x00002000,
/* entrypoint address of secondary cpu */
CORE1_ENTRY = 0xfffffff0,
/* CPU cache */ /* CPU cache */
PL310_MMIO_BASE = MMIO_1_BASE + 0xF02000, PL310_MMIO_BASE = MMIO_1_BASE + 0xF02000,
PL310_MMIO_SIZE = 0x1000, PL310_MMIO_SIZE = 0x1000,

View File

@ -8,6 +8,7 @@ if {
![have_spec arndale] && ![have_spec arndale] &&
![have_spec wand_quad] && ![have_spec wand_quad] &&
![have_spec panda] && ![have_spec panda] &&
![expr [have_spec zynq] && ![have_spec zynq_qemu] ] &&
![expr [have_spec x86_32] && [have_spec foc] ] && ![expr [have_spec x86_32] && [have_spec foc] ] &&
![expr [have_spec x86_64] && [have_spec foc] ] && ![expr [have_spec x86_64] && [have_spec foc] ] &&
![have_spec nova] && ![have_spec nova] &&