|  | /* Copyright (c) 2009 The Regents of the University  of California. | 
|  | * See the COPYRIGHT files at the top of this source tree for full | 
|  | * license information. | 
|  | * | 
|  | * Kevin Klues <klueska@cs.berkeley.edu> | 
|  | */ | 
|  |  | 
|  | #ifdef __SHARC__ | 
|  | #pragma nosharc | 
|  | #endif | 
|  |  | 
|  | #ifdef __DEPUTY__ | 
|  | #pragma nodeputy | 
|  | #endif | 
|  |  | 
|  | #include <sys/queue.h> | 
|  | #include <page_alloc.h> | 
|  | #include <pmap.h> | 
|  | #include <kmalloc.h> | 
|  | #include <multiboot.h> | 
|  | #include <colored_caches.h> | 
|  |  | 
|  | page_list_t* colored_page_free_list = NULL; | 
|  | spinlock_t colored_page_free_list_lock = SPINLOCK_INITIALIZER_IRQSAVE; | 
|  |  | 
|  | /* | 
|  | * Initialize the memory free lists. | 
|  | * After this point, ONLY use the functions below | 
|  | * to allocate and deallocate physical memory via the | 
|  | * page_free_lists. | 
|  | */ | 
|  | void page_alloc_init(struct multiboot_info *mbi) | 
|  | { | 
|  | init_once_racy(return); | 
|  |  | 
|  | size_t list_size = llc_cache->num_colors*sizeof(page_list_t);; | 
|  | page_list_t* lists = (page_list_t*)boot_alloc(list_size, PGSIZE); | 
|  |  | 
|  | size_t num_colors = llc_cache->num_colors; | 
|  | for (size_t i = 0; i < num_colors; i++) | 
|  | LIST_INIT(&lists[i]); | 
|  |  | 
|  | uintptr_t first_free_page = ROUNDUP(boot_freemem, PGSIZE); | 
|  | uintptr_t first_invalid_page = LA2PPN(boot_freelimit); | 
|  | assert(first_invalid_page == max_nr_pages); | 
|  |  | 
|  | // mark kernel pages as in-use | 
|  | for (uintptr_t page = 0; page < first_free_page; page++) | 
|  | page_setref(&pages[page], 1); | 
|  |  | 
|  | // append other pages to the free lists | 
|  | for (uintptr_t page = first_free_page; page < first_invalid_page; page++) | 
|  | { | 
|  | page_setref(&pages[page], 0); | 
|  | LIST_INSERT_HEAD(&lists[page & (num_colors-1)], &pages[page], pg_link); | 
|  | } | 
|  | nr_free_pages = first_invalid_page - first_free_page; | 
|  |  | 
|  | colored_page_free_list = lists; | 
|  | } |