diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-09 13:35:45 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-09 13:35:45 +0100 |
commit | a9a2ea9125f89347e0aa038a136ebd43e6b251b4 (patch) | |
tree | a2ef4b04803a6ce9689d472f7ee26ed477a376a0 /src/kernel/include | |
parent | 8c1f280c1bc948a20e244b32d824780b08bf85c9 (diff) | |
download | kogata-a9a2ea9125f89347e0aa038a136ebd43e6b251b4.tar.gz kogata-a9a2ea9125f89347e0aa038a136ebd43e6b251b4.zip |
Add pager interface ; implement basic functionnality to replace private maps.
Diffstat (limited to 'src/kernel/include')
-rw-r--r-- | src/kernel/include/pager.h | 73 | ||||
-rw-r--r-- | src/kernel/include/process.h | 15 | ||||
-rw-r--r-- | src/kernel/include/sys.h | 7 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 4 |
4 files changed, 90 insertions, 9 deletions
diff --git a/src/kernel/include/pager.h b/src/kernel/include/pager.h new file mode 100644 index 0000000..5491d10 --- /dev/null +++ b/src/kernel/include/pager.h @@ -0,0 +1,73 @@ +#pragma once + +#include <hashtbl.h> +#include <mutex.h> + +#include <paging.h> + +#define PAGE_PINNED 0x01 +#define PAGE_ACCESSED 0x02 +#define PAGE_DIRTY 0x04 + +typedef struct pager pager_t; +typedef struct user_region user_region_t; +typedef struct fs_node fs_node_t; + +typedef struct { + size_t (*read)(fs_node_t* data, size_t offset, size_t len, char* ptr); + size_t (*write)(fs_node_t* data, size_t offset, size_t len, const char* ptr); + bool (*resize)(fs_node_t* data, size_t new_size); +} vfs_pager_ops_t; + +typedef struct { + void (*page_in)(pager_t *p, size_t offset, size_t len); // allocates the pages + void (*page_commit)(pager_t *p, size_t offset, size_t len); // writes pages back to storage (if applicable) + void (*page_out)(pager_t *p, size_t offset, size_t len); // frees the pages (no need to write back) + void (*page_release)(pager_t *p, size_t offset, size_t len); // called on delete/resize +} pager_ops_t; + +typedef struct pager { + pager_ops_t *ops; + + union { + struct { + fs_node_t* vfs_data; + vfs_pager_ops_t *vfs_ops; + } vfs_pager; + struct { + size_t phys_offset; + } device_pager; + }; + + size_t size; + + hashtbl_t *pages; + mutex_t lock; + + user_region_t *maps; +} pager_t; + +pager_t* new_swap_pager(size_t size); +pager_t* new_vfs_pager(size_t size, fs_node_t* vfs_node, vfs_pager_ops_t *vfs_ops); +pager_t* new_dev_pager(size_t size, size_t phys_offset); + +void delete_pager(pager_t *p); + +bool pager_resize(pager_t *p, size_t newsize); + +// void pager_pin_region(pager_t *pager, size_t offset, size_t len); // implement later +// void pager_unpin_region(pager_t *pager, size_t offset, size_t len); + +void pager_access(pager_t *p, size_t offset, size_t len, bool accessed, bool dirty); +void pager_commit_dirty(pager_t *p); + +int pager_get_frame(pager_t *p, size_t offset); + +size_t pager_read(pager_t *p, size_t offset, size_t len, char* buf); +size_t pager_write(pager_t *p, size_t offset, size_t len, const char* buf); + +void pager_add_map(pager_t *p, user_region_t *reg); +void pager_rm_map(pager_t *p, user_region_t *reg); + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/process.h b/src/kernel/include/process.h index 8dfa274..8cdfe85 100644 --- a/src/kernel/include/process.h +++ b/src/kernel/include/process.h @@ -15,9 +15,9 @@ #include <thread.h> #include <vfs.h> +#include <pager.h> -#include <mmap.h> - +#include <mmap.h> // common header for mmaps #include <proc.h> // common header defining process statuses #define USERSTACK_ADDR 0xB8000000 @@ -31,12 +31,15 @@ typedef struct user_region { void* addr; size_t size; - int mode; + fs_handle_t *file; + pager_t *pager; + size_t offset; + bool own_pager; - fs_handle_t *file; // null if not mmaped-file - size_t file_offset; + int16_t mode; - struct user_region *next; + struct user_region *next_in_proc; + struct user_region *next_for_pager; } user_region_t; typedef struct process { diff --git a/src/kernel/include/sys.h b/src/kernel/include/sys.h index 944df96..61bfc59 100644 --- a/src/kernel/include/sys.h +++ b/src/kernel/include/sys.h @@ -75,9 +75,10 @@ static inline void invlpg(void* addr) { #define PAGE_SIZE 0x1000 #define PAGE_MASK 0xFFFFF000 -#define PAGE_ALIGN_DOWN(x) (((size_t)x) & PAGE_MASK) -#define PAGE_ALIGN_UP(x) ((((size_t)x)&(~PAGE_MASK)) == 0 ? ((size_t)x) : (((size_t)x) & PAGE_MASK) + PAGE_SIZE) -#define PAGE_ID(x) (((size_t)x) / PAGE_SIZE) +#define PAGE_ALIGNED(x) ((((size_t)(x)) & (~PAGE_MASK)) == 0) +#define PAGE_ALIGN_DOWN(x) (((size_t)(x)) & PAGE_MASK) +#define PAGE_ALIGN_UP(x) ((((size_t)(x))&(~PAGE_MASK)) == 0 ? ((size_t)x) : (((size_t)x) & PAGE_MASK) + PAGE_SIZE) +#define PAGE_ID(x) (((size_t)(x)) / PAGE_SIZE) #define PAGE_SHIFT 12 #define PT_SHIFT 10 // PAGE_SHIFT + PT_SHIFT + PT_SHIFT = 32 diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index cc6d11c..cdd9e8d 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -8,6 +8,8 @@ #include <fs.h> // common header +#include <pager.h> + // How to use : // - When using a filesystem : never call the operations in fs_*_ops_t directly, use // the functions defined bellow in section "public functions"; @@ -108,6 +110,8 @@ typedef struct fs_node { // These fields are filled by the FS's specific walk() code fs_node_ops_t *ops; fs_node_ptr data; + + pager_t *pager; } fs_node_t; // ------------------------------------------- |