/kernel/trunk/arch/ia32/include/interrupt.h |
---|
83,11 → 83,6 |
__u32 stack[]; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
istate->eip = retaddr; |
} |
extern void (* disable_irqs_function)(__u16 irqmask); |
extern void (* enable_irqs_function)(__u16 irqmask); |
extern void (* eoi_function)(void); |
/kernel/trunk/arch/ia32/src/boot/boot.S |
---|
34,6 → 34,14 |
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) |
.section K_TEXT_START, "ax" |
KTEXT=8 |
427,8 → 435,12 |
e_vesa_init: |
#endif |
.section K_DATA_START, "aw", @progbits |
.align 4096 |
page_directory: |
.space 4096, 0 |
/kernel/trunk/arch/ia32/src/asm.S |
---|
37,68 → 37,7 |
.global paging_on |
.global enable_l_apic_in_msr |
.global interrupt_handlers |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace |
.global memcpy_to_uspace_failover_address |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |
/** Copy memory to/from userspace. |
* |
* This is almost conventional memcpy(). |
* The difference is that there is a failover part |
* to where control is returned from a page fault |
* if the page fault occurs during copy_from_uspace() |
* or copy_to_uspace(). |
* |
* @param MEMCPY_DST(%esp) Destination address. |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movl %edi, %edx /* save %edi */ |
movl %esi, %eax /* save %esi */ |
movl MEMCPY_SIZE(%esp), %ecx |
shrl $2, %ecx /* size / 4 */ |
movl MEMCPY_DST(%esp), %edi |
movl MEMCPY_SRC(%esp), %esi |
rep movsl /* copy as much as possible word by word */ |
movl MEMCPY_SIZE(%esp), %ecx |
andl $3, %ecx /* size % 4 */ |
jz 0f |
rep movsb /* copy the rest byte by byte */ |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
ret |
/* |
* We got here from as_page_fault() after the memory operations |
* above had caused a page fault. |
*/ |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
movl %edx, %edi |
movl %eax, %esi |
xorl %eax, %eax /* return 0, failure */ |
ret |
## Turn paging on |
# |
# Enable paging and write-back caching in CR0. |
/kernel/trunk/arch/ia32/src/interrupt.c |
---|
144,7 → 144,7 |
__address page; |
page = read_cr2(); |
if (as_page_fault(page, istate) == AS_PF_FAULT) { |
if (!as_page_fault(page)) { |
PRINT_INFO_ERRCODE(istate); |
printf("page fault address: %#x\n", page); |
panic("page fault\n"); |
/kernel/trunk/arch/ppc32/include/exception.h |
---|
76,9 → 76,4 |
__u32 sp; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
/* TODO */ |
} |
#endif |
/kernel/trunk/arch/ppc32/include/interrupt.h |
---|
29,8 → 29,6 |
#ifndef __ppc32_INTERRUPT_H__ |
#define __ppc32_INTERRUPT_H__ |
#include <arch/exception.h> |
#define IRQ_COUNT 1 |
#define IVT_ITEMS 15 |
#define INT_OFFSET 0 |
/kernel/trunk/arch/ppc32/src/asm.S |
---|
35,10 → 35,6 |
.global iret_syscall |
.global memsetb |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
userspace_asm: |
237,9 → 233,6 |
blr |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
srwi. r7, r5, 3 |
addi r6, r3, -4 |
addi r4, r4, -4 |
300,7 → 293,3 |
beq 2b |
mtctr r7 |
b 1b |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
/kernel/trunk/arch/ppc32/src/mm/tlb.c |
---|
68,12 → 68,10 |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @return PTE on success, NULL otherwise. |
* |
*/ |
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr) |
static pte_t *find_mapping_and_check(__address badvaddr) |
{ |
/* |
* Check if the mapping exists in page tables. |
86,15 → 84,12 |
*/ |
return pte; |
} else { |
int rc; |
/* |
* Mapping not found in page tables. |
* Resort to higher-level page fault handler. |
*/ |
page_table_unlock(AS, true); |
switch (rc = as_page_fault(badvaddr, istate)) { |
case AS_PF_OK: |
if (as_page_fault(badvaddr)) { |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
103,22 → 98,12 |
pte = page_mapping_find(AS, badvaddr); |
ASSERT((pte) && (pte->p)); |
return pte; |
break; |
case AS_PF_DEFER: |
} else { |
page_table_lock(AS, true); |
*pfcr = rc; |
return NULL; |
break; |
case AS_PF_FAULT: |
page_table_lock(AS, true); |
printf("Page fault.\n"); |
*pfcr = rc; |
return NULL; |
break; |
default: |
panic("unexpected rc (%d)\n", rc); |
break; |
} |
} |
} |
} |
154,7 → 139,6 |
__u32 vsid; |
__u32 hash; |
__u32 i; |
int pfcr; |
if (data) { |
asm volatile ( |
170,24 → 154,9 |
page_table_lock(AS, true); |
pte = find_mapping_and_check(badvaddr, istate, &pfcr); |
if (!pte) { |
switch (pfcr) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfcr); |
break; |
} |
} |
pte = find_mapping_and_check(badvaddr); |
if (!pte) |
goto fail; |
/* Record access to PTE */ |
pte->a = 1; |
/kernel/trunk/arch/amd64/src/asm_utils.S |
---|
60,60 → 60,16 |
movq $halt, (%rsp) |
jmp printf |
.global memcpy |
memcpy: |
jmp _memcpy |
.global cpuid |
.global has_cpuid |
.global rdtsc |
.global read_efer_flag |
.global set_efer_flag |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
#define MEMCPY_DST %rdi |
#define MEMCPY_SRC %rsi |
#define MEMCPY_SIZE %rdx |
/** |
* Copy memory from/to userspace. |
* |
* This is almost conventional memcpy(). |
* The difference is that there is a failover part |
* to where control is returned from a page fault if |
* the page fault occurs during copy_from_uspace() |
* or copy_to_uspace(). |
* |
* @param MEMCPY_DST Destination address. |
* @param MEMCPY_SRC Source address. |
* @param MEMCPY_SIZE Number of bytes to copy. |
* |
* @retrun MEMCPY_SRC on success, 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movq MEMCPY_SRC, %rax |
movq MEMCPY_SIZE, %rcx |
shrq $3, %rcx /* size / 8 */ |
rep movsq /* copy as much as possible word by word */ |
movq MEMCPY_SIZE, %rcx |
andq $7, %rcx /* size % 8 */ |
jz 0f |
rep movsb /* copy the rest byte by byte */ |
0: |
ret /* return MEMCPY_SRC, success */ |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
xorq %rax, %rax /* return 0, failure */ |
ret |
## Determine CPUID support |
# |
# Return 0 in EAX if CPUID is not support, 1 if supported. |
/kernel/trunk/arch/amd64/src/mm/page.c |
---|
166,7 → 166,7 |
__address page; |
page = read_cr2(); |
if (as_page_fault(page, istate) == AS_PF_FAULT) { |
if (!as_page_fault(page)) { |
print_info_errcode(n, istate); |
printf("Page fault address: %llX\n", page); |
panic("page fault\n"); |
/kernel/trunk/arch/amd64/include/interrupt.h |
---|
86,11 → 86,6 |
__u64 stack[]; /* Additional data on stack */ |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
istate->rip = retaddr; |
} |
extern void (* disable_irqs_function)(__u16 irqmask); |
extern void (* enable_irqs_function)(__u16 irqmask); |
extern void (* eoi_function)(void); |
/kernel/trunk/arch/sparc64/src/asm.S |
---|
29,24 → 29,12 |
.text |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
.global memsetb |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
b _memcpy |
nop |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
nop |
memsetb: |
b _memsetb |
nop |
/kernel/trunk/arch/sparc64/include/interrupt.h |
---|
30,7 → 30,6 |
#define __sparc64_INTERRUPT_H__ |
#include <typedefs.h> |
#include <arch/types.h> |
#define IRQ_COUNT 1 /* TODO */ |
44,14 → 43,6 |
#define trap_virtual_enable_irqs(x) |
#define trap_virtual_eoi() |
struct istate { |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
/* TODO */ |
} |
extern void interrupt_register(int n, const char *name, iroutine f); |
#endif |
/kernel/trunk/arch/ia64/src/mm/tlb.c |
---|
447,7 → 447,7 |
* Forward the page fault to address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, istate) == AS_PF_FAULT) { |
if (!as_page_fault(va)) { |
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, istate->cr_ifa, rr.map.rid, istate->cr_iip); |
} |
} |
493,7 → 493,7 |
* Forward the page fault to address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, istate) == AS_PF_FAULT) { |
if (!as_page_fault(va)) { |
panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip); |
} |
} |
608,7 → 608,7 |
page_table_unlock(AS, true); |
} else { |
page_table_unlock(AS, true); |
if (as_page_fault(va, istate) == AS_PF_FAULT) { |
if (!as_page_fault(va)) { |
panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rr.map.rid); |
} |
} |
/kernel/trunk/arch/ia64/src/asm.S |
---|
30,25 → 30,9 |
.text |
/** Copy memory from/to userspace. |
* |
* @param in0 Destination address. |
* @param in1 Source address. |
* @param in2 Number of byte to copy. |
*/ |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
br _memcpy |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
br memcpy_from_uspace_failover_address |
.global memsetb |
memsetb: |
/kernel/trunk/arch/ia64/include/interrupt.h |
---|
106,11 → 106,6 |
__u64 in4; |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
/* TODO */ |
} |
extern void *ivt; |
extern void general_exception(__u64 vector, istate_t *istate); |
/kernel/trunk/arch/mips32/src/mm/tlb.c |
---|
44,7 → 44,7 |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc); |
static pte_t *find_mapping_and_check(__address badvaddr); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
91,7 → 91,6 |
asid_t asid; |
__address badvaddr; |
pte_t *pte; |
int pfrc; |
badvaddr = cp0_badvaddr_read(); |
101,23 → 100,9 |
page_table_lock(AS, true); |
pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte = find_mapping_and_check(badvaddr); |
if (!pte) |
goto fail; |
/* |
* Record access to PTE. |
163,7 → 148,6 |
entry_lo_t lo; |
entry_hi_t hi; |
pte_t *pte; |
int pfrc; |
badvaddr = cp0_badvaddr_read(); |
186,23 → 170,9 |
goto fail; |
} |
pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte = find_mapping_and_check(badvaddr); |
if (!pte) |
goto fail; |
/* |
* Read the faulting TLB entry. |
247,7 → 217,6 |
entry_lo_t lo; |
entry_hi_t hi; |
pte_t *pte; |
int pfrc; |
badvaddr = cp0_badvaddr_read(); |
270,23 → 239,9 |
goto fail; |
} |
pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte = find_mapping_and_check(badvaddr); |
if (!pte) |
goto fail; |
/* |
* Fail if the page is not writable. |
366,12 → 321,10 |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc) |
pte_t *find_mapping_and_check(__address badvaddr) |
{ |
entry_hi_t hi; |
pte_t *pte; |
397,15 → 350,12 |
*/ |
return pte; |
} else { |
int rc; |
/* |
* Mapping not found in page tables. |
* Resort to higher-level page fault handler. |
*/ |
page_table_unlock(AS, true); |
switch (rc = as_page_fault(badvaddr, istate)) { |
case AS_PF_OK: |
if (as_page_fault(badvaddr)) { |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
414,20 → 364,10 |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
return pte; |
break; |
case AS_PF_DEFER: |
} else { |
page_table_lock(AS, true); |
*pfrc = AS_PF_DEFER; |
return NULL; |
break; |
case AS_PF_FAULT: |
page_table_lock(AS, true); |
printf("Page fault.\n"); |
*pfrc = AS_PF_FAULT; |
return NULL; |
break; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
/kernel/trunk/arch/mips32/src/asm.S |
---|
57,25 → 57,11 |
j _memsetb |
nop |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
j _memcpy |
nop |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
j memcpy_from_uspace_failover_address |
nop |
.macro fpu_gp_save reg ctx |
mfc1 $t0,$\reg |
sw $t0, \reg*4(\ctx) |
/kernel/trunk/arch/mips32/include/exception.h |
---|
93,11 → 93,6 |
__u32 k1; /* We use it as thread-local pointer */ |
}; |
static inline void istate_set_retaddr(istate_t *istate, __address retaddr) |
{ |
/* TODO */ |
} |
extern void exception(istate_t *istate); |
extern void tlb_refill_entry(void); |
extern void exception_entry(void); |