From bfe0031304b2271bf28cdac75fa6eeffed356195 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Thu, 11 Jan 2018 16:46:09 +0100 Subject: [PATCH] base-hw: enable SMP support for Zynq-7000 boards Issue #2641 --- .../lib/mk/spec/zynq_qemu/bootstrap-hw.mk | 4 +++- .../src/bootstrap/spec/arm/cortex_a9_actlr.h | 7 +++++++ .../src/bootstrap/spec/arm/cortex_a9_mmu.cc | 1 + repos/base-hw/src/bootstrap/spec/arm/cpu.cc | 2 +- repos/base-hw/src/bootstrap/spec/panda/board.h | 2 ++ .../spec/{zynq_qemu => zynq}/platform.cc | 18 +++++++++++++++++- repos/base-hw/src/core/spec/arm/cpu_support.h | 6 ++---- repos/base-hw/src/lib/hw/spec/arm/cpu.h | 5 +++-- repos/base/include/drivers/defs/zynq.h | 3 +++ repos/base/run/affinity.run | 1 + 10 files changed, 40 insertions(+), 9 deletions(-) rename repos/base-hw/src/bootstrap/spec/{zynq_qemu => zynq}/platform.cc (72%) diff --git a/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk index 4bb70cad7e..addf8a952c 100644 --- a/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk @@ -5,8 +5,10 @@ SRC_S += bootstrap/spec/arm/crt0.s SRC_CC += bootstrap/spec/arm/cpu.cc SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.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/32bit/memory_map.cc +NR_OF_CPUS = 1 + include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_actlr.h b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_actlr.h index 1b041abfaf..8b5777ce71 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_actlr.h +++ b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_actlr.h @@ -28,6 +28,13 @@ struct Bootstrap::Actlr : Bootstrap::Cpu::Actlr Smp::set(v, 1); write(v); } + + static void disable_smp() + { + auto v = read(); + Smp::set(v, 0); + write(v); + } }; #endif /* _SRC__BOOTSTRAP__SPEC__ARM__CORTEX_A9_ACTLR_H_ */ diff --git a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc index 14ccb0340c..5ba69c79d4 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc @@ -109,6 +109,7 @@ unsigned Bootstrap::Platform::enable_mmu() Cpu::Sctlr::init(); Cpu::Cpsr::init(); + Actlr::disable_smp(); /* locally initialize interrupt controller */ pic.init_cpu_local(); diff --git a/repos/base-hw/src/bootstrap/spec/arm/cpu.cc b/repos/base-hw/src/bootstrap/spec/arm/cpu.cc index ea308d52f0..90559b4a32 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/cpu.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/cpu.cc @@ -28,7 +28,7 @@ void Bootstrap::Cpu::enable_mmu_and_caches(Genode::addr_t table) Ttbr::access_t ttbr = Ttbr::Ba::masked(table); 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::S::set(ttbr, 1); } else diff --git a/repos/base-hw/src/bootstrap/spec/panda/board.h b/repos/base-hw/src/bootstrap/spec/panda/board.h index ada9a5a3fa..f6fb7d6f28 100644 --- a/repos/base-hw/src/bootstrap/spec/panda/board.h +++ b/repos/base-hw/src/bootstrap/spec/panda/board.h @@ -44,6 +44,8 @@ struct Bootstrap::Actlr { static void enable_smp() { Hw::call_panda_firmware(Hw::CPU_ACTLR_SMP_BIT_RAISE, 0); } + + static void disable_smp() { /* not implemented */ } }; diff --git a/repos/base-hw/src/bootstrap/spec/zynq_qemu/platform.cc b/repos/base-hw/src/bootstrap/spec/zynq/platform.cc similarity index 72% rename from repos/base-hw/src/bootstrap/spec/zynq_qemu/platform.cc rename to repos/base-hw/src/bootstrap/spec/zynq/platform.cc index fb74143bb8..689153099b 100644 --- a/repos/base-hw/src/bootstrap/spec/zynq_qemu/platform.cc +++ b/repos/base-hw/src/bootstrap/spec/zynq/platform.cc @@ -23,7 +23,7 @@ Bootstrap::Platform::Board::Board() late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }), core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE, CORTEX_A9_PRIVATE_MEM_SIZE }, - Memory_region { UART_0_MMIO_BASE, + Memory_region { UART_BASE, UART_SIZE }, Memory_region { PL310_MMIO_BASE, PL310_MMIO_SIZE }) { } @@ -31,3 +31,19 @@ Bootstrap::Platform::Board::Board() bool Bootstrap::Cpu::errata(Bootstrap::Cpu::Errata) { 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((addr_t)ip); + } + }; + + Wakeup_generator wgen(ip); + asm volatile("dsb\n" + "sev\n"); +} diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index fa5061d171..903484f1a7 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -42,8 +42,6 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu */ struct Ttbr0 : Hw::Arm_cpu::Ttbr0 { - enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 }; - /** * Return initialized value * @@ -52,9 +50,9 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu static access_t init(addr_t const 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); - if (Board::SMP) Ttbr::Irgn::set(v, CACHEABLE); + if (Board::SMP) Ttbr::Irgn::set(v, Ttbr::CACHEABLE); else Ttbr::C::set(v, 1); return v; } diff --git a/repos/base-hw/src/lib/hw/spec/arm/cpu.h b/repos/base-hw/src/lib/hw/spec/arm/cpu.h index 36dcc16b79..8be3ff9167 100644 --- a/repos/base-hw/src/lib/hw/spec/arm/cpu.h +++ b/repos/base-hw/src/lib/hw/spec/arm/cpu.h @@ -32,7 +32,8 @@ struct Hw::Arm_cpu /* Multiprocessor Affinity Register */ 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 */ @@ -90,7 +91,7 @@ struct Hw::Arm_cpu */ 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 S : Bitfield<1,1> { }; /* shareable */ diff --git a/repos/base/include/drivers/defs/zynq.h b/repos/base/include/drivers/defs/zynq.h index 6a9d721ed8..4bf4099bda 100644 --- a/repos/base/include/drivers/defs/zynq.h +++ b/repos/base/include/drivers/defs/zynq.h @@ -47,6 +47,9 @@ namespace Zynq { CORTEX_A9_PRIVATE_MEM_BASE = 0xf8f00000, CORTEX_A9_PRIVATE_MEM_SIZE = 0x00002000, + /* entrypoint address of secondary cpu */ + CORE1_ENTRY = 0xfffffff0, + /* CPU cache */ PL310_MMIO_BASE = MMIO_1_BASE + 0xF02000, PL310_MMIO_SIZE = 0x1000, diff --git a/repos/base/run/affinity.run b/repos/base/run/affinity.run index cc662dc185..aafc857511 100644 --- a/repos/base/run/affinity.run +++ b/repos/base/run/affinity.run @@ -8,6 +8,7 @@ if { ![have_spec arndale] && ![have_spec wand_quad] && ![have_spec panda] && + ![expr [have_spec zynq] && ![have_spec zynq_qemu] ] && ![expr [have_spec x86_32] && [have_spec foc] ] && ![expr [have_spec x86_64] && [have_spec foc] ] && ![have_spec nova] &&