/trunk/kernel/genarch/include/kbrd/kbrd.h |
---|
37,9 → 37,23 |
#define KERN_KBD_H_ |
#include <console/chardev.h> |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
extern void kbrd_init(indev_t *devin); |
typedef struct { |
thread_t *thread; |
indev_t *sink; |
indev_t raw; |
SPINLOCK_DECLARE(keylock); /**< keylock protects keyflags and lockflags. */ |
volatile unsigned int keyflags; /**< Tracking of multiple keypresses. */ |
volatile unsigned int lockflags; /**< Tracking of multiple keys lockings. */ |
} kbrd_instance_t; |
extern kbrd_instance_t *kbrd_init(void); |
extern indev_t *kbrd_wire(kbrd_instance_t *, indev_t *); |
#endif |
/** @} |
/trunk/kernel/genarch/include/drivers/ns16550/ns16550.h |
---|
62,12 → 62,13 |
/** Structure representing the ns16550 device. */ |
typedef struct { |
irq_t irq; |
ns16550_t *ns16550; |
irq_t irq; |
indev_t kbrdin; |
indev_t *kbrdin; |
} ns16550_instance_t; |
extern indev_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *); |
extern ns16550_instance_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *); |
extern void ns16550_wire(ns16550_instance_t *, indev_t *); |
#endif |
/trunk/kernel/genarch/include/drivers/dsrln/dsrlnin.h |
---|
49,10 → 49,11 |
typedef struct { |
irq_t irq; |
dsrlnin_t *dsrlnin; |
indev_t kbrdin; |
indev_t *srlnin; |
} dsrlnin_instance_t; |
extern indev_t *dsrlnin_init(dsrlnin_t *, inr_t); |
extern dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *, inr_t); |
extern void dsrlnin_wire(dsrlnin_instance_t *, indev_t *); |
#endif |
/trunk/kernel/genarch/include/drivers/i8042/i8042.h |
---|
49,10 → 49,11 |
typedef struct { |
irq_t irq; |
i8042_t *i8042; |
indev_t kbrdin; |
indev_t *kbrdin; |
} i8042_instance_t; |
extern indev_t *i8042_init(i8042_t *, inr_t); |
extern i8042_instance_t *i8042_init(i8042_t *, inr_t); |
extern void i8042_wire(i8042_instance_t *, indev_t *); |
extern void i8042_cpu_reset(i8042_t *); |
#endif |
/trunk/kernel/genarch/include/drivers/z8530/z8530.h |
---|
116,10 → 116,11 |
typedef struct { |
irq_t irq; |
z8530_t *z8530; |
indev_t kbrdin; |
indev_t *kbrdin; |
} z8530_instance_t; |
extern indev_t *z8530_init(z8530_t *, inr_t, cir_t, void *); |
extern z8530_instance_t *z8530_init(z8530_t *, inr_t, cir_t, void *); |
extern void z8530_wire(z8530_instance_t *, indev_t *); |
#endif |
/trunk/kernel/genarch/include/drivers/via-cuda/cuda.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_CUDA_H_ |
#define KERN_CUDA_H_ |
#include <ddi/irq.h> |
#include <arch/types.h> |
#include <console/chardev.h> |
typedef struct { |
} cuda_t; |
typedef struct { |
irq_t irq; |
cuda_t *cuda; |
indev_t *kbrdin; |
} cuda_instance_t; |
extern cuda_instance_t *cuda_init(cuda_t *, inr_t, cir_t, void *); |
extern void cuda_wire(cuda_instance_t *, indev_t *); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/trunk/kernel/genarch/include/srln/srln.h |
---|
37,9 → 37,18 |
#define KERN_SRLN_H_ |
#include <console/chardev.h> |
#include <proc/thread.h> |
extern void srln_init(indev_t *devin); |
typedef struct { |
thread_t *thread; |
indev_t *sink; |
indev_t raw; |
} srln_instance_t; |
extern srln_instance_t *srln_init(void); |
extern indev_t *srln_wire(srln_instance_t *, indev_t *); |
#endif |
/** @} |
/trunk/kernel/genarch/Makefile.inc |
---|
93,6 → 93,11 |
genarch/src/drivers/z8530/z8530.c |
endif |
ifeq ($(CONFIG_VIA_CUDA),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/via-cuda/cuda.c |
endif |
ifeq ($(CONFIG_PC_KBD),y) |
GENARCH_SOURCES += \ |
genarch/src/kbrd/kbrd.c \ |
/trunk/kernel/genarch/src/kbrd/kbrd.c |
---|
59,39 → 59,35 |
#define PRESSED_CAPSLOCK (1 << 1) |
#define LOCKED_CAPSLOCK (1 << 0) |
static indev_t kbrdout; |
indev_operations_t kbrdout_ops = { |
static indev_operations_t kbrd_raw_ops = { |
.poll = NULL |
}; |
SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
/** Process release of key. |
* |
* @param sc Scancode of the key being released. |
*/ |
static void key_released(wchar_t sc) |
static void key_released(kbrd_instance_t *instance, wchar_t sc) |
{ |
spinlock_lock(&keylock); |
spinlock_lock(&instance->keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags &= ~PRESSED_SHIFT; |
instance->keyflags &= ~PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags &= ~PRESSED_CAPSLOCK; |
if (lockflags & LOCKED_CAPSLOCK) |
lockflags &= ~LOCKED_CAPSLOCK; |
instance->keyflags &= ~PRESSED_CAPSLOCK; |
if (instance->lockflags & LOCKED_CAPSLOCK) |
instance->lockflags &= ~LOCKED_CAPSLOCK; |
else |
lockflags |= LOCKED_CAPSLOCK; |
instance->lockflags |= LOCKED_CAPSLOCK; |
break; |
default: |
break; |
} |
spinlock_unlock(&keylock); |
spinlock_unlock(&instance->keylock); |
} |
/** Process keypress. |
98,69 → 94,94 |
* |
* @param sc Scancode of the key being pressed. |
*/ |
static void key_pressed(wchar_t sc) |
static void key_pressed(kbrd_instance_t *instance, wchar_t sc) |
{ |
bool letter; |
bool shift; |
bool capslock; |
spinlock_lock(&keylock); |
spinlock_lock(&instance->keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags |= PRESSED_SHIFT; |
instance->keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
instance->keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SCAN_ESCAPE: |
break; |
default: |
letter = islower(sc_primary_map[sc]); |
shift = keyflags & PRESSED_SHIFT; |
capslock = (keyflags & PRESSED_CAPSLOCK) || |
(lockflags & LOCKED_CAPSLOCK); |
shift = instance->keyflags & PRESSED_SHIFT; |
capslock = (instance->keyflags & PRESSED_CAPSLOCK) || |
(instance->lockflags & LOCKED_CAPSLOCK); |
if ((letter) && (capslock)) |
shift = !shift; |
if (shift) |
indev_push_character(stdin, sc_secondary_map[sc]); |
indev_push_character(instance->sink, sc_secondary_map[sc]); |
else |
indev_push_character(stdin, sc_primary_map[sc]); |
indev_push_character(instance->sink, sc_primary_map[sc]); |
break; |
} |
spinlock_unlock(&keylock); |
spinlock_unlock(&instance->keylock); |
} |
static void kkbrd(void *arg) |
{ |
indev_t *in = (indev_t *) arg; |
kbrd_instance_t *instance = (kbrd_instance_t *) arg; |
while (true) { |
wchar_t sc = _getc(in); |
wchar_t sc = indev_pop_character(&instance->raw); |
if (sc == IGNORE_CODE) |
continue; |
if (sc & KEY_RELEASE) |
key_released((sc ^ KEY_RELEASE) & 0x7f); |
key_released(instance, (sc ^ KEY_RELEASE) & 0x7f); |
else |
key_pressed(sc & 0x7f); |
key_pressed(instance, sc & 0x7f); |
} |
} |
void kbrd_init(indev_t *devin) |
kbrd_instance_t *kbrd_init(void) |
{ |
indev_initialize("kbrd", &kbrdout, &kbrdout_ops); |
thread_t *thread |
= thread_create(kkbrd, devin, TASK, 0, "kkbrd", false); |
kbrd_instance_t *instance |
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC); |
if (instance) { |
instance->thread |
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false); |
if (thread) { |
stdin = &kbrdout; |
thread_ready(thread); |
if (!instance->thread) { |
free(instance); |
return NULL; |
} |
instance->sink = NULL; |
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops); |
spinlock_initialize(&instance->keylock, "instance_keylock"); |
instance->keyflags = 0; |
instance->lockflags = 0; |
} |
return instance; |
} |
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink) |
{ |
ASSERT(instance); |
ASSERT(sink); |
instance->sink = sink; |
thread_ready(instance->thread); |
return &instance->raw; |
} |
/** @} |
*/ |
/trunk/kernel/genarch/src/drivers/ns16550/ns16550.c |
---|
43,10 → 43,6 |
#define LSR_DATA_READY 0x01 |
static indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
static irq_ownership_t ns16550_claim(irq_t *irq) |
{ |
ns16550_instance_t *instance = irq->instance; |
64,11 → 60,18 |
ns16550_t *dev = instance->ns16550; |
if (pio_read_8(&dev->lsr) & LSR_DATA_READY) { |
uint8_t x = pio_read_8(&dev->rbr); |
indev_push_character(&instance->kbrdin, x); |
uint8_t data = pio_read_8(&dev->rbr); |
indev_push_character(instance->kbrdin, data); |
} |
} |
/**< Clear input buffer. */ |
static void ns16550_clear_buffer(ns16550_t *dev) |
{ |
while ((pio_read_8(&dev->lsr) & LSR_DATA_READY)) |
(void) pio_read_8(&dev->rbr); |
} |
/** Initialize ns16550. |
* |
* @param dev Addrress of the beginning of the device in I/O space. |
77,19 → 80,16 |
* @param cir Clear interrupt function. |
* @param cir_arg First argument to cir. |
* |
* @return Keyboard device pointer or NULL on failure. |
* @return Keyboard instance or NULL on failure. |
* |
*/ |
indev_t *ns16550_init(ns16550_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
ns16550_instance_t *ns16550_init(ns16550_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
{ |
ns16550_instance_t *instance |
= malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
indev_initialize("ns16550", &instance->kbrdin, &kbrdin_ops); |
if (instance) { |
instance->ns16550 = dev; |
instance->kbrdin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
99,16 → 99,24 |
instance->irq.instance = instance; |
instance->irq.cir = cir; |
instance->irq.cir_arg = cir_arg; |
} |
return instance; |
} |
void ns16550_wire(ns16550_instance_t *instance, indev_t *kbrdin) |
{ |
ASSERT(instance); |
ASSERT(kbrdin); |
instance->kbrdin = kbrdin; |
irq_register(&instance->irq); |
while ((pio_read_8(&dev->lsr) & LSR_DATA_READY)) |
(void) pio_read_8(&dev->rbr); |
ns16550_clear_buffer(instance->ns16550); |
/* Enable interrupts */ |
pio_write_8(&dev->ier, IER_ERBFI); |
pio_write_8(&dev->mcr, MCR_OUT2); |
return &instance->kbrdin; |
pio_write_8(&instance->ns16550->ier, IER_ERBFI); |
pio_write_8(&instance->ns16550->mcr, MCR_OUT2); |
} |
/** @} |
/trunk/kernel/genarch/src/drivers/dsrln/dsrlnin.c |
---|
40,10 → 40,6 |
#include <arch/asm.h> |
#include <ddi/device.h> |
static indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
static irq_ownership_t dsrlnin_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
54,19 → 50,16 |
dsrlnin_instance_t *instance = irq->instance; |
dsrlnin_t *dev = instance->dsrlnin; |
indev_push_character(&instance->kbrdin, pio_read_8(&dev->data)); |
indev_push_character(instance->srlnin, pio_read_8(&dev->data)); |
} |
indev_t *dsrlnin_init(dsrlnin_t *dev, inr_t inr) |
dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *dev, inr_t inr) |
{ |
dsrlnin_instance_t *instance |
= malloc(sizeof(dsrlnin_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
indev_initialize("dsrlnin", &instance->kbrdin, &kbrdin_ops); |
if (instance) { |
instance->dsrlnin = dev; |
instance->srlnin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
74,10 → 67,19 |
instance->irq.claim = dsrlnin_claim; |
instance->irq.handler = dsrlnin_irq_handler; |
instance->irq.instance = instance; |
irq_register(&instance->irq); |
} |
return &instance->kbrdin; |
return instance; |
} |
void dsrlnin_wire(dsrlnin_instance_t *instance, indev_t *srlnin) |
{ |
ASSERT(instance); |
ASSERT(srlnin); |
instance->srlnin = srlnin; |
irq_register(&instance->irq); |
} |
/** @} |
*/ |
/trunk/kernel/genarch/src/drivers/i8042/i8042.c |
---|
44,10 → 44,6 |
#include <mm/slab.h> |
#include <ddi/device.h> |
static indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
#define i8042_SET_COMMAND 0x60 |
#define i8042_COMMAND 0x69 |
#define i8042_CPU_RESET 0xfe |
74,21 → 70,25 |
if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) { |
uint8_t data = pio_read_8(&dev->data); |
indev_push_character(&instance->kbrdin, data); |
indev_push_character(instance->kbrdin, data); |
} |
} |
/**< Clear input buffer. */ |
static void i8042_clear_buffer(i8042_t *dev) |
{ |
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK) |
(void) pio_read_8(&dev->data); |
} |
/** Initialize i8042. */ |
indev_t *i8042_init(i8042_t *dev, inr_t inr) |
i8042_instance_t *i8042_init(i8042_t *dev, inr_t inr) |
{ |
i8042_instance_t *instance |
= malloc(sizeof(i8042_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
indev_initialize("i8042", &instance->kbrdin, &kbrdin_ops); |
if (instance) { |
instance->i8042 = dev; |
instance->kbrdin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
96,23 → 96,28 |
instance->irq.claim = i8042_claim; |
instance->irq.handler = i8042_irq_handler; |
instance->irq.instance = instance; |
irq_register(&instance->irq); |
/* Clear input buffer */ |
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK) |
(void) pio_read_8(&dev->data); |
} |
return &instance->kbrdin; |
return instance; |
} |
void i8042_wire(i8042_instance_t *instance, indev_t *kbrdin) |
{ |
ASSERT(instance); |
ASSERT(kbrdin); |
instance->kbrdin = kbrdin; |
irq_register(&instance->irq); |
i8042_clear_buffer(instance->i8042); |
} |
/* Reset CPU by pulsing pin 0 */ |
void i8042_cpu_reset(i8042_t *dev) |
{ |
interrupts_disable(); |
/* Clear input buffer */ |
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK) |
(void) pio_read_8(&dev->data); |
i8042_clear_buffer(dev); |
/* Reset CPU */ |
pio_write_8(&dev->status, i8042_CPU_RESET); |
/trunk/kernel/genarch/src/drivers/z8530/z8530.c |
---|
41,10 → 41,6 |
#include <mm/slab.h> |
#include <ddi/device.h> |
static indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val) |
{ |
/* |
82,22 → 78,19 |
z8530_t *dev = instance->z8530; |
if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) { |
uint8_t x = z8530_read(&dev->ctl_a, RR8); |
indev_push_character(&instance->kbrdin, x); |
uint8_t data = z8530_read(&dev->ctl_a, RR8); |
indev_push_character(instance->kbrdin, data); |
} |
} |
/** Initialize z8530. */ |
indev_t *z8530_init(z8530_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
z8530_instance_t *z8530_init(z8530_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
{ |
z8530_instance_t *instance |
= malloc(sizeof(z8530_instance_t), FRAME_ATOMIC); |
if (!instance) |
return false; |
indev_initialize("z8530", &instance->kbrdin, &kbrdin_ops); |
if (instance) { |
instance->z8530 = dev; |
instance->kbrdin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
107,26 → 100,36 |
instance->irq.instance = instance; |
instance->irq.cir = cir; |
instance->irq.cir_arg = cir_arg; |
} |
return instance; |
} |
void z8530_wire(z8530_instance_t *instance, indev_t *kbrdin) |
{ |
ASSERT(instance); |
ASSERT(kbrdin); |
instance->kbrdin = kbrdin; |
irq_register(&instance->irq); |
(void) z8530_read(&dev->ctl_a, RR8); |
(void) z8530_read(&instance->z8530->ctl_a, RR8); |
/* |
* Clear any pending TX interrupts or we never manage |
* to set FHC UART interrupt state to idle. |
*/ |
z8530_write(&dev->ctl_a, WR0, WR0_TX_IP_RST); |
z8530_write(&instance->z8530->ctl_a, WR0, WR0_TX_IP_RST); |
/* interrupt on all characters */ |
z8530_write(&dev->ctl_a, WR1, WR1_IARCSC); |
z8530_write(&instance->z8530->ctl_a, WR1, WR1_IARCSC); |
/* 8 bits per character and enable receiver */ |
z8530_write(&dev->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); |
z8530_write(&instance->z8530->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); |
/* Master Interrupt Enable. */ |
z8530_write(&dev->ctl_a, WR9, WR9_MIE); |
return &instance->kbrdin; |
z8530_write(&instance->z8530->ctl_a, WR9, WR9_MIE); |
} |
/** @} |
/trunk/kernel/genarch/src/drivers/via-cuda/cuda.c |
---|
0,0 → 1,78 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
*/ |
#include <genarch/drivers/via-cuda/cuda.h> |
#include <console/chardev.h> |
#include <ddi/irq.h> |
#include <arch/asm.h> |
#include <mm/slab.h> |
#include <ddi/device.h> |
static irq_ownership_t cuda_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
static void cuda_irq_handler(irq_t *irq) |
{ |
} |
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg) |
{ |
cuda_instance_t *instance |
= malloc(sizeof(cuda_instance_t), FRAME_ATOMIC); |
if (instance) { |
instance->cuda = dev; |
instance->kbrdin = NULL; |
irq_initialize(&instance->irq); |
instance->irq.devno = device_assign_devno(); |
instance->irq.inr = inr; |
instance->irq.claim = cuda_claim; |
instance->irq.handler = cuda_irq_handler; |
instance->irq.instance = instance; |
instance->irq.cir = cir; |
instance->irq.cir_arg = cir_arg; |
} |
return instance; |
} |
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin) |
{ |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/trunk/kernel/genarch/src/srln/srln.c |
---|
41,20 → 41,18 |
#include <arch.h> |
#include <string.h> |
static indev_t srlnout; |
indev_operations_t srlnout_ops = { |
static indev_operations_t srln_raw_ops = { |
.poll = NULL |
}; |
static void ksrln(void *arg) |
{ |
indev_t *in = (indev_t *) arg; |
srln_instance_t *instance = (srln_instance_t *) arg; |
bool cr = false; |
uint32_t escape = 0; |
while (true) { |
wchar_t ch = _getc(in); |
wchar_t ch = indev_pop_character(&instance->raw); |
/* ANSI escape sequence processing */ |
if (escape != 0) { |
122,21 → 120,40 |
if (ch == 0x7f) |
ch = '\b'; |
indev_push_character(stdin, ch); |
indev_push_character(instance->sink, ch); |
} |
} |
void srln_init(indev_t *devin) |
srln_instance_t *srln_init(void) |
{ |
indev_initialize("srln", &srlnout, &srlnout_ops); |
thread_t *thread |
= thread_create(ksrln, devin, TASK, 0, "ksrln", false); |
srln_instance_t *instance |
= malloc(sizeof(srln_instance_t), FRAME_ATOMIC); |
if (instance) { |
instance->thread |
= thread_create(ksrln, (void *) instance, TASK, 0, "ksrln", false); |
if (thread) { |
stdin = &srlnout; |
thread_ready(thread); |
if (!instance->thread) { |
free(instance); |
return NULL; |
} |
instance->sink = NULL; |
indev_initialize("srln", &instance->raw, &srln_raw_ops); |
} |
return instance; |
} |
indev_t *srln_wire(srln_instance_t *instance, indev_t *sink) |
{ |
ASSERT(instance); |
ASSERT(sink); |
instance->sink = sink; |
thread_ready(instance->thread); |
return &instance->raw; |
} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/include/drivers/kbd.h |
---|
38,15 → 38,6 |
#include <arch/types.h> |
#include <genarch/ofw/ofw_tree.h> |
typedef enum { |
KBD_UNKNOWN, |
KBD_Z8530, |
KBD_NS16550, |
KBD_SGCN |
} kbd_type_t; |
extern kbd_type_t kbd_type; |
extern void kbd_init(ofw_tree_node_t *node); |
#endif |
/trunk/kernel/arch/sparc64/src/console.c |
---|
135,16 → 135,10 |
scr_redraw(); |
#endif |
switch (kbd_type) { |
#ifdef CONFIG_SGCN_KBD |
case KBD_SGCN: |
sgcn_grab(); |
break; |
#endif |
default: |
break; |
} |
} |
/** Return console to userspace |
* |
151,16 → 145,10 |
*/ |
void arch_release_console(void) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_SGCN_KBD |
case KBD_SGCN: |
sgcn_release(); |
break; |
#endif |
default: |
break; |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/src/drivers/kbd.c |
---|
54,102 → 54,56 |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
kbd_type_t kbd_type = KBD_UNKNOWN; |
#ifdef CONFIG_SUN_KBD |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
size_t offset; |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
cir_t cir; |
void *cir_arg; |
#ifdef CONFIG_NS16550 |
ns16550_t *ns16550; |
#endif |
#ifdef CONFIG_Z8530 |
z8530_t *z8530; |
#endif |
name = ofw_tree_node_name(node); |
static bool kbd_z8530_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
/* |
* Determine keyboard serial controller type. |
*/ |
if (str_cmp(name, "zs") == 0) |
kbd_type = KBD_Z8530; |
else if (str_cmp(name, "su") == 0) |
kbd_type = KBD_NS16550; |
if (str_cmp(name, "zs") != 0) |
return false; |
if (kbd_type == KBD_UNKNOWN) { |
printf("Unknown keyboard device.\n"); |
return; |
} |
/* |
* Read 'interrupts' property. |
*/ |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'interrupt' property."); |
interrupts = *((uint32_t *) prop->value); |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find interrupts property\n"); |
return false; |
} |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'reg' property."); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find reg property\n"); |
return false; |
} |
size_t size = ((ofw_fhc_reg_t *) prop->value)->size; |
uintptr_t pa; |
size_t size; |
inr_t inr; |
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)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
printf("z8530: Failed to determine address\n"); |
return false; |
} |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
printf("z8530: Failed to determine interrupt\n"); |
return false; |
} |
break; |
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)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
default: |
panic("Unexpected keyboard type."); |
} |
/* |
* We need to pass aligned address to hw_map(). |
* However, the physical keyboard address can |
156,18 → 110,21 |
* be pretty much unaligned, depending on the |
* underlying controller. |
*/ |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530 = (z8530_t *) |
z8530_t *z8530 = (z8530_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
indev_t *kbrdin_z8530 = z8530_init(z8530, inr, cir, cir_arg); |
if (kbrdin_z8530) |
kbrd_init(kbrdin_z8530); |
z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg); |
if (z8530_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
z8530_wire(z8530_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace drivers are |
174,41 → 131,123 |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
#endif |
sysinfo_set_item_val("kbd.type.z8530", NULL, true); |
return true; |
} |
#endif /* CONFIG_Z8530 */ |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550 = (ns16550_t *) |
static bool kbd_ns16550_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
if (str_cmp(name, "su") != 0) |
return false; |
/* |
* Read 'interrupts' property. |
*/ |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find interrupts property\n"); |
return false; |
} |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find reg property\n"); |
return false; |
} |
size_t size = ((ofw_ebus_reg_t *) prop->value)->size; |
uintptr_t pa; |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
printf("ns16550: Failed to determine address\n"); |
return false; |
} |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("ns16550: Failed to determine interrupt\n"); |
return false; |
} |
/* |
* We need to pass aligned address to hw_map(). |
* However, the physical keyboard address can |
* be pretty much unaligned, depending on the |
* underlying controller. |
*/ |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
ns16550_t *ns16550 = (ns16550_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
indev_t *kbrdin_ns16550 = ns16550_init(ns16550, inr, cir, cir_arg); |
if (kbrdin_ns16550) |
kbrd_init(kbrdin_ns16550); |
ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg); |
if (ns16550_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
ns16550_wire(ns16550_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard " |
"driver this machine requires.\n"); |
sysinfo_set_item_val("kbd.type.ns16550", NULL, true); |
return true; |
} |
} |
#endif /* CONFIG_NS16550 */ |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
* |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
#ifdef CONFIG_Z8530 |
kbd_z8530_init(node); |
#endif |
#ifdef CONFIG_NS16550 |
kbd_ns16550_init(node); |
#endif |
} |
#endif /* CONFIG_SUN_KBD */ |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
101,9 → 101,6 |
/** Returns a pointer to the console buffer header. */ |
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0)) |
/** defined in drivers/kbd.c */ |
extern kbd_type_t kbd_type; |
/** starting address of SRAM, will be set by the init_sram_begin function */ |
static uintptr_t sram_begin; |
353,10 → 350,7 |
{ |
sgcn_buffer_begin_init(); |
kbd_type = KBD_SGCN; |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN); |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
/trunk/kernel/arch/ia64/include/ski/ski.h |
---|
File deleted |
/trunk/kernel/arch/ia64/include/arch.h |
---|
37,7 → 37,7 |
#define LOADED_PROG_STACK_PAGES_NO 2 |
#include <arch/ski/ski.h> |
#include <arch/drivers/ski.h> |
extern void arch_pre_main(void); |
/trunk/kernel/arch/ia64/include/drivers/ski.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia64_SKI_H_ |
#define KERN_ia64_SKI_H_ |
#include <console/chardev.h> |
#include <proc/thread.h> |
typedef struct { |
thread_t *thread; |
indev_t *srlnin; |
} ski_instance_t; |
extern void skiout_init(void); |
extern ski_instance_t *skiin_init(void); |
extern void skiin_wire(ski_instance_t *, indev_t *); |
extern void ski_kbd_grab(void); |
extern void ski_kbd_release(void); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/trunk/kernel/arch/ia64/Makefile.inc |
---|
64,8 → 64,7 |
arch/$(KARCH)/src/drivers/it.c |
ifeq ($(MACHINE),ski) |
ARCH_SOURCES += arch/$(KARCH)/src/ski/ski.c |
DEFS += -DSKI |
ARCH_SOURCES += arch/$(KARCH)/src/drivers/ski.c |
BFD = binary |
endif |
/trunk/kernel/arch/ia64/src/ski/ski.c |
---|
File deleted |
/trunk/kernel/arch/ia64/src/smp/smp.c |
---|
33,7 → 33,7 |
*/ |
#include <arch.h> |
#include <arch/ski/ski.h> |
#include <arch/drivers/ski.h> |
#include <arch/drivers/it.h> |
#include <arch/interrupt.h> |
#include <arch/barrier.h> |
/trunk/kernel/arch/ia64/src/ia64.c |
---|
33,7 → 33,7 |
*/ |
#include <arch.h> |
#include <arch/ski/ski.h> |
#include <arch/drivers/ski.h> |
#include <arch/drivers/it.h> |
#include <arch/interrupt.h> |
#include <arch/barrier.h> |
148,11 → 148,17 |
void arch_post_smp_init(void) |
{ |
#ifdef SKI |
indev_t *in; |
in = skiin_init(); |
if (in) |
srln_init(in); |
#ifdef MACHINE_ski |
ski_instance_t *ski_instance = skiin_init(); |
if (ski_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
skiin_wire(ski_instance, srln); |
} |
} |
skiout_init(); |
#endif |
161,10 → 167,16 |
#endif |
#ifdef CONFIG_NS16550 |
indev_t *kbrdin_ns16550 |
ns16550_instance_t *ns16550_instance |
= ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL); |
if (kbrdin_ns16550) |
srln_init(kbrdin_ns16550); |
if (ns16550_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
ns16550_wire(ns16550_instance, srln); |
} |
} |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ); |
176,9 → 188,15 |
#endif |
#ifdef CONFIG_I8042 |
indev_t *kbrdin_i8042 = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin_i8042) |
kbrd_init(kbrdin_i8042); |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
} |
} |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
238,7 → 256,7 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef SKI |
#ifdef MACHINE_ski |
ski_kbd_grab(); |
#endif |
} |
248,7 → 266,7 |
*/ |
void arch_release_console(void) |
{ |
#ifdef SKI |
#ifdef MACHINE_ski |
ski_kbd_release(); |
#endif |
} |
/trunk/kernel/arch/ia64/src/drivers/ski.c |
---|
0,0 → 1,226 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/drivers/ski.h> |
#include <console/console.h> |
#include <console/chardev.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/types.h> |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch/drivers/kbd.h> |
#include <string.h> |
#include <arch.h> |
#define POLL_INTERVAL 10000 /* 10 ms */ |
#define SKI_INIT_CONSOLE 20 |
#define SKI_GETCHAR 21 |
#define SKI_PUTCHAR 31 |
static void ski_putchar(outdev_t *, const wchar_t, bool); |
static outdev_operations_t skiout_ops = { |
.write = ski_putchar |
}; |
static outdev_t skiout; /**< Ski output device. */ |
static bool initialized = false; |
static bool kbd_disabled = false; |
/** Initialize debug console |
* |
* Issue SSC (Simulator System Call) to |
* to open debug console. |
* |
*/ |
static void ski_init(void) |
{ |
if (initialized) |
return; |
asm volatile ( |
"mov r15 = %0\n" |
"break 0x80000\n" |
: |
: "i" (SKI_INIT_CONSOLE) |
: "r15", "r8" |
); |
initialized = true; |
} |
static void ski_do_putchar(const wchar_t ch) |
{ |
asm volatile ( |
"mov r15 = %[cmd]\n" |
"mov r32 = %[ch]\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch) |
: "r15", "in0", "r8" |
); |
} |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
* display character on debug console. |
* |
* @param dev Character device. |
* @param ch Character to be printed. |
* @param silent Whether the output should be silenced. |
* |
*/ |
static void ski_putchar(outdev_t *dev, const wchar_t ch, bool silent) |
{ |
if (!silent) { |
if (ascii_check(ch)) { |
if (ch == '\n') |
ski_do_putchar('\r'); |
ski_do_putchar(ch); |
} else |
ski_do_putchar(U_SPECIAL); |
} |
} |
void skiout_init(void) |
{ |
ski_init(); |
outdev_initialize("skiout", &skiout, &skiout_ops); |
stdout = &skiout; |
sysinfo_set_item_val("fb", NULL, false); |
} |
/** Ask debug console if a key was pressed. |
* |
* Use SSC (Simulator System Call) to |
* get character from debug console. |
* |
* This call is non-blocking. |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
* |
*/ |
static wchar_t ski_getchar(void) |
{ |
uint64_t ch; |
asm volatile ( |
"mov r15 = %1\n" |
"break 0x80000;;\n" /* modifies r8 */ |
"mov %0 = r8;;\n" |
: "=r" (ch) |
: "i" (SKI_GETCHAR) |
: "r15", "r8" |
); |
return (wchar_t) ch; |
} |
/** Ask keyboard if a key was pressed. */ |
static void poll_keyboard(ski_instance_t *instance) |
{ |
if (kbd_disabled) |
return; |
wchar_t ch = ski_getchar(); |
if (ch != 0) |
indev_push_character(instance->srlnin, ch); |
} |
/** Kernel thread for polling keyboard. */ |
static void kskipoll(void *arg) |
{ |
ski_instance_t *instance = (ski_instance_t *) arg; |
while (true) { |
if (!silent) |
poll_keyboard(instance); |
thread_usleep(POLL_INTERVAL); |
} |
} |
ski_instance_t *skiin_init(void) |
{ |
ski_init(); |
ski_instance_t *instance |
= malloc(sizeof(ski_instance_t), FRAME_ATOMIC); |
if (instance) { |
instance->thread = thread_create(kskipoll, (void *) instance, TASK, 0, "kskipoll", true); |
if (!instance->thread) { |
free(instance); |
return NULL; |
} |
instance->srlnin = NULL; |
} |
return instance; |
} |
void skiin_wire(ski_instance_t *instance, indev_t *srlnin) |
{ |
ASSERT(instance); |
ASSERT(srlnin); |
instance->srlnin = srlnin; |
thread_ready(instance->thread); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI); |
} |
void ski_kbd_grab(void) |
{ |
kbd_disabled = true; |
} |
void ski_kbd_release(void) |
{ |
kbd_disabled = false; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/trunk/kernel/arch/arm32/include/console.h |
---|
File deleted |
/trunk/kernel/arch/arm32/Makefile.inc |
---|
51,7 → 51,6 |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/mm/as.c \ |
/trunk/kernel/arch/arm32/src/console.c |
---|
File deleted |
/trunk/kernel/arch/arm32/src/arm32.c |
---|
35,7 → 35,6 |
#include <arch.h> |
#include <config.h> |
#include <arch/console.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/drivers/dsrln/dsrlnin.h> |
42,6 → 41,7 |
#include <genarch/drivers/dsrln/dsrlnout.h> |
#include <genarch/srln/srln.h> |
#include <sysinfo/sysinfo.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <arch/drivers/gxemul.h> |
#include <print.h> |
129,11 → 129,18 |
#ifdef CONFIG_ARM_KBD |
/* |
* Initialize the GXemul keyboard port. Then initialize the serial line |
* module and connect it to the GXemul keyboard. Enable keyboard interrupts. |
* module and connect it to the GXemul keyboard. |
*/ |
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ); |
if (kbrdin) |
srln_init(kbrdin); |
dsrlnin_instance_t *dsrlnin_instance |
= dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ); |
if (dsrlnin_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
dsrlnin_wire(dsrlnin_instance, srln); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
201,5 → 208,18 |
return addr; |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
} |
/** @} |
*/ |
/trunk/kernel/arch/ppc32/include/drivers/cuda.h |
---|
File deleted |
/trunk/kernel/arch/ppc32/include/drivers/pic.h |
---|
36,6 → 36,7 |
#define KERN_ppc32_PIC_H_ |
#include <arch/types.h> |
#include <ddi/irq.h> |
#define PIC_PENDING_LOW 8 |
#define PIC_PENDING_HIGH 4 |
44,11 → 45,11 |
#define PIC_ACK_LOW 10 |
#define PIC_ACK_HIGH 6 |
void pic_init(uintptr_t base, size_t size); |
void pic_enable_interrupt(int intnum); |
void pic_disable_interrupt(int intnum); |
void pic_ack_interrupt(int intnum); |
int pic_get_pending(void); |
extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg); |
extern void pic_enable_interrupt(inr_t intnum); |
extern void pic_disable_interrupt(inr_t intnum); |
extern void pic_ack_interrupt(void *arg, inr_t intnum); |
extern int pic_get_pending(void); |
#endif |
/trunk/kernel/arch/ppc32/Makefile.inc |
---|
54,7 → 54,6 |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/cuda.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
/trunk/kernel/arch/ppc32/src/ppc32.c |
---|
35,7 → 35,7 |
#include <config.h> |
#include <arch.h> |
#include <arch/boot/boot.h> |
#include <arch/drivers/cuda.h> |
#include <genarch/drivers/via-cuda/cuda.h> |
#include <arch/interrupt.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
44,10 → 44,12 |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <arch/drivers/pic.h> |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
#define IRQ_COUNT 64 |
#define IRQ_CUDA 10 |
bootinfo_t bootinfo; |
117,11 → 119,28 |
if (bootinfo.macio.addr) { |
/* Initialize PIC */ |
pic_init(bootinfo.macio.addr, PAGE_SIZE); |
cir_t cir; |
void *cir_arg; |
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg); |
#ifdef CONFIG_VIA_CUDA |
uintptr_t pa = bootinfo.macio.addr + 0x16000; |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
size_t size = 2 * PAGE_SIZE; |
cuda_t *cuda = (cuda_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
/* Initialize I/O controller */ |
cuda_init(bootinfo.macio.addr + 0x16000, 2 * PAGE_SIZE); |
cuda_instance_t *cuda_instance = |
cuda_init(cuda, IRQ_CUDA, cir, cir_arg); |
if (cuda_instance) { |
indev_t *sink = stdin_wire(); |
cuda_wire(cuda_instance, sink); |
} |
#endif |
} |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
186,5 → 205,11 |
return addr; |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ppc32/src/dummy.s |
---|
30,6 → 30,7 |
.global asm_delay_loop |
.global sys_tls_set |
.global cpu_halt |
sys_tls_set: |
b sys_tls_set |
36,3 → 37,6 |
asm_delay_loop: |
blr |
cpu_halt: |
b cpu_halt |
/trunk/kernel/arch/ppc32/src/interrupt.c |
---|
60,7 → 60,6 |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
69,11 → 68,17 |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
pic_ack_interrupt(inum); |
ack = true; |
if (irq->cir) |
irq->cir(irq->cir_arg, irq->inr); |
} |
irq->handler(irq); |
if (!irq->preack) { |
if (irq->cir) |
irq->cir(irq->cir_arg, irq->inr); |
} |
spinlock_unlock(&irq->lock); |
} else { |
/* |
83,9 → 88,6 |
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
/trunk/kernel/arch/ppc32/src/drivers/cuda.c |
---|
File deleted |
/trunk/kernel/arch/ppc32/src/drivers/pic.c |
---|
40,12 → 40,14 |
static volatile uint32_t *pic = NULL; |
void pic_init(uintptr_t base, size_t size) |
void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg) |
{ |
pic = (uint32_t *) hw_map(base, size); |
*cir = pic_ack_interrupt; |
*cir_arg = NULL; |
} |
void pic_enable_interrupt(int intnum) |
void pic_enable_interrupt(inr_t intnum) |
{ |
if (pic) { |
if (intnum < 32) |
56,7 → 58,7 |
} |
void pic_disable_interrupt(int intnum) |
void pic_disable_interrupt(inr_t intnum) |
{ |
if (pic) { |
if (intnum < 32) |
66,7 → 68,7 |
} |
} |
void pic_ack_interrupt(int intnum) |
void pic_ack_interrupt(void *arg, inr_t intnum) |
{ |
if (pic) { |
if (intnum < 32) |
/trunk/kernel/arch/amd64/src/amd64.c |
---|
197,11 → 197,16 |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin) { |
kbrd_init(kbrdin); |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
/trunk/kernel/arch/mips32/include/console.h |
---|
File deleted |
/trunk/kernel/arch/mips32/Makefile.inc |
---|
60,7 → 60,6 |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/mips32.c \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/interrupt.c \ |
/trunk/kernel/arch/mips32/src/console.c |
---|
File deleted |
/trunk/kernel/arch/mips32/src/mips32.c |
---|
36,16 → 36,14 |
#include <arch/cp0.h> |
#include <arch/exception.h> |
#include <mm/as.h> |
#include <userspace.h> |
#include <arch/console.h> |
#include <memstr.h> |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <print.h> |
#include <console/console.h> |
#include <syscall/syscall.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
59,7 → 57,6 |
#include <config.h> |
#include <string.h> |
#include <arch/drivers/msim.h> |
#include <arch/asm/regname.h> |
/* Size of the code jumping to the exception handler code |
169,11 → 166,17 |
* Initialize the msim/GXemul keyboard port. Then initialize the serial line |
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ); |
if (kbrdin) { |
srln_init(kbrdin); |
dsrlnin_instance_t *dsrlnin_instance |
= dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ); |
if (dsrlnin_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
dsrlnin_wire(dsrlnin_instance, srln); |
cp0_unmask_int(MSIM_KBD_IRQ); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
248,5 → 251,19 |
return addr; |
} |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32/src/ia32.c |
---|
155,11 → 155,16 |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin) { |
kbrd_init(kbrdin); |
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (i8042_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
i8042_wire(i8042_instance, kbrd); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |