/trunk/kernel/genarch/include/kbd/ns16550.h |
---|
58,6 → 58,7 |
#define IIR_REG 2 /** Interrupt Ident Register (read). */ |
#define FCR_REG 2 /** FIFO control register (write). */ |
#define LCR_REG 3 /** Line Control register. */ |
#define MCR_REG 4 /** Modem Control Register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ |
64,10 → 65,13 |
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */ |
#define MCR_OUT2 0x08 /** OUT2. */ |
/** Structure representing the ns16550 device. */ |
typedef struct { |
devno_t devno; |
volatile ioport_t io_port; /** Memory mapped registers of the ns16550. */ |
/** Memory mapped registers of the ns16550. */ |
volatile ioport_t io_port; |
} ns16550_t; |
static inline uint8_t ns16550_rbr_read(ns16550_t *dev) |
114,7 → 118,15 |
return inb(dev->io_port+LSR_REG); |
} |
static inline uint8_t ns16550_mcr_read(ns16550_t *dev) |
{ |
return inb(dev->io_port + MCR_REG); |
} |
static inline void ns16550_mcr_write(ns16550_t *dev, uint8_t v) |
{ |
outb(dev->io_port + MCR_REG, v); |
} |
#endif |
/trunk/kernel/genarch/src/kbd/ns16550.c |
---|
134,6 → 134,12 |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, port); |
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN |
/* Enable interrupts */ |
ns16550_ier_write(&ns16550, IER_ERBFI); |
ns16550_mcr_write(&ns16550, MCR_OUT2); |
#endif |
#ifdef ia64 |
uint8_t c; |
c = ns16550_lcr_read(&ns16550); |
149,10 → 155,7 |
/** Process ns16550 interrupt. */ |
void ns16550_interrupt(void) |
{ |
/* TODO |
* |
* ns16550 works in the polled mode so far. |
*/ |
ns16550_poll(); |
} |
/* Called from getc(). */ |
201,6 → 204,7 |
*/ |
void ns16550_poll(void) |
{ |
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN |
ipl_t ipl; |
ipl = interrupts_disable(); |
220,6 → 224,7 |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
#endif |
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
uint8_t x; |
251,7 → 256,10 |
void ns16550_irq_handler(irq_t *irq, void *arg, ...) |
{ |
panic("Not yet implemented, ns16550 works in polled mode.\n"); |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else |
ns16550_interrupt(); |
} |
/** @} |