/branches/network/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 |
/** @} |
/branches/network/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 |
/branches/network/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 |
/branches/network/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 |
/branches/network/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 |
/branches/network/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 |
/branches/network/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 |
/** @} |
/branches/network/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 \ |
/branches/network/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; |
} |
/** @} |
*/ |
/branches/network/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); |
} |
/** @} |
/branches/network/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); |
} |
/** @} |
*/ |
/branches/network/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); |
/branches/network/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); |
} |
/** @} |
/branches/network/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 |
/branches/network/kernel/genarch/src/drivers/ega/ega.c |
---|
426,38 → 426,47 |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
static void ega_check_cursor(bool silent) |
{ |
if (ega_cursor < EGA_SCREEN) |
return; |
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
if (!silent) { |
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
} |
ega_cursor = ega_cursor - EGA_COLS; |
} |
static void ega_show_cursor(void) |
static void ega_show_cursor(bool silent) |
{ |
if (!silent) { |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a); |
uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG); |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a); |
pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5))); |
} |
} |
static void ega_move_cursor(void) |
static void ega_move_cursor(bool silent) |
{ |
if (!silent) { |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e); |
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f); |
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); |
} |
} |
static void ega_sync_cursor(void) |
static void ega_sync_cursor(bool silent) |
{ |
if (!silent) { |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e); |
uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG); |
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f); |
464,6 → 473,8 |
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG); |
ega_cursor = (hi << 8) | lo; |
} else |
ega_cursor = 0; |
if (ega_cursor >= EGA_SCREEN) |
ega_cursor = 0; |
471,12 → 482,14 |
if ((ega_cursor % EGA_COLS) != 0) |
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; |
memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
ega_check_cursor(); |
ega_move_cursor(); |
ega_show_cursor(); |
if (!silent) |
memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
ega_check_cursor(silent); |
ega_move_cursor(silent); |
ega_show_cursor(silent); |
} |
static void ega_display_char(wchar_t ch, bool silent) |
525,11 → 538,9 |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
ega_check_cursor(silent); |
ega_move_cursor(silent); |
if (!silent) |
ega_move_cursor(); |
spinlock_unlock(&egalock); |
interrupts_restore(ipl); |
} |
552,7 → 563,7 |
/* Synchronize the back buffer and cursor position. */ |
memcpy(backbuf, videoram, EGA_VRAM_SIZE); |
ega_sync_cursor(); |
ega_sync_cursor(silent); |
outdev_initialize("ega", &ega_console, &ega_ops); |
stdout = &ega_console; |
568,8 → 579,8 |
void ega_redraw(void) |
{ |
memcpy(videoram, backbuf, EGA_VRAM_SIZE); |
ega_move_cursor(); |
ega_show_cursor(); |
ega_move_cursor(silent); |
ega_show_cursor(silent); |
} |
/** @} |
/branches/network/kernel/genarch/src/multiboot/multiboot.c |
---|
69,7 → 69,7 |
} |
/* Copy the command. */ |
str_ncpy(buf, start, min(sz, (size_t) (end - start) + 1)); |
str_ncpy(buf, sz, start, (size_t) (end - start)); |
} |
/** Parse multiboot information structure. |
/branches/network/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; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/include/string.h |
---|
86,7 → 86,8 |
extern int str_cmp(const char *s1, const char *s2); |
extern int str_lcmp(const char *s1, const char *s2, count_t max_len); |
extern void str_ncpy(char *dst, const char *src, size_t size); |
extern void str_cpy(char *dest, size_t size, const char *src); |
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n); |
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); |
extern const char *str_chr(const char *str, wchar_t ch); |
/branches/network/kernel/generic/include/console/chardev.h |
---|
89,10 → 89,13 |
extern void indev_initialize(char *name, indev_t *indev, |
indev_operations_t *op); |
extern void indev_push_character(indev_t *indev, wchar_t ch); |
extern wchar_t indev_pop_character(indev_t *indev); |
extern void outdev_initialize(char *name, outdev_t *outdev, |
outdev_operations_t *op); |
extern bool check_poll(indev_t *indev); |
#endif /* KERN_CHARDEV_H_ */ |
/** @} |
/branches/network/kernel/generic/include/console/console.h |
---|
40,17 → 40,15 |
extern indev_t *stdin; |
extern outdev_t *stdout; |
extern bool silent; |
extern indev_t *stdin_wire(void); |
extern void console_init(void); |
extern void klog_init(void); |
extern void klog_update(void); |
extern bool check_poll(indev_t *indev); |
extern wchar_t getc(indev_t *indev); |
extern wchar_t _getc(indev_t *indev); |
extern count_t gets(indev_t *indev, char *buf, size_t buflen); |
extern unative_t sys_klog(int fd, const void *buf, size_t size); |
/branches/network/kernel/generic/src/main/kinit.c |
---|
190,9 → 190,9 |
name = "<unknown>"; |
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN); |
str_ncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN); |
str_ncpy(namebuf + INIT_PREFIX_LEN, name, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN); |
str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX); |
str_cpy(namebuf + INIT_PREFIX_LEN, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name); |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
namebuf, &programs[i]); |
218,20 → 218,12 |
} |
/* |
* Run user tasks with small delays |
* to avoid intermixed klog output. |
* |
* TODO: This certainly does not guarantee |
* anything, it just works in most of the |
* cases. Some better way how to achieve |
* nice klog output should be found. |
* Run user tasks. |
*/ |
for (i = 0; i < init.cnt; i++) { |
if (programs[i].task != NULL) { |
if (programs[i].task != NULL) |
program_ready(&programs[i]); |
thread_usleep(10000); |
} |
} |
#ifdef CONFIG_KCONSOLE |
if (!stdin) { |
/branches/network/kernel/generic/src/debug/symtab.c |
---|
120,7 → 120,7 |
for (pos = *startpos; symbol_table[pos].address_le; pos++) { |
const char *curname = symbol_table[pos].symbol_name; |
/* Find a ':' in name */ |
/* Find a ':' in curname */ |
const char *colon = str_chr(curname, ':'); |
if (colon == NULL) |
continue; |
225,7 → 225,7 |
while ((hint = symtab_search_one(name, &pos))) { |
if ((found == 0) || (str_length(output) > str_length(hint))) |
str_ncpy(output, hint, MAX_SYMBOL_NAME); |
str_cpy(output, MAX_SYMBOL_NAME, hint); |
pos++; |
found++; |
241,7 → 241,7 |
} |
if (found > 0) |
str_ncpy(input, output, size); |
str_cpy(input, size, output); |
return found; |
/branches/network/kernel/generic/src/interrupt/interrupt.c |
---|
145,7 → 145,7 |
if (((i + 1) % 20) == 0) { |
printf(" -- Press any key to continue -- "); |
spinlock_unlock(&exctbl_lock); |
_getc(stdin); |
indev_pop_character(stdin); |
spinlock_lock(&exctbl_lock); |
printf("\n"); |
} |
/branches/network/kernel/generic/src/ddi/irq.c |
---|
355,7 → 355,8 |
*/ |
void irq_ht_remove(link_t *lnk) |
{ |
irq_t *irq = hash_table_get_instance(lnk, irq_t, link); |
irq_t *irq __attribute__((unused)) |
= hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq->lock); |
} |
424,7 → 425,8 |
*/ |
void irq_lin_remove(link_t *lnk) |
{ |
irq_t *irq = hash_table_get_instance(lnk, irq_t, link); |
irq_t *irq __attribute__((unused)) |
= hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq->lock); |
} |
/branches/network/kernel/generic/src/console/console.c |
---|
44,7 → 44,6 |
#include <ipc/event.h> |
#include <ipc/irq.h> |
#include <arch.h> |
#include <func.h> |
#include <print.h> |
#include <putchar.h> |
#include <atomic.h> |
70,9 → 69,6 |
/** Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/** Silence output */ |
bool silent = false; |
/** Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
79,10 → 75,28 |
/** Physical memory area used for klog buffer */ |
static parea_t klog_parea; |
static indev_operations_t stdin_ops = { |
.poll = NULL |
}; |
/** Silence output */ |
bool silent = false; |
/** Standard input and output character devices */ |
indev_t *stdin = NULL; |
outdev_t *stdout = NULL; |
indev_t *stdin_wire(void) |
{ |
if (stdin == NULL) { |
stdin = malloc(sizeof(indev_t), FRAME_ATOMIC); |
if (stdin != NULL) |
indev_initialize("stdin", stdin, &stdin_ops); |
} |
return stdin; |
} |
/** Initialize kernel logging facility |
* |
* The shared area contains kernel cyclic buffer. Userspace application may |
110,8 → 124,14 |
void grab_console(void) |
{ |
bool prev = silent; |
silent = false; |
arch_grab_console(); |
/* Force the console to print the prompt */ |
if ((stdin) && (prev)) |
indev_push_character(stdin, '\n'); |
} |
void release_console(void) |
138,55 → 158,6 |
return true; |
} |
bool check_poll(indev_t *indev) |
{ |
if (indev == NULL) |
return false; |
if (indev->op == NULL) |
return false; |
return (indev->op->poll != NULL); |
} |
/** Get character from input character device. Do not echo character. |
* |
* @param indev Input character device. |
* @return Character read. |
* |
*/ |
wchar_t _getc(indev_t *indev) |
{ |
if (atomic_get(&haltstate)) { |
/* If we are here, we are hopefully on the processor that |
* issued the 'halt' command, so proceed to read the character |
* directly from input |
*/ |
if (check_poll(indev)) |
return indev->op->poll(indev); |
/* No other way of interacting with user */ |
interrupts_disable(); |
if (CPU) |
printf("cpu%u: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted (no polling input)\n"); |
cpu_halt(); |
} |
waitq_sleep(&indev->wq); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&indev->lock); |
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN]; |
indev->counter--; |
spinlock_unlock(&indev->lock); |
interrupts_restore(ipl); |
return ch; |
} |
/** Get string from input character device. |
* |
* Read characters from input character device until first occurrence |
206,7 → 177,7 |
buf[offset] = 0; |
wchar_t ch; |
while ((ch = _getc(indev)) != '\n') { |
while ((ch = indev_pop_character(indev)) != '\n') { |
if (ch == '\b') { |
if (count > 0) { |
/* Space, backspace, space */ |
232,7 → 203,7 |
/** Get character from input device & echo it to screen */ |
wchar_t getc(indev_t *indev) |
{ |
wchar_t ch = _getc(indev); |
wchar_t ch = indev_pop_character(indev); |
putchar(ch); |
return ch; |
} |
/branches/network/kernel/generic/src/console/cmd.c |
---|
956,6 → 956,7 |
release_console(); |
event_notify_0(EVENT_KCONSOLE); |
indev_pop_character(stdin); |
return 1; |
} |
/branches/network/kernel/generic/src/console/chardev.c |
---|
35,6 → 35,9 |
#include <console/chardev.h> |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#include <print.h> |
#include <func.h> |
#include <arch.h> |
/** Initialize input character device. |
* |
79,6 → 82,46 |
spinlock_unlock(&indev->lock); |
} |
/** Pop character from input character device. |
* |
* @param indev Input character device. |
* |
* @return Character read. |
* |
*/ |
wchar_t indev_pop_character(indev_t *indev) |
{ |
if (atomic_get(&haltstate)) { |
/* If we are here, we are hopefully on the processor that |
* issued the 'halt' command, so proceed to read the character |
* directly from input |
*/ |
if (check_poll(indev)) |
return indev->op->poll(indev); |
/* No other way of interacting with user */ |
interrupts_disable(); |
if (CPU) |
printf("cpu%u: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted (no polling input)\n"); |
cpu_halt(); |
} |
waitq_sleep(&indev->wq); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&indev->lock); |
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN]; |
indev->counter--; |
spinlock_unlock(&indev->lock); |
interrupts_restore(ipl); |
return ch; |
} |
/** Initialize output character device. |
* |
* @param outdev Output character device. |
93,5 → 136,16 |
outdev->op = op; |
} |
bool check_poll(indev_t *indev) |
{ |
if (indev == NULL) |
return false; |
if (indev->op == NULL) |
return false; |
return (indev->op->poll != NULL); |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/console/kconsole.c |
---|
214,7 → 214,7 |
while ((hint = cmdtab_search_one(name, &pos))) { |
if ((found == 0) || (str_length(output) > str_length(hint))) |
str_ncpy(output, hint, MAX_CMDLINE); |
str_cpy(output, MAX_CMDLINE, hint); |
pos = pos->next; |
found++; |
231,7 → 231,7 |
} |
if (found > 0) |
str_ncpy(input, output, size); |
str_cpy(input, size, output); |
return found; |
} |
245,7 → 245,7 |
current[0] = 0; |
while (true) { |
wchar_t ch = _getc(indev); |
wchar_t ch = indev_pop_character(indev); |
if (ch == '\n') { |
/* Enter */ |
302,6 → 302,16 |
if (found == 0) |
continue; |
if (found > 1) { |
/* No unique hint, list was printed */ |
printf("%s> ", prompt); |
printf("%ls", current); |
print_cc('\b', wstr_length(current) - position); |
continue; |
} |
/* We have a hint */ |
size_t off = 0; |
count_t i = 0; |
while ((ch = str_decode(tmp, &off, STR_NO_LIMIT)) != 0) { |
310,26 → 320,17 |
i++; |
} |
if ((str_length(tmp) > 0) || (found == 1)) { |
/* We have a hint */ |
printf("%ls", current + position); |
position += str_length(tmp); |
print_cc('\b', wstr_length(current) - position); |
position += str_length(tmp); |
if ((found == 1) && (position == wstr_length(current))) { |
if (position == wstr_length(current)) { |
/* Insert a space after the last completed argument */ |
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) { |
printf("%ls", current + position); |
position++; |
} |
} |
} else { |
/* No unique hint, list was printed */ |
printf("%s> ", prompt); |
printf("%ls", current); |
position += str_length(tmp); |
} |
print_cc('\b', wstr_length(current) - position); |
continue; |
} |
438,7 → 439,7 |
if ((text[0] < '0') || (text[0] > '9')) { |
char symname[MAX_SYMBOL_NAME]; |
str_ncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1); |
uintptr_t symaddr; |
int rc = symtab_addr_lookup(symname, &symaddr); |
580,8 → 581,8 |
switch (cmd->argv[i].type) { |
case ARG_TYPE_STRING: |
buf = (char *) cmd->argv[i].buffer; |
str_ncpy(buf, cmdline + start, |
min((end - start) + 1, cmd->argv[i].len)); |
str_ncpy(buf, cmd->argv[i].len, cmdline + start, |
end - start); |
break; |
case ARG_TYPE_INT: |
if (!parse_int_arg(cmdline + start, end - start, |
592,8 → 593,9 |
if ((start < end - 1) && (cmdline[start] == '"')) { |
if (cmdline[end - 1] == '"') { |
buf = (char *) cmd->argv[i].buffer; |
str_ncpy(buf, cmdline + start + 1, |
min((end - start) - 1, cmd->argv[i].len)); |
str_ncpy(buf, cmd->argv[i].len, |
cmdline + start + 1, |
(end - start) - 1); |
cmd->argv[i].intval = (unative_t) buf; |
cmd->argv[i].vartype = ARG_TYPE_STRING; |
} else { |
651,7 → 653,7 |
printf("%s", msg); |
if (kcon) |
_getc(stdin); |
indev_pop_character(stdin); |
else |
printf("Type \"exit\" to leave the console.\n"); |
/branches/network/kernel/generic/src/proc/task.c |
---|
273,8 → 273,8 |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = 0; |
str_ncpy(TASK->name, namebuf, TASK_NAME_BUFLEN); |
namebuf[name_len] = '\0'; |
str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf); |
return EOK; |
} |
/branches/network/kernel/generic/src/lib/string.c |
---|
108,6 → 108,7 |
#include <arch.h> |
#include <errno.h> |
#include <align.h> |
#include <debug.h> |
/** Byte mask consisting of lowest @n bits (out of 8) */ |
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
528,38 → 529,70 |
} |
/** Copy NULL-terminated string. |
/** Copy string. |
* |
* Copy source string @a src to destination buffer @a dst. |
* No more than @a size bytes are written. NULL-terminator is always |
* written after the last succesfully copied character (i.e. if the |
* destination buffer is has at least 1 byte, it will be always |
* NULL-terminated). |
* Copy source string @a src to destination buffer @a dest. |
* No more than @a size bytes are written. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
*/ |
void str_cpy(char *dest, size_t size, const char *src) |
{ |
wchar_t ch; |
size_t src_off; |
size_t dest_off; |
/* There must be space for a null terminator in the buffer. */ |
ASSERT(size > 0); |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
dest[dest_off] = '\0'; |
} |
/** Copy size-limited substring. |
* |
* Copy prefix of string @a src of max. size @a size to destination buffer |
* @a dest. No more than @a size bytes are written. The output string will |
* always be well-formed, i.e. null-terminated and containing only complete |
* characters. |
* |
* No more than @a n bytes are read from the input string, so it does not |
* have to be null-terminated. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
* @param n Maximum number of bytes to read from @a src. |
*/ |
void str_ncpy(char *dst, const char *src, size_t size) |
void str_ncpy(char *dest, size_t size, const char *src, size_t n) |
{ |
/* No space for the NULL-terminator in the buffer */ |
if (size == 0) |
return; |
wchar_t ch; |
size_t str_off = 0; |
size_t dst_off = 0; |
size_t src_off; |
size_t dest_off; |
while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dst, &dst_off, size) != EOK) |
/* There must be space for a null terminator in the buffer. */ |
ASSERT(size > 0); |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, n)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
if (dst_off >= size) |
dst[size - 1] = 0; |
else |
dst[dst_off] = 0; |
dest[dest_off] = '\0'; |
} |
/** Copy NULL-terminated wide string to string |
608,10 → 641,12 |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
return (str + off); |
return (str + last); |
last = off; |
} |
return NULL; |
/branches/network/kernel/generic/src/mm/slab.c |
---|
936,7 → 936,7 |
void *malloc(unsigned int size, int flags) |
{ |
ASSERT(_slab_initialized); |
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W)); |
ASSERT(size <= (1 << SLAB_MAX_MALLOC_W)); |
if (size < (1 << SLAB_MIN_MALLOC_W)) |
size = (1 << SLAB_MIN_MALLOC_W); |
/branches/network/kernel/generic/src/ipc/sysipc.c |
---|
332,7 → 332,7 |
src = IPC_GET_ARG1(call->data); |
size = IPC_GET_ARG2(call->data); |
if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
if (size > DATA_XFER_LIMIT) |
return ELIMIT; |
call->buffer = (uint8_t *) malloc(size, 0); |
/branches/network/kernel/generic/src/ipc/irq.c |
---|
137,6 → 137,7 |
* @param ucode Uspace pointer to top-half pseudocode. |
* |
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
* |
*/ |
int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, |
unative_t method, irq_code_t *ucode) |
181,7 → 182,9 |
spinlock_lock(&irq_uspace_hash_table_lock); |
hlp = hash_table_find(&irq_uspace_hash_table, key); |
if (hlp) { |
irq_t *hirq = hash_table_get_instance(hlp, irq_t, link); |
irq_t *hirq __attribute__((unused)) |
= hash_table_get_instance(hlp, irq_t, link); |
/* hirq is locked */ |
spinlock_unlock(&hirq->lock); |
code_free(code); |
190,7 → 193,8 |
interrupts_restore(ipl); |
return EEXISTS; |
} |
spinlock_lock(&irq->lock); /* not really necessary, but paranoid */ |
spinlock_lock(&irq->lock); /* Not really necessary, but paranoid */ |
spinlock_lock(&box->irq_lock); |
hash_table_insert(&irq_uspace_hash_table, key, &irq->link); |
list_append(&irq->notif_cfg.link, &box->irq_head); |
200,10 → 204,7 |
interrupts_restore(ipl); |
// explicitly enable irq |
/* different byteorder? |
* trap_virtual_enable_irqs( 1 << ( irq->inr - 1 )); |
*/ |
trap_virtual_enable_irqs( 1 << ( irq->inr + 7 )); |
trap_virtual_enable_irqs( 1 << irq->inr ); |
return EOK; |
} |
/branches/network/kernel/arch/sparc64/include/atomic.h |
---|
123,7 → 123,7 |
"ldx %0, %2\n" |
"brz %2, 0b\n" |
"nop\n" |
"ba 1b\n" |
"ba %xcc, 1b\n" |
"nop\n" |
"2:\n" |
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0) |
/branches/network/kernel/arch/sparc64/include/trap/trap_table.h |
---|
100,7 → 100,7 |
.macro PREEMPTIBLE_HANDLER f |
sethi %hi(\f), %g1 |
b preemptible_handler |
ba %xcc, preemptible_handler |
or %g1, %lo(\f), %g1 |
.endm |
/branches/network/kernel/arch/sparc64/include/trap/mmu.h |
---|
103,17 → 103,20 |
* Note that branch-delay slots are used in order to save space. |
*/ |
0: |
mov VA_DMMU_TAG_ACCESS, %g1 |
ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN |
sethi %hi(fast_data_access_mmu_miss_data_hi), %g7 |
wr %g0, ASI_DMMU, %asi |
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1 ! read the faulting Context and VPN |
set TLB_TAG_ACCESS_CONTEXT_MASK, %g2 |
andcc %g1, %g2, %g3 ! get Context |
bnz 0f ! Context is non-zero |
bnz %xcc, 0f ! Context is non-zero |
andncc %g1, %g2, %g3 ! get page address into %g3 |
bz 0f ! page address is zero |
bz %xcc, 0f ! page address is zero |
ldx [%g7 + %lo(end_of_identity)], %g4 |
cmp %g3, %g4 |
bgeu %xcc, 0f |
sethi %hi(kernel_8k_tlb_data_template), %g2 |
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2 |
or %g3, %g2, %g2 |
ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2 |
add %g3, %g2, %g2 |
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page |
retry |
138,8 → 141,7 |
* Read the Tag Access register for the higher-level handler. |
* This is necessary to survive nested DTLB misses. |
*/ |
mov VA_DMMU_TAG_ACCESS, %g2 |
ldxa [%g2] ASI_DMMU, %g2 |
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2 |
/* |
* g2 will be passed as an argument to fast_data_access_mmu_miss(). |
/branches/network/kernel/arch/sparc64/include/mm/frame.h |
---|
73,6 → 73,8 |
typedef union frame_address frame_address_t; |
extern uintptr_t last_frame; |
extern uintptr_t end_of_identity; |
extern void frame_arch_init(void); |
#define physmem_print() |
/branches/network/kernel/arch/sparc64/include/drivers/sgcn.h |
---|
37,6 → 37,7 |
#include <arch/types.h> |
#include <console/chardev.h> |
#include <proc/thread.h> |
/* number of bytes in the TOC magic, including the NULL-terminator */ |
#define TOC_MAGIC_BYTES 8 |
116,11 → 117,17 |
uint32_t out_wrptr; |
} __attribute__ ((packed)) sgcn_buffer_header_t; |
void sgcn_grab(void); |
void sgcn_release(void); |
indev_t *sgcnin_init(void); |
void sgcnout_init(void); |
typedef struct { |
thread_t *thread; |
indev_t *srlnin; |
} sgcn_instance_t; |
extern void sgcn_grab(void); |
extern void sgcn_release(void); |
extern sgcn_instance_t *sgcnin_init(void); |
extern void sgcnin_wire(sgcn_instance_t *, indev_t *); |
extern void sgcnout_init(void); |
#endif |
/** @} |
/branches/network/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 |
/branches/network/kernel/arch/sparc64/src/asm.S |
---|
225,12 → 225,12 |
.global memsetb |
memsetb: |
b _memsetb |
ba %xcc, _memsetb |
nop |
.global memsetw |
memsetw: |
b _memsetw |
ba %xcc, _memsetw |
nop |
/branches/network/kernel/arch/sparc64/src/console.c |
---|
92,10 → 92,15 |
static void serengeti_init(void) |
{ |
#ifdef CONFIG_SGCN_KBD |
indev_t *kbrdin; |
kbrdin = sgcnin_init(); |
if (kbrdin) |
srlnin_init(kbrdin); |
sgcn_instance_t *sgcn_instance = sgcnin_init(); |
if (sgcn_instance) { |
srln_instance_t *srln_instance = srln_init(); |
if (srln_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *srln = srln_wire(srln_instance, sink); |
sgcnin_wire(sgcn_instance, srln); |
} |
} |
#endif |
#ifdef CONFIG_SGCN_PRN |
sgcnout_init(); |
134,16 → 139,11 |
#ifdef CONFIG_FB |
scr_redraw(); |
#endif |
switch (kbd_type) { |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
#ifdef CONFIG_SGCN_KBD |
sgcn_grab(); |
break; |
#endif |
default: |
break; |
} |
} |
/** Return console to userspace |
* |
150,16 → 150,10 |
*/ |
void arch_release_console(void) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
#ifdef CONFIG_SGCN_KBD |
sgcn_release(); |
break; |
#endif |
default: |
break; |
} |
} |
/** @} |
*/ |
/branches/network/kernel/arch/sparc64/src/sparc64.c |
---|
61,8 → 61,8 |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr; |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
str_ncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo.taskmap.tasks[i].name); |
} |
/* Copy boot allocations info. */ |
/branches/network/kernel/arch/sparc64/src/trap/trap_table.S |
---|
341,7 → 341,7 |
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE |
.global trap_instruction_\cur\()_tl0 |
trap_instruction_\cur\()_tl0: |
ba trap_instruction_handler |
ba %xcc, trap_instruction_handler |
mov \cur, %g2 |
.endr |
478,9 → 478,9 |
*/ |
rdpr %tl, %g3 |
cmp %g3, 1 |
be 1f |
be %xcc, 1f |
nop |
0: ba 0b ! this is for debugging, if we ever get here |
0: ba %xcc, 0b ! this is for debugging, if we ever get here |
nop ! it will be easy to find |
1: |
499,7 → 499,7 |
wrpr %g4, 0, %cwp ! resynchronize CWP |
andcc %g3, TSTATE_PRIV_BIT, %g0 ! if this trap came from the privileged mode... |
bnz 0f ! ...skip setting of kernel stack and primary context |
bnz %xcc, 0f ! ...skip setting of kernel stack and primary context |
nop |
.endif |
545,7 → 545,7 |
flush %l0 |
.if NOT(\is_syscall) |
ba 1f |
ba %xcc, 1f |
nop |
0: |
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
672,7 → 672,7 |
and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS |
rdpr %cwp, %l1 |
cmp %l0, %l1 |
bz 0f ! CWP is ok |
bz %xcc, 0f ! CWP is ok |
nop |
/* |
712,7 → 712,7 |
.if NOT(\is_syscall) |
rdpr %tstate, %g1 |
andcc %g1, TSTATE_PRIV_BIT, %g0 ! if we are not returning to userspace..., |
bnz 1f ! ...skip restoring userspace windows |
bnz %xcc, 1f ! ...skip restoring userspace windows |
nop |
.endif |
749,7 → 749,7 |
*/ |
clr %g4 |
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check |
bz 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
bz %xcc, 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
nop |
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
774,7 → 774,7 |
and %g3, NWINDOWS - 1, %g3 |
wrpr %g3, 0, %cwp ! switch to the preceeding window |
ba 0b |
ba %xcc, 0b |
inc %g4 |
0: |
785,7 → 785,7 |
wrpr %g1, 0, %cwp |
add %g4, %g2, %g2 |
cmp %g2, NWINDOWS - 2 |
bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
bg %xcc, 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly |
mov NWINDOWS - 2, %g1 ! use dealy slot for both cases |
sub %g1, %g2, %g1 |
/branches/network/kernel/arch/sparc64/src/mm/tlb.c |
---|
199,12 → 199,12 |
/** ITLB miss handler. */ |
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate) |
{ |
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; |
pte_t *t; |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
t = page_mapping_find(AS, page_16k); |
if (t && PTE_EXECUTABLE(t)) { |
/* |
* The mapping was found in the software page hash table. |
222,7 → 222,8 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) == |
AS_PF_FAULT) { |
do_fast_instruction_access_mmu_miss_fault(istate, |
__func__); |
} |
242,11 → 243,13 |
*/ |
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
uintptr_t va; |
uintptr_t page_8k; |
uintptr_t page_16k; |
index_t index; |
pte_t *t; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH; |
page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; |
if (tag.context == ASID_KERNEL) { |
254,6 → 257,15 |
/* NULL access in kernel */ |
do_fast_data_access_mmu_miss_fault(istate, tag, |
__func__); |
} else if (page_8k >= end_of_identity) { |
/* |
* The kernel is accessing the I/O space. |
* We still do identity mapping for I/O, |
* but without caching. |
*/ |
dtlb_insert_mapping(page_8k, KA2PA(page_8k), |
PAGESIZE_8K, false, false); |
return; |
} |
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected " |
"kernel page fault."); |
260,7 → 272,7 |
} |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
t = page_mapping_find(AS, page_16k); |
if (t) { |
/* |
* The mapping was found in the software page hash table. |
278,7 → 290,8 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
if (as_page_fault(page_16k, PF_ACCESS_READ, istate) == |
AS_PF_FAULT) { |
do_fast_data_access_mmu_miss_fault(istate, tag, |
__func__); |
} |
295,15 → 308,15 |
*/ |
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
uintptr_t va; |
uintptr_t page_16k; |
index_t index; |
pte_t *t; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */ |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
t = page_mapping_find(AS, page_16k); |
if (t && PTE_WRITABLE(t)) { |
/* |
* The mapping was found in the software page hash table and is |
313,7 → 326,7 |
t->a = true; |
t->d = true; |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, |
va + index * MMU_PAGE_SIZE); |
page_16k + index * MMU_PAGE_SIZE); |
dtlb_pte_copy(t, index, false); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, index, false); |
325,7 → 338,8 |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { |
if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) == |
AS_PF_FAULT) { |
do_fast_data_access_protection_fault(istate, tag, |
__func__); |
} |
/branches/network/kernel/arch/sparc64/src/mm/frame.c |
---|
79,6 → 79,8 |
*/ |
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); |
} |
end_of_identity = PA2KA(last_frame); |
} |
/** @} |
/branches/network/kernel/arch/sparc64/src/mm/page.c |
---|
62,20 → 62,8 |
*/ |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { |
uintptr_t addr = PFN2ADDR(i); |
page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
return PA2KA(physaddr); |
} |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/** @} |
*/ |
/branches/network/kernel/arch/sparc64/src/dummy.s |
---|
42,5 → 42,5 |
.global cpu_halt |
cpu_halt: |
b cpu_halt |
ba %xcc, cpu_halt |
nop |
/branches/network/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 *) hw_map(aligned_addr, offset + size) + |
offset; |
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 *) 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); |
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; |
/* |
* This is the necessary evil until the userspace driver is |
* 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); |
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.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 */ |
/** @} |
*/ |
/branches/network/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; |
137,12 → 134,6 |
.write = sgcn_putchar |
}; |
/** SGCN input device operations */ |
static indev_operations_t sgcnin_ops = { |
.poll = NULL |
}; |
static indev_t sgcnin; /**< SGCN input device. */ |
static outdev_t sgcnout; /**< SGCN output device. */ |
/** |
304,7 → 295,7 |
* there are some unread characters in the input queue. If so, it picks them up |
* and sends them to the upper layers of HelenOS. |
*/ |
static void sgcn_poll() |
static void sgcn_poll(sgcn_instance_t *instance) |
{ |
uint32_t begin = SGCN_BUFFER_HEADER->in_begin; |
uint32_t end = SGCN_BUFFER_HEADER->in_end; |
322,13 → 313,12 |
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); |
while (*in_rdptr_ptr != *in_wrptr_ptr) { |
buf_ptr = (volatile char *) |
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
char c = *buf_ptr; |
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; |
indev_push_character(&sgcnin, c); |
indev_push_character(instance->srlnin, c); |
} |
spinlock_unlock(&sgcn_input_lock); |
337,11 → 327,10 |
/** |
* Polling thread function. |
*/ |
static void kkbdpoll(void *arg) { |
static void ksgcnpoll(void *instance) { |
while (1) { |
if (!silent) { |
sgcn_poll(); |
} |
if (!silent) |
sgcn_poll(instance); |
thread_usleep(POLL_INTERVAL); |
} |
} |
349,23 → 338,35 |
/** |
* A public function which initializes input from the Serengeti console. |
*/ |
indev_t *sgcnin_init(void) |
sgcn_instance_t *sgcnin_init(void) |
{ |
sgcn_buffer_begin_init(); |
kbd_type = KBD_SGCN; |
sgcn_instance_t *instance = |
malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN); |
instance->srlnin = NULL; |
instance->thread = thread_create(ksgcnpoll, instance, TASK, 0, |
"ksgcnpoll", true); |
if (!instance->thread) { |
free(instance); |
return NULL; |
} |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("Cannot create kkbdpoll."); |
thread_ready(t); |
return instance; |
} |
indev_initialize("sgcnin", &sgcnin, &sgcnin_ops); |
void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin) |
{ |
ASSERT(instance); |
ASSERT(srlnin); |
return &sgcnin; |
instance->srlnin = srlnin; |
thread_ready(instance->thread); |
sysinfo_set_item_val("kbd", NULL, true); |
} |
/** |
/branches/network/kernel/arch/sparc64/src/start.S |
---|
294,7 → 294,7 |
/* Not reached. */ |
0: |
ba 0b |
ba %xcc, 0b |
nop |
333,7 → 333,7 |
2: |
ldx [%g2], %g3 |
cmp %g3, %g1 |
bne 2b |
bne %xcc, 2b |
nop |
/* |
352,7 → 352,7 |
#endif |
0: |
ba 0b |
ba %xcc, 0b |
nop |
381,10 → 381,31 |
.quad 0 |
/* |
* This variable is used by the fast_data_MMU_miss trap handler. In runtime, it |
* is further modified to reflect the starting address of physical memory. |
* The fast_data_access_mmu_miss_data_hi label and the end_of_identity and |
* kernel_8k_tlb_data_template variables are meant to stay together, |
* aligned on 16B boundary. |
*/ |
.global fast_data_access_mmu_miss_data_hi |
.global end_of_identity |
.global kernel_8k_tlb_data_template |
.align 16 |
/* |
* This label is used by the fast_data_access_MMU_miss trap handler. |
*/ |
fast_data_access_mmu_miss_data_hi: |
/* |
* This variable is used by the fast_data_access_MMU_miss trap handler. |
* In runtime, it is modified to contain the address of the end of physical |
* memory. |
*/ |
end_of_identity: |
.quad -1 |
/* |
* This variable is used by the fast_data_access_MMU_miss trap handler. |
* In runtime, it is further modified to reflect the starting address of |
* physical memory. |
*/ |
kernel_8k_tlb_data_template: |
#ifdef CONFIG_VIRT_IDX_DCACHE |
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \ |
/branches/network/kernel/arch/ia64/include/ski/ski.h |
---|
File deleted |
/branches/network/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); |
/branches/network/kernel/arch/ia64/include/asm.h |
---|
46,7 → 46,7 |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint8_t *)(IA64_IOSPACE_ADDRESS + |
*((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
56,7 → 56,7 |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint16_t *)(IA64_IOSPACE_ADDRESS + |
*((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
66,7 → 66,7 |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint32_t *)(IA64_IOSPACE_ADDRESS + |
*((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
78,7 → 78,7 |
asm volatile ("mf\n" ::: "memory"); |
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + |
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
88,7 → 88,7 |
asm volatile ("mf\n" ::: "memory"); |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + |
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
98,7 → 98,7 |
asm volatile ("mf\n" ::: "memory"); |
return *((uint32_t *)(IA64_IOSPACE_ADDRESS + |
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
/branches/network/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 |
/branches/network/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 |
/branches/network/kernel/arch/ia64/src/ski/ski.c |
---|
File deleted |
/branches/network/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> |
/branches/network/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> |
87,8 → 87,8 |
((unsigned long) bootinfo->taskmap.tasks[i].addr) | |
VRN_MASK; |
init.tasks[i].size = bootinfo->taskmap.tasks[i].size; |
str_ncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->taskmap.tasks[i].name); |
} |
} |
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 |
} |
/branches/network/kernel/arch/ia64/src/drivers/ski.c |
---|
0,0 → 1,227 |
/* |
* 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, 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 |
/branches/network/kernel/arch/arm32/include/console.h |
---|
File deleted |
/branches/network/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 \ |
/branches/network/kernel/arch/arm32/src/console.c |
---|
File deleted |
/branches/network/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> |
62,8 → 62,8 |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
str_ncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->tasks[i].name); |
} |
} |
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) |
{ |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ppc32/include/drivers/cuda.h |
---|
File deleted |
/branches/network/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 |
/branches/network/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 \ |
/branches/network/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; |
61,8 → 63,8 |
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
str_ncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo.taskmap.tasks[i].name); |
} |
} |
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); |
} |
/** @} |
*/ |
/branches/network/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 |
/branches/network/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); |
} |
} |
/branches/network/kernel/arch/ppc32/src/drivers/cuda.c |
---|
File deleted |
/branches/network/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) |
/branches/network/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 |
/branches/network/kernel/arch/mips32/include/console.h |
---|
File deleted |
/branches/network/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 \ |
/branches/network/kernel/arch/mips32/src/console.c |
---|
File deleted |
/branches/network/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 |
91,8 → 88,8 |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
str_ncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, |
bootinfo->tasks[i].name); |
} |
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { |
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) |
{ |
} |
/** @} |
*/ |
/branches/network/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 |