arch.h (3321B)
1 /* aarch64 seed-kernel backend contract. */ 2 #ifndef SEED_ARCH_H 3 #define SEED_ARCH_H 4 5 #define ARCH_NAME "aarch64" 6 #define ARCH_ELF_MACHINE 0xb7 7 #define ARCH_ELF_MACHINE_NAME "aarch64" 8 9 #define ARCH_DEVICE_ALIAS_BASE 0x100000000UL 10 #define ARCH_UART0_PA 0x09000000UL 11 #define ARCH_KERNEL_HEAP_END 0x4b000000UL 12 13 #define ARCH_USER_POOL_A_PA 0x4c000000UL 14 #define ARCH_USER_POOL_B_PA 0x7c000000UL 15 #define ARCH_USER_POOL_SIZE 0x30000000UL 16 #define ARCH_USER_VA_LO 0x00200000UL 17 #define ARCH_USER_VA_HI 0x30200000UL 18 #define ARCH_USER_POOL_FIRST_SLOT 1 19 #define ARCH_USER_POOL_LAST_SLOT 384 20 21 #define ARCH_SYS_unlinkat 35 22 #define ARCH_SYS_openat 56 23 #define ARCH_SYS_close 57 24 #define ARCH_SYS_lseek 62 25 #define ARCH_SYS_read 63 26 #define ARCH_SYS_write 64 27 #define ARCH_SYS_exit_group 93 28 #define ARCH_SYS_waitid 95 29 #define ARCH_SYS_brk 214 30 #define ARCH_SYS_spawn 1024 31 32 #define ARCH_TRAPFRAME_NREGS 31 33 struct trapframe { 34 u64 x[ARCH_TRAPFRAME_NREGS]; 35 u64 elr; 36 u64 spsr; 37 }; 38 39 #define ARCH_SYSCALL_ARG(tf, i) ((tf)->x[(i)]) 40 #define ARCH_SYSCALL_NR(tf) ((tf)->x[8]) 41 #define ARCH_SET_RET(tf, v) ((tf)->x[0] = (u64)(v)) 42 #define ARCH_SET_PC(tf, v) ((tf)->elr = (u64)(v)) 43 #define ARCH_TF_PC(tf) ((tf)->elr) 44 #define ARCH_IS_SYSCALL(cause) ((((u32)(((cause) >> 26) & 0x3f))) == 0x15) 45 46 enum { SR_MAIR_EL1, SR_TCR_EL1, SR_TTBR0_EL1, SR_SCTLR_EL1, 47 SR_CPACR_EL1, SR_SP_EL0, SR_FAR_EL1 }; 48 enum { BAR_DSB_SY, BAR_DSB_ISH, BAR_DMB_ISH, BAR_DMB_ISHST, BAR_ISB }; 49 enum { PAUSE_WFE, PAUSE_WFI, PAUSE_YIELD }; 50 51 extern u64 sysreg_read(int id); 52 extern void sysreg_write(int id, u64 v); 53 extern void arm64_barrier(int kind); 54 extern void arm64_ic_iallu(void); 55 extern void arm64_tlbi_vmalle1(void); 56 extern void cpu_pause(int kind); 57 extern u64 arm64_psci_call(int conduit, u64 fnid); 58 extern void eret_to_user(u64 entry, u64 sp); 59 extern void arch_setup_mmu(void); 60 extern void arch_swap_user_pool(int which); 61 62 #define arch_read_user_sp() sysreg_read(SR_SP_EL0) 63 #define arch_write_user_sp(v) sysreg_write(SR_SP_EL0, (v)) 64 #define arch_fault_addr() sysreg_read(SR_FAR_EL1) 65 #define arch_pause() cpu_pause(PAUSE_WFE) 66 #define arch_idle_forever() do { for (;;) cpu_pause(PAUSE_WFI); } while (0) 67 #define arch_mmio_ptr(pa) ((volatile u8 *)(ARCH_DEVICE_ALIAS_BASE + (u64)(pa))) 68 #define arch_wmb() arm64_barrier(BAR_DMB_ISHST) 69 #define arch_rmb() arm64_barrier(BAR_DMB_ISH) 70 #define arch_icache_sync() do { arm64_barrier(BAR_DSB_SY); arm64_ic_iallu(); arm64_barrier(BAR_DSB_SY); arm64_barrier(BAR_ISB); } while (0) 71 #define arch_icache_context_sync() do { arm64_ic_iallu(); arm64_barrier(BAR_DSB_ISH); arm64_barrier(BAR_ISB); } while (0) 72 #define arch_system_off() do { arm64_psci_call(0, 0x84000008); arm64_psci_call(1, 0x84000008); } while (0) 73 74 static inline void arch_clear_to_user_entry(struct trapframe *tf, u64 entry) { 75 for (int i = 0; i < ARCH_TRAPFRAME_NREGS; i++) tf->x[i] = 0; 76 tf->elr = entry; 77 } 78 79 static inline void arch_console_putc(char c) { 80 volatile u32 *dr = (volatile u32 *)(ARCH_DEVICE_ALIAS_BASE + ARCH_UART0_PA + 0x00); 81 volatile u32 *fr = (volatile u32 *)(ARCH_DEVICE_ALIAS_BASE + ARCH_UART0_PA + 0x18); 82 while (*fr & (1u << 5)) { } 83 *dr = (u32)(u8)c; 84 } 85 86 #endif