Squash commits for public release

This commit is contained in:
2025-02-12 09:54:05 -05:00
commit 7118adc514
1108 changed files with 80873 additions and 0 deletions

163
boot/arm32/drivers/pl181.c Normal file
View File

@@ -0,0 +1,163 @@
#include "pl181.h"
#include <libboot/devtree/devtree.h>
#include <libboot/log/log.h>
// #define DEBUG_PL181
static sd_card_t sd_card;
static volatile pl181_registers_t* registers;
static inline int _pl181_map_itself(devtree_entry_t* dev)
{
registers = (pl181_registers_t*)(uint32_t)dev->region_base;
return 0;
}
static inline void _pl181_clear_flags()
{
registers->clear = 0x5FF;
}
static int _pl181_send_cmd(uint32_t cmd, uint32_t param)
{
_pl181_clear_flags();
registers->arg = param;
registers->cmd = cmd;
while (registers->status & MMC_STAT_CMD_ACTIVE_MASK) { }
if ((cmd & MMC_CMD_RESP_MASK) == MMC_CMD_RESP_MASK) {
while (((registers->status & MMC_STAT_CMD_RESP_END_MASK) != MMC_STAT_CMD_RESP_END_MASK) || (registers->status & MMC_STAT_CMD_ACTIVE_MASK)) {
if (registers->status & MMC_STAT_CMD_TIMEOUT_MASK) {
return -1;
}
}
} else {
while ((registers->status & MMC_STAT_CMD_SENT_MASK) != MMC_STAT_CMD_SENT_MASK) { }
}
return 0;
}
static int _pl181_send_app_cmd(uint32_t cmd, uint32_t param)
{
for (int i = 0; i < 5; i++) {
_pl181_send_cmd(CMD_APP_CMD | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, 0);
if (registers->response[0] & (1 << 5)) {
return _pl181_send_cmd(cmd, param);
}
}
log_error("Failed to send app command");
return -4;
}
inline static int _pl181_select_card(uint32_t rca)
{
return _pl181_send_cmd(CMD_SELECT | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, rca);
}
static int _pl181_read_block(uint32_t lba_like, void* read_data)
{
sd_card_t* sd_card_ptr = &sd_card;
uint32_t* read_data32 = (uint32_t*)read_data;
uint32_t bytes_read = 0;
registers->data_length = PL181_SECTOR_SIZE; // Set length of bytes to transfer
registers->data_control = 0b11; // Enable dpsm and set direction from card to host
if (sd_card_ptr->ishc) {
_pl181_send_cmd(CMD_READ_SINGLE_BLOCK | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, lba_like);
} else {
_pl181_send_cmd(CMD_READ_SINGLE_BLOCK | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, lba_like * PL181_SECTOR_SIZE);
}
while (registers->status & MMC_STAT_FIFO_DATA_AVAIL_TO_READ_MASK) {
*read_data32 = registers->fifo_data[0];
read_data32++;
bytes_read += 4;
}
return bytes_read;
}
static int _pl181_register_device(uint32_t rca, bool ishc, uint32_t capacity)
{
sd_card.rca = rca;
sd_card.ishc = ishc;
sd_card.capacity = capacity;
_pl181_select_card(rca);
_pl181_send_cmd(CMD_SET_SECTOR_SIZE | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, PL181_SECTOR_SIZE);
if (registers->response[0] != 0x900) {
log_error("PL181(pl181_add_new_device): Can't set sector size");
return -1;
}
return 0;
}
int pl181_init(drive_desc_t* drive_desc)
{
devtree_entry_t* dev = devtree_find_device("pl181");
if (!dev) {
return -1;
}
if (_pl181_map_itself(dev)) {
#ifdef DEBUG_PL181
log_error("PL181: Can't map itself!");
#endif
return -1;
}
#ifdef DEBUG_PL181
log("PL181: Turning on");
#endif
registers->clock = 0x1C6;
registers->power = 0x86;
// Send cmd 0 to set all cards into idle state
_pl181_send_cmd(CMD_GO_IDLE_STATE | MMC_CMD_ENABLE_MASK, 0x0);
// Voltage Check
_pl181_send_cmd(8 | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, 0x1AA);
if ((registers->response[0] & 0x1AA) != 0x1AA) {
#ifdef DEBUG_PL181
log_error("PL181: Can't set voltage!");
#endif
return -1;
}
if (_pl181_send_app_cmd(CMD_SD_SEND_OP_COND | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, 1 << 30 | 0x1AA)) {
#ifdef DEBUG_PL181
log_error("PL181: Can't send APP_CMD!");
#endif
return -1;
}
bool ishc = 0;
if (registers->response[0] & 1 << 30) {
ishc = 1;
#ifdef DEBUG_PL181
log("PL181: ishc = 1");
#endif
}
_pl181_send_cmd(CMD_ALL_SEND_CID | MMC_CMD_ENABLE_MASK | MMC_CMD_LONG_RESP_MASK, 0x0);
_pl181_send_cmd(CMD_SET_RELATIVE_ADDR | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK, 0x0);
// Get the card RCA from the response it is the top 16 bits of the 32 bit response
uint32_t rca = (registers->response[0] & 0xFFFF0000);
_pl181_send_cmd(CMD_SEND_CSD | MMC_CMD_ENABLE_MASK | MMC_CMD_RESP_MASK | MMC_CMD_LONG_RESP_MASK, rca);
uint32_t resp1 = registers->response[1];
uint32_t capacity = ((resp1 >> 8) & 0x3) << 10;
capacity |= (resp1 & 0xFF) << 2;
capacity = 256 * 1024 * (capacity + 1);
_pl181_register_device(rca, ishc, capacity);
drive_desc->read = _pl181_read_block;
return 0;
}

View File

@@ -0,0 +1,73 @@
#ifndef _BOOT_DRIVERS_PL181_H
#define _BOOT_DRIVERS_PL181_H
#include <libboot/abi/drivers.h>
#include <libboot/types.h>
#define PL181_SECTOR_SIZE 512
enum PL181CommandMasks {
MASKDEFINE(MMC_CMD_IDX, 0, 6),
MASKDEFINE(MMC_CMD_RESP, 6, 1),
MASKDEFINE(MMC_CMD_LONG_RESP, 7, 1),
MASKDEFINE(MMC_CMD_INTERRUPT, 8, 1),
MASKDEFINE(MMC_CMD_PENDING, 9, 1),
MASKDEFINE(MMC_CMD_ENABLE, 10, 1),
};
enum PL181StatusMasks {
MASKDEFINE(MMC_STAT_CRC_FAIL, 0, 1),
MASKDEFINE(MMC_STAT_CMD_TIMEOUT, 2, 1),
MASKDEFINE(MMC_STAT_CMD_RESP_END, 6, 1),
MASKDEFINE(MMC_STAT_CMD_SENT, 7, 1),
MASKDEFINE(MMC_STAT_CMD_ACTIVE, 11, 1),
MASKDEFINE(MMC_STAT_TRANSMIT_FIFO_EMPTY, 18, 1),
MASKDEFINE(MMC_STAT_FIFO_DATA_AVAIL_TO_READ, 21, 1),
};
enum PL181Commands {
CMD_GO_IDLE_STATE = 0,
CMD_ALL_SEND_CID = 2,
CMD_SET_RELATIVE_ADDR = 3,
CMD_SELECT = 7,
CMD_SEND_CSD = 9,
CMD_SEND_CID = 10,
CMD_SET_SECTOR_SIZE = 16,
CMD_READ_SINGLE_BLOCK = 17,
CMD_WRITE_SINGLE_BLOCK = 24,
CMD_SD_SEND_OP_COND = 41,
CMD_APP_CMD = 55,
};
struct pl181_registers {
uint32_t power;
uint32_t clock;
uint32_t arg;
uint32_t cmd;
uint32_t resp_cmd;
uint32_t response[4];
uint32_t data_timer;
uint32_t data_length;
uint32_t data_control;
uint32_t data_count;
uint32_t status;
uint32_t clear;
uint32_t interrupt_mask[2];
uint32_t interrupt_select;
uint32_t fifo_count;
char res[0x34];
uint32_t fifo_data[16];
// TO BE CONTINUED
};
typedef struct pl181_registers pl181_registers_t;
struct sd_card {
uint32_t rca;
uint32_t ishc;
uint32_t capacity;
};
typedef struct sd_card sd_card_t;
int pl181_init(drive_desc_t* drive_desc);
#endif // _BOOT_DRIVERS_PL181_H

23
boot/arm32/drivers/uart.c Normal file
View File

@@ -0,0 +1,23 @@
#include "uart.h"
#include <libboot/devtree/devtree.h>
volatile uint32_t* output = NULL;
void uart_init()
{
devtree_entry_t* dev = devtree_find_device("uart");
if (!dev) {
while (1) { };
}
output = (uint32_t*)(uint32_t)dev->region_base;
}
int uart_write(uint8_t data)
{
if (!output) {
return 1;
}
*output = data;
return 0;
}

View File

@@ -0,0 +1,9 @@
#ifndef _BOOT_DRIVERS_UART_H
#define _BOOT_DRIVERS_UART_H
#include <libboot/types.h>
void uart_init();
int uart_write(uint8_t data);
#endif // _BOOT_DRIVERS_UART_H

30
boot/arm32/entry.s Normal file
View File

@@ -0,0 +1,30 @@
.extern _start
.extern _start_secondary_cpu
.section ".xos_boot_text"
xos_loader:
ldr sp, =STACK_PHYZ_TOP
mrc p15, #0, r0, c0, c0, #5 // Read CPU ID register.
and r0, r0, #3
cmp r0, #0
bne secondary_cpu_loader
ldr r0, =_start
mov pc, r0
secondary_cpu_loader:
ldr sp, =STACK_SECONDARY_PHYZ_TOP
mov r9, #512
mrc p15, #0, r8, c0, c0, #5 // Read CPU ID register.
and r8, r8, #3
1:
sub r8, r8, #1
cmp r8, #0
beq secondary_cpu_loader_exit
add r9, r9, #512
b 1b
secondary_cpu_loader_exit:
subs sp, r9
ldr r0, =_start_secondary_cpu
mov pc, r0

13
boot/arm32/hw/ram.c Normal file
View File

@@ -0,0 +1,13 @@
#include "ram.h"
#include <libboot/devtree/devtree.h>
#include <libboot/log/log.h>
size_t hw_ram_get_size()
{
devtree_entry_t* dev = devtree_find_device("ram");
if (!dev) {
log("Can't find RAM in devtree");
while (1) { };
}
return dev->region_size;
}

8
boot/arm32/hw/ram.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _BOOT_HW_RAM_H
#define _BOOT_HW_RAM_H
#include <libboot/types.h>
size_t hw_ram_get_size();
#endif //_BOOT_HW_RAM_H

153
boot/arm32/main.c Normal file
View File

@@ -0,0 +1,153 @@
#include "drivers/pl181.h"
#include "drivers/uart.h"
#include "vmm/vmm.h"
#include <libboot/crypto/sha256.h>
#include <libboot/crypto/signature.h>
#include <libboot/crypto/uint2048.h>
#include <libboot/crypto/validate.h>
#include <libboot/devtree/devtree.h>
#include <libboot/elf/elf_lite.h>
#include <libboot/fs/ext2_lite.h>
#include <libboot/log/log.h>
#include <libboot/mem/alloc.h>
#include <libboot/mem/mem.h>
// #define DEBUG_BOOT
#define KERNEL_PATH "/boot/kernel.bin"
#define LAUNCH_SERVER_PATH "/System/launch_server"
extern void jump_to_kernel(void*);
extern uint32_t _odt_phys[];
extern uint32_t _odt_phys_end[];
static void* bootdesc_ptr;
static size_t kernel_vaddr = 0;
static size_t kernel_paddr = 0;
static size_t kernel_size = 0;
static int sync = 0;
static int alloc_init()
{
devtree_entry_t* dev = devtree_find_device("ram");
if (!dev) {
log("Can't find RAM in devtree");
while (1) { };
}
extern int bootloader_start[];
size_t alloc_space = (size_t)bootloader_start - dev->region_base;
malloc_init((void*)(uint32_t)dev->region_base, alloc_space);
return 0;
}
static memory_boot_desc_t memory_boot_desc_init()
{
devtree_entry_t* dev = devtree_find_device("ram");
if (!dev) {
log("Can't find RAM in devtree");
while (1) { };
}
char dummy_data = 0x0;
memory_boot_desc_t res;
memory_layout_t* mem_layout_paddr = copy_after_kernel(kernel_paddr, &dummy_data, sizeof(dummy_data), &kernel_size, VMM_PAGE_SIZE);
// Init of trailing element.
mem_layout_paddr[0].flags = MEMORY_LAYOUT_FLAG_TERMINATE;
memory_layout_t* mem_layout_vaddr = paddr_to_vaddr(mem_layout_paddr, kernel_paddr, kernel_vaddr);
#ifdef DEBUG_BOOT
log("initing MEMLAYOUT %lx of %d elems", mem_layout_vaddr, memory_layout_size);
#endif
res.ram_base = dev->region_base;
res.ram_size = dev->region_size;
res.reserved_areas = mem_layout_vaddr;
return res;
}
static int prepare_boot_disk(drive_desc_t* drive_desc)
{
pl181_init(drive_desc);
return -1;
}
static int prepare_fs(drive_desc_t* drive_desc, fs_desc_t* fs_desc)
{
if (ext2_lite_init(drive_desc, fs_desc) == 0) {
return 0;
}
return -1;
}
static int validate_kernel(drive_desc_t* drive_desc, fs_desc_t* fs_desc)
{
log("Validating Kernel...");
if (!validate_elf(KERNEL_PATH, drive_desc, fs_desc)) {
log("Can't validate kernel");
while (1) { }
}
if (!validate_elf(LAUNCH_SERVER_PATH, drive_desc, fs_desc)) {
log("Can't validate launch_server");
while (1) { }
}
return 0;
}
static void load_kernel(drive_desc_t* drive_desc, fs_desc_t* fs_desc)
{
int res = elf_load_kernel(drive_desc, fs_desc, KERNEL_PATH, &kernel_vaddr, &kernel_paddr, &kernel_size);
kernel_size = align_size(kernel_size, VMM_PAGE_SIZE);
#ifdef DEBUG_BOOT
log("kernel %x %x %x", kernel_vaddr, kernel_paddr, kernel_size);
#endif
void* odt_ptr = paddr_to_vaddr(copy_after_kernel(kernel_paddr, devtree_start(), devtree_size(), &kernel_size, VMM_PAGE_SIZE), kernel_paddr, kernel_vaddr);
#ifdef DEBUG_BOOT
log("copying ODT %x -> %x of %d", devtree_start(), odt_ptr, devtree_size());
#endif
size_t kernel_data_size = kernel_size + align_size(sizeof(boot_args_t), VMM_PAGE_SIZE) + VMM_PAGE_SIZE;
boot_args_t boot_args;
boot_args.vaddr = kernel_vaddr;
boot_args.paddr = kernel_paddr;
boot_args.kernel_data_size = kernel_data_size;
boot_args.devtree = odt_ptr;
boot_args.mem_boot_desc = memory_boot_desc_init();
memcpy(boot_args.init_process, LAUNCH_SERVER_PATH, sizeof(LAUNCH_SERVER_PATH));
bootdesc_ptr = paddr_to_vaddr(copy_after_kernel(kernel_paddr, &boot_args, sizeof(boot_args), &kernel_size, VMM_PAGE_SIZE), kernel_paddr, kernel_vaddr);
#ifdef DEBUG_BOOT
log("copying BOOTDESC %x -> %x of %d", &boot_args, bootdesc_ptr, sizeof(boot_args));
#endif
}
void load_boot_cpu()
{
devtree_init((void*)_odt_phys, (uint32_t)_odt_phys_end - (uint32_t)_odt_phys);
uart_init();
log_init(uart_write);
alloc_init();
drive_desc_t drive_desc;
fs_desc_t fs_desc;
prepare_boot_disk(&drive_desc);
prepare_fs(&drive_desc, &fs_desc);
validate_kernel(&drive_desc, &fs_desc);
load_kernel(&drive_desc, &fs_desc);
vm_setup(kernel_vaddr, kernel_paddr, kernel_size);
__atomic_store_n(&sync, 1, __ATOMIC_RELEASE);
jump_to_kernel(bootdesc_ptr);
}
void load_secondary_cpu()
{
while (__atomic_load_n(&sync, __ATOMIC_ACQUIRE) == 0) {
continue;
}
vm_setup_secondary_cpu();
jump_to_kernel(bootdesc_ptr);
}

25
boot/arm32/start_kernel.s Normal file
View File

@@ -0,0 +1,25 @@
.extern load_boot_cpu
.extern load_secondary_cpu
.global _start
_start:
ldr r0, =load_boot_cpu
mov pc, r0
1:
b 1b
.size _start, . - _start
.global _start_secondary_cpu
_start_secondary_cpu:
ldr r0, =load_secondary_cpu
mov pc, r0
2:
b 2b
.global jump_to_kernel
jump_to_kernel:
isb
mov r5, #0xc0000000
mov pc, r5
3:
b 3b

17
boot/arm32/vmm/consts.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _BOOT_VMM_CONSTS_H
#define _BOOT_VMM_CONSTS_H
#define VMM_LV0_ENTITY_COUNT (256)
#define VMM_LV1_ENTITY_COUNT (4096)
#define VMM_PAGE_SIZE (4096)
#define VMM_OFFSET_IN_DIRECTORY(a) (((a) >> 20) & 0xfff)
#define VMM_OFFSET_IN_TABLE(a) (((a) >> 12) & 0xff)
#define VMM_OFFSET_IN_PAGE(a) ((a)&0xfff)
#define TABLE_START(vaddr) ((vaddr >> 20) << 20)
#define PAGE_START(vaddr) ((vaddr >> 12) << 12)
#define FRAME(addr) (addr / VMM_PAGE_SIZE)
#define PTABLE_TOP_KERNEL_OFFSET 3072
#endif //_BOOT_VMM_CONSTS_H

147
boot/arm32/vmm/vmm.c Normal file
View File

@@ -0,0 +1,147 @@
#include "vmm.h"
#include <libboot/log/log.h>
#include <libboot/mem/alloc.h>
#include <libboot/mem/mem.h>
#include <libboot/types.h>
// #define DEBUG_VMM
#define VMM_OFFSET_IN_DIRECTORY(a) (((a) >> 20) & 0xfff)
#define VMM_OFFSET_IN_TABLE(a) (((a) >> 12) & 0xff)
#define VMM_OFFSET_IN_PAGE(a) ((a)&0xfff)
#define ALIGN_TO_TABLE(a) ((a)&0xfff00000)
static pdirectory_t* pdir = NULL;
static ptable_t* map_table(size_t tphyz, size_t tvirt);
static void mmu_enable();
static inline void write_ttbcr(uint32_t val)
{
asm volatile("mcr p15, 0, %0, c2, c0, 2"
:
: "r"(val)
: "memory");
asm volatile("dmb");
}
static inline void write_ttbr0(uint32_t val)
{
asm volatile("mcr p15, 0, %0, c2, c0, 0"
:
: "r"(val)
: "memory");
asm volatile("dmb");
}
static inline void write_dacr(uint32_t val)
{
asm volatile("mcr p15, 0, %0, c3, c0, 0"
:
: "r"(val));
asm volatile("dmb");
}
static void mmu_enable()
{
volatile uint32_t val;
asm volatile("mrc p15, 0, %0, c1, c0, 0"
: "=r"(val));
asm volatile("orr %0, %1, #0x1"
: "=r"(val)
: "r"(val));
asm volatile("mcr p15, 0, %0, c1, c0, 0" ::"r"(val)
: "memory");
asm volatile("isb");
}
static pdirectory_t* vm_alloc_pdir()
{
return (pdirectory_t*)malloc_aligned(sizeof(pdirectory_t), sizeof(pdirectory_t));
}
static ptable_t* vm_alloc_ptable()
{
return (ptable_t*)malloc_aligned(sizeof(ptable_t), sizeof(ptable_t));
}
static ptable_t* map_table(size_t tphyz, size_t tvirt)
{
ptable_t* table = vm_alloc_ptable();
for (size_t phyz = tphyz, virt = tvirt, i = 0; i < VMM_LV0_ENTITY_COUNT; phyz += VMM_PAGE_SIZE, virt += VMM_PAGE_SIZE, i++) {
page_desc_t new_page;
new_page.one = 1;
new_page.baddr = (phyz / VMM_PAGE_SIZE);
new_page.tex = 0b001;
new_page.c = 1;
new_page.b = 1;
new_page.ap1 = 0b11;
new_page.ap2 = 0b0;
new_page.s = 1;
table->entities[i] = new_page;
}
uint32_t table_int = (uint32_t)table;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].valid = 1;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].zero1 = 0;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].zero2 = 0;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].ns = 0;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].zero3 = 0;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].domain = 0b0011;
pdir->entities[VMM_OFFSET_IN_DIRECTORY(tvirt)].baddr = ((table_int / 1024));
return table;
}
static void vm_init()
{
pdir = vm_alloc_pdir();
for (int i = 0; i < VMM_LV1_ENTITY_COUNT; i++) {
pdir->entities[i].valid = 0;
}
}
static void vm_map_devices()
{
map_table(0x1c000000, 0x1c000000); // mapping uart
}
void vm_setup(size_t kernel_vaddr, size_t kernel_paddr, size_t kernel_size)
{
vm_init();
vm_map_devices();
extern int bootloader_start[];
size_t bootloader_start_aligned = ALIGN_TO_TABLE((size_t)bootloader_start);
map_table(bootloader_start_aligned, bootloader_start_aligned);
#ifdef DEBUG_VMM
log("map %x to %x", bootloader_start_aligned, bootloader_start_aligned);
#endif
size_t table_paddr = ALIGN_TO_TABLE(kernel_paddr);
size_t table_vaddr = ALIGN_TO_TABLE(kernel_vaddr);
const size_t bytes_per_table = VMM_LV0_ENTITY_COUNT * VMM_PAGE_SIZE;
const size_t tables_per_kernel = align_size((kernel_size + bytes_per_table - 1) / bytes_per_table, 4);
for (int i = 0; i < tables_per_kernel; i++) {
map_table(table_paddr, table_paddr);
map_table(table_paddr, table_vaddr);
#ifdef DEBUG_VMM
log("map %x to %x", table_paddr, table_paddr);
log("map %x to %x", table_paddr, table_vaddr);
#endif
table_paddr += bytes_per_table;
table_vaddr += bytes_per_table;
}
write_ttbr0((size_t)(pdir));
write_dacr(0x55555555);
mmu_enable();
}
void vm_setup_secondary_cpu()
{
write_ttbr0((uint32_t)(pdir));
write_dacr(0x55555555);
mmu_enable();
}

54
boot/arm32/vmm/vmm.h Normal file
View File

@@ -0,0 +1,54 @@
#ifndef _BOOT_VMM_VMM_H
#define _BOOT_VMM_VMM_H
#include "consts.h"
#include <libboot/types.h>
struct PACKED page_desc {
union {
struct {
unsigned int xn : 1; // Execute never. Stops execution of page.
unsigned int one : 1; // Always one for tables
unsigned int b : 1; // cacheable
unsigned int c : 1; // Cacheable
unsigned int ap1 : 2;
unsigned int tex : 3;
unsigned int ap2 : 1;
unsigned int s : 1;
unsigned int ng : 1;
unsigned int baddr : 20;
};
uint32_t data;
};
};
typedef struct page_desc page_desc_t;
struct PACKED table_desc {
union {
struct {
int valid : 1; /* Valid mapping */
int zero1 : 1;
int zero2 : 1;
int ns : 1;
int zero3 : 1;
int domain : 4;
int imp : 1;
int baddr : 22;
};
uint32_t data;
};
};
typedef struct table_desc table_desc_t;
typedef struct {
page_desc_t entities[VMM_LV0_ENTITY_COUNT];
} ptable_t;
typedef struct pdirectory {
table_desc_t entities[VMM_LV1_ENTITY_COUNT];
} pdirectory_t;
void vm_setup(size_t kernel_vaddr, size_t kernel_paddr, size_t kernel_size);
void vm_setup_secondary_cpu();
#endif // _BOOT_VMM_VMM_H