These two sorts of cores are separated into "clusters". We have cluster 0, which has the four A53 cores, and cluster 1, which has the two A72 cores.
The cores start up in 64 bit (aarch64) mode. Now that I have disassembled part of the bootrom, I can see that the bootrom is entirely 64 bit code, and all the cores start running at address ffff0000 which is the start of the bootrom.
The bootrom inspects the mpidr_el1 register which yields both the cluster number and the core in the cluster. If the cpu running is cluster 0, core 0, it continues to run the boot code. All other cores enter a WFE loop.
I have verified by reading the midr_el1 register that core 0 in cluster 0 is an A53 core.
The WFE loop monitors a pair of addresses in SRAM which are dubbed a "mailbox". I call these SRAM[1] and SRAM[2]. SRAM[0] is used for something else which is so far mysterious. These are 32 bit locations. To bring the cores out of this WFE loop, you place a run address into SRAM[2] and the write 0xdeadbeaf into SRAM[1].
It turns out that PSCI is the "Power State Coordination Interface", which is an ARM standard for enabling and disabling processors and such. Being a standard, we can learn how to play the game and away we go. They say that the PSCI business relies on "firmware", and it turns out the firmware in question is ATF (i.e. bl31).
Linux has plenty of code to deal with PSCI:
drivers/firmware/psci/psci.c drivers/cpuidle/cpuidle-psci.c include/linux/psci.h include/kvm/arm_psci.h virt/kvm/arm/psci.cPart of the trick (like ATF) is to get past the hype and buzzwords and figure out what is going on.
I did a search for "beaf" in the Xulong/linux-orangepi directory and found code that manipulated these locations in
/u1/Projects/OrangePi/Xulong/linux-orangepi/arch/arm/mach-rockchip/platsmp.cNo doubt study of this entire directory would be rewarding. The code that brings the cores out of the parked WFE loop in SRAM is this:
writel(__pa_symbol(secondary_startup), sram_base_addr + 8); writel(0xDEADBEAF, sram_base_addr + 4);I will just note that when I have attempted (using U-Boot) to access sram, I have had my hands slapped with a synchronous exception, so the kernel must do something interesting to gain access.
The symbol "secondary_startup" is in arch/arm64/kernel/head.S
This calls the first C code of secondary_start_kernel() in linux-orangepi/arch/arm64/kernel/smp.c
This eventually calls this: cpu_startup_entry(CPUHP_AP_ONLINE_IDLE) in linux-orangepi/kernel/sched/idle.c
To idle the CPU, this will call: arch_cpu_idle_enter() in linux-orangepi/arch/arm/kernel/process.c
and cpuidle_idle_call() in linux-orangepi/kernel/sched/idle.c
There is lots to study here, but most of this is not RK3399 specific.
The linux kernel gets the sram base address by inspecting a resource named "rockchip,rk3066-smp-sram". This gets involved with something called "mmio-sram". Interestingly, this resource is specified in linux-orangepi/arch/arm/boot/dts/rk3288.dtsi and the declaration is like so:
bus_intmem@ff700000 { compatible = "mmio-sram"; reg = <0x0 0xff700000 0x0 0x18000>; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x0 0xff700000 0x18000>; smp-sram@0 { compatible = "rockchip,rk3066-smp-sram"; reg = <0x00 0x10>; }; };This is shown from ff6f0000 to ff71ffff as a 192k reserved region. Could this be an address alias for the sram? Why the heck are the proper sram addresses made illegal?
In passing, I'll note that there is also "pmu-sram" whatever that is.
Tom's electronics pages / tom@mmto.org