Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1930 → Rev 1931

/trunk/kernel/genarch/src/kbd/ns16550.c
38,9 → 38,10
#include <genarch/kbd/key.h>
#include <genarch/kbd/scanc.h>
#include <genarch/kbd/scanc_sun.h>
#include <arch/drivers/kbd.h>
#include <arch/drivers/ns16550.h>
#include <ddi/irq.h>
#include <arch/interrupt.h>
#include <ipc/irq.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
48,7 → 49,9
#include <console/chardev.h>
#include <console/console.h>
#include <interrupt.h>
#include <arch/interrupt.h>
#include <sysinfo/sysinfo.h>
#include <synch/spinlock.h>
 
#define LSR_DATA_READY 0x01
 
58,6 → 61,8
/** Structure for ns16550's IRQ. */
static irq_t ns16550_irq;
 
static ipc_notif_cfg_t saved_notif_cfg;
 
/*
* These codes read from ns16550 data register are silently ignored.
*/
72,19 → 77,30
.read = ns16550_key_read
};
 
void ns16550_interrupt(int n, istate_t *istate);
void ns16550_wait(void);
void ns16550_interrupt(void);
 
/** Initialize keyboard and service interrupts using kernel routine */
void ns16550_grab(void)
{
/* TODO */
ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
(void) ns16550_rbr_read(&ns16550);
 
if (ns16550_irq.notif_cfg.answerbox) {
saved_notif_cfg = ns16550_irq.notif_cfg;
ns16550_irq.notif_cfg.answerbox = NULL;
ns16550_irq.notif_cfg.code = NULL;
ns16550_irq.notif_cfg.method = 0;
ns16550_irq.notif_cfg.counter = 0;
}
}
 
/** Resume the former interrupt vector */
void ns16550_release(void)
{
/* TODO */
if (saved_notif_cfg.answerbox)
ns16550_irq.notif_cfg = saved_notif_cfg;
}
 
/** Initialize ns16550.
95,7 → 111,6
*/
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
{
ns16550_grab();
chardev_initialize("ns16550_kbd", &kbrd, &ops);
stdin = &kbrd;
110,31 → 125,23
irq_register(&ns16550_irq);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
(void) ns16550_rbr_read(&ns16550);
ns16550_grab();
}
 
/** Process ns16550 interrupt.
*
* @param n Interrupt vector.
* @param istate Interrupted state.
*/
void ns16550_interrupt(int n, istate_t *istate)
/** Process ns16550 interrupt. */
void ns16550_interrupt(void)
{
/* TODO */
/* TODO
*
* ns16550 works in the polled mode so far.
*/
}
 
/** Wait until the controller reads its data. */
void ns16550_wait(void)
{
}
 
/* Called from getc(). */
void ns16550_resume(chardev_t *d)
{
170,9 → 177,29
*/
void ns16550_poll(void)
{
uint8_t x;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&ns16550_irq.lock);
 
if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
if (ns16550_irq.notif_cfg.answerbox) {
/*
* Send IPC notification.
*/
ipc_irq_send_notif(&ns16550_irq);
spinlock_unlock(&ns16550_irq.lock);
interrupts_restore(ipl);
return;
}
}
 
spinlock_unlock(&ns16550_irq.lock);
interrupts_restore(ipl);
 
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
uint8_t x;
x = ns16550_rbr_read(&ns16550);
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
185,13 → 212,12
 
irq_ownership_t ns16550_claim(void)
{
/* TODO */
return IRQ_ACCEPT;
return (ns16550_lsr_read(&ns16550) & LSR_DATA_READY);
}
 
void ns16550_irq_handler(irq_t *irq, void *arg, ...)
{
panic("Not yet implemented.\n");
panic("Not yet implemented, ns16550 works in polled mode.\n");
}
 
/** @}
/trunk/kernel/genarch/src/kbd/z8530.c
124,6 → 124,7
irq_register(&z8530_irq);
 
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);