Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4310 → Rev 4311

/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 (!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;
}
if (thread) {
stdin = &kbrdout;
thread_ready(thread);
}
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,38 → 80,43
* @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;
if (instance) {
instance->ns16550 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = ns16550_claim;
instance->irq.handler = ns16550_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
indev_initialize("ns16550", &instance->kbrdin, &kbrdin_ops);
return instance;
}
 
void ns16550_wire(ns16550_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->ns16550 = dev;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = ns16550_claim;
instance->irq.handler = ns16550_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
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,29 → 50,35
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;
if (instance) {
instance->dsrlnin = dev;
instance->srlnin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = dsrlnin_claim;
instance->irq.handler = dsrlnin_irq_handler;
instance->irq.instance = instance;
}
indev_initialize("dsrlnin", &instance->kbrdin, &kbrdin_ops);
return instance;
}
 
void dsrlnin_wire(dsrlnin_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
instance->dsrlnin = dev;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = dsrlnin_claim;
instance->irq.handler = dsrlnin_irq_handler;
instance->irq.instance = instance;
instance->srlnin = srlnin;
irq_register(&instance->irq);
return &instance->kbrdin;
}
 
/** @}
/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,35 → 70,46
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;
if (instance) {
instance->i8042 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = i8042_claim;
instance->irq.handler = i8042_irq_handler;
instance->irq.instance = instance;
}
indev_initialize("i8042", &instance->kbrdin, &kbrdin_ops);
return instance;
}
 
void i8042_wire(i8042_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->i8042 = dev;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = i8042_claim;
instance->irq.handler = i8042_irq_handler;
instance->irq.instance = instance;
instance->kbrdin = kbrdin;
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;
i8042_clear_buffer(instance->i8042);
}
 
/* Reset CPU by pulsing pin 0 */
110,9 → 117,7
{
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,51 → 78,58
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;
if (instance) {
instance->z8530 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = z8530_claim;
instance->irq.handler = z8530_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
indev_initialize("z8530", &instance->kbrdin, &kbrdin_ops);
return instance;
}
 
void z8530_wire(z8530_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->z8530 = dev;
instance->kbrdin = kbrdin;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = z8530_claim;
instance->irq.handler = z8530_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
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 (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("srln", &instance->raw, &srln_raw_ops);
}
if (thread) {
stdin = &srlnout;
thread_ready(thread);
}
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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
135,15 → 135,9
scr_redraw();
#endif
switch (kbd_type) {
#ifdef CONFIG_SGCN_KBD
case KBD_SGCN:
sgcn_grab();
break;
sgcn_grab();
#endif
default:
break;
}
}
 
/** Return console to userspace
151,15 → 145,9
*/
void arch_release_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_SGCN_KBD
case KBD_SGCN:
sgcn_release();
break;
sgcn_release();
#endif
default:
break;
}
}
 
/** @}
/trunk/kernel/arch/sparc64/src/drivers/kbd.c
54,100 → 54,140
#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)
#ifdef CONFIG_Z8530
 
static bool kbd_z8530_init(ofw_tree_node_t *node)
{
size_t offset;
uintptr_t aligned_addr;
ofw_tree_property_t *prop;
const char *name;
const char *name = ofw_tree_node_name(node);
if (str_cmp(name, "zs") != 0)
return false;
/*
* Read 'interrupts' property.
*/
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)) {
printf("z8530: Unable to find reg property\n");
return false;
}
size_t size = ((ofw_fhc_reg_t *) prop->value)->size;
uintptr_t pa;
if (!ofw_fhc_apply_ranges(node->parent,
((ofw_fhc_reg_t *) prop->value), &pa)) {
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("z8530: Failed to determine interrupt\n");
return false;
}
#ifdef CONFIG_NS16550
ns16550_t *ns16550;
#endif
#ifdef CONFIG_Z8530
z8530_t *z8530;
#endif
/*
* 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;
name = ofw_tree_node_name(node);
z8530_t *z8530 = (z8530_t *)
(hw_map(aligned_addr, offset + size) + offset);
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);
}
}
/*
* Determine keyboard serial controller type.
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
*/
if (str_cmp(name, "zs") == 0)
kbd_type = KBD_Z8530;
else if (str_cmp(name, "su") == 0)
kbd_type = KBD_NS16550;
sysinfo_set_item_val("kbd", NULL, true);
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);
sysinfo_set_item_val("kbd.type.z8530", NULL, true);
if (kbd_type == KBD_UNKNOWN) {
printf("Unknown keyboard device.\n");
return;
}
return true;
}
 
#endif /* CONFIG_Z8530 */
 
#ifdef CONFIG_NS16550
 
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.
*/
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("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))
panic("Cannot find 'reg' property.");
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;
size_t size;
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;
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;
}
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;
}
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.");
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;
}
/*
156,59 → 196,58
* 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) {
ns16550_t *ns16550 = (ns16550_t *)
(hw_map(aligned_addr, offset + size) + offset);
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 drivers are
* entirely self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
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);
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
case KBD_Z8530:
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);
/*
* 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_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;
kbd_z8530_init(node);
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
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);
/*
* This is the necessary evil until the userspace driver is
* 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;
kbd_ns16550_init(node);
#endif
default:
printf("Kernel is not compiled with the necessary keyboard "
"driver this machine requires.\n");
}
}
 
#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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64
/** @addtogroup ia64
* @{
*/
/** @file
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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
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,10 → 119,27
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 */
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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
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,10 → 197,15
* 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);
trap_virtual_enable_irqs(1 << IRQ_KBD);
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);
}
}
/*
/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,10 → 166,16
* 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);
cp0_unmask_int(MSIM_KBD_IRQ);
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);
}
}
/*
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
80,7 → 80,7
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi)
{
/* Parse multiboot information obtained from the bootloader. */
multiboot_info_parse(signature, mi);
multiboot_info_parse(signature, mi);
#ifdef CONFIG_SMP
/* Copy AP bootstrap routines below 1 MB. */
155,10 → 155,15
* 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);
trap_virtual_enable_irqs(1 << IRQ_KBD);
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);
}
}
/*