Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 702 → Rev 703

/kernel/trunk/doc/mm
1,10 → 1,16
Memory management
=================
 
SPARTAN kernel deploys generic interface for 4-level page tables,
no matter what the real underlying hardware architecture is.
1. Virtual Address Translation
 
1.1 Hierarchical 4-level per address space page tables
 
SPARTAN kernel deploys generic interface for 4-level page tables
for these architectures: amd64, ia32, mips32 and ppc32. In this
setting, page tables are hierarchical and are not shared by
address spaces (i.e. one set of page tables per address space).
 
 
VADDR
+-----------------------------------------------------------------------------+
| PTL0_INDEX | PTL1_INDEX | PTL2_INDEX | PTL3_INDEX | OFFSET |
50,3 → 56,12
On architectures whose hardware has fewer levels, PTL2 and, if need be, PTL1 are
left out. TLB-only architectures are to define custom format for software page
tables.
 
 
 
1.2 Single global page hash table
 
Generic page hash table interface is deployed on 64-bit architectures without
implied hardware support for hierarchical page tables, i.e. ia64 and sparc64.
There is only one global page hash table in the system shared by all address
spaces.
/kernel/trunk/generic/include/proc/task.h
33,11 → 33,12
#include <synch/spinlock.h>
#include <list.h>
 
/** Task structure. */
struct task {
SPINLOCK_DECLARE(lock);
link_t th_head; /**< List of threads contained in this task. */
link_t tasks_link; /**< Link to other tasks within the system. */
vm_t *vm;
as_t *as; /**< Address space. */
};
 
extern spinlock_t tasks_lock;
44,6 → 45,6
extern link_t tasks_head;
 
extern void task_init(void);
extern task_t *task_create(vm_t *m);
extern task_t *task_create(as_t *as);
 
#endif
/kernel/trunk/generic/include/arch.h
39,7 → 39,7
#define CPU THE->cpu
#define THREAD THE->thread
#define TASK THE->task
#define VM THE->vm
#define AS THE->as
#define PREEMPTION_DISABLED THE->preemption_disabled
 
/**
52,7 → 52,7
thread_t *thread; /**< Current thread. */
task_t *task; /**< Current task. */
cpu_t *cpu; /**< Executing cpu. */
vm_t *vm; /**< Current vm. */
as_t *as; /**< Current address space. */
};
 
#define THE ((the_t *)(get_stack_base()))
/kernel/trunk/generic/include/typedefs.h
70,9 → 70,9
typedef struct frame frame_t;
typedef struct region region_t;
 
typedef enum vm_type vm_type_t;
typedef struct vm_area vm_area_t;
typedef struct vm vm_t;
typedef enum as_area_type as_area_type_t;
typedef struct as_area as_area_t;
typedef struct as as_t;
 
typedef struct link link_t;
 
/kernel/trunk/generic/include/mm/vm.h
File deleted
/kernel/trunk/generic/include/mm/as.h
0,0 → 1,101
/*
* Copyright (C) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __AS_H__
#define __AS_H__
 
#include <arch/mm/page.h>
#include <arch/mm/as.h>
#include <arch/mm/asid.h>
#include <arch/types.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <list.h>
 
#define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
#define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
#define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
#define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
 
#define IS_KA(addr) ((addr)>=KERNEL_ADDRESS_SPACE_START && (addr)<=KERNEL_ADDRESS_SPACE_END)
 
#define UTEXT_ADDRESS UTEXT_ADDRESS_ARCH
#define USTACK_ADDRESS USTACK_ADDRESS_ARCH
#define UDATA_ADDRESS UDATA_ADDRESS_ARCH
 
enum as_area_type {
AS_AREA_TEXT = 1, AS_AREA_DATA, AS_AREA_STACK
};
 
/** Address space area structure.
*
* Each as_area_t structure describes one contiguous area of virtual memory.
* In the future, it should not be difficult to support shared areas.
*/
struct as_area {
SPINLOCK_DECLARE(lock);
link_t link;
as_area_type_t type;
size_t size; /**< Size of this area. */
__address base; /**< Base address of this area. */
index_t *mapping; /**< Map of physical frame numbers mapped to virtual page numbers in this area. */
};
 
/** Address space structure.
*
* as_t contains the list of as_areas of userspace accessible
* pages for one or more tasks. Ranges of kernel memory pages are not
* supposed to figure in the list as they are shared by all tasks and
* set up during system initialization.
*/
struct as {
SPINLOCK_DECLARE(lock);
link_t as_area_head;
pte_t *ptl0;
asid_t asid; /**< Address space identifier. */
};
 
extern as_t * as_create(pte_t *ptl0);
extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base);
extern void as_area_load_mapping(as_area_t *a, index_t *pfn);
extern int as_page_fault(__address page);
extern void as_install(as_t *m);
 
/*
* Each architecture should implement this function.
* Its main purpose is to do TLB purges according
* to architecture's requirements. Note that
* some architectures invalidate their TLB automatically
* on hardware address space switch (e.g. ia32 and
* amd64).
*/
#ifndef as_install_arch
extern void as_install_arch(as_t *as);
#endif /* !def as_install_arch */
 
#endif
/kernel/trunk/generic/src/proc/scheduler.c
32,7 → 32,7
#include <mm/heap.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <arch/asm.h>
#include <arch/faddr.h>
#include <arch/atomic.h>
352,28 → 352,28
* If both the old and the new task are the same, lots of work is avoided.
*/
if (TASK != THREAD->task) {
vm_t *m1 = NULL;
vm_t *m2;
as_t *as1 = NULL;
as_t *as2;
 
if (TASK) {
spinlock_lock(&TASK->lock);
m1 = TASK->vm;
as1 = TASK->as;
spinlock_unlock(&TASK->lock);
}
 
spinlock_lock(&THREAD->task->lock);
m2 = THREAD->task->vm;
as2 = THREAD->task->as;
spinlock_unlock(&THREAD->task->lock);
/*
* Note that it is possible for two tasks to share one vm mapping.
* Note that it is possible for two tasks to share one address space.
*/
if (m1 != m2) {
if (as1 != as2) {
/*
* Both tasks and vm mappings are different.
* Both tasks and address spaces are different.
* Replace the old one with the new one.
*/
vm_install(m2);
as_install(as2);
}
TASK = THREAD->task;
}
/kernel/trunk/generic/src/proc/the.c
42,7 → 42,7
the->cpu = NULL;
the->thread = NULL;
the->task = NULL;
the->vm = NULL;
the->as = NULL;
}
 
/** Copy THE structure
/kernel/trunk/generic/src/proc/task.c
28,7 → 28,7
 
#include <proc/thread.h>
#include <proc/task.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <mm/heap.h>
 
#include <synch/spinlock.h>
54,12 → 54,12
*
* Create new task with no threads.
*
* @param m Task's virtual memory structure.
* @param as Task's address space.
*
* @return New task's structure on success, NULL on failure.
*
*/
task_t *task_create(vm_t *m)
task_t *task_create(as_t *as)
{
ipl_t ipl;
task_t *ta;
69,7 → 69,7
spinlock_initialize(&ta->lock, "task_ta_lock");
list_initialize(&ta->th_head);
list_initialize(&ta->tasks_link);
ta->vm = m;
ta->as = as;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
/kernel/trunk/generic/src/main/kinit.c
39,7 → 39,7
#include <arch/asm.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <mm/frame.h>
#include <print.h>
#include <memstr.h>
70,8 → 70,10
{
thread_t *t;
#ifdef CONFIG_USERSPACE
vm_t *m;
vm_area_t *a;
as_t *as;
as_area_t *a;
__address frame;
index_t pfn[1];
task_t *u;
#endif
 
141,10 → 143,10
/*
* Create the first user task.
*/
m = vm_create(NULL);
if (!m)
panic("vm_create\n");
u = task_create(m);
as = as_create(NULL);
if (!as)
panic("as_create\n");
u = task_create(as);
if (!u)
panic("task_create\n");
t = thread_create(uinit, NULL, u, THREAD_USER_STACK);
152,24 → 154,28
panic("thread_create\n");
 
/*
* Create the text vm_area and copy the userspace code there.
* Create the text as_area and copy the userspace code there.
*/
a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS);
a = as_area_create(as, AS_AREA_TEXT, 1, UTEXT_ADDRESS);
if (!a)
panic("vm_area_create: vm_text\n");
vm_area_map(a, m);
panic("as_area_create: text\n");
 
frame = frame_alloc(0, ONE_FRAME, NULL);
 
if (config.init_size > 0)
memcpy((void *) PA2KA(a->mapping[0]), (void *) config.init_addr, config.init_size < PAGE_SIZE ? config.init_size : PAGE_SIZE);
memcpy((void *) PA2KA(frame), (void *) config.init_addr, config.init_size < PAGE_SIZE ? config.init_size : PAGE_SIZE);
else
memcpy((void *) PA2KA(a->mapping[0]), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE);
memcpy((void *) PA2KA(frame), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE);
pfn[0] = frame / FRAME_SIZE;
as_area_load_mapping(a, pfn);
 
/*
* Create the data vm_area.
* Create the data as_area.
*/
a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS);
a = as_area_create(as, AS_AREA_STACK, 1, USTACK_ADDRESS);
if (!a)
panic("vm_area_create: vm_stack\n");
vm_area_map(a, m);
panic("as_area_create: stack\n");
thread_ready(t);
#endif /* CONFIG_USERSPACE */
/kernel/trunk/generic/src/main/main.c
48,7 → 48,7
#include <mm/page.h>
#include <genarch/mm/page_pt.h>
#include <mm/tlb.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <synch/waitq.h>
#include <arch/arch.h>
#include <arch.h>
135,7 → 135,7
*/
void main_bsp_separated_stack(void)
{
vm_t *m;
as_t *as;
task_t *k;
thread_t *t;
183,16 → 183,16
printf("config.init_addr=%X, config.init_size=%d\n", config.init_addr, config.init_size);
 
/*
* Create kernel vm mapping.
* Create kernel address space.
*/
m = vm_create(GET_PTL0_ADDRESS());
if (!m)
panic("can't create kernel vm address space\n");
as = as_create(GET_PTL0_ADDRESS());
if (!as)
panic("can't create kernel address space\n");
 
/*
* Create kernel task.
*/
k = task_create(m);
k = task_create(as);
if (!k)
panic("can't create kernel task\n");
/kernel/trunk/generic/src/mm/vm.c
File deleted
/kernel/trunk/generic/src/mm/as.c
0,0 → 1,304
/*
* Copyright (C) 2001-2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/*
* This file contains address space manipulation functions.
* Roughly speaking, this is a higher-level client of
* Virtual Address Translation (VAT) subsystem.
*/
 
#include <mm/as.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/tlb.h>
#include <mm/heap.h>
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <arch/mm/asid.h>
#include <arch/mm/as.h>
#include <arch/types.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <config.h>
#include <list.h>
#include <panic.h>
#include <arch/asm.h>
#include <debug.h>
#include <memstr.h>
#include <arch.h>
#include <print.h>
 
#define KAS_START_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)
#define KAS_END_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_END)
#define KAS_INDICES (1+(KAS_END_INDEX-KAS_START_INDEX))
 
/*
* Here we assume that PFN (Physical Frame Numbers) space
* is smaller than the width of index_t. UNALLOCATED_PFN
* can be then used to mark mappings wich were not
* allocated a physical frame.
*/
#define UNALLOCATED_PFN ((index_t) -1)
 
/** Create address space. */
/*
* FIXME: this interface must be meaningful for all possible VAT
* (Virtual Address Translation) mechanisms.
*/
as_t *as_create(pte_t *ptl0)
{
as_t *as;
 
as = (as_t *) malloc(sizeof(as_t));
if (as) {
spinlock_initialize(&as->lock, "as_lock");
list_initialize(&as->as_area_head);
 
as->asid = asid_get();
 
as->ptl0 = ptl0;
if (!as->ptl0) {
pte_t *src_ptl0, *dst_ptl0;
src_ptl0 = (pte_t *) PA2KA((__address) GET_PTL0_ADDRESS());
dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
 
// memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
// memcpy((void *) &dst_ptl0[KAS_START_INDEX], (void *) &src_ptl0[KAS_START_INDEX], KAS_INDICES);
memcpy((void *) dst_ptl0,(void *) src_ptl0, PAGE_SIZE);
 
as->ptl0 = (pte_t *) KA2PA((__address) dst_ptl0);
}
}
 
return as;
}
 
/** Create address space area of common attributes.
*
* The created address space area is added to the target address space.
*
* @param as Target address space.
* @param type Type of area.
* @param size Size of area in multiples of PAGE_SIZE.
* @param base Base address of area.
*
* @return Address space area on success or NULL on failure.
*/
as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base)
{
ipl_t ipl;
as_area_t *a;
if (base % PAGE_SIZE)
panic("addr not aligned to a page boundary");
ipl = interrupts_disable();
spinlock_lock(&as->lock);
/*
* TODO: test as_area which is to be created doesn't overlap with an existing one.
*/
a = (as_area_t *) malloc(sizeof(as_area_t));
if (a) {
int i;
a->mapping = (index_t *) malloc(size * sizeof(index_t));
if (!a->mapping) {
free(a);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return NULL;
}
for (i=0; i<size; i++) {
/*
* Frames will be allocated on-demand by
* as_page_fault().
*/
a->mapping[i] = UNALLOCATED_PFN;
}
spinlock_initialize(&a->lock, "as_area_lock");
link_initialize(&a->link);
a->type = type;
a->size = size;
a->base = base;
list_append(&a->link, &as->as_area_head);
 
}
 
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return a;
}
 
/** Load mapping for address space area.
*
* Initialize a->mapping.
*
* @param a Target address space area.
* @param pfn Array of frame numbers. Number of elements must match with a->mapping.
*/
void as_area_load_mapping(as_area_t *a, index_t *pfn)
{
ipl_t ipl;
int i;
ipl = interrupts_disable();
spinlock_lock(&a->lock);
 
for (i = 0; i < a->size; i++) {
ASSERT(a->mapping[i] == UNALLOCATED_PFN);
a->mapping[i] = pfn[i];
}
spinlock_unlock(&a->lock);
interrupts_restore(ipl);
}
 
/** Handle page fault within the current address space.
*
* This is the high-level page fault handler.
* Interrupts are assumed disabled.
*
* @param page Faulting page.
*
* @return 0 on page fault, 1 if address space operation
*/
int as_page_fault(__address page)
{
int flags;
link_t *cur;
as_area_t *a, *area = NULL;
index_t vpn;
__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
*/
vpn = (page - a->base) / PAGE_SIZE;
area = a;
break;
}
spinlock_unlock(&a->lock);
}
if (!area) {
/*
* No area contained mapping for 'page'.
* Signal page fault to low-level handler.
*/
spinlock_unlock(&AS->lock);
return 0;
}
 
/*
* Note: area->lock is held.
*/
/*
* Decide if a frame needs to be allocated.
* If so, allocate it and adjust area->mapping map.
*/
if (area->mapping[vpn] == UNALLOCATED_PFN) {
frame = frame_alloc(0, ONE_FRAME, NULL);
memsetb(frame, FRAME_SIZE, 0);
area->mapping[vpn] = frame / FRAME_SIZE;
} else {
frame = area->mapping[vpn] * FRAME_SIZE;
}
switch (area->type) {
case AS_AREA_TEXT:
flags = PAGE_EXEC | PAGE_READ | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE;
break;
case AS_AREA_DATA:
case AS_AREA_STACK:
flags = PAGE_READ | PAGE_WRITE | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE;
break;
default:
panic("unexpected as_area_type_t %d", area->type);
}
 
/*
* Map 'page' to 'frame'.
* Note that TLB shootdown is not attempted as only new information is being
* inserted into page tables.
*/
page_mapping_insert(page, AS->asid, frame, flags, (__address) AS->ptl0);
spinlock_unlock(&area->lock);
spinlock_unlock(&AS->lock);
 
return 1;
}
 
/** Install address space on CPU.
*
* @param as Address space.
*/
void as_install(as_t *as)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&as->lock);
ASSERT(as->ptl0);
SET_PTL0_ADDRESS(as->ptl0);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
 
/*
* Perform architecture-specific steps.
* (e.g. invalidate TLB, install ASID etc.)
*/
as_install_arch(as);
AS = as;
}
/kernel/trunk/generic/src/mm/frame.c
31,7 → 31,7
#include <arch/types.h>
#include <mm/heap.h>
#include <mm/frame.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <panic.h>
#include <debug.h>
#include <list.h>
/kernel/trunk/generic/src/mm/page.c
1,5 → 1,5
/*
* Copyright (C) 2001-2004 Jakub Jermar
* Copyright (C) 2001-2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,6 → 26,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/*
* Virtual Address Translation subsystem.
*/
 
#include <mm/page.h>
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
/kernel/trunk/Makefile
117,7 → 117,7
generic/src/mm/frame.c \
generic/src/mm/page.c \
generic/src/mm/tlb.c \
generic/src/mm/vm.c \
generic/src/mm/as.c \
generic/src/lib/func.c \
generic/src/lib/list.c \
generic/src/lib/memstr.c \
/kernel/trunk/arch/sparc64/include/mm/vm.h
File deleted
/kernel/trunk/arch/sparc64/include/mm/as.h
0,0 → 1,45
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __sparc64_AS_H__
#define __sparc64_AS_H__
 
#include <arch/types.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (__address) 0x0000000000000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (__address) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (__address) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (__address) 0xffffffffffffffff
 
#define UTEXT_ADDRESS_ARCH (0x0000000000000000+PAGE_SIZE)
#define USTACK_ADDRESS_ARCH (0x7fffffffffffffff-(PAGE_SIZE-1))
#define UDATA_ADDRESS_ARCH 0x8000000000000000
 
#define as_install_arch(as)
 
#endif
/kernel/trunk/arch/ia64/include/mm/vm.h
File deleted
/kernel/trunk/arch/ia64/include/mm/as.h
0,0 → 1,45
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ia64_AS_H__
#define __ia64_AS_H__
 
#include <arch/types.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (__address) 0x8000000000000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (__address) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (__address) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (__address) 0x7fffffffffffffff
 
#define UTEXT_ADDRESS_ARCH 0x0000000000001000
#define USTACK_ADDRESS_ARCH (0x7fffffffffffffff-(PAGE_SIZE-1))
#define UDATA_ADDRESS_ARCH 0x0000000001001000
 
#define as_install_arch(as)
 
#endif
/kernel/trunk/arch/ppc32/include/mm/vm.h
File deleted
/kernel/trunk/arch/ppc32/include/mm/as.h
0,0 → 1,45
/*
* Copyright (C) 2005 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ppc32_AS_H__
#define __ppc32_AS_H__
 
#include <arch/types.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (__address) 0x80000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (__address) 0xffffffff
#define USER_ADDRESS_SPACE_START_ARCH (__address) 0x00000000
#define USER_ADDRESS_SPACE_END_ARCH (__address) 0x7fffffff
 
#define UTEXT_ADDRESS_ARCH 0x00001000
#define USTACK_ADDRESS_ARCH (0x7fffffff-(PAGE_SIZE-1))
#define UDATA_ADDRESS_ARCH 0x21000000
 
#define as_install_arch(as)
 
#endif
/kernel/trunk/arch/amd64/include/mm/vm.h
File deleted
/kernel/trunk/arch/amd64/include/mm/as.h
0,0 → 1,45
/*
* Copyright (C) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __amd64_AS_H__
#define __amd64_AS_H__
 
#include <arch/types.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (__address) 0xffffffff80000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (__address) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (__address) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (__address) 0x00008fffffffffff
 
#define UTEXT_ADDRESS_ARCH 0x00001000
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
#define UDATA_ADDRESS_ARCH 0x21000000
 
#define as_install_arch(as)
 
#endif
/kernel/trunk/arch/amd64/src/userspace.c
31,7 → 31,7
#include <arch/types.h>
#include <arch.h>
#include <proc/thread.h>
#include <mm/vm.h>
#include <mm/as.h>
 
 
/** Enter userspace
/kernel/trunk/arch/amd64/src/interrupt.c
35,6 → 35,7
#include <cpu.h>
#include <arch/asm.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <arch/asm.h>
124,13 → 125,16
#endif
}
 
 
 
void page_fault(int n, void *stack)
{
print_info_errcode(n,stack);
printf("Page fault address: %Q\n", read_cr2());
panic("page fault\n");
__address page;
page = read_cr2();
if (!as_page_fault(page)) {
print_info_errcode(n,stack);
printf("Page fault address: %Q\n", page);
panic("page fault\n");
}
}
 
void syscall(int n, void *stack)
/kernel/trunk/arch/mips32/include/mm/vm.h
File deleted
/kernel/trunk/arch/mips32/include/mm/as.h
0,0 → 1,44
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __mips32_AS_H__
#define __mips32_AS_H__
 
#include <arch/types.h>
#include <typedefs.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (__address) 0x80000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (__address) 0xffffffff
#define USER_ADDRESS_SPACE_START_ARCH (__address) 0x00000000
#define USER_ADDRESS_SPACE_END_ARCH (__address) 0x7fffffff
 
#define UTEXT_ADDRESS_ARCH 0x00004000
#define USTACK_ADDRESS_ARCH (0x80000000-PAGE_SIZE)
#define UDATA_ADDRESS_ARCH 0x01001000
 
#endif
/kernel/trunk/arch/mips32/Makefile.inc
112,7 → 112,7
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/vm.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/drivers/arc.c \
arch/$(ARCH)/src/drivers/msim.c \
/kernel/trunk/arch/mips32/src/mm/vm.c
File deleted
/kernel/trunk/arch/mips32/src/mm/tlb.c
30,7 → 30,7
#include <arch/mm/asid.h>
#include <mm/tlb.h>
#include <mm/page.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <arch/cp0.h>
#include <panic.h>
#include <arch.h>
92,7 → 92,7
 
badvaddr = cp0_badvaddr_read();
 
spinlock_lock(&VM->lock);
spinlock_lock(&AS->lock);
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
103,7 → 103,7
*/
pte->a = 1;
 
prepare_entry_hi(&hi, VM->asid, badvaddr);
prepare_entry_hi(&hi, AS->asid, badvaddr);
prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn);
 
/*
121,11 → 121,11
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwr();
 
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
return;
fail:
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
tlb_refill_fail(pstate);
}
 
154,7 → 154,7
tlbp();
index.value = cp0_index_read();
spinlock_lock(&VM->lock);
spinlock_lock(&AS->lock);
/*
* Fail if the entry is not in TLB.
190,11 → 190,11
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwi();
 
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
return;
fail:
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
tlb_invalid_fail(pstate);
}
 
223,7 → 223,7
tlbp();
index.value = cp0_index_read();
spinlock_lock(&VM->lock);
spinlock_lock(&AS->lock);
/*
* Fail if the entry is not in TLB.
266,11 → 266,11
cp0_pagemask_write(TLB_PAGE_MASK_16K);
tlbwi();
 
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
return;
fail:
spinlock_unlock(&VM->lock);
spinlock_unlock(&AS->lock);
tlb_modified_fail(pstate);
}
 
312,7 → 312,7
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The VM->lock must be held on entry to this function.
* The AS->lock must be held on entry to this function.
*
* @param badvaddr Faulting virtual address.
*
328,15 → 328,40
/*
* Handler cannot succeed if the ASIDs don't match.
*/
if (hi.asid != VM->asid) {
printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
if (hi.asid != AS->asid) {
printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
return NULL;
}
 
/*
* Check if the mapping exists in page tables.
*/
pte = page_mapping_find(badvaddr, AS->asid, 0);
if (pte && pte->lo.v) {
/*
* Mapping found in page tables.
* Immediately succeed.
*/
return pte;
} else {
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
if (as_page_fault(badvaddr)) {
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
pte = page_mapping_find(badvaddr, AS->asid, 0);
ASSERT(pte && pte->lo.v);
return pte;
}
}
 
/*
* Handler cannot succeed if badvaddr has no mapping.
*/
pte = page_mapping_find(badvaddr, VM->asid, 0);
if (!pte) {
printf("No such mapping.\n");
return NULL;
/kernel/trunk/arch/mips32/src/mm/as.c
0,0 → 1,63
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <arch/mm/as.h>
#include <arch/mm/tlb.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch/cp0.h>
#include <arch.h>
 
/** Install address space.
*
* Install ASID and if necessary, purge TLB.
*
* @param as Address space structure.
*/
void as_install_arch(as_t *as)
{
entry_hi_t hi;
ipl_t ipl;
 
/*
* If necessary, purge TLB.
*/
tlb_invalidate_asid(as->asid); /* TODO: do it only if necessary */
 
/*
* Install ASID.
*/
hi.value = cp0_entry_hi_read();
 
ipl = interrupts_disable();
spinlock_lock(&as->lock);
hi.asid = as->asid;
cp0_entry_hi_write(hi.value);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
}
/kernel/trunk/arch/mips32/src/mips32.c
31,7 → 31,7
#include <arch/cp0.h>
#include <arch/exception.h>
#include <arch/asm.h>
#include <mm/vm.h>
#include <mm/as.h>
 
#include <userspace.h>
#include <arch/console.h>
/kernel/trunk/arch/ia32/include/mm/vm.h
File deleted
/kernel/trunk/arch/ia32/include/mm/as.h
0,0 → 1,45
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ia32_AS_H__
#define __ia32_AS_H__
 
#include <arch/types.h>
 
#define KERNEL_ADDRESS_SPACE_START_ARCH ((__address) 0x80000000)
#define KERNEL_ADDRESS_SPACE_END_ARCH ((__address) 0xffffffff)
#define USER_ADDRESS_SPACE_START_ARCH ((__address) 0x00000000)
#define USER_ADDRESS_SPACE_END_ARCH ((__address) 0x7fffffff)
 
#define UTEXT_ADDRESS_ARCH 0x00001000
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
#define UDATA_ADDRESS_ARCH 0x21000000
 
#define as_install_arch(as)
 
#endif
/kernel/trunk/arch/ia32/src/mm/frame.c
28,7 → 28,7
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <mm/vm.h>
#include <mm/as.h>
#include <config.h>
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
/kernel/trunk/arch/ia32/src/userspace.c
31,7 → 31,7
#include <arch/types.h>
#include <arch.h>
#include <proc/thread.h>
#include <mm/vm.h>
#include <mm/as.h>
 
 
/** Enter userspace
47,11 → 47,11
 
__asm__ volatile (
/* CLNT */
"pushfl;"
"pop %%eax;"
"and $0xFFFFBFFF,%%eax;"
"push %%eax;"
"popfl;"
"pushfl\n"
"pop %%eax\n"
"and $0xffffbfff,%%eax\n"
"push %%eax\n"
"popfl\n"
 
"pushl %0\n"
"pushl %1\n"
64,5 → 64,6
: "eax");
/* Unreachable */
for(;;);
for(;;)
;
}
/kernel/trunk/arch/ia32/src/interrupt.c
35,6 → 35,7
#include <cpu.h>
#include <arch/asm.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <proc/thread.h>
99,9 → 100,14
 
void page_fault(int n, void *stack)
{
PRINT_INFO_ERRCODE(stack);
printf("page fault address: %X\n", read_cr2());
panic("page fault\n");
__address page;
 
page = read_cr2();
if (!as_page_fault(page)) {
PRINT_INFO_ERRCODE(stack);
printf("page fault address: %X\n", page);
panic("page fault\n");
}
}
 
void syscall(int n, void *stack)