Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1957 → Rev 1958

/trunk/kernel/arch/amd64/include/interrupt.h
45,30 → 45,29
#define IRQ_COUNT 16
 
#define IVT_EXCBASE 0
#define IVT_IRQBASE (IVT_EXCBASE+EXC_COUNT)
#define IVT_FREEBASE (IVT_IRQBASE+IRQ_COUNT)
#define IVT_IRQBASE (IVT_EXCBASE + EXC_COUNT)
#define IVT_FREEBASE (IVT_IRQBASE + IRQ_COUNT)
 
#define IRQ_CLK 0
#define IRQ_KBD 1
#define IRQ_PIC1 2
#define IRQ_CLK 0
#define IRQ_KBD 1
#define IRQ_PIC1 2
#define IRQ_PIC_SPUR 7
#define IRQ_MOUSE 12
 
/* this one must have four least significant bits set to ones */
#define VECTOR_APIC_SPUR (IVT_ITEMS-1)
#define VECTOR_APIC_SPUR (IVT_ITEMS - 1)
 
#if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
#if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
#error Wrong definition of VECTOR_APIC_SPUR
#endif
 
#define VECTOR_DEBUG 1
#define VECTOR_PIC_SPUR (IVT_IRQBASE+IRQ_PIC_SPUR)
#define VECTOR_CLK (IVT_IRQBASE+IRQ_CLK)
#define VECTOR_KBD (IVT_IRQBASE+IRQ_KBD)
#define VECTOR_DEBUG 1
#define VECTOR_CLK (IVT_IRQBASE + IRQ_CLK)
#define VECTOR_PIC_SPUR (IVT_IRQBASE + IRQ_PIC_SPUR)
#define VECTOR_SYSCALL IVT_FREEBASE
#define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE + 1)
#define VECTOR_DEBUG_IPI (IVT_FREEBASE + 2)
 
#define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE+0)
#define VECTOR_WAKEUP_IPI (IVT_FREEBASE+1)
#define VECTOR_DEBUG_IPI (IVT_FREEBASE+2)
 
/** This is passed to interrupt handlers */
struct istate {
uint64_t rax;
112,18 → 111,10
extern void (* enable_irqs_function)(uint16_t irqmask);
extern void (* eoi_function)(void);
 
extern void print_info_errcode(int n, istate_t *istate);
extern void null_interrupt(int n, istate_t *istate);
extern void gp_fault(int n, istate_t *istate);
extern void nm_fault(int n, istate_t *istate);
extern void ss_fault(int n, istate_t *istate);
extern void page_fault(int n, istate_t *istate);
extern void syscall(int n, istate_t *istate);
extern void tlb_shootdown_ipi(int n, istate_t *istate);
 
extern void decode_istate(int n, istate_t *istate);
extern void interrupt_init(void);
extern void trap_virtual_enable_irqs(uint16_t irqmask);
extern void trap_virtual_disable_irqs(uint16_t irqmask);
extern void trap_virtual_eoi(void);
/* AMD64 - specific page handler */
extern void ident_page_fault(int n, istate_t *istate);
 
/trunk/kernel/arch/amd64/include/mm/page.h
190,6 → 190,7
}
 
extern void page_arch_init(void);
extern void page_fault(int n, istate_t *istate);
 
#endif /* __ASM__ */
 
/trunk/kernel/arch/amd64/src/amd64.c
61,6 → 61,8
#include <arch/debugger.h>
#include <syscall/syscall.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <ddi/device.h>
 
 
/** Disable I/O on non-privileged levels
130,14 → 132,11
clean_AM_flag();
 
if (config.cpu_active == 1) {
interrupt_init();
bios_init();
i8259_init(); /* PIC */
i8254_init(); /* hard clock */
 
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
tlb_shootdown_ipi);
#endif /* CONFIG_SMP */
/* PIC */
i8259_init();
}
}
 
144,6 → 143,12
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
/* hard clock */
i8254_init();
 
#ifdef CONFIG_FB
if (vesa_present())
vesa_init();
150,6 → 155,7
else
#endif
ega_init(); /* video */
/* Enable debugger */
debugger_init();
/* Merge all memory zones to 1 big zone */
183,13 → 189,20
 
void arch_post_smp_init(void)
{
i8042_init(); /* keyboard controller */
/* keyboard controller */
i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE);
}
 
void calibrate_delay_loop(void)
{
i8254_calibrate_delay_loop();
i8254_normal_operation();
if (config.cpu_active == 1) {
/*
* This has to be done only on UP.
* On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
*/
i8254_normal_operation();
}
}
 
/** Set thread-local-storage pointer
/trunk/kernel/arch/amd64/src/pm.c
180,13 → 180,7
d->type = AR_INTERRUPT; /* masking interrupt */
 
idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
exc_register(i, "undef", (iroutine)null_interrupt);
}
 
exc_register( 7, "nm_fault", nm_fault);
exc_register(12, "ss_fault", ss_fault);
exc_register(13, "gp_fault", gp_fault);
exc_register(14, "ident_mapper", ident_page_fault);
}
 
/** Initialize segmentation - code/data/idt tables
/trunk/kernel/arch/amd64/src/mm/page.c
110,7 → 110,7
page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
}
 
exc_register(14, "page_fault", (iroutine)page_fault);
exc_register(14, "page_fault", (iroutine) page_fault);
write_cr3((uintptr_t) AS_KERNEL->page_table);
}
else {
193,7 → 193,7
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
 
print_info_errcode(n, istate);
decode_istate(n, istate);
printf("Page fault address: %llx\n", page);
panic("page fault\n");
}
/trunk/kernel/arch/amd64/src/interrupt.c
51,9 → 51,17
#include <synch/spinlock.h>
#include <arch/ddi/ddi.h>
#include <interrupt.h>
#include <ipc/irq.h>
#include <ddi/irq.h>
 
void print_info_errcode(int n, istate_t *istate)
/*
* Interrupt and exception dispatching.
*/
 
void (* disable_irqs_function)(uint16_t irqmask) = NULL;
void (* enable_irqs_function)(uint16_t irqmask) = NULL;
void (* eoi_function)(void) = NULL;
 
void decode_istate(int n, istate_t *istate)
{
char *symbol;
/* uint64_t *x = &istate->stack[0]; */
75,23 → 83,24
printf("%%rsp=%#llx\n", &istate->stack[0]);
}
 
/*
* Interrupt and exception dispatching.
*/
static void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
void (* disable_irqs_function)(uint16_t irqmask) = NULL;
void (* enable_irqs_function)(uint16_t irqmask) = NULL;
void (* eoi_function)(void) = NULL;
}
 
void null_interrupt(int n, istate_t *istate)
static void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
print_info_errcode(n, istate);
decode_istate(n, istate);
panic("unserviced interrupt\n");
}
 
/** General Protection Fault. */
void gp_fault(int n, istate_t *istate)
static void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
114,18 → 123,18
fault_if_from_uspace(istate, "general protection fault");
}
 
print_info_errcode(n, istate);
decode_istate(n, istate);
panic("general protection fault\n");
}
 
void ss_fault(int n, istate_t *istate)
static void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
print_info_errcode(n, istate);
decode_istate(n, istate);
panic("stack fault\n");
}
 
void nm_fault(int n, istate_t *istate)
static void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
135,12 → 144,61
#endif
}
 
void tlb_shootdown_ipi(int n, istate_t *istate)
static void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
 
/** Handler of IRQ exceptions */
static void irq_interrupt(int n, istate_t *istate)
{
ASSERT(n >= IVT_IRQBASE);
int inum = n - IVT_IRQBASE;
ASSERT(inum < IRQ_COUNT);
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/*
* Spurious interrupt.
*/
#ifdef CONFIG_DEBUG
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
trap_virtual_eoi();
}
 
void interrupt_init(void)
{
int i;
for (i = 0; i < IVT_ITEMS; i++)
exc_register(i, "null", (iroutine) null_interrupt);
for (i = 0; i < IRQ_COUNT; i++) {
if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt);
}
exc_register(7, "nm_fault", (iroutine) nm_fault);
exc_register(12, "ss_fault", (iroutine) ss_fault);
exc_register(13, "gp_fault", (iroutine) gp_fault);
exc_register(14, "ident_mapper", (iroutine) ident_page_fault);
#ifdef CONFIG_SMP
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi);
#endif
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
if (enable_irqs_function)
157,14 → 215,5
panic("no disable_irqs_function\n");
}
 
void trap_virtual_eoi(void)
{
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
 
}
 
/** @}
*/