arch.h (3631B)
1 /* amd64 seed-kernel backend constants. 2 * Low-level boot/trap/MMU and block transport are kept out of common C. */ 3 #ifndef SEED_ARCH_H 4 #define SEED_ARCH_H 5 6 #define ARCH_NAME "amd64" 7 #define ARCH_ELF_MACHINE 0x3e 8 #define ARCH_ELF_MACHINE_NAME "amd64" 9 10 #define ARCH_DEVICE_ALIAS_BASE 0xffff800000000000UL 11 #define ARCH_UART0_PA 0x000003f8UL 12 #define ARCH_KERNEL_HEAP_END 0x4b000000UL 13 14 #define ARCH_STATIC_MEM_START 0x00100000UL 15 #define ARCH_STATIC_MEM_SIZE 0x7ff00000UL 16 #define ARCH_STATIC_VIRTIO_MMIO_BASE 0xfeb00000UL 17 #define ARCH_STATIC_VIRTIO_MMIO_STRIDE 0x200UL 18 #define ARCH_STATIC_VIRTIO_MMIO_COUNT 8 19 20 #define ARCH_USER_POOL_A_PA 0x04c00000UL 21 /* Pool B must start above ARCH_KERNEL_HEAP_END (0x4b000000): the kernel 22 * image is loaded at PA 0x40000000 and the kheap extends to 0x4b000000, 23 * so a pool whose PA range crosses 0x40000000 lets sys_spawn's load_elf 24 * (zeroing the new image's BSS through the alt-pool VA mapping) trample 25 * the running kernel. aarch64/riscv64 don't hit this because their 26 * kernels are loaded above both pools. */ 27 #define ARCH_USER_POOL_B_PA 0x4b000000UL 28 #define ARCH_USER_POOL_SIZE 0x30000000UL 29 #define ARCH_USER_VA_LO 0x00200000UL 30 #define ARCH_USER_VA_HI 0x30200000UL 31 #define ARCH_USER_POOL_FIRST_SLOT 1 32 #define ARCH_USER_POOL_LAST_SLOT 384 33 34 #define ARCH_SYS_read 0 35 #define ARCH_SYS_write 1 36 #define ARCH_SYS_open 2 37 #define ARCH_SYS_close 3 38 #define ARCH_SYS_lseek 8 39 #define ARCH_SYS_brk 12 40 #define ARCH_SYS_exit_group 60 41 #define ARCH_SYS_waitid 247 42 #define ARCH_SYS_openat 257 43 #define ARCH_SYS_unlinkat 263 44 #define ARCH_SYS_spawn 1024 45 46 struct trapframe { 47 u64 x[24]; 48 u64 pc; 49 u64 flags; 50 }; 51 52 #define ARCH_TRAPFRAME_NREGS 24 53 #define ARCH_SYSCALL_ARG(tf, i) ((i) == 0 ? (tf)->x[0] : \ 54 (i) == 1 ? (tf)->x[1] : \ 55 (i) == 2 ? (tf)->x[2] : \ 56 (i) == 3 ? (tf)->x[3] : \ 57 (i) == 4 ? (tf)->x[4] : (tf)->x[5]) 58 #define ARCH_SYSCALL_NR(tf) ((tf)->x[6]) 59 #define ARCH_SET_RET(tf, v) ((tf)->x[6] = (u64)(v)) 60 #define ARCH_SET_PC(tf, v) ((tf)->pc = (u64)(v)) 61 #define ARCH_TF_PC(tf) ((tf)->pc) 62 #define ARCH_IS_SYSCALL(cause) ((cause) == 0) 63 64 enum { BAR_WMB, BAR_RMB }; 65 enum { PAUSE_PAUSE, PAUSE_HLT }; 66 67 extern u64 saved_user_sp; 68 extern void cpu_pause(int kind); 69 extern void amd64_fence(int kind); 70 extern u64 amd64_read_cr2(void); 71 extern void arch_setup_mmu(void); 72 extern void arch_swap_user_pool(int which); 73 extern void arch_system_off(void); 74 extern void eret_to_user(u64 entry, u64 sp); 75 extern void amd64_outb(u16 port, u8 val); 76 extern u8 amd64_inb(u16 port); 77 78 #define arch_read_user_sp() (saved_user_sp) 79 #define arch_write_user_sp(v) (saved_user_sp = (v)) 80 #define arch_fault_addr() amd64_read_cr2() 81 #define arch_pause() cpu_pause(PAUSE_PAUSE) 82 #define arch_idle_forever() do { for (;;) cpu_pause(PAUSE_HLT); } while (0) 83 #define arch_mmio_ptr(pa) ((volatile u8 *)(ARCH_DEVICE_ALIAS_BASE + (u64)(pa))) 84 #define arch_wmb() amd64_fence(BAR_WMB) 85 #define arch_rmb() amd64_fence(BAR_RMB) 86 #define arch_icache_sync() do {} while (0) 87 #define arch_icache_context_sync() do {} while (0) 88 89 static inline void arch_clear_to_user_entry(struct trapframe *tf, u64 entry) { 90 for (int i = 0; i < ARCH_TRAPFRAME_NREGS; i++) tf->x[i] = 0; 91 tf->pc = entry; 92 } 93 94 static inline void arch_console_putc(char c) { 95 while ((amd64_inb((u16)(ARCH_UART0_PA + 5)) & 0x20) == 0) { } 96 amd64_outb((u16)ARCH_UART0_PA, (u8)c); 97 } 98 99 #endif