aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/include
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-09 13:35:45 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-09 13:35:45 +0100
commita9a2ea9125f89347e0aa038a136ebd43e6b251b4 (patch)
treea2ef4b04803a6ce9689d472f7ee26ed477a376a0 /src/kernel/include
parent8c1f280c1bc948a20e244b32d824780b08bf85c9 (diff)
downloadkogata-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.h73
-rw-r--r--src/kernel/include/process.h15
-rw-r--r--src/kernel/include/sys.h7
-rw-r--r--src/kernel/include/vfs.h4
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;
// -------------------------------------------