Fixes icache_put on creation and KFS refcounting
[akaros.git] / kern / arch / sparc / 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 #include <multiboot.h>
21 #include <colored_caches.h>
22
23 page_list_t *COUNT(llc_cache->num_colors) colored_page_free_list = NULL;
24 spinlock_t colored_page_free_list_lock;
25
26 void page_alloc_bootstrap() {
27         // Allocate space for the array required to manage the free lists
28         size_t list_size = llc_cache->num_colors*sizeof(page_list_t);
29         colored_page_free_list = (page_list_t*) boot_alloc(list_size, PGSIZE);
30 }
31
32 /*
33  * Initialize the memory free lists.
34  * After this point, ONLY use the functions below
35  * to allocate and deallocate physical memory via the 
36  * page_free_lists. 
37  */
38 void page_alloc_init() 
39 {
40         // First Bootstrap the page alloc process
41         static bool bootstrapped = FALSE;
42         if(!bootstrapped) {
43                 bootstrapped = TRUE;
44                 page_alloc_bootstrap();
45         }
46
47         // Then, initialize the array required to manage the 
48                 // colored page free list
49         for(int i=0; i<llc_cache->num_colors; i++) {
50                 LIST_INIT(&(colored_page_free_list[i]));
51         }
52         
53         //  Finally, mark the pages already in use by the kernel. 
54         //  1) Mark page 0 as in use.
55         //     This way we preserve the real-mode IDT and BIOS structures
56         //     in case we ever need them.  (Currently we don't, but...)
57         //  2) Mark the rest of base memory as free.
58         //  3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM).
59         //     Mark it as in use so that it can never be allocated.      
60         //  4) Then extended memory [EXTPHYSMEM, ...).
61         //     Some of it is in use, some is free.
62         int i;
63         physaddr_t physaddr_after_kernel = PADDR(ROUNDUP(boot_freemem, PGSIZE));
64
65         // mark [0, physaddr_after_kernel) as in-use
66         for(i = 0; i < LA2PPN(physaddr_after_kernel); i++)
67                 atomic_init(&pages[i].pg_refcnt, 1);
68
69         // mark [physaddr_after_kernel, maxaddrpa) as free
70         for(i = LA2PPN(physaddr_after_kernel); i < LA2PPN(maxaddrpa); i++)
71         {
72                 pages[i].pg_refcnt = 0;
73                 LIST_INSERT_HEAD(
74                    &(colored_page_free_list[get_page_color(i,llc_cache)]),
75                    &pages[i],
76                    pg_link
77                 );
78         }
79
80         // mark [maxaddrpa, ...) as in-use (as they are invalid)
81         for(i = LA2PPN(maxaddrpa); i < npages; i++)
82                 atomic_init(&pages[i].pg_refcnt, 1);
83 }