kern
view 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 source
1 #include <stdio.h>
2 #include <string.h>
3 #include <inttypes.h>
4 #include "vm.h"
5 #include <stdio.h>
6 #include "intr.h"
7 #include "mem.h"
8 #include "panic.h"
11 /* defined in vm-asm.S */
12 void enable_paging(void);
13 void set_pgdir_addr(uint32_t addr);
14 uint32_t get_fault_addr(void);
16 static void pgfault(int inum, uint32_t err);
18 /* page directory */
19 static uint32_t pgdir[1024];
21 #define KMEM_START 0xc0000000
22 #define IDMAP_START 0xa0000
24 #define ATTR_PGDIR_MASK 0x3f
25 #define ATTR_PGTBL_MASK 0x1ff
26 #define ADDR_PGENT_MASK 0xfffff000
28 #define PAGEFAULT 14
30 void init_vm(struct mboot_info *mb)
31 {
32 init_mem(mb);
34 memset(pgdir, 0, sizeof pgdir);
36 /* map the video memory and kernel code 1-1 */
37 map_mem_range(IDMAP_START, MAX_BRK - IDMAP_START, IDMAP_START, 0);
39 interrupt(PAGEFAULT, pgfault);
41 set_pgdir_addr((int32_t)pgdir);
42 enable_paging();
43 }
45 void map_page(int vpage, int ppage, unsigned int attr)
46 {
47 uint32_t *pgtbl;
48 int diridx = PAGE_TO_PGTBL(vpage);
49 int pgidx = PAGE_TO_PGTBL_PG(vpage);
51 if(!(pgdir[diridx] & PG_PRESENT)) {
52 uint32_t addr = alloc_phys_page();
53 pgtbl = (uint32_t*)addr;
54 pgdir[diridx] = addr | (attr & ATTR_PGDIR_MASK) | PG_PRESENT;
55 } else {
56 pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK);
57 }
59 pgtbl[pgidx] = PAGE_TO_ADDR(ppage) | (attr & ATTR_PGTBL_MASK) | PG_PRESENT;
60 }
62 void unmap_page(int vpage)
63 {
64 uint32_t *pgtbl;
65 int diridx = PAGE_TO_PGTBL(vpage);
66 int pgidx = PAGE_TO_PGTBL_PG(vpage);
68 if(!(pgdir[diridx] & PG_PRESENT)) {
69 goto err;
70 }
71 pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK);
73 if(!(pgtbl[pgidx] & PG_PRESENT)) {
74 goto err;
75 }
76 pgtbl[pgidx] = 0;
78 return;
79 err:
80 printf("unmap_page(%d): page already not mapped\n", vpage);
81 }
83 void map_page_range(int vpg_start, int pgcount, int ppg_start, unsigned int attr)
84 {
85 int i;
87 for(i=0; i<pgcount; i++) {
88 map_page(vpg_start + i, ppg_start + i, attr);
89 }
90 }
92 void map_mem_range(uint32_t vaddr, size_t sz, uint32_t paddr, unsigned int attr)
93 {
94 int vpg_start, ppg_start, num_pages;
96 if(!sz) return;
98 if(ADDR_TO_PGOFFS(paddr)) {
99 panic("map_mem_range called with unaligned physical address: %x\n", paddr);
100 }
102 vpg_start = ADDR_TO_PAGE(vaddr);
103 ppg_start = ADDR_TO_PAGE(paddr);
104 num_pages = ADDR_TO_PAGE(sz) + 1;
106 map_page_range(vpg_start, num_pages, ppg_start, attr);
107 }
110 /* if(mb->flags & MB_MMAP) {
111 struct mboot_mmap *mem, *mmap_end;
113 mem = mb->mmap;
114 mmap_end = (struct mboot_mmap*)((char*)mb->mmap + mb->mmap_len);
116 printf("memory map:\n");
117 while(mem < mmap_end) {
118 unsigned int end = mem->base_low + mem->length_low;
119 char *type = mem->type == MB_MEM_VALID ? "free:" : "hole:";
121 printf(" %s %x - %x (%u bytes)\n", type, mem->base_low, end, mem->length_low);
122 mem = (struct mboot_mmap*)((char*)mem + mem->skip + sizeof mem->skip);
123 }
124 }
126 if(mb->flags & MB_MEM) {
127 printf("lower memory: %ukb, upper mem: %ukb\n", mb->mem_lower, mb->mem_upper);
128 }
129 */
131 static void pgfault(int inum, uint32_t err)
132 {
133 printf("~~~~ PAGE FAULT ~~~~\n");
135 printf("fault address: %x\n", get_fault_addr());
137 if(err & PG_PRESENT) {
138 if(err & 8) {
139 printf("reserved bit set in some paging structure\n");
140 } else {
141 printf("%s protection violation ", (err & PG_WRITABLE) ? "write" : "read");
142 printf("in %s mode\n", err & PG_USER ? "user" : "kernel");
143 }
144 } else {
145 printf("page not present\n");
146 }
147 }