/* * This file implements the Page object. A Page refers to a page of data in a * file or region of memory. The offset tracks how far into the file the page * is, and the frame tracks where in physical memory the data is located. */ #include #include /* Structure for a Page in a Cache */ struct Page { Object obj; off_t offset; page_t frame; }; /* Information for find callback */ struct FindData { off_t offset; Page *result; }; static void page_delete(Object *); /* Page object type */ ObjectType pageType = { .name = "PAGE", .size = sizeof(Page), .delete = page_delete, }; /* Destroy a Page object */ static void page_delete(Object *obj) { Page *page = (void *) obj; free_frame(PAGE_ADDR(page->frame)); } /* Callback for finding a Page by offset */ static int compare_page_offset(void *object, void *data) { Page *page = object; struct FindData *find = data; if (page->offset == find->offset) { find->result = get(page); return 1; } return 0; } /* Create a new Page entry */ Page * create_page(ObjectList *cache, page_t frame, off_t offset) { Page *page = new(&pageType); page->frame = frame; page->offset = offset; add(cache, page); return page; } /* Find a Page by offset in a cache */ Page * find_page(ObjectList *cache, off_t offset) { struct FindData data = { .offset = offset, .result = NULL, }; iterate(cache, compare_page_offset, &data); return data.result; } /* Get the virtual address for the mapping of a page */ void * map_page(Page *page) { /* * Since this x86 kernel doesn't keep all physical memory mapped into * the virtual address space, the page needs to be mapped into memory. * If more virtual memory was available (e.g. x86_64) all of physical * memory could be mapped to an offset, and this function would just * return (page->frame + offset); */ set_page(0x7FF000, page->frame | PTE_PRESENT | PTE_WRITE); flush_tlb(0x7FF000); return (void *) 0x7FF000; }