Subversion Repositories HelenOS-historic

Compare Revisions

No changes between revisions

Ignore whitespace Rev 798 → Rev 799

/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);
}