Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / test_vm / src / geekos / mem_bak.c
1 /*
2  * Physical memory allocation
3  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
5  * $Revision: 1.1 $
6  * 
7  * This is free software.  You are permitted to use,
8  * redistribute, and modify it as specified in the file "COPYING".
9  */
10
11 #include <geekos/defs.h>
12 #include <geekos/ktypes.h>
13 #include <geekos/kassert.h>
14 #include <geekos/bootinfo.h>
15 #include <geekos/gdt.h>
16 #include <geekos/screen.h>
17 #include <geekos/int.h>
18 #include <geekos/malloc.h>
19 #include <geekos/string.h>
20 #include <geekos/mem.h>
21
22
23 #include <geekos/serial.h>
24
25 /* ----------------------------------------------------------------------
26  * Global data
27  * ---------------------------------------------------------------------- */
28
29 /*
30  * List of Page structures representing each page of physical memory.
31  */
32 struct Page* g_pageList;
33
34 /*
35  * Number of pages currently available on the freelist.
36  */
37 uint_t g_freePageCount = 0;
38
39 /* ----------------------------------------------------------------------
40  * Private data and functions
41  * ---------------------------------------------------------------------- */
42
43 /*
44  * Defined in paging.c
45  */
46 extern int debugFaults;
47 #define Debug(args...) if (debugFaults) Print(args)
48
49 /*
50  * List of pages available for allocation.
51  */
52 static struct Page_List s_freeList;
53
54 /*
55  * Total number of physical pages.
56  */
57 int unsigned s_numPages;
58
59 /*
60  * Add a range of pages to the inventory of physical memory.
61  */
62 static void Add_Page_Range(ulong_t start, ulong_t end, int flags)
63 {
64     ulong_t addr;
65
66     PrintBoth("Start: %u, End: %u\n", (unsigned int)start, (unsigned int)end);
67
68     KASSERT(Is_Page_Multiple(start));
69     KASSERT(Is_Page_Multiple(end));
70     KASSERT(start < end);
71
72     //Print("Adding %lu pages\n", (end - start) / PAGE_SIZE);
73
74     for (addr = start; addr < end; addr += PAGE_SIZE) {
75       //      Print("Adding Page at %u\n", (unsigned int)addr);
76         struct Page *page = Get_Page(addr);
77
78         page->flags = flags;
79
80         if (flags == PAGE_AVAIL) {
81             /* Add the page to the freelist */
82             Add_To_Back_Of_Page_List(&s_freeList, page);
83
84             /* Update free page count */
85             ++g_freePageCount;
86         } else {
87             Set_Next_In_Page_List(page, 0);
88             Set_Prev_In_Page_List(page, 0);
89         }
90
91     }
92     //   Print("%d pages now in freelist\n", g_freePageCount);
93
94 }
95
96 /* ----------------------------------------------------------------------
97  * Public functions
98  * ---------------------------------------------------------------------- */
99
100 /*
101  * The linker defines this symbol to indicate the end of
102  * the executable image.
103  */
104 extern char end;
105
106 /*
107  * Initialize memory management data structures.
108  * Enables the use of Alloc_Page() and Free_Page() functions.
109  */
110 void Init_Mem(struct Boot_Info* bootInfo)
111 {
112     ulong_t numPages = bootInfo->memSizeKB >> 2;
113     ulong_t endOfMem = numPages * PAGE_SIZE;
114     unsigned numPageListBytes = sizeof(struct Page) * numPages;
115     ulong_t pageListAddr;
116     ulong_t pageListEnd;
117     ulong_t kernEnd;
118
119
120     KASSERT(bootInfo->memSizeKB > 0);
121
122     if (bootInfo->memSizeKB != TOP_OF_MEM/1024) { 
123       PrintBoth("Kernel compiled for %d KB machine, but machine claims %d KB\n",TOP_OF_MEM/1024,bootInfo->memSizeKB);
124       if (bootInfo->memSizeKB < TOP_OF_MEM/1024) { 
125         PrintBoth("Kernel compiled for more memory than machine has.  Panicking\n");
126         KASSERT(0);
127       }
128     }
129
130
131     bootInfo->memSizeKB = TOP_OF_MEM / 1024;
132
133     /*
134      * Before we do anything, switch from setup.asm's temporary GDT
135      * to the kernel's permanent GDT.
136      */
137     Init_GDT();
138
139     /*
140      * We'll put the list of Page objects right after the end
141      * of the kernel, and mark it as "kernel".  This will bootstrap
142      * us sufficiently that we can start allocating pages and
143      * keeping track of them.
144      */
145
146     // JRL: This is stupid... 
147     // with large mem sizes the page list overruns into the ISA 
148     // hole. By blind luck this causes an unrelated assertion failure, otherwise
149     // I might never have caught it...
150     // We fix it by moving the page list after the kernel heap...
151     // For now we'll make our own stupid assumption that the mem size
152     // is large enough to accomodate the list in high mem.
153
154     PrintBoth("Total Memory Size: %u MBytes\n", bootInfo->memSizeKB/1024);
155
156     
157
158     PrintBoth("Page struct size: %u bytes\n", sizeof(struct Page));
159     PrintBoth("Page List Size: %u bytes\n", numPageListBytes);
160
161   
162     //pageListAddr = Round_Up_To_Page((ulong_t) &end);
163     //pageListAddr = Round_Up_To_Page(HIGHMEM_START + KERNEL_HEAP_SIZE);
164
165     // Note that this is now moved to be just above the kernel heap
166     // see defs.h for layout
167     pageListAddr=Round_Up_To_Page(KERNEL_PAGELIST);
168       
169     pageListEnd = Round_Up_To_Page(pageListAddr + numPageListBytes);
170
171     g_pageList = (struct Page*) pageListAddr;
172     //    kernEnd = Round_Up_To_Page(pageListAddr + numPageListBytes);
173     //
174     // PAD - Note: I am changing this so that everything through the end of 
175     // the VM boot package (bioses/vmxassist) is off limits
176     //kernEnd = Round_Up_To_Page((ulong_t) &end);
177     kernEnd = Round_Up_To_Page(end);
178     s_numPages = numPages;
179
180     PrintBoth("Pagelist addr: %p\n", g_pageList);
181     PrintBoth("index: %p\n", &g_pageList[3]);
182     PrintBoth("direct offset: %p\n", g_pageList + (sizeof(struct Page) * 2));
183     //  PrintBoth("Kernel Size=%lx\n", (kernEnd - KERNEL_START_ADDR));
184     // PrintBoth("Kernel Start=%x\n", KERNEL_START_ADDR);
185     PrintBoth("Kernel End=%lx\n", kernEnd);
186     //PrintBoth("end=%x\n", end);
187
188
189     /*
190      * The initial kernel thread and its stack are placed
191      * just beyond the ISA hole.
192      */
193     // This is no longer true
194     // KASSERT(ISA_HOLE_END == KERN_THREAD_OBJ);
195     // instead, 
196     //KASSERT(KERN_THREAD_OBJ==(START_OF_VM+VM_SIZE));
197     //KASSERT(KERN_STACK == KERN_THREAD_OBJ + PAGE_SIZE);
198
199     /*
200      * Memory looks like this:
201      * 0 - start: available (might want to preserve BIOS data area)
202      * start - end: kernel
203      * end - ISA_HOLE_START: available
204      * ISA_HOLE_START - ISA_HOLE_END: used by hardware (and ROM BIOS?)
205      * ISA_HOLE_END - HIGHMEM_START: used by initial kernel thread
206      * HIGHMEM_START - end of memory: available
207      *    (the kernel heap is located at HIGHMEM_START; any unused memory
208      *    beyond that is added to the freelist)
209      */
210
211   
212
213
214     // The kernel is still in low memory at this point, in the VM region
215     // Thus we will mark it as kernel use
216     // Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN);
217     
218     
219     //Add_Page_Range(kernEnd, ISA_HOLE_START, PAGE_AVAIL);
220     // ISA hole remains closed (no actual memory)
221     // Add_Page_Range(ISA_HOLE_START, ISA_HOLE_END, PAGE_HW);
222     
223     //Add_Page_Range(ISA_HOLE_END, HIGHMEM_START, PAGE_ALLOCATED);
224     // Add_Page_Range(HIGHMEM_START, HIGHMEM_START + KERNEL_HEAP_SIZE, PAGE_HEAP);
225     //Add_Page_Range(HIGHMEM_START + KERNEL_HEAP_SIZE, endOfMem, PAGE_AVAIL);
226     /* JRL: move page list after kernel heap */
227     
228     //Now, above the VM region...
229
230     // Kernel thread object
231     Add_Page_Range(KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE,PAGE_ALLOCATED);
232     // Kernel stack
233     Add_Page_Range(KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE,PAGE_ALLOCATED);
234     // Kernel heap
235     Add_Page_Range(KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE,PAGE_HEAP);
236     // Kernel page list
237     Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN);
238     // Free space
239     Add_Page_Range(pageListEnd,Round_Down_To_Page(FINAL_KERNEL_START), PAGE_AVAIL);
240     // The kernel 
241     Add_Page_Range(Round_Down_To_Page(FINAL_KERNEL_START),Round_Up_To_Page(FINAL_VMBOOTEND+1),PAGE_KERN);
242     // The vmbootpackage 
243     // IDT (this should be one page)
244     Add_Page_Range(IDT_LOCATION,TSS_LOCATION,PAGE_KERN);
245     // TSS (this should be one page)
246     Add_Page_Range(TSS_LOCATION,GDT_LOCATION, PAGE_KERN);
247     // GDT (this should be one page)
248     Add_Page_Range(GDT_LOCATION,TOP_OF_MEM, PAGE_KERN);
249
250     /* Initialize the kernel heap */
251     Init_Heap(KERNEL_HEAP, KERNEL_HEAP_SIZE);
252
253     PrintBoth("%uKB memory detected, %u pages in freelist, %d bytes in kernel heap\n",
254         bootInfo->memSizeKB, g_freePageCount, KERNEL_HEAP_SIZE);
255
256     PrintBoth("Memory Layout:\n");
257
258     PrintBoth("%x to %x - INITIAL THREAD\n",KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE-1);
259     PrintBoth("%x to %x - KERNEL STACK\n",KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE-1);
260     PrintBoth("%x to %x - KERNEL HEAP\n",KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE-1);
261     PrintBoth("%lx to %lx - PAGE LIST\n",pageListAddr,pageListEnd-1);
262     PrintBoth("%lx to %x - FREE\n",pageListEnd,FINAL_KERNEL_START-1);
263     PrintBoth("%x to %x - KERNEL CODE\n",FINAL_KERNEL_START,FINAL_KERNEL_END);
264     PrintBoth("%x to %x - IDT\n",IDT_LOCATION,TSS_LOCATION-1);
265     PrintBoth("%x to %x - TSS\n",TSS_LOCATION,GDT_LOCATION-1);
266     PrintBoth("%x to %x - GDT\n",GDT_LOCATION,TOP_OF_MEM-1);
267
268
269 }
270
271 /*
272  * Initialize the .bss section of the kernel executable image.
273  */
274 void Init_BSS(void)
275 {
276     extern char BSS_START, BSS_END;
277
278     /* Fill .bss with zeroes */
279     memset(&BSS_START, '\0', &BSS_END - &BSS_START);
280     PrintBoth("BSS Inited, BSS_START=%x, BSS_END=%x\n",BSS_START,BSS_END);
281 }
282
283 /*
284  * Allocate a page of physical memory.
285  */
286 void* Alloc_Page(void)
287 {
288     struct Page* page;
289     void *result = 0;
290
291     bool iflag = Begin_Int_Atomic();
292
293     /* See if we have a free page */
294     if (!Is_Page_List_Empty(&s_freeList)) {
295         /* Remove the first page on the freelist. */
296         page = Get_Front_Of_Page_List(&s_freeList);
297         KASSERT((page->flags & PAGE_ALLOCATED) == 0);
298         Remove_From_Front_Of_Page_List(&s_freeList);
299
300         /* Mark page as having been allocated. */
301         page->flags |= PAGE_ALLOCATED;
302         g_freePageCount--;
303         result = (void*) Get_Page_Address(page);
304     }
305
306     End_Int_Atomic(iflag);
307
308     return result;
309 }
310
311 /*
312  * Free a page of physical memory.
313  */
314 void Free_Page(void* pageAddr)
315 {
316     ulong_t addr = (ulong_t) pageAddr;
317     struct Page* page;
318     bool iflag;
319
320     iflag = Begin_Int_Atomic();
321
322     KASSERT(Is_Page_Multiple(addr));
323
324     /* Get the Page object for this page */
325     page = Get_Page(addr);
326     KASSERT((page->flags & PAGE_ALLOCATED) != 0);
327
328     /* Clear the allocation bit */
329     page->flags &= ~(PAGE_ALLOCATED);
330
331     /* Put the page back on the freelist */
332     Add_To_Back_Of_Page_List(&s_freeList, page);
333     g_freePageCount++;
334
335     End_Int_Atomic(iflag);
336 }