-/* Copyright (c) 2009 The Regents of the University of California.
+/* Copyright (c) 2009, 2010 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>
- */
+ * Barret Rhoden <brho@cs.berkeley.edu> */
#ifndef PAGE_ALLOC_H
#define PAGE_ALLOC_H
#include <atomic.h>
#include <sys/queue.h>
-#include <ros/error.h>
+#include <error.h>
#include <arch/mmu.h>
#include <colored_page_alloc.h>
+#include <process.h>
+#include <kref.h>
+#include <kthread.h>
+#include <multiboot.h>
+
+struct page_map; /* preprocessor games */
/****************** Page Structures *********************/
-struct Page;
+struct page;
typedef size_t ppn_t;
-typedef struct Page page_t;
-typedef LIST_HEAD(PageList, Page) page_list_t;
-typedef LIST_ENTRY(Page) page_list_entry_t;
-
-/* TODO: this struct is not protected from concurrent operations in any
- * function. We may want a lock, but a better thing would be a good use of
- * reference counting and atomic operations. */
-struct Page {
- page_list_entry_t LCKD(&colored_page_free_list_lock)page_link;
- size_t page_ref;
-};
+typedef struct page page_t;
+typedef BSD_LIST_HEAD(PageList, page) page_list_t;
+typedef BSD_LIST_ENTRY(page) page_list_entry_t;
+/* Per-page flag bits related to their state in the page cache */
+#define PG_LOCKED 0x001 /* involved in an IO op */
+#define PG_UPTODATE 0x002 /* page map, filled with file data */
+#define PG_DIRTY 0x004 /* page map, data is dirty */
+#define PG_BUFFER 0x008 /* is a buffer page, has BHs */
+#define PG_PAGEMAP 0x010 /* belongs to a page map */
+#define PG_REMOVAL 0x020 /* Working flag for page map removal */
+
+/* TODO: this struct is not protected from concurrent operations in some
+ * functions. If you want to lock on it, use the spinlock in the semaphore.
+ * This structure is getting pretty big (and we're wasting RAM). If it becomes
+ * an issue, we can dynamically allocate some of these things when we're a
+ * buffer page (in a page mapping) */
+struct page {
+ BSD_LIST_ENTRY(page) pg_link; /* membership in various lists */
+ struct kref pg_kref;
+ atomic_t pg_flags;
+ struct page_map *pg_mapping; /* for debugging... */
+ unsigned long pg_index;
+ void **pg_tree_slot;
+ void *pg_private; /* type depends on page usage */
+ struct semaphore pg_sem; /* for blocking on IO */
+ uint64_t gpa; /* physical address in guest */
+ /* pg_private is overloaded. */
+};
/******** Externally visible global variables ************/
-extern uint16_t RO llc_num_colors;
+extern uint8_t* global_cache_colors_map;
extern spinlock_t colored_page_free_list_lock;
extern page_list_t LCKD(&colored_page_free_list_lock) * RO CT(llc_num_colors)
colored_page_free_list;
/*************** Functional Interface *******************/
-void page_alloc_init(void);
-error_t page_alloc(page_t *SAFE *page);
+void page_alloc_init(struct multiboot_info *mbi);
+void colored_page_alloc_init(void);
+
+error_t upage_alloc(struct proc* p, page_t *SAFE *page, int zero);
+error_t kpage_alloc(page_t *SAFE *page);
+void *kpage_alloc_addr(void);
+void *kpage_zalloc_addr(void);
+error_t upage_alloc_specific(struct proc* p, page_t *SAFE *page, size_t ppn);
+error_t kpage_alloc_specific(page_t *SAFE *page, size_t ppn);
+
void *CT(1 << order) get_cont_pages(size_t order, int flags);
+void *CT(1 << order) get_cont_pages_node(int node, size_t order, int flags);
+void *get_cont_phys_pages_at(size_t order, physaddr_t at, int flags);
void free_cont_pages(void *buf, size_t order);
-error_t page_alloc_specific(page_t *SAFE *page, size_t ppn);
-error_t l1_page_alloc(page_t *SAFE *page, size_t color);
-error_t l2_page_alloc(page_t *SAFE *page, size_t color);
-error_t l3_page_alloc(page_t *SAFE *page, size_t color);
-error_t page_free(page_t *SAFE page);
+
void page_incref(page_t *SAFE page);
void page_decref(page_t *SAFE page);
-size_t page_getref(page_t *SAFE page);
void page_setref(page_t *SAFE page, size_t val);
+
int page_is_free(size_t ppn);
+void lock_page(struct page *page);
+void unlock_page(struct page *page);
+void print_pageinfo(struct page *page);
#endif //PAGE_ALLOC_H