kern
diff src/vm.c @ 17:098b1cb5eeaa
forgot to add a shitload of files
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 26 Mar 2011 21:39:14 +0200 |
parents | |
children | 096807345aa2 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/vm.c Sat Mar 26 21:39:14 2011 +0200 1.3 @@ -0,0 +1,147 @@ 1.4 +#include <stdio.h> 1.5 +#include <string.h> 1.6 +#include <inttypes.h> 1.7 +#include "vm.h" 1.8 +#include <stdio.h> 1.9 +#include "intr.h" 1.10 +#include "mem.h" 1.11 +#include "panic.h" 1.12 + 1.13 + 1.14 +/* defined in vm-asm.S */ 1.15 +void enable_paging(void); 1.16 +void set_pgdir_addr(uint32_t addr); 1.17 +uint32_t get_fault_addr(void); 1.18 + 1.19 +static void pgfault(int inum, uint32_t err); 1.20 + 1.21 +/* page directory */ 1.22 +static uint32_t pgdir[1024]; 1.23 + 1.24 +#define KMEM_START 0xc0000000 1.25 +#define IDMAP_START 0xa0000 1.26 + 1.27 +#define ATTR_PGDIR_MASK 0x3f 1.28 +#define ATTR_PGTBL_MASK 0x1ff 1.29 +#define ADDR_PGENT_MASK 0xfffff000 1.30 + 1.31 +#define PAGEFAULT 14 1.32 + 1.33 +void init_vm(struct mboot_info *mb) 1.34 +{ 1.35 + init_mem(mb); 1.36 + 1.37 + memset(pgdir, 0, sizeof pgdir); 1.38 + 1.39 + /* map the video memory and kernel code 1-1 */ 1.40 + map_mem_range(IDMAP_START, MAX_BRK - IDMAP_START, IDMAP_START, 0); 1.41 + 1.42 + interrupt(PAGEFAULT, pgfault); 1.43 + 1.44 + set_pgdir_addr((int32_t)pgdir); 1.45 + enable_paging(); 1.46 +} 1.47 + 1.48 +void map_page(int vpage, int ppage, unsigned int attr) 1.49 +{ 1.50 + uint32_t *pgtbl; 1.51 + int diridx = PAGE_TO_PGTBL(vpage); 1.52 + int pgidx = PAGE_TO_PGTBL_PG(vpage); 1.53 + 1.54 + if(!(pgdir[diridx] & PG_PRESENT)) { 1.55 + uint32_t addr = alloc_phys_page(); 1.56 + pgtbl = (uint32_t*)addr; 1.57 + pgdir[diridx] = addr | (attr & ATTR_PGDIR_MASK) | PG_PRESENT; 1.58 + } else { 1.59 + pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); 1.60 + } 1.61 + 1.62 + pgtbl[pgidx] = PAGE_TO_ADDR(ppage) | (attr & ATTR_PGTBL_MASK) | PG_PRESENT; 1.63 +} 1.64 + 1.65 +void unmap_page(int vpage) 1.66 +{ 1.67 + uint32_t *pgtbl; 1.68 + int diridx = PAGE_TO_PGTBL(vpage); 1.69 + int pgidx = PAGE_TO_PGTBL_PG(vpage); 1.70 + 1.71 + if(!(pgdir[diridx] & PG_PRESENT)) { 1.72 + goto err; 1.73 + } 1.74 + pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); 1.75 + 1.76 + if(!(pgtbl[pgidx] & PG_PRESENT)) { 1.77 + goto err; 1.78 + } 1.79 + pgtbl[pgidx] = 0; 1.80 + 1.81 + return; 1.82 +err: 1.83 + printf("unmap_page(%d): page already not mapped\n", vpage); 1.84 +} 1.85 + 1.86 +void map_page_range(int vpg_start, int pgcount, int ppg_start, unsigned int attr) 1.87 +{ 1.88 + int i; 1.89 + 1.90 + for(i=0; i<pgcount; i++) { 1.91 + map_page(vpg_start + i, ppg_start + i, attr); 1.92 + } 1.93 +} 1.94 + 1.95 +void map_mem_range(uint32_t vaddr, size_t sz, uint32_t paddr, unsigned int attr) 1.96 +{ 1.97 + int vpg_start, ppg_start, num_pages; 1.98 + 1.99 + if(!sz) return; 1.100 + 1.101 + if(ADDR_TO_PGOFFS(paddr)) { 1.102 + panic("map_mem_range called with unaligned physical address: %x\n", paddr); 1.103 + } 1.104 + 1.105 + vpg_start = ADDR_TO_PAGE(vaddr); 1.106 + ppg_start = ADDR_TO_PAGE(paddr); 1.107 + num_pages = ADDR_TO_PAGE(sz) + 1; 1.108 + 1.109 + map_page_range(vpg_start, num_pages, ppg_start, attr); 1.110 +} 1.111 + 1.112 + 1.113 +/* if(mb->flags & MB_MMAP) { 1.114 + struct mboot_mmap *mem, *mmap_end; 1.115 + 1.116 + mem = mb->mmap; 1.117 + mmap_end = (struct mboot_mmap*)((char*)mb->mmap + mb->mmap_len); 1.118 + 1.119 + printf("memory map:\n"); 1.120 + while(mem < mmap_end) { 1.121 + unsigned int end = mem->base_low + mem->length_low; 1.122 + char *type = mem->type == MB_MEM_VALID ? "free:" : "hole:"; 1.123 + 1.124 + printf(" %s %x - %x (%u bytes)\n", type, mem->base_low, end, mem->length_low); 1.125 + mem = (struct mboot_mmap*)((char*)mem + mem->skip + sizeof mem->skip); 1.126 + } 1.127 + } 1.128 + 1.129 + if(mb->flags & MB_MEM) { 1.130 + printf("lower memory: %ukb, upper mem: %ukb\n", mb->mem_lower, mb->mem_upper); 1.131 + } 1.132 +*/ 1.133 + 1.134 +static void pgfault(int inum, uint32_t err) 1.135 +{ 1.136 + printf("~~~~ PAGE FAULT ~~~~\n"); 1.137 + 1.138 + printf("fault address: %x\n", get_fault_addr()); 1.139 + 1.140 + if(err & PG_PRESENT) { 1.141 + if(err & 8) { 1.142 + printf("reserved bit set in some paging structure\n"); 1.143 + } else { 1.144 + printf("%s protection violation ", (err & PG_WRITABLE) ? "write" : "read"); 1.145 + printf("in %s mode\n", err & PG_USER ? "user" : "kernel"); 1.146 + } 1.147 + } else { 1.148 + printf("page not present\n"); 1.149 + } 1.150 +}