/trunk/kernel/arch/sparc64/include/interrupt.h |
---|
40,8 → 40,6 |
#include <arch/types.h> |
#include <arch/regdef.h> |
#define IRQ_COUNT 1 /* TODO */ |
#define IVT_ITEMS 15 |
#define IVT_FIRST 1 |
/trunk/kernel/arch/ia64/include/interrupt.h |
---|
39,9 → 39,17 |
#include <arch/types.h> |
#include <arch/register.h> |
#define IRQ_COUNT 257 /* 256 NOT suppotred IRQS*//* TODO */ |
#define IRQ_KBD 256 /* One simulated interrupt for ski simulator keyboard*/ |
/** ia64 has 256 INRs. */ |
#define INR_COUNT 256 |
/* |
* 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 |
136,7 → 144,6 |
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,12 → 42,14 |
#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 chardev_t ski_uconsole; |
extern int kbd_uspace; |
extern void ski_kbd_grab(void); |
extern void ski_kbd_release(void); |
#endif |
/trunk/kernel/arch/ia64/include/drivers/it.h |
---|
44,7 → 44,6 |
#define IT_DELTA 100000 |
extern void it_init(void); |
extern void it_interrupt(void); |
#endif |
/trunk/kernel/arch/ia64/src/ia64.c |
---|
49,9 → 49,8 |
#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. */ |
80,12 → 79,13 |
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,8 → 145,7 |
*/ |
void arch_grab_console(void) |
{ |
kbd_release=kbd_uspace; |
kbd_uspace=0; |
ski_kbd_grab(); |
} |
/** Return console to userspace |
* |
153,7 → 152,7 |
*/ |
void arch_release_console(void) |
{ |
kbd_uspace=kbd_release; |
ski_kbd_release(); |
} |
/** @} |
/trunk/kernel/arch/ia64/src/ski/ski.c |
---|
37,12 → 37,24 |
#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); |
115,52 → 127,71 |
{ |
char ch; |
static char last; |
ipl_t ipl; |
if (kb_disable) |
ipl = interrupts_disable(); |
if (kbd_disabled) { |
interrupts_restore(ipl); |
return; |
} |
spinlock_lock(&ski_kbd_irq.lock); |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch){ |
if(kbd_uspace){ |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, ch); |
virtual_interrupt(IRQ_KBD,NULL); |
} |
else { |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
chardev_push_character(&ski_console, ch); |
} |
last = ch; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
return; |
} |
if (last){ |
if(kbd_uspace){ |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, 0); |
virtual_interrupt(IRQ_KBD,NULL); |
ipc_irq_send_notif(&ski_kbd_irq); |
} |
else { |
} |
last = 0; |
} |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
/* Called from getc(). */ |
static void ski_kb_enable(chardev_t *d) |
static void ski_kbd_enable(chardev_t *d) |
{ |
kb_disable = false; |
kbd_disabled = false; |
} |
/* Called from getc(). */ |
static void ski_kb_disable(chardev_t *d) |
static void ski_kbd_disable(chardev_t *d) |
{ |
kb_disable = true; |
kbd_disabled = 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_kb_enable, |
.suspend = ski_kb_disable, |
.resume = ski_kbd_enable, |
.suspend = ski_kbd_disable, |
.write = ski_putchar, |
.read = ski_getchar_blocking |
}; |
185,6 → 216,14 |
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) |
196,8 → 235,20 |
void ski_set_console_sysinfo(void) |
{ |
sysinfo_set_item_val("kbd",NULL,true); |
sysinfo_set_item_val("kbd.irq",NULL,IRQ_KBD); |
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR); |
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno); |
} |
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/interrupt.c |
---|
34,17 → 34,18 |
*/ |
#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> |
51,9 → 52,8 |
#include <ipc/sysipc.h> |
#include <ipc/irq.h> |
#include <ipc/ipc.h> |
#include <interrupt.h> |
#include <synch/spinlock.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
#define VECTORS_16_BUNDLE_START 0x5000 |
61,7 → 61,6 |
#define BUNDLE_SIZE 16 |
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = { |
"VHPT Translation vector", |
"Instruction TLB vector", |
197,12 → 196,10 |
#endif |
} |
void nop_handler(uint64_t vector, istate_t *istate) |
{ |
} |
/** Handle syscall. */ |
int break_instruction(uint64_t vector, istate_t *istate) |
{ |
228,36 → 225,30 |
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_TIMER: |
it_interrupt(); |
break; |
case INTERRUPT_SPURIOUS: |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt\n", CPU->id); |
#endif |
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/drivers/it.c |
---|
41,16 → 41,29 |
#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; |
67,9 → 80,19 |
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(void) |
void it_interrupt(irq_t *irq, void *arg, ...) |
{ |
int64_t c; |
int64_t m; |
93,6 → 116,11 |
srlz_d(); /* propagate changes */ |
clock(); |
/* |
* This one is a good candidate for moving to a separate |
* kernel thread private to ski.c |
*/ |
poll_keyboard(); |
} |