blob: 111e977a85ce6538a9e4689964f99dbc91eab1fa [file] [log] [blame]
/* 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>
*/
#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++)
BSD_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);
BSD_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;
}