arm64: PSCI+GICv2 SMP support

* SCTLR register definitions made 64-bit
* isb added after writing to SCTLR, to ensure we don't execute
  instructions requiring the MMU prior to the MMU being enabled
* GICv2 has per-cpu registers for IRQs < 32, so enabling or
  disabling those IRQs needs to be done on all cores
* MMU setup code in kernel and bootloader made per-cpu
* Signiture of arch_smp_boot_other_cpus is now the same on all
  architectures, with an addr_t page table

Change-Id: I13bef7ca4efc5504d643833664560a9a6a6a6964
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10649
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Sam Roberts
2026-04-04 20:26:46 +00:00
committed by waddlesplash
parent 99b6da1e4a
commit 777cfcfb8b
16 changed files with 340 additions and 112 deletions
@@ -527,41 +527,41 @@
#define PAR_S_MASK (0x1 << PAR_S_SHIFT)
/* SCTLR_EL1 - System Control Register */
#define SCTLR_RES0 0xc8222440 /* Reserved ARMv8.0, write 0 */
#define SCTLR_RES1 0x30d00800 /* Reserved ARMv8.0, write 1 */
#define SCTLR_RES0 0xc8222440UL /* Reserved ARMv8.0, write 0 */
#define SCTLR_RES1 0x30d00800UL /* Reserved ARMv8.0, write 1 */
#define SCTLR_M 0x00000001
#define SCTLR_A 0x00000002
#define SCTLR_C 0x00000004
#define SCTLR_SA 0x00000008
#define SCTLR_SA0 0x00000010
#define SCTLR_CP15BEN 0x00000020
#define SCTLR_M 0x00000001UL
#define SCTLR_A 0x00000002UL
#define SCTLR_C 0x00000004UL
#define SCTLR_SA 0x00000008UL
#define SCTLR_SA0 0x00000010UL
#define SCTLR_CP15BEN 0x00000020UL
/* Bit 6 is reserved */
#define SCTLR_ITD 0x00000080
#define SCTLR_SED 0x00000100
#define SCTLR_UMA 0x00000200
#define SCTLR_ITD 0x00000080UL
#define SCTLR_SED 0x00000100UL
#define SCTLR_UMA 0x00000200UL
/* Bit 10 is reserved */
/* Bit 11 is reserved */
#define SCTLR_I 0x00001000
#define SCTLR_EnDB 0x00002000 /* ARMv8.3 */
#define SCTLR_DZE 0x00004000
#define SCTLR_UCT 0x00008000
#define SCTLR_nTWI 0x00010000
#define SCTLR_I 0x00001000UL
#define SCTLR_EnDB 0x00002000UL /* ARMv8.3 */
#define SCTLR_DZE 0x00004000UL
#define SCTLR_UCT 0x00008000UL
#define SCTLR_nTWI 0x00010000UL
/* Bit 17 is reserved */
#define SCTLR_nTWE 0x00040000
#define SCTLR_WXN 0x00080000
#define SCTLR_nTWE 0x00040000UL
#define SCTLR_WXN 0x00080000UL
/* Bit 20 is reserved */
#define SCTLR_IESB 0x00200000 /* ARMv8.2 */
#define SCTLR_IESB 0x00200000UL /* ARMv8.2 */
/* Bit 22 is reserved */
#define SCTLR_SPAN 0x00800000 /* ARMv8.1 */
#define SCTLR_EOE 0x01000000
#define SCTLR_EE 0x02000000
#define SCTLR_UCI 0x04000000
#define SCTLR_EnDA 0x08000000 /* ARMv8.3 */
#define SCTLR_nTLSMD 0x10000000 /* ARMv8.2 */
#define SCTLR_LSMAOE 0x20000000 /* ARMv8.2 */
#define SCTLR_EnIB 0x40000000 /* ARMv8.3 */
#define SCTLR_EnIA 0x80000000 /* ARMv8.3 */
#define SCTLR_SPAN 0x00800000UL /* ARMv8.1 */
#define SCTLR_EOE 0x01000000UL
#define SCTLR_EE 0x02000000UL
#define SCTLR_UCI 0x04000000UL
#define SCTLR_EnDA 0x08000000UL /* ARMv8.3 */
#define SCTLR_nTLSMD 0x10000000UL /* ARMv8.2 */
#define SCTLR_LSMAOE 0x20000000UL /* ARMv8.2 */
#define SCTLR_EnIB 0x40000000UL /* ARMv8.3 */
#define SCTLR_EnIA 0x80000000UL /* ARMv8.3 */
/* SPSR_EL1 */
/*
@@ -9,33 +9,34 @@
#include <boot/menu.h>
#if defined(__riscv) || defined(__ARM__) || defined(__aarch64__)
// These platforms take inventory of cpu cores from fdt
struct platform_cpu_info {
uint32 id; // hart id on riscv
#if defined(__riscv)
struct platform_cpu_info {
uint32 id;
uint32 phandle;
uint32 plicContext;
#endif
};
#if defined(__riscv)
extern uint32 gBootHart;
#endif
void arch_smp_register_cpu(platform_cpu_info** cpu);
platform_cpu_info* arch_smp_find_cpu(uint32 phandle);
#elif defined(__ARM__)
struct platform_cpu_info {
uint32 id;
};
void arch_smp_register_cpu(platform_cpu_info** cpu);
#elif defined(__aarch64__)
struct platform_cpu_info {
uint32 id;
uint64 mpidr;
};
void arch_smp_register_cpu(platform_cpu_info** cpu);
#endif
int arch_smp_get_current_cpu(void);
void arch_smp_init_other_cpus(void);
#ifdef __riscv
platform_cpu_info* arch_smp_find_cpu(uint32 phandle);
void arch_smp_boot_other_cpus(uint64 satp, uint64 kernelEntry, addr_t virtKernelArgs);
#else
void arch_smp_boot_other_cpus(uint32 pml4, uint64 kernelEntry, addr_t virtKernelArgs);
#endif
void arch_smp_boot_other_cpus(addr_t pageTable, uint64 kernelEntry, addr_t virtKernelArgs);
void arch_smp_add_safemode_menus(Menu *menu);
void arch_smp_init(void);