/trunk/kernel/arch/ppc32/include/interrupt.h |
---|
37,13 → 37,9 |
#include <arch/exception.h> |
#define IRQ_COUNT 64 |
#define IVT_ITEMS 16 |
#define IVT_FIRST 0 |
#define IVT_ITEMS (16 + IRQ_COUNT) |
#define INT_OFFSET 16 |
#define int_register(it, name, handler) exc_register(((it) + INT_OFFSET), name, handler) |
#define VECTOR_DATA_STORAGE 2 |
#define VECTOR_INSTRUCTION_STORAGE 3 |
#define VECTOR_EXTERNAL 4 |
/trunk/kernel/arch/ppc32/include/drivers/cuda.h |
---|
38,9 → 38,7 |
#include <arch/types.h> |
#include <typedefs.h> |
#define CUDA_IRQ 10 |
extern void cuda_init(uintptr_t base, size_t size); |
extern void cuda_init(devno_t devno, uintptr_t base, size_t size); |
extern int cuda_get_scancode(void); |
extern void cuda_grab(void); |
extern void cuda_release(void); |
/trunk/kernel/arch/ppc32/src/ppc32.c |
---|
41,8 → 41,12 |
#include <userspace.h> |
#include <proc/uarg.h> |
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/drivers/pic.h> |
#define IRQ_COUNT 64 |
bootinfo_t bootinfo; |
void arch_pre_main(void) |
70,12 → 74,17 |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* Initialize framebuffer */ |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline, false); |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
/* Initialize PIC */ |
pic_init(bootinfo.keyboard.addr, PAGE_SIZE); |
cuda_init(bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE); |
/* Initialize I/O controller */ |
cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE); |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
/trunk/kernel/arch/ppc32/src/interrupt.c |
---|
32,6 → 32,7 |
/** @file |
*/ |
#include <ddi/irq.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <arch/types.h> |
40,6 → 41,7 |
#include <ipc/sysipc.h> |
#include <arch/drivers/pic.h> |
#include <arch/mm/tlb.h> |
#include <print.h> |
void start_decrementer(void) |
56,9 → 58,23 |
static void exception_external(int n, istate_t *istate) |
{ |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
exc_dispatch(inum + INT_OFFSET, istate); |
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 |
} |
pic_ack_interrupt(inum); |
} |
} |
/trunk/kernel/arch/ppc32/src/drivers/pic.c |
---|
80,13 → 80,13 |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) { |
if (pending) |
return fnzb32(pending); |
} |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) { |
if (pending) |
return fnzb32(pending) + 32; |
} |
return -1; |
} |
/trunk/kernel/arch/ppc32/src/drivers/cuda.c |
---|
33,6 → 33,7 |
*/ |
#include <arch/drivers/cuda.h> |
#include <ddi/irq.h> |
#include <arch/asm.h> |
#include <console/console.h> |
#include <console/chardev.h> |
41,6 → 42,7 |
#include <interrupt.h> |
#include <stdarg.h> |
#define CUDA_IRQ 10 |
#define SPECIAL '?' |
#define PACKET_ADB 0x00 |
60,9 → 62,11 |
static volatile uint8_t *cuda = NULL; |
static iroutine vector; |
static irq_t cuda_irq; /**< Cuda's IRQ. */ |
static ipc_notif_cfg_t saved_notif_cfg; |
static char lchars[0x80] = { |
'a', |
's', |
248,22 → 252,37 |
return -1; |
} |
static void cuda_irq(int n, istate_t *istate) |
static void cuda_irq_handler(irq_t *irq, void *arg, ...) |
{ |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
if (irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else { |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
} |
} |
static irq_ownership_t cuda_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Initialize keyboard and service interrupts using kernel routine */ |
void cuda_grab(void) |
{ |
vector = int_register(CUDA_IRQ, "cuda", cuda_irq); |
if (cuda_irq.notif_cfg.answerbox) { |
saved_notif_cfg = cuda_irq.notif_cfg; |
cuda_irq.notif_cfg.answerbox = NULL; |
cuda_irq.notif_cfg.code = NULL; |
cuda_irq.notif_cfg.method = 0; |
cuda_irq.notif_cfg.counter = 0; |
} |
} |
270,23 → 289,33 |
/** Resume the former interrupt vector */ |
void cuda_release(void) |
{ |
if (vector) |
int_register(CUDA_IRQ, "user_interrupt", vector); |
if (saved_notif_cfg.answerbox) |
cuda_irq.notif_cfg = saved_notif_cfg; |
} |
void cuda_init(uintptr_t base, size_t size) |
void cuda_init(devno_t devno, uintptr_t base, size_t size) |
{ |
cuda = (uint8_t *) hw_map(base, size); |
cuda = (uint8_t *) hw_map(base, size); |
int_register(CUDA_IRQ, "cuda", cuda_irq); |
pic_enable_interrupt(CUDA_IRQ); |
chardev_initialize("cuda_kbd", &kbrd, &ops); |
stdin = &kbrd; |
sysinfo_set_item_val("cuda", NULL, true); |
sysinfo_set_item_val("cuda.irq", NULL, CUDA_IRQ); |
irq_initialize(&cuda_irq); |
cuda_irq.devno = devno; |
cuda_irq.inr = CUDA_IRQ; |
cuda_irq.claim = cuda_claim; |
cuda_irq.handler = cuda_irq_handler; |
irq_register(&cuda_irq); |
pic_enable_interrupt(CUDA_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, base); |
cuda_grab(); |
} |