diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-08 10:49:18 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-08 10:49:18 -0400 |
commit | c8a1e0531d7ccdce5f76aec8a5b6147c686d3403 (patch) | |
tree | 2a68ab7da901a96fea975ca2ec02a9c77137686b /kernel/old/include/vm.h | |
parent | tty => term (diff) | |
download | comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.tar.gz comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.tar.bz2 comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.zip |
fix old checkout
Diffstat (limited to 'kernel/old/include/vm.h')
-rw-r--r-- | kernel/old/include/vm.h | 356 |
1 files changed, 149 insertions, 207 deletions
diff --git a/kernel/old/include/vm.h b/kernel/old/include/vm.h index dc12568..6e3935e 100644 --- a/kernel/old/include/vm.h +++ b/kernel/old/include/vm.h @@ -64,91 +64,87 @@ */ // user virtual addresses -#define USER_BASE 0x00000000 -#define USER_MAX 0x003fffff -#define USER_TEXT 0x00001000 -#define USER_STACK 0x003fe000 -#define USER_STACK_P1 USER_STACK -#define USER_STACK_P2 0x003ff000 -#define USER_STK_END 0x00400000 +#define USER_TEXT 0x00001000 +#define USER_STACK 0x003fe000 +#define USER_STK_END 0x00400000 // how to find the addresses of the stack pages in the VM hierarchy // user address space is the first 4MB of virtual memory -#define USER_PDE 0 -// the stack occupies this range of pages in the user address space -#define USER_STK_FIRST_PTE 1022 -#define USER_STK_LAST_PTE 1023 +#define USER_PDE 0 +// the stack occupies the last two pages of the address space +#define USER_STK_PTE1 1022 +#define USER_STK_PTE2 1023 // some important memory addresses -#define KERN_BASE 0x80000000 // start of "kernel" memory -#define EXT_BASE 0x00100000 // start of "extended" memory (1MB) -#define DEV_BASE 0xfe000000 // "device" memory -#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1) +#define KERN_BASE 0x80000000 // start of "kernel" memory +#define EXT_BASE 0x00100000 // start of "extended" memory (1MB) +#define DEV_BASE 0xfe000000 // "device" memory +#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1) // where the kernel actually lives -#define KERN_PLINK 0x00010000 -#define KERN_VLINK (KERN_BASE + KERN_PLINK) +#define KERN_PLINK 0x00010000 +#define KERN_VLINK (KERN_BASE + KERN_PLINK) // number of entries in a page directory or page table -#define N_PDE 1024 -#define N_PTE 1024 +#define N_PDE 1024 +#define N_PTE 1024 // index field shift counts and masks -#define PDIX_SHIFT 22 -#define PTIX_SHIFT 12 -#define PIX2I_MASK 0x3ff +#define PDIX_SHIFT 22 +#define PTIX_SHIFT 12 +#define PIX2I_MASK 0x3ff // physical/virtual converters that don't use casting // (usable from anywhere) -#define V2PNC(a) ((a) - KERN_BASE) -#define P2VNC(a) ((a) + KERN_BASE) +#define V2PNC(a) ((a) - KERN_BASE) +#define P2VNC(a) ((a) + KERN_BASE) // page-size address rounding macros -#define SZ_PG_M1 MOD4K_BITS -#define SZ_PG_MASK MOD4K_MASK -#define PGUP(a) (((a) + SZ_PG_M1) & SZ_PG_MASK) -#define PGDOWN(a) ((a) & SZ_PG_MASK) +#define SZ_PG_M1 MOD4K_BITS +#define SZ_PG_MASK MOD4K_MASK +#define PGUP(a) (((a)+SZ_PG_M1) & SZ_PG_MASK) +#define PGDOWN(a) ((a) & SZ_PG_MASK) // page directory entry bit fields -#define PDE_P 0x00000001 // 1 = present -#define PDE_RW 0x00000002 // 1 = writable -#define PDE_US 0x00000004 // 1 = user and system usable -#define PDE_PWT 0x00000008 // cache: 1 = write-through -#define PDE_PCD 0x00000010 // cache: 1 = disabled -#define PDE_A 0x00000020 // accessed -#define PDE_D 0x00000040 // dirty (4MB pages) -#define PDE_AVL1 0x00000040 // ignored (4KB pages) -#define PDE_PS 0x00000080 // 1 = 4MB page size -#define PDE_G 0x00000100 // global -#define PDE_AVL2 0x00000e00 // ignored -#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table -#define PDE_PTA 0xfffff000 // page table address field (4KB pages) -#define PDE_FA 0xffc00000 // frame address field (4MB pages) +#define PDE_P 0x00000001 // 1 = present +#define PDE_RW 0x00000002 // 1 = writable +#define PDE_US 0x00000004 // 1 = user and system usable +#define PDE_PWT 0x00000008 // cache: 1 = write-through +#define PDE_PCD 0x00000010 // cache: 1 = disabled +#define PDE_A 0x00000020 // accessed +#define PDE_D 0x00000040 // dirty (4MB pages) +#define PDE_AVL1 0x00000040 // ignored (4KB pages) +#define PDE_PS 0x00000080 // 1 = 4MB page size +#define PDE_G 0x00000100 // global +#define PDE_AVL2 0x00000e00 // ignored +#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table +#define PDE_PTA 0xfffff000 // page table address field (4KB pages) +#define PDE_FA 0xffc00000 // frame address field (4MB pages) // page table entry bit fields -#define PTE_P 0x00000001 // present -#define PTE_RW 0x00000002 // 1 = writable -#define PTE_US 0x00000004 // 1 = user and system usable -#define PTE_PWT 0x00000008 // cache: 1 = write-through -#define PTE_PCD 0x00000010 // cache: 1 = disabled -#define PTE_A 0x00000020 // accessed -#define PTE_D 0x00000040 // dirty -#define PTE_PAT 0x00000080 // use page attribute table -#define PTE_G 0x00000100 // global -#define PTE_AVL2 0x00000e00 // ignored -#define PTE_FA 0xfffff000 // frame address field +#define PTE_P 0x00000001 // present +#define PTE_RW 0x00000002 // 1 = writable +#define PTE_US 0x00000004 // 1 = user and system usable +#define PTE_PWT 0x00000008 // cache: 1 = write-through +#define PTE_PCD 0x00000010 // cache: 1 = disabled +#define PTE_A 0x00000020 // accessed +#define PTE_D 0x00000040 // dirty +#define PTE_PAT 0x00000080 // use page attribute table +#define PTE_G 0x00000100 // global +#define PTE_AVL2 0x00000e00 // ignored +#define PTE_FA 0xfffff000 // frame address field // error code bit assignments for page faults -#define PFLT_P 0x00000001 -#define PFLT_W 0x00000002 -#define PFLT_US 0x00000004 -#define PFLT_RSVD 0x00000008 -#define PFLT_ID 0x00000010 -#define PFLT_PK 0x00000020 -#define PFLT_SS 0x00000040 -#define PFLT_HLAT 0x00000080 -#define PFLT_SGX 0x00008000 -#define PFLT_UNUSED 0xffff7f00 +#define PFLT_P 0x00000001 +#define PFLT_W 0x00000002 +#define PFLT_US 0x00000004 +#define PFLT_RSVD 0x00000008 +#define PFLT_ID 0x00000010 +#define PFLT_PK 0x00000020 +#define PFLT_SS 0x00000040 +#define PFLT_HLAT 0x00000080 +#define PFLT_SGX 0x00008000 +#define PFLT_UNUSED 0xffff7f00 #ifndef ASM_SRC @@ -158,59 +154,54 @@ // physical/virtual converters that do use casting // (not usable from assembly) -#define V2P(a) (((uint32_t)(a)) - KERN_BASE) -#define P2V(a) (((uint32_t)(a)) + KERN_BASE) +#define V2P(a) (((uint32_t)(a)) - KERN_BASE) +#define P2V(a) (((uint32_t)(a)) + KERN_BASE) // create a pde/pte from an integer frame number and permission bits -#define MKPDE(f, p) ((pde_t)(TO_FRAME((f)) | (p))) -#define MKPTE(f, p) ((pte_t)(TO_FRAME((f)) | (p))) +#define MKPDE(f,p) ((pde_t)( TO_FRAME((f)) | (p) )) +#define MKPTE(f,p) ((pte_t)( TO_FRAME((f)) | (p) )) // is a PDE/PTE present? // (P bit is in the same place in both) -#define IS_PRESENT(entry) (((entry) & PDE_P) != 0) +#define IS_PRESENT(entry) (((entry) & PDE_P) != 0 ) // is a PDE a 4MB page entry? -#define IS_LARGE(pde) (((pde) & PDE_PS) != 0) +#define IS_LARGE(pde) (((pde) & PDE_PS) != 0 ) // is this entry "system only" or "system and user"? -#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0) -#define IS_USER(entry) (((entry) & PDE_US) != 0) +#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0 ) +#define IS_USER(entry) (((entry) & PDE_US) != 0 ) // low-order nine bits of PDEs and PTEs hold "permission" flag bits -#define PERMS_MASK MOD4K_BITS +#define PERMS_MASK MOD4K_MASK // 4KB frame numbers are 20 bits wide -#define FRAME_4K_SHIFT 12 -#define FRAME2I_4K_MASK 0x000fffff -#define TO_4KFRAME(n) (((n) & FRAME2I_4K_MASK) << FRAME_4K_SHIFT) -#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT) & FRAME2I_4K_MASK) -#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK) -#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK) +#define FRAME_4K_SHIFT 12 +#define FRAME2I_4K_MASK 0x000fffff +#define TO_4KFRAME(n) (((n)&FRAME2I_4K_MASK) << FRAME_4K_SHIFT) +#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT)&F2I_4K_MASK) +#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK) +#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK) // 4MB frame numbers are 10 bits wide -#define FRAME_4M_SHIFT 22 -#define FRAME2I_4M_MASK 0x000003ff -#define TO_4MFRAME(n) (((n) & FRAME2I_4M_MASK) << FRAME_4M_SHIFT) -#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT) & FRAME2I_4M_MASK) -#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK) -#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK) +#define FRAME_4M_SHIFT 22 +#define FRAME2I_4M_MASK 0x000003ff +#define TO_4MFRAME(n) (((n)&FRAME2I_4M_MASK) << FRAME_4M_SHIFT) +#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT)&F2I_4M_MASK) +#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK) +#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK) // extract the PMT address or frame address from a table entry // PDEs could point to 4MB pages, or 4KB PMTs -#define PDE_ADDR(p) \ - (IS_LARGE(p) ? (((uint32_t)p) & PDE_FA) : (((uint32_t)p) & PDE_PTA)) +#define PDE_ADDR(p) (IS_LARGE(p)?(((uint32_t)p)&PDE_FA):(((uint32_t)p)&PDE_PTA)) // PTEs always point to 4KB pages -#define PTE_ADDR(p) (((uint32_t)(p)) & PTE_FA) +#define PTE_ADDR(p) (((uint32_t)(p))&PTE_FA) // everything has nine bits of permission flags -#define PERMS(p) (((uint32_t)(p)) & PERMS_MASK) +#define PERMS(p) (((uint32_t)(p))&PERMS_MASK) -// extract the table indices from a 32-bit VA -#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK) -#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK) - -// extract the byte offset from a 32-bit VA -#define OFFSET_4K(v) (((uint32_t)(v)) & MOD4K_BITS) -#define OFFSET_4M(v) (((uint32_t)(v)) & MOD4M_BITS) +// extract the table indices from a 32-bit address +#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK) +#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK) /* ** Types @@ -223,34 +214,31 @@ // PDE for 4KB pages typedef struct pdek_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t avl1 : 1; // 6: ignored (available) - uint_t ps : 1; // 7: page size (must be 0) - uint_t avl2 : 4; // 11-8: ignored (available) - uint_t fa : 20; // 31-12: frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t avl1 :1; // ignored (available) + uint_t ps :1; // page size (must be 0) + uint_t avl2 :4; // ignored (available) + uint_t fa :20; // frame address } pdek_f_t; // PDE for 4MB pages typedef struct pdem_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t d : 1; // 6: dirty - uint_t ps : 1; // 7: page size (must be 1) - uint_t g : 1; // 8: global - uint_t avl : 3; // 11-9: ignored (available) - uint_t pat : 1; // 12: page attribute table in use - uint_t fa2 : 4; // 16-13: bits 35-32 of frame address (36-bit addrs) - uint_t rsv : 5; // 21-17: reserved - must be zero - uint_t fa : 10; // 31-22: bits 31-22 of frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t ps :1; // page size (must be 1) + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address } pdem_f_t; // page table entries @@ -260,33 +248,33 @@ typedef struct pdem_s { // broken out into fields typedef struct pte_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t d : 1; // 6: dirty - uint_t pat : 1; // 7: page attribute table in use - uint_t g : 1; // 8: global - uint_t avl : 3; // 11-9: ignored (available) - uint_t fa : 20; // 31-12: frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t pat :1; // page attribute table in use + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address } ptef_t; // page fault error code bits // comment: meaning when 1 / meaning when 0 struct pfec_s { - uint_t p : 1; // page-level protection violation / !present - uint_t w : 1; // write / read - uint_t us : 1; // user-mode access / supervisor-mode access - uint_t rsvd : 1; // reserved bit violation / not - uint_t id : 1; // instruction fetch / data fetch - uint_t pk : 1; // protection-key violation / !pk - uint_t ss : 1; // shadow stack access / !ss - uint_t hlat : 1; // HLAT paging / ordinary paging or access rights - uint_t xtr1 : 7; // unused - uint_t sgz : 1; // SGX-specific access control violation / !SGX - uint_t xtr2 : 16; // more unused + uint_t p :1; // page-level protection violation / !present + uint_t w :1; // write / read + uint_t us :1; // user-mode access / supervisor-mode access + uint_t rsvd :1; // reserved bit violation / not + uint_t id :1; // instruction fetch / data fetch + uint_t pk :1; // protection-key violation / !pk + uint_t ss :1; // shadow stack access / !ss + uint_t hlat :1; // HLAT paging / ordinary paging or access rights + uint_t xtr1 :7; // unused + uint_t sgz :1; // SGX-specific access control violation / !SGX + uint_t xtr2 :16; // more unused }; typedef union pfec_u { @@ -296,23 +284,12 @@ typedef union pfec_u { // Mapping descriptor for VA::PA mappings typedef struct mapping_t { - uint32_t va_start; // starting virtual address for this range - uint32_t pa_start; // first physical address in the range - uint32_t pa_end; // last physical address in the range - uint32_t perm; // access control + uint32_t va_start; // starting virtual address for this range + uint32_t pa_start; // first physical address in the range + uint32_t pa_end; // last physical address in the range + uint32_t perm; // access control } mapping_t; -// Modes for dumping out page hierarchies -enum vmmode_e { - Simple = 0, // just count 'present' entries at each level - OneLevel, // top-level only: count entries, decode 'present' - TwoLevel, // count entries & decode at each level - Full // ??? in case we need more? - // sentinel - , - N_VMMODES -}; - /* ** Globals */ @@ -332,20 +309,7 @@ extern pde_t *kpdir; ** Note: should not be called until after the memory free list has ** been set up. */ -void vm_init(void); - -/** -** Name: vm_uva2kva -** -** Convert a user VA into a kernel address. Works for all addresses - -** if the address is a page address, the low-order nine bits will be -** zeroes; otherwise, they is the offset into the page, which is -** unchanged within the address spaces. -** -** @param pdir Pointer to the page directory to examine -** @param va Virtual address to check -*/ -void *vm_uva2kva(pde_t *pdir, void *va); +void vm_init( void ); /** ** Name: vm_pagedup @@ -356,18 +320,7 @@ void *vm_uva2kva(pde_t *pdir, void *va); ** ** @return a pointer to the new, duplicate page, or NULL */ -void *vm_pagedup(void *old); - -/** -** Name: vm_pdedup -** -** Duplicate a page directory entry -** -** @param entry The entry to be duplicated -** -** @return the new entry, or -1 on error. -*/ -pde_t vm_pdedup(pde_t entry); +void *vm_pagedup( void *old ); /** ** Name: vm_ptdup @@ -379,7 +332,7 @@ pde_t vm_pdedup(pde_t entry); ** ** @return true on success, else false */ -bool_t vm_ptdup(pde_t *dst, pde_t *curr); +bool_t vm_ptdup( pde_t *dst, pde_t *curr ); /** ** Name: vm_getpte @@ -395,28 +348,28 @@ bool_t vm_ptdup(pde_t *dst, pde_t *curr); ** ** @return A pointer to the page table entry for this VA, or NULL */ -pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc); +pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc ); /** ** Name: vm_mkkvm ** ** Create the kernel's page table hierarchy */ -pde_t *vm_mkkvm(void); +pde_t *vm_mkkvm( void ); /** ** Name: vm_mkuvm ** ** Create the page table hierarchy for a user process */ -pde_t *vm_mkuvm(void); +pde_t *vm_mkuvm( void ); /** ** Name: vm_set_kvm ** ** Switch the page table register to the kernel's page directory */ -void vm_set_kvm(void); +void vm_set_kvm( void ); /** ** Name: vm_set_uvm @@ -425,7 +378,7 @@ void vm_set_kvm(void); ** ** @param p The PCB of the user process */ -void vm_set_uvm(pcb_t *p); +void vm_set_uvm( pcb_t *p ); /** ** Name: vm_add @@ -443,8 +396,8 @@ void vm_set_uvm(pcb_t *p); ** ** @return status of the allocation attempt */ -int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, - char *data, uint32_t bytes); +int vm_add( pde_t *pdir, bool_t wr, bool_t sys, + void *va, uint32_t size, char *data, uint32_t bytes ); /** ** Name: vm_free @@ -454,7 +407,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, ** ** @param pdir Pointer to the page directory */ -void vm_free(pde_t *pdir); +void vm_free( pde_t *pdir ); /* ** Name: vm_map @@ -465,11 +418,11 @@ void vm_free(pde_t *pdir); ** ** @param pdir Page directory for this address space ** @param va The starting virtual address -** @param pa The starting physical address ** @param size Length of the range to be mapped +** @param pa The starting physical address ** @param perm Permission bits for the PTEs */ -int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm); +int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ); /** ** Name: vm_uvmdup @@ -478,24 +431,13 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm); ** hierarchy. We assume that the "new" page directory exists and ** the system portions of it should not be touched. ** -** @param new New page directory ** @param old Existing page directory +** @param new New page directory ** ** @return status of the duplication attempt */ -int vm_uvmdup(pde_t *new, pde_t *old); - -/** -** Name: vm_print -** -** Print out a paging hierarchy. -** -** @param pt Page table to display -** @param dir Is it a page directory (vs. a page table)? -** @param mode How to display the entries -*/ -void vm_print(void *pt, bool_t dir, enum vmmode_e mode); +int vm_uvmdup( pde_t *old, pde_t *new ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif |