Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3635 → Rev 3646

/trunk/kernel/kernel.config
141,6 → 141,8
# Support for NS16550 serial port
! [ARCH=sparc64|ARCH=ia64] CONFIG_NS16550 (y/n)
 
# Interrupt-driven driver for NS16550?
! [CONFIG_NS16550=y] CONFIG_NS16550_INTERRUPT_DRIVEN (n/y)
 
# Virtually indexed D-cache support
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
/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,57 → 65,68
 
#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)
{
return inb(dev->io_port+RBR_REG);
return inb(dev->io_port + RBR_REG);
}
static inline void ns16550_rbr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+RBR_REG,v);
outb(dev->io_port + RBR_REG, v);
}
 
static inline uint8_t ns16550_ier_read(ns16550_t *dev)
{
return inb(dev->io_port+IER_REG);
return inb(dev->io_port + IER_REG);
}
 
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+IER_REG,v);
outb(dev->io_port + IER_REG, v);
}
 
static inline uint8_t ns16550_iir_read(ns16550_t *dev)
{
return inb(dev->io_port+IIR_REG);
return inb(dev->io_port + IIR_REG);
}
 
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+FCR_REG,v);
outb(dev->io_port + FCR_REG, v);
}
 
static inline uint8_t ns16550_lcr_read(ns16550_t *dev)
{
return inb(dev->io_port+LCR_REG);
return inb(dev->io_port + LCR_REG);
}
 
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+LCR_REG,v);
outb(dev->io_port + LCR_REG, v);
}
 
static inline uint8_t ns16550_lsr_read(ns16550_t *dev)
{
return inb(dev->io_port+LSR_REG);
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();
}
 
/** @}
/trunk/kernel/Makefile
126,6 → 126,10
DEFS += -DCONFIG_NS16550
endif
 
ifeq ($(CONFIG_NS16550_INTERRUPT_DRIVEN),y)
DEFS += -DCONFIG_NS16550_INTERRUPT_DRIVEN
endif
 
ifeq ($(CONFIG_VIRT_IDX_DCACHE),y)
DEFS += -DCONFIG_VIRT_IDX_DCACHE
endif
/trunk/kernel/arch/sparc64/src/console.c
112,11 → 112,23
}
#endif
 
#ifdef CONFIG_NS16550
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550) {
/*
* The ns16550 driver is interrupt-driven.
*/
return;
}
#endif
#endif
while (1) {
#ifdef CONFIG_NS16550
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550)
ns16550_poll();
#endif
#endif
thread_usleep(KEYBOARD_POLL_PAUSE);
}
}
/trunk/kernel/arch/sparc64/src/drivers/kbd.c
103,11 → 103,13
switch (kbd_type) {
case KBD_Z8530:
size = ((ofw_fhc_reg_t *) prop->value)->size;
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) {
if (!ofw_fhc_apply_ranges(node->parent,
((ofw_fhc_reg_t *) prop->value), &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
if (!ofw_fhc_map_interrupt(node->parent,
((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
}
115,11 → 117,13
case KBD_NS16550:
size = ((ofw_ebus_reg_t *) prop->value)->size;
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) {
if (!ofw_ebus_apply_ranges(node->parent,
((ofw_ebus_reg_t *) prop->value), &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
if (!ofw_ebus_map_interrupt(node->parent,
((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
};
151,7 → 155,8
break;
#endif
default:
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n");
printf("Kernel is not compiled with the necessary keyboard "
"driver this machine requires.\n");
}
}