71fb695abb3e8c9bcabdb4a6f23a1cf8be52cf90
[akaros.git] / kern / arch / i386 / page_alloc.c
1 /* Copyright (c) 2009 The Regents of the University  of California. 
2  * See the COPYRIGHT files at the top of this source tree for full 
3  * license information.
4  * 
5  * Kevin Klues <klueska@cs.berkeley.edu>    
6  */
7
8 #ifdef __SHARC__
9 #pragma nosharc
10 #endif
11
12 #ifdef __DEPUTY__
13 //#pragma nodeputy
14 #endif
15
16 #include <sys/queue.h>
17 #include <page_alloc.h>
18 #include <pmap.h>
19 #include <kmalloc.h>
20
21 page_list_t page_free_list;    // Free list of physical pages
22 DECLARE_CACHE_COLORED_PAGE_FREE_LISTS(); // Free list of pages filed by color
23
24 /*
25  * Initialize the memory free lists.
26  * After this point, ONLY use the functions below
27  * to allocate and deallocate physical memory via the 
28  * page_free_lists. 
29  */
30 void page_alloc_init() 
31 {
32         // Now, initialize the lists required to manage the page free lists
33         LIST_INIT(&page_free_list);
34         INIT_CACHE_COLORED_PAGE_FREE_LISTS();
35         
36         //  Finally, mark the pages already in use by the kernel. 
37         //  1) Mark page 0 as in use.
38         //     This way we preserve the real-mode IDT and BIOS structures
39         //     in case we ever need them.  (Currently we don't, but...)
40         //  2) Mark the rest of base memory as free.
41         //  3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM).
42         //     Mark it as in use so that it can never be allocated.      
43         //  4) Then extended memory [EXTPHYSMEM, ...).
44         //     Some of it is in use, some is free.
45         int i;
46         extern char (SNT end)[];
47         physaddr_t physaddr_after_kernel = PADDR(PTRROUNDUP(boot_freemem, PGSIZE));
48
49         pages[0].page_ref = 1;
50         // alloc the second page, since we will need it later to init the other cores
51         // probably need to be smarter about what page we use (make this dynamic) TODO
52         pages[1].page_ref = 1;
53         for (i = 2; i < PPN(IOPHYSMEM); i++) {
54                 pages[i].page_ref = 0;
55                 LIST_INSERT_HEAD(&page_free_list, &pages[i], global_link);
56                 INSERT_CACHE_COLORING_PAGE_ONTO_FREE_LISTS(&pages[i]);
57         }
58         for (i = PPN(IOPHYSMEM); i < PPN(EXTPHYSMEM); i++) {
59                 pages[i].page_ref = 1;
60         }
61         for (i = PPN(EXTPHYSMEM); i < PPN(physaddr_after_kernel); i++) {
62                 pages[i].page_ref = 1;
63         }
64         for (i = PPN(physaddr_after_kernel); i < PPN(maxaddrpa); i++) {
65                 pages[i].page_ref = 0;
66                 LIST_INSERT_HEAD(&page_free_list, &pages[i], global_link);
67                 INSERT_CACHE_COLORING_PAGE_ONTO_FREE_LISTS(&pages[i]);
68         }
69         // this block out all memory above maxaddrpa.  will need another mechanism
70         // to allocate and map these into the kernel address space
71         for (i = PPN(maxaddrpa); i < npages; i++) {
72                 pages[i].page_ref = 1;
73         }
74 }
75