Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4326 → Rev 4327

/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 (!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;
}
 
/** @}
*/
/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,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);
}
 
/** @}
/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,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;
}
 
/** @}
/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,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);
/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,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);
}
 
/** @}
/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,45 → 426,56
/*
* 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 *) 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);
if (!silent) {
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
(EGA_SCREEN - EGA_COLS) * 2);
memsetw(videoram + (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)
{
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)));
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)
{
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));
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)
{
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);
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
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);
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
ega_cursor = (hi << 8) | lo;
} else
ega_cursor = 0;
ega_cursor = (hi << 8) | lo;
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 (!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;
}
 
/** @}
*/
/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,10 → 190,10
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,19 → 218,11
}
/*
* 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
/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
351,11 → 351,12
 
/** Unlock IRQ structure after hash_table_remove().
*
* @param lnk Link in the removed and locked IRQ structure.
* @param lnk Link in the removed and locked IRQ structure.
*/
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);
print_cc('\b', wstr_length(current) - position);
position += str_length(tmp);
if ((found == 1) && (position == wstr_length(current))) {
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) {
printf("%ls", current + position);
position++;
}
printf("%ls", current + position);
position += str_length(tmp);
print_cc('\b', wstr_length(current) - position);
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;
 
/* There must be space for a null terminator in the buffer. */
ASSERT(size > 0);
while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) {
if (chr_encode(ch, dst, &dst_off, size) != EOK)
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
130,13 → 130,14
 
/** Register an answerbox as a receiving end for IRQ notifications.
*
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
*
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
* @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)
149,7 → 150,7
(unative_t) inr,
(unative_t) devno
};
 
if (ucode) {
code = code_from_uspace(ucode);
if (!code)
157,7 → 158,7
} else {
code = NULL;
}
 
/*
* Allocate and populate the IRQ structure.
*/
172,7 → 173,7
irq->notif_cfg.method = method;
irq->notif_cfg.code = code;
irq->notif_cfg.counter = 0;
 
/*
* Enlist the IRQ structure in the uspace IRQ hash table and the
* answerbox's list.
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);
197,13 → 201,10
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
 
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
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
/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
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
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,15 → 139,10
#ifdef CONFIG_FB
scr_redraw();
#endif
switch (kbd_type) {
#ifdef CONFIG_SGCN
case KBD_SGCN:
sgcn_grab();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_grab();
#endif
default:
break;
}
}
 
/** Return console to userspace
150,15 → 150,9
*/
void arch_release_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_SGCN
case KBD_SGCN:
sgcn_release();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_release();
#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,19 → 62,7
*/
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);
}
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
return PA2KA(physaddr);
}
 
/** @}
/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,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 */
 
/** @}
*/
/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);
 
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
instance->srlnin = NULL;
instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
"ksgcnpoll", true);
if (!instance->thread) {
free(instance);
return NULL;
}
indev_initialize("sgcnin", &sgcnin, &sgcnin_ops);
return instance;
}
 
return &sgcnin;
void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
 
instance->srlnin = srlnin;
thread_ready(instance->thread);
 
sysinfo_set_item_val("kbd", NULL, true);
}
 
/**
/branches/network/kernel/arch/sparc64/src/start.S
84,7 → 84,7
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5
 
/*
* Setup basic runtime environment.
*/
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
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);
 
/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
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
 
/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,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);
}
 
/** @}
*/
/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
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)
/branches/network/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);
}
}
/*
/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,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)
{
}
 
/** @}
*/
/branches/network/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);
}
}
/*