boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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