/kernel/trunk/genarch/include/mm/page_pt.h |
---|
92,10 → 92,9 |
#define SET_PTL3_FLAGS(ptl2, i, x) SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS(ptl3, i, x) SET_FRAME_FLAGS_ARCH(ptl3, i, x) |
/* |
* Determine whether the mapping is valid. |
*/ |
#define PTE_VALID(p) PTE_VALID_ARCH((p)) |
#define PTE_VALID(p) PTE_VALID_ARCH((p)) |
#define PTE_PRESENT(p) PTE_PRESENT_ARCH((p)) |
#define PTE_GET_FRAME(p) PTE_GET_FRAME_ARCH((p)) |
extern page_mapping_operations_t pt_mapping_operations; |
/kernel/trunk/genarch/include/mm/page_ht.h |
---|
46,6 → 46,10 |
#define PAGE_HT_ENTRIES_BITS 13 |
#define PAGE_HT_ENTRIES (1<<PAGE_HT_ENTRIES_BITS) |
#define PTE_VALID_ARCH(pte) ((pte) != NULL) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((pte)->frame) |
struct pte { |
link_t link; /**< Page hash table link. */ |
as_t *as; /**< Address space. */ |
/kernel/trunk/generic/include/mm/page.h |
---|
60,7 → 60,6 |
#define PAGE_GLOBAL (1<<PAGE_GLOBAL_SHIFT) |
/* TODO - check that userspace is OK, platform specific functions etc */ |
static inline void copy_to_uspace(void *dst, void *src, count_t cnt) |
{ |
/kernel/trunk/generic/include/mm/as.h |
---|
104,6 → 104,7 |
extern void as_init(void); |
extern as_t *as_create(int flags); |
extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base); |
extern __address as_remap(as_t *as, __address address, size_t size, int flags); |
extern void as_set_mapping(as_t *as, __address page, __address frame); |
extern int as_page_fault(__address page); |
extern void as_switch(as_t *old, as_t *new); |
/kernel/trunk/generic/include/syscall/syscall.h |
---|
32,6 → 32,7 |
typedef enum { |
SYS_CTL = 0, |
SYS_IO, |
SYS_MREMAP, |
SYS_IPC_CALL_SYNC, |
SYS_IPC_CALL_SYNC_MEDIUM, |
SYS_IPC_CALL_ASYNC, |
/kernel/trunk/generic/src/mm/as.c |
---|
69,6 → 69,7 |
as_t *AS_KERNEL = NULL; |
static int get_area_flags(as_area_t *a); |
static as_area_t *find_area_and_lock(as_t *as, __address va); |
/** Initialize address space subsystem. */ |
void as_init(void) |
168,36 → 169,17 |
*/ |
void as_set_mapping(as_t *as, __address page, __address frame) |
{ |
as_area_t *a, *area = NULL; |
link_t *cur; |
as_area_t *area; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&as->lock); |
/* |
* First, try locate an area. |
*/ |
for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { |
a = list_get_instance(cur, as_area_t, link); |
spinlock_lock(&a->lock); |
if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) { |
area = a; |
break; |
} |
spinlock_unlock(&a->lock); |
} |
area = find_area_and_lock(as, page); |
if (!area) { |
panic("page not part of any as_area\n"); |
} |
/* |
* Note: area->lock is held. |
*/ |
page_mapping_insert(as, page, frame, get_area_flags(area)); |
spinlock_unlock(&area->lock); |
216,33 → 198,13 |
*/ |
int as_page_fault(__address page) |
{ |
link_t *cur; |
as_area_t *a, *area = NULL; |
as_area_t *area; |
__address frame; |
ASSERT(AS); |
spinlock_lock(&AS->lock); |
/* |
* Search this areas of this address space for presence of 'page'. |
*/ |
for (cur = AS->as_area_head.next; cur != &AS->as_area_head; cur = cur->next) { |
a = list_get_instance(cur, as_area_t, link); |
spinlock_lock(&a->lock); |
if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) { |
/* |
* We found the area containing 'page'. |
* TODO: access checking |
*/ |
area = a; |
break; |
} |
spinlock_unlock(&a->lock); |
} |
area = find_area_and_lock(AS, page); |
if (!area) { |
/* |
* No area contained mapping for 'page'. |
253,10 → 215,6 |
} |
/* |
* Note: area->lock is held. |
*/ |
/* |
* In general, there can be several reasons that |
* can have caused this fault. |
* |
399,3 → 357,98 |
return as_operations->page_table_create(flags); |
} |
/** Find address space area and change it. |
* |
* @param as Address space. |
* @param address Virtual address belonging to the area to be changed. Must be page-aligned. |
* @param size New size of the virtual memory block starting at address. |
* @param flags Flags influencing the remap operation. Currently unused. |
* |
* @return address on success, (__address) -1 otherwise. |
*/ |
__address as_remap(as_t *as, __address address, size_t size, int flags) |
{ |
as_area_t *area = NULL; |
ipl_t ipl; |
size_t pages; |
ipl = interrupts_disable(); |
spinlock_lock(&as->lock); |
/* |
* Locate the area. |
*/ |
area = find_area_and_lock(as, address); |
if (!area) { |
spinlock_unlock(&as->lock); |
return (__address) -1; |
} |
pages = SIZE2FRAMES((address - area->base) + size); |
if (pages < area->size) { |
int i; |
/* |
* Shrinking the area. |
*/ |
for (i = pages; i < area->size; i++) { |
pte_t *pte; |
/* |
* Releasing physical memory. |
* This depends on the fact that the memory was allocated using frame_alloc(). |
*/ |
pte = page_mapping_find(as, area->base + i*PAGE_SIZE); |
if (pte) { |
ASSERT(PTE_PRESENT(pte)); |
frame_free(ADDR2PFN(PTE_GET_FRAME(pte))); |
} |
page_mapping_remove(as, area->base + i*PAGE_SIZE); |
} |
/* |
* Invalidate TLB's. |
*/ |
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area->size - pages); |
tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area->size - pages); |
tlb_shootdown_finalize(); |
} else { |
/* |
* Growing the area. |
*/ |
area->size = size; |
} |
spinlock_unlock(&area->lock); |
spinlock_unlock(&as->lock); |
interrupts_restore(ipl); |
return address; |
} |
/** Find address space area and lock it. |
* |
* The address space must be locked and interrupts must be disabled. |
* |
* @param as Address space. |
* @param va Virtual address. |
* |
* @return Locked address space area containing va on success or NULL on failure. |
*/ |
as_area_t *find_area_and_lock(as_t *as, __address va) |
{ |
link_t *cur; |
as_area_t *a; |
for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { |
a = list_get_instance(cur, as_area_t, link); |
spinlock_lock(&a->lock); |
if ((va >= a->base) && (va < a->base + a->size * PAGE_SIZE)) |
return a; |
spinlock_unlock(&a->lock); |
} |
return NULL; |
} |
/kernel/trunk/generic/src/syscall/syscall.c |
---|
28,6 → 28,7 |
#include <syscall/syscall.h> |
#include <proc/thread.h> |
#include <mm/as.h> |
#include <print.h> |
#include <putchar.h> |
#include <ipc/ipc.h> |
181,10 → 182,15 |
return (__native)call; |
} |
static __native sys_mremap(void *address, size_t size, unsigned long flags) |
{ |
return as_remap(AS, (__address) address, size, 0); |
} |
syshandler_t syscall_table[SYSCALL_END] = { |
sys_ctl, |
sys_io, |
sys_mremap, |
sys_ipc_call_sync, |
sys_ipc_call_sync_medium, |
sys_ipc_call_async, |
/kernel/trunk/arch/sparc64/include/types.h |
---|
47,7 → 47,7 |
typedef __u64 ipl_t; |
typedef __u64 __native; |
typedef __s64 __native; |
typedef __s64 __snative; |
typedef struct pte pte_t; |
/kernel/trunk/arch/sparc64/include/mm/page.h |
---|
38,6 → 38,7 |
#include <mm/page.h> |
#include <arch/types.h> |
#include <genarch/mm/page_ht.h> |
#define KA2PA(x) ((__address) (x)) |
#define PA2KA(x) ((__address) (x)) |
/kernel/trunk/arch/ppc32/include/mm/page.h |
---|
77,6 → 77,8 |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) |
#define PTE_VALID_ARCH(p) 1 |
#define PTE_PRESENT_ARCH(p) 1 |
#define PTE_GET_FRAME_ARCH(p) 0 |
#ifndef __ASM__ |
/kernel/trunk/arch/ppc32/src/dummy.s |
---|
36,6 → 36,9 |
.global fpu_init |
.global fpu_enable |
.global fpu_disable |
.global tlb_invalidate_all |
.global tlb_invalidate_asid |
.global tlb_invalidate_pages |
before_thread_runs_arch: |
after_thread_ran_arch: |
44,7 → 47,11 |
fpu_init: |
fpu_enable: |
fpu_disable: |
tlb_invalidate_all: |
tlb_invalidate_asid: |
tlb_invalidate_pages: |
dummy: |
0: |
b 0b |
/kernel/trunk/arch/amd64/include/mm/page.h |
---|
81,6 → 81,8 |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x)) |
#define PTE_VALID_ARCH(p) (*((__u64 *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) ((((__address)(p)->addr_12_31)<<12) | ((__address)(p)->addr_32_51<<32)) |
#ifndef __ASM__ |
/kernel/trunk/arch/mips32/include/mm/page.h |
---|
94,7 → 94,9 |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x)) |
#define PTE_VALID_ARCH(p) (*((__u32 *) (p)) != 0) |
#define PTE_VALID_ARCH(pte) (*((__u32 *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn<<FRAME_WIDTH) |
#ifndef __ASM__ |
/kernel/trunk/arch/ia32/include/mm/page.h |
---|
80,6 → 80,8 |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x)) |
#define PTE_VALID_ARCH(p) (*((__u32 *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) ((p)->frame_address<<FRAME_WIDTH) |
#ifndef __ASM__ |