/kernel/trunk/tools/amd64/gencontext.c |
---|
16,6 → 16,9 |
struct context ctx; |
struct context *pctx = &ctx; |
struct interrupt_context ictx; |
struct interrupt_context *ipctx = &ictx; |
f = fopen(FILENAME,"w"); |
if (!f) { |
perror(FILENAME); |
33,6 → 36,29 |
fprintf(f,"#define OFFSET_R14 0x%x\n",((int)&pctx->r14) - (int )pctx); |
fprintf(f,"#define OFFSET_R15 0x%x\n",((int)&pctx->r15) - (int )pctx); |
fprintf(f,"#define OFFSET_IPL 0x%x\n",((int)&pctx->ipl) - (int )pctx); |
fprintf(f, "\n"); |
#define ifpr(big,nm) fprintf(f, "#define IOFFSET_" #big " 0x%x\n", ((int)&ipctx->nm) - (int) ipctx) |
ifpr(RAX, rax); |
ifpr(RBX, rbx); |
ifpr(RCX, rcx); |
ifpr(RDX, rdx); |
ifpr(RSI, rsi); |
ifpr(RDI, rdi); |
ifpr(R8, r8); |
ifpr(R9, r9); |
ifpr(R10, r10); |
ifpr(R11, r11); |
ifpr(R12, r12); |
ifpr(R13, r13); |
ifpr(R14, r14); |
ifpr(R15, r15); |
ifpr(RBP, rbp); |
fprintf(f, "#define IREGISTER_SPACE %d\n", sizeof(ictx)); |
fclose(f); |
return 0; |
/kernel/trunk/generic/src/main/main.c |
---|
189,7 → 189,7 |
thread_init(); |
if (config.init_size > 0) |
printf("config.init_addr=%X, config.init_size=%d\n", config.init_addr, config.init_size); |
printf("config.init_addr=%P, config.init_size=%d\n", config.init_addr, config.init_size); |
/* |
* Create kernel task. |
/kernel/trunk/arch/amd64/include/interrupt.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/kernel/trunk/arch/amd64/include/context_offset.h |
---|
8,3 → 8,20 |
#define OFFSET_R14 0x30 |
#define OFFSET_R15 0x38 |
#define OFFSET_IPL 0x40 |
#define IOFFSET_RAX 0x0 |
#define IOFFSET_RBX 0x8 |
#define IOFFSET_RCX 0x10 |
#define IOFFSET_RDX 0x18 |
#define IOFFSET_RSI 0x20 |
#define IOFFSET_RDI 0x28 |
#define IOFFSET_R8 0x30 |
#define IOFFSET_R9 0x38 |
#define IOFFSET_R10 0x40 |
#define IOFFSET_R11 0x48 |
#define IOFFSET_R12 0x50 |
#define IOFFSET_R13 0x58 |
#define IOFFSET_R14 0x60 |
#define IOFFSET_R15 0x68 |
#define IOFFSET_RBP 0x70 |
#define IREGISTER_SPACE 120 |
/kernel/trunk/arch/amd64/include/context.h |
---|
58,4 → 58,25 |
ipl_t ipl; |
} __attribute__ ((packed)); |
/** This is passed to interrupt handlers */ |
struct interrupt_context { |
__u64 rax; |
__u64 rbx; |
__u64 rcx; |
__u64 rdx; |
__u64 rsi; |
__u64 rdi; |
__u64 r8; |
__u64 r9; |
__u64 r10; |
__u64 r11; |
__u64 r12; |
__u64 r13; |
__u64 r14; |
__u64 r15; |
/* These 2 items MUST be last parts of the structure */ |
__u64 rbp; |
__u64 stack[0]; /* Additional data on stack */ |
} __attribute__ ((packed)); |
#endif |
/kernel/trunk/arch/amd64/include/cpu.h |
---|
50,7 → 50,14 |
struct tss *tss; |
}; |
struct star_msr { |
}; |
struct lstar_msr { |
}; |
extern void set_efer_flag(int flag); |
extern __u64 read_efer_flag(void); |
void cpu_setup_fpu(void); |
/kernel/trunk/arch/amd64/src/amd64.c |
---|
46,6 → 46,42 |
#include <panic.h> |
#include <interrupt.h> |
/** Disable I/O on non-privileged levels |
* |
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register |
*/ |
static void clean_IOPL_NT_flags(void) |
{ |
asm |
( |
"pushfq;" |
"pop %%rax;" |
"and $~(0x7000),%%rax;" |
"pushq %%rax;" |
"popfq;" |
: |
: |
:"%rax" |
); |
} |
/** Disable alignment check |
* |
* Clean AM(18) flag in CR0 register |
*/ |
static void clean_AM_flag(void) |
{ |
asm |
( |
"mov %%cr0,%%rax;" |
"and $~(0x40000),%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
void arch_pre_mm_init(void) |
{ |
struct cpu_info cpuid_s; |
63,18 → 99,26 |
/* Enable No-execute pages */ |
set_efer_flag(AMD_NXE_FLAG); |
/* Enable SYSCALL/SYSRET */ |
set_efer_flag(AMD_SCE_FLAG); |
/* Enable FPU */ |
cpu_setup_fpu(); |
/* Initialize segmentation */ |
pm_init(); |
/* Disable I/O on nonprivileged levels |
* clear the NT(nested-thread) flag |
*/ |
clean_IOPL_NT_flags(); |
/* Disable alignment check */ |
clean_AM_flag(); |
if (config.cpu_active == 1) { |
bios_init(); |
i8259_init(); /* PIC */ |
i8254_init(); /* hard clock */ |
exc_register(VECTOR_SYSCALL, "syscall", syscall); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", |
tlb_shootdown_ipi); |
/kernel/trunk/arch/amd64/src/pm.c |
---|
1,5 → 1,6 |
/* |
* Copyright (C) 2001-2004 Jakub Jermar |
* Copyright (C) 2005-2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
167,15 → 168,8 |
d->present = 1; |
d->type = AR_INTERRUPT; /* masking interrupt */ |
if (i == VECTOR_SYSCALL) { |
/* |
* The syscall interrupt gate must be calleable from userland. |
*/ |
d->dpl |= PL_USER; |
} |
idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size); |
exc_register(i, "undef", null_interrupt); |
exc_register(i, "undef", (iroutine)null_interrupt); |
} |
exc_register(13, "gp_fault", gp_fault); |
exc_register( 7, "nm_fault", nm_fault); |
182,37 → 176,9 |
exc_register(12, "ss_fault", ss_fault); |
} |
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
static void clean_IOPL_NT_flags(void) |
{ |
asm |
( |
"pushfq;" |
"pop %%rax;" |
"and $~(0x7000),%%rax;" |
"pushq %%rax;" |
"popfq;" |
: |
: |
:"%rax" |
); |
} |
/* Clean AM(18) flag in CR0 register */ |
static void clean_AM_flag(void) |
{ |
asm |
( |
"mov %%cr0,%%rax;" |
"and $~(0x40000),%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
/** Initialize segmentation - code/data/idt tables |
* |
*/ |
void pm_init(void) |
{ |
struct descriptor *gdt_p = (struct descriptor *) gdtr.base; |
254,7 → 220,4 |
* to its own TSS. We just need to load the TR register. |
*/ |
__asm__("ltr %0" : : "r" ((__u16) gdtselector(TSS_DES))); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels */ |
clean_AM_flag(); /* Disable alignment check */ |
} |
/kernel/trunk/arch/amd64/src/asm_utils.S |
---|
34,6 → 34,7 |
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00 |
#include <arch/pm.h> |
#include <arch/context_offset.h> |
.text |
.global interrupt_handlers |
103,38 → 104,40 |
ret |
# Push all general purpose registers on stack except %rbp, %rsp |
.macro push_all_gpr |
pushq %rax |
pushq %rbx |
pushq %rcx |
pushq %rdx |
pushq %rsi |
pushq %rdi |
pushq %r8 |
pushq %r9 |
pushq %r10 |
pushq %r11 |
pushq %r12 |
pushq %r13 |
pushq %r14 |
pushq %r15 |
.macro save_all_gpr |
movq %rbp, IOFFSET_RBP(%rsp) |
movq %rax, IOFFSET_RAX(%rsp) |
movq %rbx, IOFFSET_RBX(%rsp) |
movq %rcx, IOFFSET_RCX(%rsp) |
movq %rdx, IOFFSET_RDX(%rsp) |
movq %rsi, IOFFSET_RSI(%rsp) |
movq %rdi, IOFFSET_RDI(%rsp) |
movq %r8, IOFFSET_R8(%rsp) |
movq %r9, IOFFSET_R9(%rsp) |
movq %r10, IOFFSET_R10(%rsp) |
movq %r11, IOFFSET_R11(%rsp) |
movq %r12, IOFFSET_R12(%rsp) |
movq %r13, IOFFSET_R13(%rsp) |
movq %r14, IOFFSET_R14(%rsp) |
movq %r15, IOFFSET_R15(%rsp) |
.endm |
.macro pop_all_gpr |
popq %r15 |
popq %r14 |
popq %r13 |
popq %r12 |
popq %r11 |
popq %r10 |
popq %r9 |
popq %r8 |
popq %rdi |
popq %rsi |
popq %rdx |
popq %rcx |
popq %rbx |
popq %rax |
.macro restore_all_gpr |
movq IOFFSET_RBP(%rsp), %rbp |
movq IOFFSET_RAX(%rsp), %rax |
movq IOFFSET_RBX(%rsp), %rbx |
movq IOFFSET_RCX(%rsp), %rcx |
movq IOFFSET_RDX(%rsp), %rdx |
movq IOFFSET_RSI(%rsp), %rsi |
movq IOFFSET_RDI(%rsp), %rdi |
movq IOFFSET_R8(%rsp), %r8 |
movq IOFFSET_R9(%rsp), %r9 |
movq IOFFSET_R10(%rsp), %r10 |
movq IOFFSET_R11(%rsp), %r11 |
movq IOFFSET_R12(%rsp), %r12 |
movq IOFFSET_R13(%rsp), %r13 |
movq IOFFSET_R14(%rsp), %r14 |
movq IOFFSET_R15(%rsp), %r15 |
.endm |
## Declare interrupt handlers |
146,14 → 149,11 |
# and call exc_dispatch(). |
# |
.macro handler i n |
pushq %rbp |
movq %rsp,%rbp |
push_all_gpr |
subq $IREGISTER_SPACE, %rsp |
save_all_gpr |
movq $(\i),%rdi # %rdi - first parameter |
movq %rbp, %rsi |
addq $8, %rsi # %rsi - second parameter - original stack |
movq %rsp, %rsi # %rsi - pointer to interrupt_context |
call exc_dispatch # exc_dispatch(i, stack) |
# Test if this is interrupt with error word or not |
168,17 → 168,15 |
# Return with error word |
pop_all_gpr |
popq %rbp; |
addq $8,%rsp; # Skip error word |
restore_all_gpr |
# $8 = Skip error word |
addq $IREGISTER_SPACE + 0x8, %rsp |
iretq |
0: |
# Return with no error word |
pop_all_gpr |
popq %rbp |
restore_all_gpr |
addq $IREGISTER_SPACE, %rsp |
iretq |
.if (\n-\i)-1 |
/kernel/trunk/arch/amd64/src/mm/page.c |
---|
52,7 → 52,7 |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, PAGE_CACHEABLE | PAGE_EXEC); |
} |
exc_register(14, "page_fault", page_fault); |
exc_register(14, "page_fault", (iroutine)page_fault); |
write_cr3((__address) AS_KERNEL->page_table); |
} |
else { |
/kernel/trunk/arch/amd64/src/interrupt.c |
---|
58,31 → 58,30 |
printf("\n"); |
} |
*/ |
static void print_info_errcode(int n, void *st) |
static void print_info_errcode(int n, struct interrupt_context *ctx) |
{ |
char *symbol; |
__native *x = (__native *) st; |
__u64 *x = &ctx->stack[0]; |
if (!(symbol=get_symtab_entry(x[1]))) |
symbol = ""; |
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__); |
printf("%%rip: %Q (%s)\n",x[1],symbol); |
printf("ERROR_WORD=%Q\n", x[0]); |
printf("%%rcs=%Q,flags=%Q, %%cr0=%Q\n", x[2], x[3],read_cr0()); |
printf("%%rax=%Q, %%rbx=%Q, %%rcx=%Q\n",x[-2],x[-3],x[-4]); |
printf("%%rdx=%Q, %%rsi=%Q, %%rdi=%Q\n",x[-5],x[-6],x[-7]); |
printf("%%r8 =%Q, %%r9 =%Q, %%r10=%Q\n",x[-8],x[-9],x[-10]); |
printf("%%r11=%Q, %%r12=%Q, %%r13=%Q\n",x[-11],x[-12],x[-13]); |
printf("%%r14=%Q, %%r15=%Q, %%rsp=%Q\n",x[-14],x[-15],x); |
printf("%%rbp=%Q\n",x[-1]); |
printf("%%rip: %Q (%s)\n",ctx->stack[1],symbol); |
printf("ERROR_WORD=%Q\n", ctx->stack[0]); |
printf("%%rcs=%Q,flags=%Q, %%cr0=%Q\n", ctx->stack[2], |
ctx->stack[3],read_cr0()); |
printf("%%rax=%Q, %%rbx=%Q, %%rcx=%Q\n",ctx->rax,ctx->rbx,ctx->rcx); |
printf("%%rdx=%Q, %%rsi=%Q, %%rdi=%Q\n",ctx->rdx,ctx->rsi,ctx->rdi); |
printf("%%r8 =%Q, %%r9 =%Q, %%r10=%Q\n",ctx->r8,ctx->r9,ctx->r10); |
printf("%%r11=%Q, %%r12=%Q, %%r13=%Q\n",ctx->r11,ctx->r12,ctx->r13); |
printf("%%r14=%Q, %%r15=%Q, %%rsp=%Q\n",ctx->r14,ctx->r15,&ctx->stack[0]); |
printf("%%rbp=%Q\n",ctx->rbp); |
printf("stack: %Q, %Q, %Q\n", x[5], x[6], x[7]); |
printf(" %Q, %Q, %Q\n", x[8], x[9], x[10]); |
printf(" %Q, %Q, %Q\n", x[11], x[12], x[13]); |
printf(" %Q, %Q, %Q\n", x[14], x[15], x[16]); |
printf(" %Q, %Q, %Q\n", x[17], x[18], x[19]); |
printf(" %Q, %Q, %Q\n", x[20], x[21], x[22]); |
printf(" %Q, %Q, %Q\n", x[23], x[24], x[25]); |
// messy_stack_trace(&x[5]); |
} |
94,12 → 93,11 |
void (* enable_irqs_function)(__u16 irqmask) = NULL; |
void (* eoi_function)(void) = NULL; |
void null_interrupt(int n, void *st) |
void null_interrupt(int n, struct interrupt_context *ctx) |
{ |
__native *stack = (__native *) st; |
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__); \ |
printf("stack: %L, %L, %L, %L\n", stack[0], stack[1], stack[2], stack[3]); |
printf("stack: %X, %X, %X, %X\n", ctx->stack[0], ctx->stack[1], |
ctx->stack[2], ctx->stack[3]); |
panic("unserviced interrupt\n"); |
} |
125,24 → 123,18 |
#endif |
} |
void page_fault(int n, void *stack) |
void page_fault(int n, struct interrupt_context *ctx) |
{ |
__address page; |
page = read_cr2(); |
if (!as_page_fault(page)) { |
print_info_errcode(n,stack); |
print_info_errcode(n,ctx); |
printf("Page fault address: %Q\n", page); |
panic("page fault\n"); |
} |
} |
void syscall(int n, void *stack) |
{ |
printf("cpu%d: syscall\n", CPU->id); |
thread_usleep(1000); |
} |
void tlb_shootdown_ipi(int n, void *stack) |
{ |
trap_virtual_eoi(); |
/kernel/trunk/arch/mips32/src/exception.c |
---|
78,18 → 78,14 |
pstate->ra,rasymbol); |
} |
static void unhandled_exception(int n, void *data) |
static void unhandled_exception(int n, struct exception_regdump *pstate) |
{ |
struct exception_regdump *pstate = (struct exception_regdump *)data; |
print_regdump(pstate); |
panic("unhandled exception %s\n", exctable[n]); |
} |
static void breakpoint_exception(int n, void *data) |
static void breakpoint_exception(int n, struct exception_regdump *pstate) |
{ |
struct exception_regdump *pstate = (struct exception_regdump *)data; |
#ifdef CONFIG_DEBUG |
debugger_bpoint(pstate); |
#else |
100,20 → 96,18 |
#endif |
} |
static void tlbmod_exception(int n, void *data) |
static void tlbmod_exception(int n, struct exception_regdump *pstate) |
{ |
struct exception_regdump *pstate = (struct exception_regdump *)data; |
tlb_modified(pstate); |
} |
static void tlbinv_exception(int n, void *data) |
static void tlbinv_exception(int n, struct exception_regdump *pstate) |
{ |
struct exception_regdump *pstate = (struct exception_regdump *)data; |
tlb_invalid(pstate); |
} |
#ifdef CONFIG_FPU_LAZY |
static void cpuns_exception(int n, void *data) |
static void cpuns_exception(int n, struct exception_regdump *pstate) |
{ |
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id) |
scheduler_fpu_lazy_request(); |
122,7 → 116,7 |
} |
#endif |
static void interrupt_exception(int n, void *pstate) |
static void interrupt_exception(int n, struct exception_regdump *pstate) |
{ |
__u32 cause; |
int i; |
137,10 → 131,8 |
#include <debug.h> |
/** Handle syscall userspace call */ |
static void syscall_exception(int n, void *data) |
static void syscall_exception(int n, struct exception_regdump *pstate) |
{ |
struct exception_regdump *pstate = (struct exception_regdump *)data; |
if (pstate->a3 < SYSCALL_END) |
pstate->v0 = syscall_table[pstate->a3](pstate->a0, |
pstate->a1, |
197,14 → 189,14 |
/* Clear exception table */ |
for (i=0;i < IVT_ITEMS; i++) |
exc_register(i, "undef", unhandled_exception); |
exc_register(EXC_Bp, "bkpoint", breakpoint_exception); |
exc_register(EXC_Mod, "tlb_mod", tlbmod_exception); |
exc_register(EXC_TLBL, "tlbinvl", tlbinv_exception); |
exc_register(EXC_TLBS, "tlbinvl", tlbinv_exception); |
exc_register(EXC_Int, "interrupt", interrupt_exception); |
exc_register(i, "undef", (iroutine) unhandled_exception); |
exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception); |
exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception); |
exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception); |
exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception); |
exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception); |
#ifdef CONFIG_FPU_LAZY |
exc_register(EXC_CpU, "cpunus", cpuns_exception); |
exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception); |
#endif |
exc_register(EXC_Sys, "syscall", syscall_exception); |
exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception); |
} |