mirror of
https://github.com/drasko/codezero.git
synced 2026-01-13 11:23:16 +01:00
53 lines
1.3 KiB
C
53 lines
1.3 KiB
C
/*
|
|
* Copyright (C) 2008 Bahadir Balban
|
|
*/
|
|
#include <l4/lib/list.h>
|
|
#include <vm_area.h>
|
|
#include <kmalloc/kmalloc.h>
|
|
|
|
/*
|
|
* This is yet unused, it is more of an anticipation
|
|
* of how mmaped devices would be mapped with a pager.
|
|
*/
|
|
struct mmap_device {
|
|
struct list_head page_list; /* Dyn-allocated page list */
|
|
unsigned long pfn_start; /* Physical pfn start */
|
|
unsigned long pfn_end; /* Physical pfn end */
|
|
};
|
|
|
|
struct page *memdev_page_in(struct vm_object *vm_obj,
|
|
unsigned long pfn_offset)
|
|
{
|
|
struct vm_file *f = vm_object_to_file(vm_obj);
|
|
struct mmap_device *memdev = f->priv_data;
|
|
struct page *page;
|
|
|
|
/* Check if its within device boundary */
|
|
if (pfn_offset >= memdev->pfn_end - memdev->pfn_start)
|
|
return PTR_ERR(-1);
|
|
|
|
/* Simply return the page if found */
|
|
list_for_each_entry(page, &memdev->page_list, list)
|
|
if (page->offset == pfn_offset)
|
|
return page;
|
|
|
|
/* Otherwise allocate one of our own for that offset and return it */
|
|
page = kzalloc(sizeof(struct page));
|
|
INIT_LIST_HEAD(&page->list);
|
|
spin_lock_init(&page->lock);
|
|
page->offset = pfn_offset;
|
|
page->owner = vm_obj;
|
|
list_add(&page->list, &memdev->page_list);
|
|
|
|
return page;
|
|
}
|
|
|
|
/* All mmapable devices are handled by this */
|
|
struct vm_pager memdev_pager = {
|
|
.ops = {
|
|
.page_in = memdev_page_in,
|
|
},
|
|
};
|
|
|
|
|