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/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

View File

@ -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_ */

View File

@ -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();

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::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

View File

@ -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 */ }
};

View File

@ -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<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
{
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;
}

View File

@ -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 */

View File

@ -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,

View File

@ -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] &&