/trunk/kernel/arch/ia64/src/interrupt.c |
---|
34,18 → 34,17 |
*/ |
#include <arch/interrupt.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
#include <panic.h> |
#include <print.h> |
#include <symtab.h> |
#include <debug.h> |
#include <console/console.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/register.h> |
#include <arch/drivers/it.h> |
#include <arch.h> |
#include <symtab.h> |
#include <debug.h> |
#include <syscall/syscall.h> |
#include <print.h> |
#include <proc/scheduler.h> |
52,8 → 51,9 |
#include <ipc/sysipc.h> |
#include <ipc/irq.h> |
#include <ipc/ipc.h> |
#include <synch/spinlock.h> |
#include <interrupt.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
#define VECTORS_16_BUNDLE_START 0x5000 |
61,6 → 61,7 |
#define BUNDLE_SIZE 16 |
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = { |
"VHPT Translation vector", |
"Instruction TLB vector", |
196,10 → 197,12 |
#endif |
} |
void nop_handler(uint64_t vector, istate_t *istate) |
{ |
} |
/** Handle syscall. */ |
int break_instruction(uint64_t vector, istate_t *istate) |
{ |
225,28 → 228,34 |
void external_interrupt(uint64_t vector, istate_t *istate) |
{ |
irq_t *irq; |
cr_ivr_t ivr; |
ivr.value = ivr_read(); |
srlz_d(); |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
switch (ivr.vector) { |
case INTERRUPT_SPURIOUS: |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt\n", CPU->id); |
#endif |
break; |
switch(ivr.vector) { |
case INTERRUPT_TIMER: |
it_interrupt(); |
break; |
case INTERRUPT_SPURIOUS: |
printf("cpu%d: spurious interrupt\n", CPU->id); |
break; |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector); |
break; |
} |
} |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector); |
break; |
} |
void virtual_interrupt(uint64_t irq, void *param) |
{ |
switch(irq) { |
case IRQ_KBD: |
if (kbd_uspace) |
ipc_irq_send_notif(irq); |
break; |
default: |
panic("\nUnhandled Virtual Interrupt request %d\n", irq); |
break; |
} |
} |
/trunk/kernel/arch/ia64/src/ia64.c |
---|
49,8 → 49,9 |
#include <console/console.h> |
#include <proc/uarg.h> |
#include <syscall/syscall.h> |
#include <ddi/irq.h> |
static int kbd_release=0; |
void arch_pre_main(void) |
{ |
/* Setup usermode init tasks. */ |
79,13 → 80,12 |
iva_write((uintptr_t) &ivt); |
srlz_d(); |
ski_init_console(); |
it_init(); |
} |
void arch_post_mm_init(void) |
{ |
irq_init(INR_COUNT, INR_COUNT); |
ski_init_console(); |
it_init(); |
ski_set_console_sysinfo(); |
} |
145,7 → 145,8 |
*/ |
void arch_grab_console(void) |
{ |
ski_kbd_grab(); |
kbd_release=kbd_uspace; |
kbd_uspace=0; |
} |
/** Return console to userspace |
* |
152,7 → 153,7 |
*/ |
void arch_release_console(void) |
{ |
ski_kbd_release(); |
kbd_uspace=kbd_release; |
} |
/** @} |
/trunk/kernel/arch/ia64/src/ski/ski.c |
---|
37,24 → 37,12 |
#include <console/chardev.h> |
#include <arch/interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#define SKI_KBD_INR 0 |
static irq_t ski_kbd_irq; |
static devno_t ski_kbd_devno; |
chardev_t ski_console; |
chardev_t ski_uconsole; |
static bool kb_disable; |
int kbd_uspace=0; |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
69,8 → 57,8 |
void ski_putchar(chardev_t *d, const char ch) |
{ |
__asm__ volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"mov r15=%0\n" |
"mov r32=%1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
95,13 → 83,13 |
uint64_t ch; |
__asm__ volatile ( |
"mov r15 = %1\n" |
"mov r15=%1\n" |
"break 0x80000;;\n" /* modifies r8 */ |
"mov %0 = r8;;\n" |
"mov %0=r8;;\n" |
: "=r" (ch) |
: "i" (SKI_GETCHAR) |
: "r15", "r8" |
: "r15", "r8" |
); |
return (int32_t) ch; |
115,7 → 103,7 |
{ |
int ch; |
while(!(ch = ski_getchar())) |
while(!(ch=ski_getchar())) |
; |
if(ch == '\r') |
ch = '\n'; |
127,71 → 115,52 |
{ |
char ch; |
static char last; |
ipl_t ipl; |
ipl = interrupts_disable(); |
if (kbd_disabled) { |
interrupts_restore(ipl); |
if (kb_disable) |
return; |
} |
spinlock_lock(&ski_kbd_irq.lock); |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
if (ch){ |
if(kbd_uspace){ |
chardev_push_character(&ski_uconsole, ch); |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
virtual_interrupt(IRQ_KBD,NULL); |
} |
else { |
chardev_push_character(&ski_console, ch); |
} |
last = ch; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
last = ch; |
return; |
} |
} |
if (last) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
if (last){ |
if(kbd_uspace){ |
chardev_push_character(&ski_uconsole, 0); |
ipc_irq_send_notif(&ski_kbd_irq); |
virtual_interrupt(IRQ_KBD,NULL); |
} |
last = 0; |
} |
else { |
} |
last = 0; |
} |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
/* Called from getc(). */ |
static void ski_kbd_enable(chardev_t *d) |
static void ski_kb_enable(chardev_t *d) |
{ |
kbd_disabled = false; |
kb_disable = false; |
} |
/* Called from getc(). */ |
static void ski_kbd_disable(chardev_t *d) |
static void ski_kb_disable(chardev_t *d) |
{ |
kbd_disabled = true; |
kb_disable = true; |
} |
/** Decline to service hardware IRQ. |
* |
* This is only a virtual IRQ, so always decline. |
* |
* @return Always IRQ_DECLINE. |
*/ |
static irq_ownership_t ski_kbd_claim(void) |
{ |
return IRQ_DECLINE; |
} |
static chardev_operations_t ski_ops = { |
.resume = ski_kbd_enable, |
.suspend = ski_kbd_disable, |
.resume = ski_kb_enable, |
.suspend = ski_kb_disable, |
.write = ski_putchar, |
.read = ski_getchar_blocking |
}; |
204,7 → 173,7 |
void ski_init_console(void) |
{ |
__asm__ volatile ( |
"mov r15 = %0\n" |
"mov r15=%0\n" |
"break 0x80000\n" |
: |
: "i" (SKI_INIT_CONSOLE) |
216,14 → 185,6 |
stdin = &ski_console; |
stdout = &ski_console; |
ski_kbd_devno = device_assign_devno(); |
irq_initialize(&ski_kbd_irq); |
ski_kbd_irq.inr = SKI_KBD_INR; |
ski_kbd_irq.devno = ski_kbd_devno; |
ski_kbd_irq.claim = ski_kbd_claim; |
irq_register(&ski_kbd_irq); |
} |
/** Setup console sysinfo (i.e. Keyboard IRQ) |
234,21 → 195,9 |
*/ |
void ski_set_console_sysinfo(void) |
{ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR); |
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno); |
sysinfo_set_item_val("kbd",NULL,true); |
sysinfo_set_item_val("kbd.irq",NULL,IRQ_KBD); |
} |
void ski_kbd_grab(void) |
{ |
ski_kbd_irq.notif_cfg.notify = false; |
} |
void ski_kbd_release(void) |
{ |
if (ski_kbd_irq.notif_cfg.answerbox) |
ski_kbd_irq.notif_cfg.notify = true; |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia64/src/drivers/it.c |
---|
41,29 → 41,16 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <time/clock.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <arch.h> |
#define IT_SERVICE_CLOCKS 64 |
static irq_t it_irq; |
static irq_ownership_t it_claim(void); |
static void it_interrupt(irq_t *irq, void *arg, ...); |
/** Initialize Interval Timer. */ |
void it_init(void) |
{ |
cr_itv_t itv; |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
80,19 → 67,9 |
srlz_d(); |
} |
/** Always claim ownership for this IRQ. |
* |
* Other devices are responsible to avoid using INR 0. |
* |
* @return Always IRQ_ACCEPT. |
*/ |
irq_ownership_t it_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Process Interval Timer interrupt. */ |
void it_interrupt(irq_t *irq, void *arg, ...) |
void it_interrupt(void) |
{ |
int64_t c; |
int64_t m; |
106,7 → 83,7 |
c += IT_SERVICE_CLOCKS; |
m += IT_DELTA; |
if (m - c < 0) |
if (m-c<0) |
CPU->missed_clock_ticks++; |
else |
break; |
116,11 → 93,6 |
srlz_d(); /* propagate changes */ |
clock(); |
/* |
* This one is a good candidate for moving to a separate |
* kernel thread private to ski.c |
*/ |
poll_keyboard(); |
} |
/trunk/kernel/arch/ia64/include/interrupt.h |
---|
39,17 → 39,9 |
#include <arch/types.h> |
#include <arch/register.h> |
/** ia64 has 256 INRs. */ |
#define INR_COUNT 256 |
#define IRQ_COUNT 257 /* 256 NOT suppotred IRQS*//* TODO */ |
#define IRQ_KBD 256 /* One simulated interrupt for ski simulator keyboard*/ |
/* |
* We need to keep this just to compile. |
* We might eventually move interrupt/ stuff |
* to genarch. |
*/ |
#define IVT_ITEMS 0 |
#define IVT_FIRST 0 |
/** External Interrupt vectors. */ |
#define INTERRUPT_TIMER 0 |
#define INTERRUPT_SPURIOUS 15 |
134,7 → 126,7 |
static inline int istate_from_uspace(istate_t *istate) |
{ |
return (istate->cr_iip) < 0xe000000000000000ULL; |
return (istate->cr_iip)<0xe000000000000000ULL; |
} |
extern void *ivt; |
144,6 → 136,7 |
extern void universal_handler(uint64_t vector, istate_t *istate); |
extern void nop_handler(uint64_t vector, istate_t *istate); |
extern void external_interrupt(uint64_t vector, istate_t *istate); |
extern void virtual_interrupt(uint64_t irq, void *param); |
extern void disabled_fp_register(uint64_t vector, istate_t *istate); |
#endif |
/trunk/kernel/arch/ia64/include/ski/ski.h |
---|
42,14 → 42,12 |
#define SKI_GETCHAR 21 |
#define SKI_PUTCHAR 31 |
extern chardev_t ski_uconsole; |
extern void ski_init_console(void); |
extern void ski_set_console_sysinfo(void); |
extern void poll_keyboard(void); |
extern void ski_kbd_grab(void); |
extern void ski_kbd_release(void); |
extern chardev_t ski_uconsole; |
extern int kbd_uspace; |
#endif |
/trunk/kernel/arch/ia64/include/drivers/it.h |
---|
44,6 → 44,7 |
#define IT_DELTA 100000 |
extern void it_init(void); |
extern void it_interrupt(void); |
#endif |
/trunk/kernel/arch/sparc64/include/interrupt.h |
---|
40,6 → 40,8 |
#include <arch/types.h> |
#include <arch/regdef.h> |
#define IRQ_COUNT 1 /* TODO */ |
#define IVT_ITEMS 15 |
#define IVT_FIRST 1 |