Changes ARCH i686 -> x86 (XCC)
[akaros.git] / kern / arch / x86 / 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  * Barret Rhoden <brho@cs.berkeley.edu>
6  * Kevin Klues <klueska@cs.berkeley.edu> */
7
8 #ifdef __SHARC__
9 #pragma nosharc
10 #define SINIT(x) x
11 #endif
12
13 #include <sys/queue.h>
14 #include <page_alloc.h>
15 #include <pmap.h>
16 #include <kmalloc.h>
17
18 spinlock_t colored_page_free_list_lock = SPINLOCK_INITIALIZER_IRQSAVE;
19
20 page_list_t LCKD(&colored_page_free_list_lock) * CT(llc_cache->num_colors) RO
21   colored_page_free_list = NULL;
22
23 static void page_alloc_bootstrap() {
24         // Allocate space for the array required to manage the free lists
25         size_t list_size = llc_cache->num_colors*sizeof(page_list_t);
26         page_list_t LCKD(&colored_page_free_list_lock)*tmp =
27             (page_list_t*)boot_alloc(list_size,PGSIZE);
28         colored_page_free_list = SINIT(tmp);
29 }
30
31 /*
32  * Initialize the memory free lists.
33  * After this point, ONLY use the functions below
34  * to allocate and deallocate physical memory via the 
35  * page_free_lists. 
36  */
37 void page_alloc_init()
38 {
39         // First Bootstrap the page alloc process
40         static bool RO bootstrapped = FALSE;
41         if (!bootstrapped) {
42                 bootstrapped = SINIT(TRUE);
43                 page_alloc_bootstrap();
44         }
45
46         // Then, initialize the array required to manage the colored page free list
47         for (int i = 0; i < llc_cache->num_colors; i++)
48                 LIST_INIT(&(colored_page_free_list[i]));
49
50         //  Then, mark the pages already in use by the kernel. 
51         //  1) Mark page 0 as in use.
52         //     This way we preserve the real-mode IDT and BIOS structures
53         //     in case we ever need them.  (Currently we don't, but...)
54         //  2) Mark the rest of base memory as free.
55         //  3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM).
56         //     Mark it as in use so that it can never be allocated.      
57         //  4) Then extended memory [EXTPHYSMEM, ...).
58         //     Some of it is in use, some is free.
59         int i;
60         extern char (SNT RO end)[];
61         physaddr_t physaddr_after_kernel = PADDR(PTRROUNDUP(boot_freemem, PGSIZE));
62
63         page_setref(&pages[0], 1);
64         // alloc the second page, since we will need it later to init the other cores
65         // probably need to be smarter about what page we use (make this dynamic) TODO
66         page_setref(&pages[1], 1);
67         for (i = 2; i < LA2PPN(IOPHYSMEM); i++) {
68                 /* this ought to be unnecessary */
69                 page_setref(&pages[i], 0);
70                 LIST_INSERT_HEAD(
71                    &(colored_page_free_list[get_page_color(page2ppn(&pages[i]), 
72                                                                llc_cache)]),
73                    &pages[i],
74                    pg_link
75                 );
76         }
77         for (i = LA2PPN(IOPHYSMEM); i < LA2PPN(EXTPHYSMEM); i++)
78                 page_setref(&pages[i], 1);
79         for (i = LA2PPN(EXTPHYSMEM); i < LA2PPN(physaddr_after_kernel); i++)
80                 page_setref(&pages[i], 1);
81         for (i = LA2PPN(physaddr_after_kernel); i < LA2PPN(maxaddrpa); i++) {
82                 page_setref(&pages[i], 0);
83                 LIST_INSERT_HEAD(
84                    &(colored_page_free_list[get_page_color(page2ppn(&pages[i]), 
85                                                                llc_cache)]),
86                    &pages[i],
87                    pg_link
88                 );
89         }
90         // this block out all memory above maxaddrpa.  will need another mechanism
91         // to allocate and map these into the kernel address space
92         for (i = LA2PPN(maxaddrpa); i < npages; i++)
93                 page_setref(&pages[i], 1);
94         printk("Page alloc init successful\n");
95 }
96