Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1287 → Rev 1288

/kernel/trunk/arch/sparc64/include/interrupt.h
30,6 → 30,7
#define __sparc64_INTERRUPT_H__
 
#include <typedefs.h>
#include <arch/types.h>
 
#define IRQ_COUNT 1 /* TODO */
 
43,6 → 44,14
#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/sparc64/src/asm.S
29,12 → 29,24
.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/ia64/include/interrupt.h
106,6 → 106,11
__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/ia64/src/asm.S
30,9 → 30,25
 
.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/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)) {
if (as_page_fault(va, istate) == AS_PF_FAULT) {
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)) {
if (as_page_fault(va, istate) == AS_PF_FAULT) {
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)) {
if (as_page_fault(va, istate) == AS_PF_FAULT) {
panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rr.map.rid);
}
}
/kernel/trunk/arch/ppc32/include/interrupt.h
29,6 → 29,8
#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/include/exception.h
76,4 → 76,9
__u32 sp;
};
 
static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
{
/* TODO */
}
 
#endif
/kernel/trunk/arch/ppc32/src/asm.S
35,6 → 35,10
.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:
 
233,6 → 237,9
blr
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
 
srwi. r7, r5, 3
addi r6, r3, -4
addi r4, r4, -4
293,3 → 300,7
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,10 → 68,12
* 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)
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
{
/*
* Check if the mapping exists in page tables.
84,12 → 86,15
*/
return pte;
} else {
int rc;
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(badvaddr)) {
switch (rc = as_page_fault(badvaddr, istate)) {
case AS_PF_OK:
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
98,12 → 103,22
pte = page_mapping_find(AS, badvaddr);
ASSERT((pte) && (pte->p));
return pte;
} else {
break;
case AS_PF_DEFER:
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;
}
}
}
 
139,6 → 154,7
__u32 vsid;
__u32 hash;
__u32 i;
int pfcr;
if (data) {
asm volatile (
154,9 → 170,24
page_table_lock(AS, true);
pte = find_mapping_and_check(badvaddr);
if (!pte)
goto fail;
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;
}
}
 
/* Record access to PTE */
pte->a = 1;
/kernel/trunk/arch/amd64/include/interrupt.h
86,6 → 86,11
__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/amd64/src/asm_utils.S
60,16 → 60,60
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)) {
if (as_page_fault(page, istate) == AS_PF_FAULT) {
print_info_errcode(n, istate);
printf("Page fault address: %llX\n", page);
panic("page fault\n");
/kernel/trunk/arch/mips32/include/exception.h
93,6 → 93,11
__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);
/kernel/trunk/arch/mips32/src/asm.S
57,11 → 57,25
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/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);
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc);
 
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,6 → 91,7
asid_t asid;
__address badvaddr;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
100,9 → 101,23
 
page_table_lock(AS, true);
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
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);
}
}
 
/*
* Record access to PTE.
148,6 → 163,7
entry_lo_t lo;
entry_hi_t hi;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
170,9 → 186,23
goto fail;
}
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
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);
}
}
 
/*
* Read the faulting TLB entry.
217,6 → 247,7
entry_lo_t lo;
entry_hi_t hi;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
239,9 → 270,23
goto fail;
}
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
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);
}
}
 
/*
* Fail if the page is not writable.
321,10 → 366,12
* 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)
pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc)
{
entry_hi_t hi;
pte_t *pte;
350,12 → 397,15
*/
return pte;
} else {
int rc;
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(badvaddr)) {
switch (rc = as_page_fault(badvaddr, istate)) {
case AS_PF_OK:
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
364,10 → 414,20
pte = page_mapping_find(AS, badvaddr);
ASSERT(pte && pte->p);
return pte;
} else {
break;
case AS_PF_DEFER:
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/ia32/include/interrupt.h
83,6 → 83,11
__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/asm.S
37,7 → 37,68
.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/boot/boot.S
34,14 → 34,6
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
 
 
 
 
 
 
 
 
.section K_TEXT_START, "ax"
 
KTEXT=8
435,12 → 427,8
e_vesa_init:
#endif
 
 
 
.section K_DATA_START, "aw", @progbits
 
 
 
.align 4096
page_directory:
.space 4096, 0
/kernel/trunk/arch/ia32/src/interrupt.c
144,7 → 144,7
__address page;
 
page = read_cr2();
if (!as_page_fault(page)) {
if (as_page_fault(page, istate) == AS_PF_FAULT) {
PRINT_INFO_ERRCODE(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");