Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4307 → Rev 4327

/branches/network/contrib/conf/mips32-gx.sh
1,3 → 1,3
#!/bin/sh
 
gxemul $@ -E testmips -C R4000 -X image.boot
gxemul $@ -E testmips -C R4000 -X image.boot
/branches/network/contrib/conf/ppc32-qe.sh
0,0 → 1,3
#!/bin/sh
 
qemu-system-ppc -M mac99 -boot d -cdrom image.iso
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/network/contrib/conf/arm32-gx.sh
1,3 → 1,3
#!/bin/sh
 
gxemul $@ -E testarm -X image.boot
gxemul $@ -E testarm -X image.boot
/branches/network/contrib/conf/pearpc.conf
1,7 → 1,7
ppc_start_resolution = "800x600x32"
pci_ide0_master_installed = 0
 
prom_bootmethod = "force"
prom_loadfile = "image.boot"
pci_ide0_master_installed = 1
pci_ide0_master_image = "image.iso"
pci_ide0_master_type = "cdrom"
 
key_toggle_mouse_grab = "F11"
/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);
}
}
/*
/branches/network/uspace/app/bdsh/input.c
61,7 → 61,7
if (NULL == usr->line)
return CL_EFAIL;
 
tmp = strdup(usr->line);
tmp = str_dup(usr->line);
 
cmd[n] = strtok(tmp, " ");
while (cmd[n] && n < WORD_MAX) {
146,7 → 146,6
void get_input(cliuser_t *usr)
{
char line[INPUT_MAX];
size_t len = 0;
 
console_set_style(STYLE_EMPHASIS);
printf("%s", usr->prompt);
153,11 → 152,10
console_set_style(STYLE_NORMAL);
 
read_line(line, INPUT_MAX);
len = strlen(line);
/* Make sure we don't have rubbish or a C/R happy user */
if (len == 0 || line[0] == '\n')
if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0)
return;
usr->line = strdup(line);
usr->line = str_dup(line);
 
return;
}
/branches/network/uspace/app/bdsh/cmds/mod_cmds.c
64,7 → 64,7
return -2;
 
for (mod = modules; mod->name != NULL; mod++, i++) {
if (!strcmp(mod->name, command))
if (!str_cmp(mod->name, command))
return i;
}
 
81,7 → 81,7
return -1;
 
for(i=0; mod_aliases[i] != NULL; i+=2) {
if (!strcmp(mod_aliases[i], command))
if (!str_cmp(mod_aliases[i], command))
return 1;
}
 
97,7 → 97,7
return (char *)NULL;
 
for(i=0; mod_aliases[i] != NULL; i++) {
if (!strcmp(mod_aliases[i], command))
if (!str_cmp(mod_aliases[i], command))
return (char *)mod_aliases[++i];
i++;
}
/branches/network/uspace/app/bdsh/cmds/modules/touch/touch.c
80,7 → 80,7
}
 
for (i = 1; i < argc; i ++) {
buff = strdup(argv[i]);
buff = str_dup(argv[i]);
dirp = opendir(buff);
if (dirp) {
cli_error(CL_ENOTSUP, "%s is a directory", buff);
/branches/network/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
93,7 → 93,7
 
/* Its a good idea to allocate path, plus we (may) need a copy of
* path to tokenize if parents are specified */
if (NULL == (tmp = strdup(path))) {
if (NULL == (tmp = str_dup(path))) {
cli_error(CL_ENOMEM, "%s: path too big?", cmdname);
return 1;
}
149,7 → 149,7
while (dirs[i] != NULL) {
/* Sometimes make or scripts conjoin odd paths. Account for something
* like this: ../../foo/bar/../foo/foofoo/./bar */
if (!strcmp(dirs[i], "..") || !strcmp(dirs[i], ".")) {
if (!str_cmp(dirs[i], "..") || !str_cmp(dirs[i], ".")) {
if (0 != (chdir(dirs[i]))) {
cli_error(CL_EFAIL, "%s: impossible path: %s",
cmdname, path);
/branches/network/uspace/app/bdsh/cmds/modules/help/help.c
107,7 → 107,7
}
 
if (argc == 3) {
if (!strcmp("extended", argv[2]))
if (!str_cmp("extended", argv[2]))
level = HELP_LONG;
else
level = HELP_SHORT;
/branches/network/uspace/app/bdsh/cmds/modules/ls/ls.c
182,7 → 182,7
if (argc == 1)
getcwd(buff, PATH_MAX);
else
strncpy(buff, argv[1], PATH_MAX);
str_cpy(buff, PATH_MAX, argv[1]);
 
scope = ls_scope(buff);
 
/branches/network/uspace/app/bdsh/cmds/modules/rm/rm.c
216,7 → 216,7
 
i = optind;
while (NULL != argv[i]) {
len = strlen(argv[i]) + 2;
len = str_size(argv[i]) + 2;
buff = (char *) realloc(buff, len);
if (buff == NULL) {
printf("rm: out of memory\n");
/branches/network/uspace/app/bdsh/cmds/builtin_cmds.c
49,7 → 49,7
return -2;
 
for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
if (!strcmp(cmd->name, command))
if (!str_cmp(cmd->name, command))
return i;
}
 
64,7 → 64,7
return -1;
 
for(i=0; builtin_aliases[i] != NULL; i+=2) {
if (!strcmp(builtin_aliases[i], command))
if (!str_cmp(builtin_aliases[i], command))
return 1;
}
 
79,7 → 79,7
return (char *)NULL;
 
for(i=0; builtin_aliases[i] != NULL; i++) {
if (!strcmp(builtin_aliases[i], command))
if (!str_cmp(builtin_aliases[i], command))
return (char *)builtin_aliases[++i];
i++;
}
/branches/network/uspace/app/bdsh/exec.c
71,7 → 71,7
char *path_tok;
char *path[PATH_MAX];
int n = 0, i = 0;
size_t x = strlen(cmd) + 2;
size_t x = str_size(cmd) + 2;
 
found = (char *)malloc(PATH_MAX);
 
80,12 → 80,12
return (char *) cmd;
}
 
path_tok = strdup(PATH);
path_tok = str_dup(PATH);
 
/* Extract the PATH env to a path[] array */
path[n] = strtok(path_tok, PATH_DELIM);
while (NULL != path[n]) {
if ((strlen(path[n]) + x ) > PATH_MAX) {
if ((str_size(path[n]) + x ) > PATH_MAX) {
cli_error(CL_ENOTSUP,
"Segment %d of path is too large, search ends at segment %d",
n, n-1);
114,7 → 114,7
task_id_t tid;
char *tmp;
 
tmp = strdup(find_command(cmd));
tmp = str_dup(find_command(cmd));
free(found);
 
tid = task_spawn((const char *)tmp, argv);
/branches/network/uspace/app/init/init.c
45,6 → 45,7
#include <malloc.h>
#include <macros.h>
#include <console.h>
#include <string.h>
#include "init.h"
#include "version.h"
 
51,9 → 52,13
static bool mount_fs(const char *fstype)
{
int rc = -1;
char *opts = "";
if (str_cmp(fstype, "tmpfs") == 0)
opts = "restore";
 
while (rc < 0) {
rc = mount(fstype, "/", "initrd", IPC_FLAG_BLOCKING);
rc = mount(fstype, "/", "initrd", opts, IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
83,12 → 88,8
argv[0] = fname;
argv[1] = NULL;
if (task_spawn(fname, argv)) {
/* Add reasonable delay to avoid intermixed klog output. */
usleep(10000);
} else {
if (!task_spawn(fname, argv))
printf(NAME ": Error spawning %s\n", fname);
}
}
 
int main(int argc, char *argv[])
/branches/network/uspace/app/tester/devmap/devmap1.c
140,7 → 140,7
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(phone, (char *)name, strlen(name) + 1);
retval = ipc_data_write_start(phone, (char *)name, str_size(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
173,7 → 173,7
req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0,
&answer);
 
retval = ipc_data_write_start(driver_phone, name, strlen(name) + 1);
retval = ipc_data_write_start(driver_phone, name, str_size(name) + 1);
 
if (retval != EOK) {
printf("Failed to send device name '%s'.\n", name);
215,7 → 215,7
req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(driver_phone, (char *)name,
strlen(name) + 1);
str_size(name) + 1);
 
if (retval != EOK) {
printf("Failed to send device name '%s'.\n", name);
/branches/network/uspace/app/tester/vfs/vfs1.c
45,7 → 45,7
{
int rc;
 
rc = mount("tmpfs", "/", "nulldev0", 0);
rc = mount("tmpfs", "/", "nulldev0", "", 0);
switch (rc) {
case EOK:
if (!quiet)
/branches/network/uspace/app/tetris/scores.c
117,7 → 117,8
*/
static void copyhiscore(int dest, int src)
{
strcpy(scores[dest].hs_name, scores[src].hs_name);
str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
scores[src].hs_name);
scores[dest].hs_score = scores[src].hs_score;
scores[dest].hs_level = scores[src].hs_level;
}
131,7 → 132,8
clear_screen();
moveto(10 , 10);
puts("Insert your name: ");
strncpy(scores[NUMSPOTS - 1].hs_name, "Player", MAXLOGNAME);
str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
"Player");
i = 6; off = 6;
 
moveto(10 , 28);
195,7 → 197,7
{
int i;
for(i = 0; i < NUMSPOTS; i++) {
strncpy(scores[i].hs_name, "HelenOS Team", MAXLOGNAME);
str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team");
scores[i].hs_score = (NUMSPOTS - i) * 200;
scores[i].hs_level = (i + 1 > MAXLEVEL?MAXLEVEL:i + 1);
}
289,7 → 291,7
/* change = 0; */
/* me = thisuser(); */
/* for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */
/* if (sp->hs_level != level || strcmp(sp->hs_name, me) != 0) */
/* if (sp->hs_level != level || str_cmp(sp->hs_name, me) != 0) */
/* continue; */
/* if (score > sp->hs_score) { */
/* (void)printf("%s bettered %s %d score of %d!\n", */
417,7 → 419,7
/* * This is O(n^2), but do you think we care? */
/* *\/ */
/* for (j = 0, pu = count; j < numnames; j++, pu++) */
/* if (strcmp(sp->hs_name, pu->name) == 0) */
/* if (str_cmp(sp->hs_name, pu->name) == 0) */
/* break; */
/* if (j == numnames) { */
/* /\* */
554,7 → 556,7
/* if (me != NULL && */
/* sp->hs_level == level && */
/* sp->hs_score == score && */
/* strcmp(sp->hs_name, me) == 0) { */
/* str_cmp(sp->hs_name, me) == 0) { */
/* putpad(SOstr); */
/* highlight = 1; */
/* } */
/branches/network/uspace/app/tetris/input.c
115,7 → 115,7
if (!lastchar) {
again:
if (!getchar_inprog) {
cons_phone = console_phone_get(true);
cons_phone = console_open(true);
getchar_inprog = async_send_2(cons_phone,
CONSOLE_GETKEY, 0, 0, &charcall);
}
/branches/network/uspace/app/tetris/screen.c
280,7 → 280,7
scr_msg(char *s, int set)
{
int l = strlen(s);
int l = str_size(s);
moveto(Rows - 2, ((Cols - l) >> 1) - 1);
if (set)
/branches/network/uspace/app/tetris/tetris.c
277,7 → 277,7
/* classic = 1; */
/* break; */
/* case 'k': */
/* if (strlen(keys = optarg) != 6) */
/* if (str_size(keys = optarg) != 6) */
/* usage(); */
/* break; */
/* case 'l': */
311,7 → 311,7
errx(1, "duplicate command keys specified.");
}
if (keys[i] == ' ')
strncpy(key_write[i], "<space>", sizeof key_write[i]);
str_cpy(key_write[i], sizeof key_write[i], "<space>");
else {
key_write[i][0] = keys[i];
key_write[i][1] = '\0';
/branches/network/uspace/lib/libc/include/console.h
27,7 → 27,7
*/
 
/** @addtogroup libc
* @{
* @{
*/
/** @file
*/
40,17 → 40,15
#include <sys/types.h>
#include <bool.h>
 
extern void console_open(bool);
extern int console_open(bool);
extern void console_close(void);
 
extern int console_phone_get(bool);
extern void console_wait(void);
 
extern void console_clear(void);
extern void console_goto(int, int);
extern void console_putchar(wchar_t);
extern ssize_t console_write(const char *buf, size_t nbyte);
extern void console_putstr(const char *s);
extern ssize_t console_write(const char *, size_t);
extern void console_putstr(const char *);
extern void console_flush(void);
 
extern int console_get_size(int *, int *);
62,6 → 60,6
extern void console_kcon_enable(void);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/string.h
45,8 → 45,8
/**< No size limit constant */
#define STR_NO_LIMIT ((size_t) -1)
 
/**< Maximum size of a string containing cnt characters */
#define STR_BOUNDS(cnt) (cnt << 2)
/**< Maximum size of a string containing @c length characters */
#define STR_BOUNDS(length) ((length) << 2)
 
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
69,34 → 69,26
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 str_append(char *dest, size_t size, const char *src);
 
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
extern const char *str_chr(const char *str, wchar_t ch);
extern const char *str_rchr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos);
extern bool wstr_remove(wchar_t *str, count_t pos);
 
extern char *str_dup(const char *);
 
/*
* TODO: Get rid of this.
*/
 
extern int strcmp(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern int stricmp(const char *, const char *);
 
extern char *strcpy(char *, const char *);
extern char *strncpy(char *, const char *, size_t);
 
extern char *strcat(char *, const char *);
 
extern size_t strlen(const char *);
 
extern char *strdup(const char *);
 
extern char *strchr(const char *, int);
extern char *strrchr(const char *, int);
 
extern long int strtol(const char *, char **, int);
extern unsigned long strtoul(const char *, char **, int);
 
/branches/network/uspace/lib/libc/include/vfs/vfs.h
39,7 → 39,7
 
extern char *absolutize(const char *, size_t *);
 
extern int mount(const char *, const char *, const char *,
extern int mount(const char *, const char *, const char *, const char *,
const unsigned int flags);
 
#endif
/branches/network/uspace/lib/libc/include/async.h
98,22 → 98,22
 
/* Wrappers for simple communication */
#define async_msg_0(phone, method) \
ipc_call_async_0((phone), (method), NULL, NULL, !in_interrupt_handler())
ipc_call_async_0((phone), (method), NULL, NULL, true)
#define async_msg_1(phone, method, arg1) \
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
!in_interrupt_handler())
true)
#define async_msg_2(phone, method, arg1, arg2) \
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
!in_interrupt_handler())
true)
#define async_msg_3(phone, method, arg1, arg2, arg3) \
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
!in_interrupt_handler())
true)
#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, !in_interrupt_handler())
NULL, true)
#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, !in_interrupt_handler())
(arg5), NULL, NULL, true)
 
/*
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
253,8 → 253,6
fibril_dec_sercount();
}
 
extern bool in_interrupt_handler(void);
 
extern atomic_t async_futex;
 
#endif
/branches/network/uspace/lib/libc/include/stdio.h
49,7 → 49,7
int n; \
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \
if (n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, strlen(buf)); \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, str_size(buf)); \
}
 
typedef struct {
/branches/network/uspace/lib/libc/include/thread.h
45,7 → 45,7
extern void __thread_main(uspace_arg_t *);
 
extern int thread_create(void (*)(void *), void *, char *, thread_id_t *);
extern void thread_exit(int);
extern void thread_exit(int) __attribute__ ((noreturn));
extern void thread_detach(thread_id_t);
extern int thread_join(thread_id_t);
extern thread_id_t thread_get_id(void);
/branches/network/uspace/lib/libc/include/io/stream.h
37,15 → 37,11
 
#include <libarch/types.h>
 
#define EMFILE -17
#define EMFILE -17
 
extern ssize_t read_stdin(void *, size_t);
extern void klog_update(void);
 
extern ssize_t read_stdin(void *, size_t);
extern ssize_t write_stdout(const void *, size_t);
extern ssize_t write_stderr(const void *, size_t);
extern int flush_stdout(void);
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/ipc/fb.h
66,7 → 66,9
FB_ANIM_CHGVP,
FB_ANIM_START,
FB_ANIM_STOP,
FB_POINTER_MOVE
FB_POINTER_MOVE,
FB_SCREEN_YIELD,
FB_SCREEN_RECLAIM
} fb_request_t;
 
#endif
/branches/network/uspace/lib/libc/generic/kbd.c
42,7 → 42,7
 
int kbd_get_event(kbd_event_t *ev)
{
int cons_phone = console_phone_get(true);
int cons_phone = console_open(true);
ipcarg_t r0, r1, r2, r3;
int rc;
 
/branches/network/uspace/lib/libc/generic/console.c
32,8 → 32,9
* @{
*/
/** @file
*/
*/
 
#include <libc.h>
#include <async.h>
#include <io/stream.h>
#include <ipc/console.h>
45,7 → 46,7
static int console_phone = -1;
 
/** Size of cbuffer. */
#define CBUFFER_SIZE 256
#define CBUFFER_SIZE 256
 
/** Buffer for writing characters to the console. */
static char cbuffer[CBUFFER_SIZE];
56,92 → 57,56
/** Pointer to first available field in cbuffer. */
static char *cbp = cbuffer;
 
static ssize_t cons_write(const char *buf, size_t nbyte);
static void cons_putchar(wchar_t c);
 
static void cbuffer_flush(void);
static void cbuffer_drain(void);
static inline void cbuffer_putc(int c);
 
 
void console_open(bool blocking)
/** Write one character to the console via IPC. */
static void cons_putchar(wchar_t c)
{
if (console_phone < 0) {
int phone;
if (blocking) {
phone = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_CONSOLE, 0, 0);
} else {
phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0,
0);
}
if (phone >= 0)
console_phone = phone;
}
console_wait();
async_msg_1(console_phone, CONSOLE_PUTCHAR, c);
}
 
void console_close(void)
/** Write characters to the console via IPC or to klog */
static ssize_t cons_write(const char *buf, size_t size)
{
console_open(false);
if (console_phone >= 0) {
if (ipc_hangup(console_phone) == 0) {
console_phone = -1;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_0(console_phone, CONSOLE_WRITE, &answer);
ipcarg_t rc = ipc_data_write_start(console_phone, (void *) buf, size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return (ssize_t) rc;
}
}
async_wait_for(req, &rc);
async_serialize_end();
if (rc == EOK)
return (ssize_t) IPC_GET_ARG1(answer);
else
return -1;
} else
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
}
 
int console_phone_get(bool blocking)
{
if (console_phone < 0)
console_open(blocking);
return console_phone;
}
 
void console_wait(void)
{
while (console_phone < 0)
console_open(true);
}
 
void console_clear(void)
{
int cons_phone = console_phone_get(true);
 
cbuffer_drain();
async_msg_0(cons_phone, CONSOLE_CLEAR);
}
 
void console_goto(int row, int col)
{
int cons_phone = console_phone_get(true);
 
cbuffer_flush();
async_msg_2(cons_phone, CONSOLE_GOTO, row, col);
}
 
void console_putchar(wchar_t c)
{
// cbuffer_putc(c);
cbuffer_flush();
cons_putchar(c);
}
 
/** Write all data from output buffer to the console. */
static void cbuffer_flush(void)
{
int rc;
int len;
 
len = cbp - cbuffer;
 
size_t len = cbp - cbuffer;
while (len > 0) {
rc = cons_write(cbuffer, cbp - cbuffer);
ssize_t rc = cons_write(cbuffer, cbp - cbuffer);
if (rc < 0)
return;
 
len -= rc;
}
 
cbp = cbuffer;
}
 
152,145 → 117,158
}
 
/** Write one character to the output buffer. */
static inline void cbuffer_putc(int c)
static inline void cbuffer_putc(char c)
{
if (cbp == cbuffer_end)
cbuffer_flush();
 
*cbp++ = c;
 
if (c == '\n')
cbuffer_flush();
}
 
/** Write one character to the console via IPC. */
static void cons_putchar(wchar_t c)
int console_open(bool blocking)
{
int cons_phone = console_phone_get(true);
async_msg_1(cons_phone, CONSOLE_PUTCHAR, c);
}
 
/** Write characters to the console via IPC. */
static ssize_t cons_write(const char *buf, size_t nbyte)
{
int cons_phone = console_phone_get(true);
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
 
async_serialize_start();
if (console_phone < 0) {
int phone;
if (blocking)
phone = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_CONSOLE, 0, 0);
else
phone = ipc_connect_me_to(PHONE_NS,
SERVICE_CONSOLE, 0, 0);
if (phone >= 0)
console_phone = phone;
}
req = async_send_0(cons_phone, CONSOLE_WRITE, &answer);
rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte);
 
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return (ssize_t) rc;
}
 
async_wait_for(req, &rc);
async_serialize_end();
 
if (rc == EOK)
return (ssize_t) IPC_GET_ARG1(answer);
else
return -1;
return console_phone;
}
 
/** Write characters to the console. */
ssize_t console_write(const char *buf, size_t nbyte)
void console_close(void)
{
size_t left;
 
left = nbyte;
 
while (left > 0) {
cbuffer_putc(*buf++);
--left;
if (console_phone >= 0) {
if (ipc_hangup(console_phone) == 0)
console_phone = -1;
}
 
return nbyte;
}
 
/** Write a NULL-terminated string to the console. */
void console_putstr(const char *s)
void console_wait(void)
{
size_t len;
ssize_t rc;
 
len = strlen(s);
while (len > 0) {
rc = console_write(s, len);
if (rc < 0)
return; /* Error */
s += rc;
len -= rc;
}
while (console_phone < 0)
console_open(true);
}
 
/** Flush all output to the console. */
void console_flush(void)
void console_clear(void)
{
int cons_phone = console_phone_get(false);
 
cbuffer_flush();
async_msg_0(cons_phone, CONSOLE_FLUSH);
console_wait();
cbuffer_drain();
async_msg_0(console_phone, CONSOLE_CLEAR);
}
 
int console_get_size(int *rows, int *cols)
{
int cons_phone = console_phone_get(true);
ipcarg_t r, c;
int rc;
 
rc = async_req_0_2(cons_phone, CONSOLE_GETSIZE, &r, &c);
 
console_wait();
ipcarg_t r;
ipcarg_t c;
int rc = async_req_0_2(console_phone, CONSOLE_GETSIZE, &r, &c);
*rows = (int) r;
*cols = (int) c;
 
return rc;
}
 
void console_set_style(int style)
{
int cons_phone = console_phone_get(true);
 
console_wait();
cbuffer_flush();
async_msg_1(cons_phone, CONSOLE_SET_STYLE, style);
async_msg_1(console_phone, CONSOLE_SET_STYLE, style);
}
 
void console_set_color(int fg_color, int bg_color, int flags)
{
int cons_phone = console_phone_get(true);
 
console_wait();
cbuffer_flush();
async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
async_msg_3(console_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
}
 
void console_set_rgb_color(int fg_color, int bg_color)
{
int cons_phone = console_phone_get(true);
 
console_wait();
cbuffer_flush();
async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
async_msg_2(console_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
}
 
void console_cursor_visibility(int show)
{
int cons_phone = console_phone_get(true);
 
console_wait();
cbuffer_flush();
async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
async_msg_1(console_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
}
 
void console_kcon_enable(void)
{
int cons_phone = console_phone_get(true);
console_wait();
cbuffer_flush();
async_msg_0(console_phone, CONSOLE_KCON_ENABLE);
}
 
void console_goto(int row, int col)
{
console_wait();
cbuffer_flush();
async_msg_0(cons_phone, CONSOLE_KCON_ENABLE);
async_msg_2(console_phone, CONSOLE_GOTO, row, col);
}
 
void console_putchar(wchar_t c)
{
console_wait();
cbuffer_flush();
cons_putchar(c);
}
 
/** Write characters to the console. */
ssize_t console_write(const char *buf, size_t size)
{
size_t left = size;
while (left > 0) {
cbuffer_putc(*buf++);
left--;
}
return size;
}
 
/** Write a NULL-terminated string to the console. */
void console_putstr(const char *str)
{
size_t left = str_size(str);
while (left > 0) {
ssize_t rc = console_write(str, left);
if (rc < 0) {
/* Error */
return;
}
str += rc;
left -= rc;
}
}
 
/** Flush all output to the console or klog. */
void console_flush(void)
{
cbuffer_flush();
if (console_phone >= 0)
async_msg_0(console_phone, CONSOLE_FLUSH);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/getopt.c
241,7 → 241,7
}
}
if ((optchar = (int)*place++) == (int)':' ||
(oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
(oli = str_chr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
/* option letter unknown or ':' */
if (!*place)
++optind;
377,20 → 377,20
nonopt_start = nonopt_end = -1;
return -1;
}
if ((has_equal = strchr(current_argv, '=')) != NULL) {
if ((has_equal = str_chr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
current_argv_len = str_size(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
if (str_lcmp(current_argv, long_options[i].name,
str_nlength(current_argv, current_argv_len)))
continue;
 
if (strlen(long_options[i].name) ==
if (str_size(long_options[i].name) ==
(unsigned)current_argv_len) {
/* exact match */
match = i;
/branches/network/uspace/lib/libc/generic/string.c
35,11 → 35,13
 
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <ctype.h>
#include <malloc.h>
#include <errno.h>
#include <align.h>
#include <mem.h>
#include <string.h>
 
/** Byte mask consisting of lowest @n bits (out of 8) */
461,40 → 463,91
 
}
 
/** 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';
}
 
/** Append one string to another.
*
* Append source string @a src to string in destination buffer @a dest.
* Size of the destination buffer is @a dest. 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.
* @param src Source string.
*/
void str_append(char *dest, size_t size, const char *src)
{
size_t dstr_size;
 
dstr_size = str_size(dest);
str_cpy(dest + dstr_size, size - dstr_size, src);
}
 
/** Copy NULL-terminated wide string to string
*
* Copy source wide string @a src to destination buffer @a dst.
535,21 → 588,45
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*
*/
const char *str_chr(const char *str, wchar_t ch)
{
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;
}
 
/** Find last occurence of character in string.
*
* @param str String to search.
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*/
const char *str_rchr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
size_t last = 0;
char *res = NULL;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
res = (str + last);
last = off;
}
return res;
}
 
/** Insert a wide character into a wide string.
*
* Insert a wide character into a wide string at position
606,42 → 683,6
return true;
}
 
/** Count the number of characters in the string, not including terminating 0.
*
* @param str String.
* @return Number of characters in string.
*/
size_t strlen(const char *str)
{
size_t counter = 0;
 
while (str[counter] != 0)
counter++;
 
return counter;
}
 
int strcmp(const char *a, const char *b)
{
int c = 0;
while (a[c] && b[c] && (!(a[c] - b[c])))
c++;
return (a[c] - b[c]);
}
 
int strncmp(const char *a, const char *b, size_t n)
{
size_t c = 0;
 
while (c < n && a[c] && b[c] && (!(a[c] - b[c])))
c++;
return ( c < n ? a[c] - b[c] : 0);
}
 
int stricmp(const char *a, const char *b)
{
int c = 0;
652,44 → 693,6
return (tolower(a[c]) - tolower(b[c]));
}
 
/** Return pointer to the first occurence of character c in string.
*
* @param str Scanned string.
* @param c Searched character (taken as one byte).
* @return Pointer to the matched character or NULL if it is not
* found in given string.
*/
char *strchr(const char *str, int c)
{
while (*str != '\0') {
if (*str == (char) c)
return (char *) str;
str++;
}
 
return NULL;
}
 
/** Return pointer to the last occurence of character c in string.
*
* @param str Scanned string.
* @param c Searched character (taken as one byte).
* @return Pointer to the matched character or NULL if it is not
* found in given string.
*/
char *strrchr(const char *str, int c)
{
char *retval = NULL;
 
while (*str != '\0') {
if (*str == (char) c)
retval = (char *) str;
str++;
}
 
return (char *) retval;
}
 
/** Convert string to a number.
* Core of strtol and strtoul functions.
*
839,44 → 842,15
return (sgn ? -number : number);
}
 
char *strcpy(char *dest, const char *src)
char *str_dup(const char *src)
{
char *orig = dest;
while ((*(dest++) = *(src++)))
;
return orig;
}
size_t size = str_size(src);
void *dest = malloc(size + 1);
 
char *strncpy(char *dest, const char *src, size_t n)
{
char *orig = dest;
while ((*(dest++) = *(src++)) && --n)
;
return orig;
}
 
char *strcat(char *dest, const char *src)
{
char *orig = dest;
while (*dest++)
;
--dest;
while ((*dest++ = *src++))
;
return orig;
}
 
char * strdup(const char *s1)
{
size_t len = strlen(s1) + 1;
void *ret = malloc(len);
 
if (ret == NULL)
if (dest == NULL)
return (char *) NULL;
 
return (char *) memcpy(ret, s1, len);
return (char *) memcpy(dest, src, size + 1);
}
 
char *strtok(char *s, const char *delim)
894,11 → 868,11
s = *next;
 
/* Skip over leading delimiters. */
while (*s && (strchr(delim, *s) != NULL)) ++s;
while (*s && (str_chr(delim, *s) != NULL)) ++s;
start = s;
 
/* Skip over token characters. */
while (*s && (strchr(delim, *s) == NULL)) ++s;
while (*s && (str_chr(delim, *s) == NULL)) ++s;
end = s;
*next = (*s ? s + 1 : s);
 
/branches/network/uspace/lib/libc/generic/loader.c
180,7 → 180,7
dp = arg_buf;
 
while (*ap != NULL) {
str_ncpy(dp, *ap, buffer_size - (dp - arg_buf));
str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
dp += str_size(*ap) + 1;
 
++ap;
/branches/network/uspace/lib/libc/generic/thread.c
130,6 → 130,8
void thread_exit(int status)
{
__SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
for (;;)
;
}
 
/** Detach thread.
152,6 → 154,7
*/
int thread_join(thread_id_t thread)
{
return 0;
}
 
/** Get current thread ID.
/branches/network/uspace/lib/libc/generic/libc.c
48,6 → 48,7
#include <ipc/ipc.h>
#include <async.h>
#include <as.h>
#include <console.h>
#include <loader/pcb.h>
 
extern char _heap;
83,6 → 84,7
}
 
main(argc, argv);
console_flush();
}
 
void __exit(void)
/branches/network/uspace/lib/libc/generic/async.c
30,64 → 30,65
* @{
*/
/** @file
*/
*/
 
/**
* Asynchronous library
*
* The aim of this library is facilitating writing programs utilizing the
* asynchronous nature of HelenOS IPC, yet using a normal way of programming.
* The aim of this library is to provide a facility for writing programs which
* utilize the asynchronous nature of HelenOS IPC, yet using a normal way of
* programming.
*
* You should be able to write very simple multithreaded programs, the async
* framework will automatically take care of most synchronization problems.
*
* Default semantics:
* - async_send_*(): send asynchronously. If the kernel refuses to send
* more messages, [ try to get responses from kernel, if
* nothing found, might try synchronous ]
* - async_send_*(): Send asynchronously. If the kernel refuses to send
* more messages, [ try to get responses from kernel, if
* nothing found, might try synchronous ]
*
* Example of use (pseudo C):
*
*
* 1) Multithreaded client application
*
* fibril_create(fibril1, ...);
* fibril_create(fibril2, ...);
* ...
*
* int fibril1(void *arg)
* {
* conn = ipc_connect_me_to();
* c1 = async_send(conn);
* c2 = async_send(conn);
* async_wait_for(c1);
* async_wait_for(c2);
* ...
* }
* fibril_create(fibril1, ...);
* fibril_create(fibril2, ...);
* ...
*
* int fibril1(void *arg)
* {
* conn = ipc_connect_me_to();
* c1 = async_send(conn);
* c2 = async_send(conn);
* async_wait_for(c1);
* async_wait_for(c2);
* ...
* }
*
*
* 2) Multithreaded server application
* main()
* {
* async_manager();
* }
*
*
* my_client_connection(icallid, *icall)
* {
* if (want_refuse) {
* ipc_answer_0(icallid, ELIMIT);
* return;
* }
* ipc_answer_0(icallid, EOK);
* main()
* {
* async_manager();
* }
*
* callid = async_get_call(&call);
* handle_call(callid, call);
* ipc_answer_2(callid, 1, 2, 3);
* my_client_connection(icallid, *icall)
* {
* if (want_refuse) {
* ipc_answer_0(icallid, ELIMIT);
* return;
* }
* ipc_answer_0(icallid, EOK);
*
* callid = async_get_call(&call);
* ....
* }
* callid = async_get_call(&call);
* handle_call(callid, call);
* ipc_answer_2(callid, 1, 2, 3);
*
* callid = async_get_call(&call);
* ...
* }
*
*/
 
#include <futex.h>
104,24 → 105,26
#include <bool.h>
 
atomic_t async_futex = FUTEX_INITIALIZER;
static hash_table_t conn_hash_table;
static LIST_INITIALIZE(timeout_list);
 
/** Structures of this type represent a waiting fibril. */
typedef struct {
/** Expiration time. */
struct timeval expires;
struct timeval expires;
/** If true, this struct is in the timeout list. */
int inlist;
bool inlist;
/** Timeout list link. */
link_t link;
 
/** Identification of and link to the waiting fibril. */
fid_t fid;
/** If true, this fibril is currently active. */
int active;
bool active;
/** If true, we have timed out. */
int timedout;
bool timedout;
} awaiter_t;
 
typedef struct {
128,10 → 131,11
awaiter_t wdata;
/** If reply was received. */
int done;
bool done;
/** Pointer to where the answer data is stored. */
ipc_call_t *dataptr;
 
ipc_call_t *dataptr;
ipcarg_t retval;
} amsg_t;
 
147,24 → 151,24
 
typedef struct {
awaiter_t wdata;
 
/** Hash table link. */
link_t link;
 
/** Incoming phone hash. */
ipcarg_t in_phone_hash;
 
ipcarg_t in_phone_hash;
/** Messages that should be delivered to this fibril. */
link_t msg_queue;
link_t msg_queue;
/** Identification of the opening call. */
ipc_callid_t callid;
/** Call data of the opening call. */
ipc_call_t call;
 
/** Identification of the closing call. */
ipc_callid_t close_callid;
 
/** Fibril function that will be used to handle the connection. */
void (*cfibril)(ipc_callid_t, ipc_call_t *);
} connection_t;
172,12 → 176,6
/** Identifier of the incoming connection handled by the current fibril. */
__thread connection_t *FIBRIL_connection;
 
/**
* If true, it is forbidden to use async_req functions and all preemption is
* disabled.
*/
__thread int _in_interrupt_handler;
 
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
 
185,6 → 183,7
* Pointer to a fibril function that will be used to handle connections.
*/
static async_client_conn_t client_connection = default_client_connection;
 
/**
* Pointer to a fibril function that will be used to handle interrupt
* notifications.
191,46 → 190,39
*/
static async_client_conn_t interrupt_received = default_interrupt_received;
 
/*
* Getter for _in_interrupt_handler. We need to export the value of this thread
* local variable to other modules, but the binutils 2.18 linkers die on an
* attempt to export this symbol in the header file. For now, consider this as a
* workaround.
*/
bool in_interrupt_handler(void)
{
return _in_interrupt_handler;
}
 
#define CONN_HASH_TABLE_CHAINS 32
static hash_table_t conn_hash_table;
static LIST_INITIALIZE(timeout_list);
 
 
#define CONN_HASH_TABLE_CHAINS 32
 
/** Compute hash into the connection hash table based on the source phone hash.
*
* @param key Pointer to source phone hash.
* @param key Pointer to source phone hash.
*
* @return Index into the connection hash table.
* @return Index into the connection hash table.
*
*/
static hash_index_t conn_hash(unsigned long *key)
{
assert(key);
return ((*key) >> 4) % CONN_HASH_TABLE_CHAINS;
return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
}
 
/** Compare hash table item with a key.
*
* @param key Array containing the source phone hash as the only item.
* @param keys Expected 1 but ignored.
* @param item Connection hash table item.
* @param key Array containing the source phone hash as the only item.
* @param keys Expected 1 but ignored.
* @param item Connection hash table item.
*
* @return True on match, false otherwise.
* @return True on match, false otherwise.
*
*/
static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
connection_t *hs;
 
hs = hash_table_get_instance(item, connection_t, link);
return key[0] == hs->in_phone_hash;
connection_t *hs = hash_table_get_instance(item, connection_t, link);
return (key[0] == hs->in_phone_hash);
}
 
/** Connection hash table removal callback function.
238,7 → 230,8
* This function is called whenever a connection is removed from the connection
* hash table.
*
* @param item Connection hash table item being removed.
* @param item Connection hash table item being removed.
*
*/
static void conn_remove(link_t *item)
{
255,23 → 248,24
 
/** Sort in current fibril's timeout request.
*
* @param wd Wait data of the current fibril.
* @param wd Wait data of the current fibril.
*
*/
static void insert_timeout(awaiter_t *wd)
{
link_t *tmp;
awaiter_t *cur;
 
wd->timedout = 0;
wd->inlist = 1;
 
tmp = timeout_list.next;
wd->timedout = false;
wd->inlist = true;
link_t *tmp = timeout_list.next;
while (tmp != &timeout_list) {
cur = list_get_instance(tmp, awaiter_t, link);
awaiter_t *cur = list_get_instance(tmp, awaiter_t, link);
if (tv_gteq(&cur->expires, &wd->expires))
break;
tmp = tmp->next;
}
list_append(&wd->link, tmp);
}
 
281,93 → 275,146
* its message queue. If the fibril was not active, it is activated and all
* timeouts are unregistered.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
* @return Zero if the call doesn't match any connection.
* One if the call was passed to the respective connection
* fibril.
* @return False if the call doesn't match any connection.
* True if the call was passed to the respective connection fibril.
*
*/
static int route_call(ipc_callid_t callid, ipc_call_t *call)
static bool route_call(ipc_callid_t callid, ipc_call_t *call)
{
connection_t *conn;
msg_t *msg;
link_t *hlp;
unsigned long key;
 
futex_down(&async_futex);
 
key = call->in_phone_hash;
hlp = hash_table_find(&conn_hash_table, &key);
unsigned long key = call->in_phone_hash;
link_t *hlp = hash_table_find(&conn_hash_table, &key);
if (!hlp) {
futex_up(&async_futex);
return 0;
return false;
}
conn = hash_table_get_instance(hlp, connection_t, link);
 
msg = malloc(sizeof(*msg));
connection_t *conn = hash_table_get_instance(hlp, connection_t, link);
msg_t *msg = malloc(sizeof(*msg));
if (!msg) {
futex_up(&async_futex);
return false;
}
msg->callid = callid;
msg->call = *call;
list_append(&msg->link, &conn->msg_queue);
 
if (IPC_GET_METHOD(*call) == IPC_M_PHONE_HUNGUP)
conn->close_callid = callid;
/* If the connection fibril is waiting for an event, activate it */
if (!conn->wdata.active) {
/* If in timeout list, remove it */
if (conn->wdata.inlist) {
conn->wdata.inlist = 0;
conn->wdata.inlist = false;
list_remove(&conn->wdata.link);
}
conn->wdata.active = 1;
conn->wdata.active = true;
fibril_add_ready(conn->wdata.fid);
}
 
futex_up(&async_futex);
return true;
}
 
return 1;
/** Notification fibril.
*
* When a notification arrives, a fibril with this implementing function is
* created. It calls interrupt_received() and does the final cleanup.
*
* @param arg Message structure pointer.
*
* @return Always zero.
*
*/
static int notification_fibril(void *arg)
{
msg_t *msg = (msg_t *) arg;
interrupt_received(msg->callid, &msg->call);
free(msg);
return 0;
}
 
/** Process interrupt notification.
*
* A new fibril is created which would process the notification.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
* @return False if an error occured.
* True if the call was passed to the notification fibril.
*
*/
static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
{
futex_down(&async_futex);
msg_t *msg = malloc(sizeof(*msg));
if (!msg) {
futex_up(&async_futex);
return false;
}
msg->callid = callid;
msg->call = *call;
fid_t fid = fibril_create(notification_fibril, msg);
fibril_add_ready(fid);
futex_up(&async_futex);
return true;
}
 
/** Return new incoming message for the current (fibril-local) connection.
*
* @param call Storage where the incoming call data will be stored.
* @param usecs Timeout in microseconds. Zero denotes no timeout.
* @param call Storage where the incoming call data will be stored.
* @param usecs Timeout in microseconds. Zero denotes no timeout.
*
* @return If no timeout was specified, then a hash of the
* incoming call is returned. If a timeout is specified,
* then a hash of the incoming call is returned unless
* the timeout expires prior to receiving a message. In
* that case zero is returned.
* @return If no timeout was specified, then a hash of the
* incoming call is returned. If a timeout is specified,
* then a hash of the incoming call is returned unless
* the timeout expires prior to receiving a message. In
* that case zero is returned.
*
*/
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
{
msg_t *msg;
ipc_callid_t callid;
connection_t *conn;
assert(FIBRIL_connection);
assert(FIBRIL_connection);
/* GCC 4.1.0 coughs on FIBRIL_connection-> dereference,
/* Why doing this?
* GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
* GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
* I would never expect to find so many errors in
* a compiler *($&$(*&$
* I would never expect to find so many errors in
* a compiler.
*/
conn = FIBRIL_connection;
 
connection_t *conn = FIBRIL_connection;
futex_down(&async_futex);
 
if (usecs) {
gettimeofday(&conn->wdata.expires, NULL);
tv_add(&conn->wdata.expires, usecs);
} else {
conn->wdata.inlist = 0;
}
} else
conn->wdata.inlist = false;
/* If nothing in queue, wait until something arrives */
while (list_empty(&conn->msg_queue)) {
if (usecs)
insert_timeout(&conn->wdata);
 
conn->wdata.active = 0;
conn->wdata.active = false;
/*
* Note: the current fibril will be rescheduled either due to a
* timeout or due to an arriving message destined to it. In the
375,13 → 422,14
* case, route_call() will perform the wakeup.
*/
fibril_switch(FIBRIL_TO_MANAGER);
/*
* Futex is up after getting back from async_manager get it
* again.
* Futex is up after getting back from async_manager.
* Get it again.
*/
futex_down(&async_futex);
if (usecs && conn->wdata.timedout &&
list_empty(&conn->msg_queue)) {
if ((usecs) && (conn->wdata.timedout)
&& (list_empty(&conn->msg_queue))) {
/* If we timed out -> exit */
futex_up(&async_futex);
return 0;
388,9 → 436,10
}
}
msg = list_get_instance(conn->msg_queue.next, msg_t, link);
msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link);
list_remove(&msg->link);
callid = msg->callid;
ipc_callid_t callid = msg->callid;
*call = msg->call;
free(msg);
402,8 → 451,9
*
* This function is defined as a weak symbol - to be redefined in user code.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
{
412,8 → 462,11
 
/** Default fibril function that gets called to handle interrupt notifications.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* This function is defined as a weak symbol - to be redefined in user code.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
{
424,17 → 477,17
* When a new connection arrives, a fibril with this implementing function is
* created. It calls client_connection() and does the final cleanup.
*
* @param arg Connection structure pointer.
* @param arg Connection structure pointer.
*
* @return Always zero.
* @return Always zero.
*
*/
static int connection_fibril(void *arg)
static int connection_fibril(void *arg)
{
unsigned long key;
msg_t *msg;
int close_answered = 0;
 
/* Setup fibril-local connection pointer */
/*
* Setup fibril-local connection pointer and call client_connection().
*
*/
FIBRIL_connection = (connection_t *) arg;
FIBRIL_connection->cfibril(FIBRIL_connection->callid,
&FIBRIL_connection->call);
441,20 → 494,20
/* Remove myself from the connection hash table */
futex_down(&async_futex);
key = FIBRIL_connection->in_phone_hash;
unsigned long key = FIBRIL_connection->in_phone_hash;
hash_table_remove(&conn_hash_table, &key, 1);
futex_up(&async_futex);
/* Answer all remaining messages with EHANGUP */
while (!list_empty(&FIBRIL_connection->msg_queue)) {
msg = list_get_instance(FIBRIL_connection->msg_queue.next,
msg_t, link);
msg_t *msg
= list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, link);
list_remove(&msg->link);
if (msg->callid == FIBRIL_connection->close_callid)
close_answered = 1;
ipc_answer_0(msg->callid, EHANGUP);
free(msg);
}
if (FIBRIL_connection->close_callid)
ipc_answer_0(FIBRIL_connection->close_callid, EOK);
463,43 → 516,45
 
/** Create a new fibril for a new connection.
*
* Creates new fibril for connection, fills in connection structures and inserts
* Create new fibril for connection, fill in connection structures and inserts
* it into the hash table, so that later we can easily do routing of messages to
* particular fibrils.
*
* @param in_phone_hash Identification of the incoming connection.
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call.
* If callid is zero, the connection was opened by
* accepting the IPC_M_CONNECT_TO_ME call and this function
* is called directly by the server.
* @param call Call data of the opening call.
* @param cfibril Fibril function that should be called upon opening the
* connection.
* @param in_phone_hash Identification of the incoming connection.
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call.
* If callid is zero, the connection was opened by
* accepting the IPC_M_CONNECT_TO_ME call and this function
* is called directly by the server.
* @param call Call data of the opening call.
* @param cfibril Fibril function that should be called upon opening the
* connection.
*
* @return New fibril id or NULL on failure.
* @return New fibril id or NULL on failure.
*
*/
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
{
connection_t *conn;
unsigned long key;
conn = malloc(sizeof(*conn));
connection_t *conn = malloc(sizeof(*conn));
if (!conn) {
if (callid)
ipc_answer_0(callid, ENOMEM);
return NULL;
}
conn->in_phone_hash = in_phone_hash;
list_initialize(&conn->msg_queue);
conn->callid = callid;
conn->close_callid = 0;
conn->close_callid = false;
if (call)
conn->call = *call;
conn->wdata.active = 1; /* We will activate the fibril ASAP */
/* We will activate the fibril ASAP */
conn->wdata.active = true;
conn->cfibril = cfibril;
conn->wdata.fid = fibril_create(connection_fibril, conn);
conn->wdata.fid = fibril_create(connection_fibril, conn);
if (!conn->wdata.fid) {
free(conn);
if (callid)
508,7 → 563,8
}
/* Add connection to the connection hash table */
key = conn->in_phone_hash;
ipcarg_t key = conn->in_phone_hash;
futex_down(&async_futex);
hash_table_insert(&conn_hash_table, &key, &conn->link);
futex_up(&async_futex);
523,8 → 579,8
* If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created.
* Otherwise the call is routed to its connection fibril.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
531,9 → 587,7
{
/* Unrouted call - do some default behaviour */
if ((callid & IPC_CALLID_NOTIFICATION)) {
_in_interrupt_handler = 1;
(*interrupt_received)(callid, call);
_in_interrupt_handler = 0;
process_notification(callid, call);
return;
}
557,47 → 611,44
static void handle_expired_timeouts(void)
{
struct timeval tv;
awaiter_t *waiter;
link_t *cur;
 
gettimeofday(&tv, NULL);
futex_down(&async_futex);
 
cur = timeout_list.next;
link_t *cur = timeout_list.next;
while (cur != &timeout_list) {
waiter = list_get_instance(cur, awaiter_t, link);
awaiter_t *waiter = list_get_instance(cur, awaiter_t, link);
if (tv_gt(&waiter->expires, &tv))
break;
cur = cur->next;
list_remove(&waiter->link);
waiter->inlist = 0;
waiter->timedout = 1;
waiter->inlist = false;
waiter->timedout = true;
/*
* Redundant condition?
* The fibril should not be active when it gets here.
* Redundant condition?
* The fibril should not be active when it gets here.
*/
if (!waiter->active) {
waiter->active = 1;
waiter->active = true;
fibril_add_ready(waiter->fid);
}
}
 
futex_up(&async_futex);
}
 
/** Endless loop dispatching incoming calls and answers.
*
* @return Never returns.
* @return Never returns.
*
*/
static int async_manager_worker(void)
{
ipc_call_t call;
ipc_callid_t callid;
int timeout;
awaiter_t *waiter;
struct timeval tv;
 
while (1) {
while (true) {
if (fibril_switch(FIBRIL_FROM_MANAGER)) {
futex_up(&async_futex);
/*
606,11 → 657,17
*/
continue;
}
futex_down(&async_futex);
suseconds_t timeout;
if (!list_empty(&timeout_list)) {
waiter = list_get_instance(timeout_list.next, awaiter_t,
link);
awaiter_t *waiter
= list_get_instance(timeout_list.next, awaiter_t, link);
struct timeval tv;
gettimeofday(&tv, NULL);
if (tv_gteq(&tv, &waiter->expires)) {
futex_up(&async_futex);
handle_expired_timeouts();
619,19 → 676,21
timeout = tv_sub(&waiter->expires, &tv);
} else
timeout = SYNCH_NO_TIMEOUT;
futex_up(&async_futex);
 
callid = ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE);
 
ipc_call_t call;
ipc_callid_t callid
= ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE);
if (!callid) {
handle_expired_timeouts();
continue;
}
 
if (callid & IPC_CALLID_ANSWERED) {
if (callid & IPC_CALLID_ANSWERED)
continue;
}
 
handle_call(callid, &call);
}
639,16 → 698,17
}
 
/** Function to start async_manager as a standalone fibril.
*
*
* When more kernel threads are used, one async manager should exist per thread.
*
* @param arg Unused.
* @param arg Unused.
* @return Never returns.
*
* @return Never returns.
*/
static int async_manager_fibril(void *arg)
{
futex_up(&async_futex);
/*
* async_futex is always locked when entering manager
*/
660,9 → 720,7
/** Add one manager to manager list. */
void async_create_manager(void)
{
fid_t fid;
 
fid = fibril_create(async_manager_fibril, NULL);
fid_t fid = fibril_create(async_manager_fibril, NULL);
fibril_add_manager(fid);
}
 
674,7 → 732,7
 
/** Initialize the async framework.
*
* @return Zero on success or an error code.
* @return Zero on success or an error code.
*/
int _async_init(void)
{
694,30 → 752,33
*
* Notify the fibril which is waiting for this message that it has arrived.
*
* @param private Pointer to the asynchronous message record.
* @param retval Value returned in the answer.
* @param data Call data of the answer.
* @param arg Pointer to the asynchronous message record.
* @param retval Value returned in the answer.
* @param data Call data of the answer.
*/
static void reply_received(void *private, int retval, ipc_call_t *data)
static void reply_received(void *arg, int retval, ipc_call_t *data)
{
amsg_t *msg = (amsg_t *) private;
 
amsg_t *msg = (amsg_t *) arg;
msg->retval = retval;
 
futex_down(&async_futex);
/* Copy data after futex_down, just in case the call was detached */
if (msg->dataptr)
*msg->dataptr = *data;
 
*msg->dataptr = *data;
write_barrier();
/* Remove message from timeout list */
if (msg->wdata.inlist)
list_remove(&msg->wdata.link);
msg->done = 1;
msg->done = true;
if (!msg->wdata.active) {
msg->wdata.active = 1;
msg->wdata.active = true;
fibril_add_ready(msg->wdata.fid);
}
futex_up(&async_futex);
}
 
726,31 → 787,34
* The return value can be used as input for async_wait() to wait for
* completion.
*
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
*
* @return Hash of the sent message.
* @return Hash of the sent message or 0 on error.
*
*/
aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
{
amsg_t *msg;
amsg_t *msg = malloc(sizeof(*msg));
msg = malloc(sizeof(*msg));
msg->done = 0;
if (!msg)
return 0;
msg->done = false;
msg->dataptr = dataptr;
/* We may sleep in the next method, but it will use its own mechanism */
msg->wdata.active = 1;
msg->wdata.active = true;
ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
reply_received, !_in_interrupt_handler);
reply_received, true);
return (aid_t) msg;
}
760,33 → 824,36
* The return value can be used as input for async_wait() to wait for
* completion.
*
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
*
* @return Hash of the sent message.
* @return Hash of the sent message or 0 on error.
*
*/
aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
ipc_call_t *dataptr)
{
amsg_t *msg;
amsg_t *msg = malloc(sizeof(*msg));
msg = malloc(sizeof(*msg));
msg->done = 0;
if (!msg)
return 0;
msg->done = false;
msg->dataptr = dataptr;
/* We may sleep in next method, but it will use its own mechanism */
msg->wdata.active = 1;
msg->wdata.active = true;
ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
reply_received, !_in_interrupt_handler);
reply_received, true);
return (aid_t) msg;
}
793,74 → 860,82
 
/** Wait for a message sent by the async framework.
*
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
*
*/
void async_wait_for(aid_t amsgid, ipcarg_t *retval)
{
amsg_t *msg = (amsg_t *) amsgid;
 
futex_down(&async_futex);
if (msg->done) {
futex_up(&async_futex);
goto done;
}
 
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
msg->wdata.inlist = 0;
msg->wdata.active = false;
msg->wdata.inlist = false;
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch...*/
/* Futex is up automatically after fibril_switch */
done:
if (retval)
*retval = msg->retval;
free(msg);
}
 
/** Wait for a message sent by the async framework, timeout variant.
*
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param timeout Timeout in microseconds.
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param timeout Timeout in microseconds.
*
* @return Zero on success, ETIMEOUT if the timeout has expired.
* @return Zero on success, ETIMEOUT if the timeout has expired.
*
*/
int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout)
{
amsg_t *msg = (amsg_t *) amsgid;
 
/* TODO: Let it go through the event read at least once */
if (timeout < 0)
return ETIMEOUT;
 
futex_down(&async_futex);
if (msg->done) {
futex_up(&async_futex);
goto done;
}
 
gettimeofday(&msg->wdata.expires, NULL);
tv_add(&msg->wdata.expires, timeout);
 
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
msg->wdata.active = false;
insert_timeout(&msg->wdata);
 
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch...*/
 
/* Futex is up automatically after fibril_switch */
if (!msg->done)
return ETIMEOUT;
 
done:
if (retval)
*retval = msg->retval;
free(msg);
 
return 0;
}
 
868,33 → 943,38
*
* The current fibril is suspended but the thread continues to execute.
*
* @param timeout Duration of the wait in microseconds.
* @param timeout Duration of the wait in microseconds.
*
*/
void async_usleep(suseconds_t timeout)
{
amsg_t *msg;
amsg_t *msg = malloc(sizeof(*msg));
msg = malloc(sizeof(*msg));
if (!msg)
return;
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
msg->wdata.active = false;
gettimeofday(&msg->wdata.expires, NULL);
tv_add(&msg->wdata.expires, timeout);
futex_down(&async_futex);
insert_timeout(&msg->wdata);
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch()...*/
/* Futex is up automatically after fibril_switch() */
free(msg);
}
 
/** Setter for client_connection function pointer.
*
* @param conn Function that will implement a new connection fibril.
* @param conn Function that will implement a new connection fibril.
*
*/
void async_set_client_connection(async_client_conn_t conn)
{
903,12 → 983,12
 
/** Setter for interrupt_received function pointer.
*
* @param conn Function that will implement a new interrupt
* notification fibril.
* @param intr Function that will implement a new interrupt
* notification fibril.
*/
void async_set_interrupt_received(async_client_conn_t conn)
void async_set_interrupt_received(async_client_conn_t intr)
{
interrupt_received = conn;
interrupt_received = intr;
}
 
/** Pseudo-synchronous message sending - fast version.
918,18 → 998,20
* This function can only transfer 4 register payload arguments. For
* transferring more arguments, see the slower async_req_slow().
*
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
* @return Return code of the reply or a negative error code.
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
*
* @return Return code of the reply or a negative error code.
*
*/
ipcarg_t async_req_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t *r1, ipcarg_t *r2,
936,21 → 1018,27
ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5)
{
ipc_call_t result;
ipcarg_t rc;
 
aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
&result);
ipcarg_t rc;
async_wait_for(eid, &rc);
if (r1)
if (r1)
*r1 = IPC_GET_ARG1(result);
if (r2)
*r2 = IPC_GET_ARG2(result);
if (r3)
*r3 = IPC_GET_ARG3(result);
if (r4)
*r4 = IPC_GET_ARG4(result);
if (r5)
*r5 = IPC_GET_ARG5(result);
return rc;
}
 
958,19 → 1046,21
*
* Send message asynchronously and return only after the reply arrives.
*
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
* @return Return code of the reply or a negative error code.
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
*
* @return Return code of the reply or a negative error code.
*
*/
ipcarg_t async_req_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *r1,
977,21 → 1067,27
ipcarg_t *r2, ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5)
{
ipc_call_t result;
ipcarg_t rc;
 
aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
&result);
ipcarg_t rc;
async_wait_for(eid, &rc);
if (r1)
if (r1)
*r1 = IPC_GET_ARG1(result);
if (r2)
*r2 = IPC_GET_ARG2(result);
if (r3)
*r3 = IPC_GET_ARG3(result);
if (r4)
*r4 = IPC_GET_ARG4(result);
if (r5)
*r5 = IPC_GET_ARG5(result);
return rc;
}
 
/branches/network/uspace/lib/libc/generic/vfs/vfs.c
76,7 → 76,7
futex_up(&cwd_futex);
return NULL;
}
str_ncpy(ncwd_path_nc, cwd_path, cwd_size + 1 + size + 1);
str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
ncwd_path_nc[cwd_size] = '/';
ncwd_path_nc[cwd_size + 1] = '\0';
} else {
87,7 → 87,7
}
ncwd_path_nc[0] = '\0';
}
strcat(ncwd_path_nc, path);
str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
ncwd_path = canonify(ncwd_path_nc, retlen);
if (!ncwd_path) {
futex_up(&cwd_futex);
99,7 → 99,7
* the address in ncwd_path need not be the same as ncwd_path_nc, even
* though they both point into the same dynamically allocated buffer.
*/
ncwd_path = strdup(ncwd_path);
ncwd_path = str_dup(ncwd_path);
free(ncwd_path_nc);
if (!ncwd_path) {
futex_up(&cwd_futex);
155,7 → 155,7
}
 
int mount(const char *fs_name, const char *mp, const char *dev,
const unsigned int flags)
const char *opts, const unsigned int flags)
{
int res;
ipcarg_t rc;
185,6 → 185,15
return (int) rc;
}
rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(mpa);
return (int) rc;
}
 
rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
if (rc != EOK) {
async_wait_for(req, NULL);
193,6 → 202,16
free(mpa);
return (int) rc;
}
 
/* Ask VFS whether it likes fs_name. */
rc = async_req_0_0(vfs_phone, IPC_M_PING);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(mpa);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
534,7 → 553,7
futex_up(&cwd_futex);
return NULL;
}
str_ncpy(buf, cwd_path, size);
str_cpy(buf, size, cwd_path);
futex_up(&cwd_futex);
return buf;
}
/branches/network/uspace/lib/libc/generic/io/io.c
38,6 → 38,7
#include <io/io.h>
#include <string.h>
#include <errno.h>
#include <console.h>
 
const static char nl = '\n';
 
49,8 → 50,9
return putnchars("(NULL)", 6);
for (count = 0; str[count] != 0; count++);
if (write_stdout((void *) str, count) == count) {
if (write_stdout(&nl, 1) == 1)
if (console_write((void *) str, count) == count) {
if (console_write(&nl, 1) == 1)
return 0;
}
64,7 → 66,7
*/
int putnchars(const char *buf, size_t count)
{
if (write_stdout((void *) buf, count) == count)
if (console_write((void *) buf, count) == count)
return 0;
return EOF;
81,7 → 83,7
return putnchars("(NULL)", 6);
 
for (count = 0; str[count] != 0; count++);
if (write_stdout((void *) str, count) == count)
if (console_write((void *) str, count) == count)
return 0;
return EOF;
96,7 → 98,7
if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK)
return EOF;
 
if (write_stdout((void *) buf, offs) == offs)
if (console_write((void *) buf, offs) == offs)
return c;
 
return EOF;
105,8 → 107,8
int getchar(void)
{
unsigned char c;
 
flush_stdout();
console_flush();
if (read_stdin((void *) &c, 1) == 1)
return c;
115,8 → 117,10
 
int fflush(FILE *f)
{
/* Dummy implementation */
(void) f;
return flush_stdout();
console_flush();
return 0;
}
 
/** @}
/branches/network/uspace/lib/libc/generic/io/vprintf.c
38,6 → 38,7
#include <io/printf_core.h>
#include <futex.h>
#include <async.h>
#include <console.h>
 
static atomic_t printf_futex = FUTEX_INITIALIZER;
 
50,7 → 51,7
while (offset < size) {
prev = offset;
str_decode(str, &offset, size);
write_stdout(str + prev, offset - prev);
console_write(str + prev, offset - prev);
chars++;
}
67,7 → 68,7
while (offset < size) {
boff = 0;
chr_encode(str[chars], buf, &boff, 4);
write_stdout(buf, boff);
console_write(buf, boff);
chars++;
offset += sizeof(wchar_t);
}
/branches/network/uspace/lib/libc/generic/io/stream.c
49,62 → 49,28
#include <async.h>
#include <sys/types.h>
 
ssize_t write_stderr(const void *buf, size_t count)
{
return count;
}
 
ssize_t read_stdin(void *buf, size_t count)
{
int cons_phone = console_phone_get(false);
 
int cons_phone = console_open(false);
if (cons_phone >= 0) {
kbd_event_t ev;
int rc;
size_t i = 0;
while (i < count) {
do {
rc = kbd_get_event(&ev);
if (rc < 0) return -1;
} while (ev.c == 0 || ev.type == KE_RELEASE);
 
((char *) buf)[i++] = ev.c;
}
return i;
} else {
} else
return -1;
}
}
 
ssize_t write_stdout(const void *buf, size_t count)
{
int cons_phone = console_phone_get(false);
int left, rc;
 
if (cons_phone >= 0) {
int i;
 
left = count;
while (left > 0) {
rc = console_write(buf, left);
if (rc < 0)
break;
buf += rc;
left -= rc;
}
 
return count;
} else
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count);
}
 
int flush_stdout(void)
{
console_flush();
return 0;
}
 
void klog_update(void)
{
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
/branches/network/uspace/lib/libc/arch/ia64/include/ddi.h
53,7 → 53,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");
63,7 → 63,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");
73,7 → 73,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");
85,7 → 85,7
 
asm volatile ("mf\n" ::: "memory");
 
return *((uint8_t *)(IA64_IOSPACE_ADDRESS +
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
95,7 → 95,7
 
asm volatile ("mf\n" ::: "memory");
 
return *((uint16_t *)(IA64_IOSPACE_ADDRESS +
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
105,7 → 105,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/uspace/srv/kbd/include/layout.h
41,6 → 41,7
#include <sys/types.h>
 
typedef struct {
void (*reset)(void);
wchar_t (*parse_ev)(kbd_event_t *);
} layout_op_t;
 
/branches/network/uspace/srv/kbd/include/sun.h
0,0 → 1,47
/*
* Copyright (c) 2009 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 kbdgen generic
* @brief Sun keyboard virtual port driver.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_SUN_H_
#define KBD_SUN_H_
 
extern int ns16550_port_init(void);
extern int z8530_port_init(void);
 
#endif
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/ns16550.c
35,10 → 35,12
*/
 
#include <ipc/ipc.h>
#include <ipc/bus.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <ddi.h>
 
/* NS16550 registers */
89,7 → 91,7
static uintptr_t ns16550_physical;
static uintptr_t ns16550_kernel;
 
int kbd_port_init(void)
int ns16550_port_init(void)
{
void *vaddr;
 
100,7 → 102,7
ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &ns16550_kbd);
sysinfo_value("kbd.inr"), &ns16550_kbd);
return pio_enable((void *) ns16550_physical, 8, &vaddr);
}
 
108,6 → 110,10
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
if (cir_service)
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
IPC_GET_METHOD(*call));
}
 
/**
/branches/network/uspace/srv/kbd/port/sun.c
0,0 → 1,66
/*
* Copyright (c) 2009 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 kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Sun keyboard virtual port driver.
*/
 
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sysinfo.h>
 
/** Sun keyboard virtual port driver.
*
* This is a virtual port driver which can use
* both ns16550_port_init and z8530_port_init
* according to the information passed from the
* kernel. This is just a temporal hack.
*
*/
int kbd_port_init(void)
{
if (sysinfo_value("kbd.type.z8530")) {
if (z8530_port_init() == 0)
return 0;
}
if (sysinfo_value("kbd.type.ns16550")) {
if (ns16550_port_init() == 0)
return 0;
}
return -1;
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/z8530.c
40,6 → 40,7
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sys/types.h>
#include <ddi.h>
 
82,7 → 83,7
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
int z8530_port_init(void)
{
async_set_interrupt_received(z8530_irq_handler);
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.kernel") +
/branches/network/uspace/srv/kbd/generic/kbd.c
136,6 → 136,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F1) {
active_layout = 0;
layout[active_layout]->reset();
return;
}
 
142,6 → 143,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F2) {
active_layout = 1;
layout[active_layout]->reset();
return;
}
 
148,6 → 150,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F3) {
active_layout = 2;
layout[active_layout]->reset();
return;
}
 
223,6 → 226,9
/* Initialize controller driver. */
if (kbd_ctl_init() != 0)
return -1;
 
/* Initialize (reset) layout. */
layout[active_layout]->reset();
/* Initialize key buffer */
keybuffer_init(&keybuffer);
/branches/network/uspace/srv/kbd/Makefile
59,9 → 59,11
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(UARCH), arm32)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
70,29 → 72,35
ctl/stty.c
endif
endif
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(MACHINE), i460GX)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(MACHINE), ski)
GENARCH_SOURCES += \
port/ski.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), msim)
GENARCH_SOURCES += \
port/msim.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), lgxemul)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
101,26 → 109,31
ctl/stty.c
endif
endif
 
ifeq ($(MACHINE), bgxemul)
GENARCH_SOURCES += \
port/gxemul.c \
ctl/stty.c
endif
 
ifeq ($(UARCH), ppc32)
GENARCH_SOURCES += \
port/dummy.c \
ctl/stty.c
endif
 
ifeq ($(UARCH), sparc64)
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/z8530.c \
ctl/sun.c
endif
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/sun.c \
port/z8530.c \
port/ns16550.c \
ctl/sun.c
endif
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
/branches/network/uspace/srv/kbd/layout/us_qwerty.c
36,9 → 36,11
#include <kbd/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
layout_op_t us_qwerty_op = {
layout_reset,
layout_parse_ev
};
 
197,6 → 199,10
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
wchar_t c;
/branches/network/uspace/srv/kbd/layout/cz.c
34,28 → 34,26
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <bool.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
enum m_state {
ms_start,
ms_hacek,
ms_carka
};
 
static enum m_state mstate;
 
layout_op_t cz_op = {
layout_reset,
layout_parse_ev
};
 
static wchar_t map_lcase[] = {
[KC_2] = L'ě',
[KC_3] = L'š',
[KC_4] = L'č',
[KC_5] = L'ř',
[KC_6] = L'ž',
[KC_7] = L'ý',
[KC_8] = L'á',
[KC_9] = L'í',
[KC_0] = L'é',
 
[KC_LBRACKET] = L'ú',
[KC_SEMICOLON] = L'ů',
 
[KC_Q] = 'q',
[KC_W] = 'w',
[KC_E] = 'e',
87,19 → 85,6
};
 
static wchar_t map_ucase[] = {
[KC_2] = L'Ě',
[KC_3] = L'Š',
[KC_4] = L'Č',
[KC_5] = L'Ř',
[KC_6] = L'Ž',
[KC_7] = L'Ý',
[KC_8] = L'Á',
[KC_9] = L'Í',
[KC_0] = L'É',
 
[KC_LBRACKET] = L'Ú',
[KC_SEMICOLON] = L'Ů',
 
[KC_Q] = 'Q',
[KC_W] = 'W',
[KC_E] = 'E',
172,6 → 157,36
[KC_SLASH] = '_',
};
 
static wchar_t map_ns_nocaps[] = {
[KC_2] = L'ě',
[KC_3] = L'š',
[KC_4] = L'č',
[KC_5] = L'ř',
[KC_6] = L'ž',
[KC_7] = L'ý',
[KC_8] = L'á',
[KC_9] = L'í',
[KC_0] = L'é',
 
[KC_LBRACKET] = L'ú',
[KC_SEMICOLON] = L'ů'
};
 
static wchar_t map_ns_caps[] = {
[KC_2] = L'Ě',
[KC_3] = L'Š',
[KC_4] = L'Č',
[KC_5] = L'Ř',
[KC_6] = L'Ž',
[KC_7] = L'Ý',
[KC_8] = L'Á',
[KC_9] = L'Í',
[KC_0] = L'É',
 
[KC_LBRACKET] = L'Ú',
[KC_SEMICOLON] = L'Ů'
};
 
static wchar_t map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
200,6 → 215,56
[KC_NPERIOD] = '.'
};
 
static wchar_t map_hacek_lcase[] = {
[KC_E] = L'ě',
[KC_R] = L'ř',
[KC_T] = L'ť',
[KC_Y] = L'ž',
[KC_U] = L'ů',
 
[KC_S] = L'š',
[KC_D] = L'ď',
 
[KC_C] = L'č',
[KC_N] = L'ň'
};
 
static wchar_t map_hacek_ucase[] = {
[KC_E] = L'Ě',
[KC_R] = L'Ř',
[KC_T] = L'Ť',
[KC_Y] = L'Ž',
[KC_U] = L'Ů',
 
[KC_S] = L'Š',
[KC_D] = L'Ď',
 
[KC_C] = L'Č',
[KC_N] = L'Ň'
};
 
static wchar_t map_carka_lcase[] = {
[KC_E] = L'é',
[KC_U] = L'ú',
[KC_I] = L'í',
[KC_O] = L'ó',
 
[KC_A] = L'á',
 
[KC_Z] = L'ý',
};
 
static wchar_t map_carka_ucase[] = {
[KC_E] = L'É',
[KC_U] = L'Ú',
[KC_I] = L'Í',
[KC_O] = L'Ó',
 
[KC_A] = L'Á',
 
[KC_Z] = L'Ý',
};
 
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
{
if (key >= map_length)
207,18 → 272,73
return map[key];
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
static wchar_t parse_ms_hacek(kbd_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_carka(kbd_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_start(kbd_event_t *ev)
{
wchar_t c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (ev->key == KC_EQUALS) {
if ((ev->mods & KM_SHIFT) != 0)
mstate = ms_hacek;
else
mstate = ms_carka;
 
return 0;
}
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) == 0) {
if ((ev->mods & KM_CAPS_LOCK) != 0)
c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
else
c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
 
if (c != 0)
return c;
}
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
else
243,6 → 363,41
return c;
}
 
static bool key_is_mod(unsigned key)
{
switch (key) {
case KC_LSHIFT:
case KC_RSHIFT:
case KC_LALT:
case KC_RALT:
case KC_LCTRL:
case KC_RCTRL:
return true;
default:
return false;
}
}
 
static void layout_reset(void)
{
mstate = ms_start;
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
if (ev->type != KE_PRESS)
return '\0';
 
if (key_is_mod(ev->key))
return '\0';
 
switch (mstate) {
case ms_start: return parse_ms_start(ev);
case ms_hacek: return parse_ms_hacek(ev);
case ms_carka: return parse_ms_carka(ev);
}
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/layout/us_dvorak.c
36,9 → 36,11
#include <kbd/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
layout_op_t us_dvorak_op = {
layout_reset,
layout_parse_ev
};
 
203,6 → 205,10
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
wchar_t c;
/branches/network/uspace/srv/console/console.c
141,6 → 141,16
async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
}
 
static void screen_yield(void)
{
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
}
 
static void screen_reclaim(void)
{
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
}
 
static void set_style(int style)
{
async_msg_1(fb_info.phone, FB_SET_STYLE, style);
330,7 → 340,9
async_serialize_start();
curs_hide_sync();
gcons_in_kernel();
screen_yield();
async_serialize_end();
 
if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
prev_console = active_console;
342,8 → 354,10
if (newcons != KERNEL_CONSOLE) {
async_serialize_start();
if (active_console == KERNEL_CONSOLE)
if (active_console == KERNEL_CONSOLE) {
screen_reclaim();
gcons_redraw_console();
}
active_console = newcons;
gcons_change_console(newcons);
512,6 → 526,8
gcons_notify_connect(consnum);
conn->client_phone = IPC_GET_ARG5(*icall);
screenbuffer_clear(&conn->screenbuffer);
if (consnum == active_console)
clrscr();
/* Accept the connection */
ipc_answer_0(iid, EOK);
/branches/network/uspace/srv/rd/rd.c
196,7 → 196,7
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(phone, (char *) name, strlen(name) + 1);
retval = ipc_data_write_start(phone, (char *) name, str_size(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
219,7 → 219,8
 
req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(driver_phone, (char *) name, strlen(name) + 1);
retval = ipc_data_write_start(driver_phone, (char *) name,
str_size(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
/branches/network/uspace/srv/loader/main.c
150,11 → 150,11
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_len, arg_len;
size_t buf_size, arg_size;
char *p;
int n;
if (!ipc_data_write_receive(&callid, &buf_len)) {
if (!ipc_data_write_receive(&callid, &buf_size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
170,7 → 170,7
argv = NULL;
}
arg_buf = malloc(buf_len + 1);
arg_buf = malloc(buf_size + 1);
if (!arg_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
177,9 → 177,9
return;
}
ipc_data_write_finalize(callid, arg_buf, buf_len);
ipc_data_write_finalize(callid, arg_buf, buf_size);
arg_buf[buf_len] = '\0';
arg_buf[buf_size] = '\0';
/*
* Count number of arguments
186,9 → 186,9
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
arg_len = strlen(p);
p = p + arg_len + 1;
while (p < arg_buf + buf_size) {
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
206,11 → 206,11
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
while (p < arg_buf + buf_size) {
argv[n] = p;
arg_len = strlen(p);
p = p + arg_len + 1;
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
275,7 → 275,7
const char *cp;
/* Set the task name. */
cp = strrchr(pathname, '/');
cp = str_rchr(pathname, '/');
cp = (cp == NULL) ? pathname : (cp + 1);
task_set_name(cp);
/branches/network/uspace/srv/net/net/net_standalone.c
34,7 → 34,7
*
*/
 
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
 
91,7 → 91,7
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
if( str_lcmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
98,7 → 98,7
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
}else if( str_lcmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
// standalone ethernet
/branches/network/uspace/srv/net/net/net_bundle.c
123,7 → 123,7
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
if( str_lcmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
130,7 → 130,7
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
}else if( str_lcmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
// ethernet bundled in dp8390
/branches/network/uspace/srv/net/il/arp/arp.c
40,6 → 40,7
#include <mem.h>
#include <rwlock.h>
#include <stdio.h>
#include <string.h>
#include <task.h>
 
#include <ipc/ipc.h>
434,7 → 435,7
if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
return EINVAL;
}
if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
// not already upadted?
if( ! hw_source ){
hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length ));
/branches/network/uspace/srv/net/il/ip/ip.c
36,6 → 36,7
#include <async.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
112,7 → 113,7
}else{
ip_netif->ipv = DEFAULT_IPV;
}
ip_netif->dhcp = ! strncmp( configuration[ 1 ].value, "dhcp", 4 );
ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", 4 );
if( ip_netif->dhcp ){
// TODO dhcp
net_free_settings( configuration, data );
254,7 → 255,10
if( netif->arp ){
address.value = ( char * ) & netif->gateway;
address.length = CONVERT_SIZE( in_addr_t, char, 1 );
ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
sleep( 2 );
ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
}
printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
free( translation );
free( data );
/branches/network/uspace/srv/net/netif/dp8390/dp8390.c
205,6 → 205,58
}
 
/*===========================================================================*
* dp8390_dump *
*===========================================================================*/
void dp8390_dump( dpeth_t * dep )
{
// dpeth_t *dep;
int /*i,*/ isr;
 
// printf("\n");
// for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
// {
#if XXX
if (dep->de_mode == DEM_DISABLED)
printf("dp8390 port %d is disabled\n", i);
else if (dep->de_mode == DEM_SINK)
printf("dp8390 port %d is in sink mode\n", i);
#endif
 
if (dep->de_mode != DEM_ENABLED)
// continue;
return;
 
// printf("dp8390 statistics of port %d:\n", i);
 
printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
 
printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
 
printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
 
printf("collision :%8ld\t", dep->de_stat.ets_collision);
printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
 
printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
 
printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
 
isr= inb_reg0(dep, DP_ISR);
printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
inb_reg0(dep, DP_ISR), dep->de_flags);
// }
}
 
/*===========================================================================*
* do_init *
*===========================================================================*/
int do_init( dpeth_t * dep, int mode ){
588,10 → 640,11
/*===========================================================================*
* dp_check_ints *
*===========================================================================*/
void dp_check_ints(dep)
void dp_check_ints(dep, isr)
dpeth_t *dep;
int isr;
{
int isr, tsr;
int /*isr,*/ tsr;
int size, sendq_tail;
 
if (!(dep->de_flags & DEF_ENABLED))
599,7 → 652,7
 
for(;;)
{
isr = inb_reg0(dep, DP_ISR);
// isr = inb_reg0(dep, DP_ISR);
if (!isr)
break;
outb_reg0(dep, DP_ISR, isr);
720,6 → 773,7
dep->de_flags |= DEF_STOPPED;
break;
}
isr = inb_reg0(dep, DP_ISR);
}
if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
(DEF_READING|DEF_STOPPED))
1504,8 → 1558,8
if (r < 0)
panic("", "dp8390: send failed:", r);
dep->de_read_s = 0;
*/ dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
*/ dep->de_read_s = 0;
dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
}
 
/*===========================================================================*
/branches/network/uspace/srv/net/netif/dp8390/dp8390_drv.h
40,9 → 40,10
 
_PROTOTYPE( int do_init, (dpeth_t *dep, int mode) );
_PROTOTYPE( void do_stop, (dpeth_t *dep) );
_PROTOTYPE( void dp_check_ints, (dpeth_t *dep) );
_PROTOTYPE( void dp_check_ints, (dpeth_t *dep, int isr) );
int do_probe( dpeth_t * dep );
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int );
void dp8390_dump( dpeth_t * dep );
 
#endif
 
/branches/network/uspace/srv/net/netif/dp8390/dp8390_module.c
34,6 → 34,7
*/
 
#include <assert.h>
#include <async.h>
#include <ddi.h>
#include <errno.h>
#include <malloc.h>
70,14 → 71,14
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.value = 1,
.srcarg = 2
},
{ .cmd = CMD_PIO_WRITE_8,
/* { .cmd = CMD_PIO_WRITE_8,
.addr = NULL,
.srcarg = 2
.value = 0
},
{
*/ {
.cmd = CMD_ACCEPT
}
};
141,7 → 142,6
 
void irq_handler( ipc_callid_t iid, ipc_call_t * call )
{
// int irq;
device_ref device;
dpeth_t * dep;
packet_t received;
148,35 → 148,31
device_id_t device_id;
int phone;
 
// async_serialize_start();
device_id = IRQ_GET_DEVICE( call );
// printf( "device %d - irq %x\n", device_id, IPC_GET_ISR( call ));
rwlock_write_lock( & netif_globals.lock );
if( find_device( device_id, & device ) != EOK ){
rwlock_write_unlock( & netif_globals.lock );
// async_serialize_end()
return;
}
dep = ( dpeth_t * ) device->specific;
// printf( "dev %d, irq %x\n\n", device->device_id, IPC_GET_ISR( call ));
if ( dep->de_mode != DEM_ENABLED){
// continue;
rwlock_write_unlock( & netif_globals.lock );
// async_serialize_end()
return;
}
assert( dep->de_flags & DEF_ENABLED);
// irq= dep.de_irq;
// assert(irq >= 0 && irq < NR_IRQ_VECTORS);
// if ( dep->de_int_pending || 1)
// {
dep->de_int_pending= 0;
dp_check_ints( dep );
// do_int(dep);
/* r= sys_irqenable(&dep->de_hook);
if (r != OK)
{
panic("DP8390",
"unable enable interrupts", r);
}
*/// }
dep->de_int_pending= 0;
printf( "I%d -%d\n", device_id, IPC_GET_ISR( call ));
/* putchar( 'I' );
putchar( '0' + device_id );
putchar( '-' );
putchar( '0' + IPC_GET_ISR( call ) / 100 );
putchar( '0' + ( IPC_GET_ISR( call ) % 100 ) / 10 );
putchar( '0' + IPC_GET_ISR( call ) % 10 );
putchar( '\n' );
*/ dp_check_ints( dep, IPC_GET_ISR( call ));
if( dep->received_queue ){
received = dep->received_queue;
phone = device->nil_phone;
187,6 → 183,7
rwlock_write_unlock( & netif_globals.lock );
}
ipc_answer_0( iid, EOK );
// async_serialize_end()
}
 
int netif_probe_auto_message( void ){
236,12 → 233,13
dpeth_t * dep;
packet_t next;
 
ERROR_PROPAGATE( find_device( device_id, & device ));
dep = ( dpeth_t * ) device->specific;
// TODO remove debug dump:
uint8_t * data;
data = packet_get_data( packet );
printf( "Sending packet:\n\tid\t= %d\n\tlength\t= %d\n\tdata\t= %.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX\n\t\t%.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX\n", packet_get_id( packet ), packet_get_data_length( packet ), data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ], data[ 8 ], data[ 9 ], data[ 10 ], data[ 11 ], data[ 12 ], data[ 13 ], data[ 14 ], data[ 15 ], data[ 16 ], data[ 17 ], data[ 18 ], data[ 19 ], data[ 20 ], data[ 21 ], data[ 22 ], data[ 23 ], data[ 24 ], data[ 25 ], data[ 26 ], data[ 27 ], data[ 28 ], data[ 29 ], data[ 30 ], data[ 31 ], data[ 32 ], data[ 33 ], data[ 34 ], data[ 35 ], data[ 36 ], data[ 37 ], data[ 38 ], data[ 39 ], data[ 40 ], data[ 41 ], data[ 42 ], data[ 43 ], data[ 44 ], data[ 45 ], data[ 46 ], data[ 47 ], data[ 48 ], data[ 49 ], data[ 50 ], data[ 51 ], data[ 52 ], data[ 53 ], data[ 54 ], data[ 55 ], data[ 56 ], data[ 57 ], data[ 58 ], data[ 59 ] );
 
ERROR_PROPAGATE( find_device( device_id, & device ));
dep = ( dpeth_t * ) device->specific;
// process packet queue
do{
next = pq_detach( packet );
250,6 → 248,7
}
packet = next;
}while( packet );
dp8390_dump( dep );
return EOK;
}
 
/branches/network/uspace/srv/fb/serial_console.c
274,9 → 274,6
serial_goto(y, x);
 
for (i = 0; i < w; i++) {
unsigned int col = x + i;
unsigned int row = y + j;
 
field = &data[j * w + i];
 
a1 = &field->attrs;
304,12 → 301,9
 
wchar_t c;
int col, row, w, h;
int fgcolor;
int bgcolor;
int flags;
int style;
int i;
 
attrs_t cur_attr;
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
318,6 → 312,9
client_connected = 1;
ipc_answer_0(iid, EOK);
 
cur_attr.t = at_style;
cur_attr.a.s.style = STYLE_NORMAL;
/* Clear the terminal, set scrolling region
to 0 - height rows. */
388,23 → 385,28
retval = 0;
break;
case FB_SET_STYLE:
style = IPC_GET_ARG1(call);
serial_set_style(style);
cur_attr.t = at_style;
cur_attr.a.s.style = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
retval = 0;
break;
case FB_SET_COLOR:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
flags = IPC_GET_ARG3(call);
cur_attr.t = at_idx;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
cur_attr.a.i.flags = IPC_GET_ARG3(call);
serial_set_attrs(&cur_attr);
 
serial_set_idx(fgcolor, bgcolor, flags);
retval = 0;
break;
case FB_SET_RGB_COLOR:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
cur_attr.t = at_rgb;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
serial_set_rgb(fgcolor, bgcolor);
retval = 0;
break;
case FB_SCROLL:
424,6 → 426,18
serial_cursor_disable();
retval = 0;
break;
case FB_SCREEN_YIELD:
serial_sgr(SGR_RESET);
serial_puts("\033[2J");
serial_goto(0, 0);
serial_cursor_enable();
retval = 0;
break;
case FB_SCREEN_RECLAIM:
serial_clrscr();
serial_set_attrs(&cur_attr);
retval = 0;
break;
default:
retval = ENOENT;
}
/branches/network/uspace/srv/fb/fb.c
30,7 → 30,7
 
/**
* @defgroup fb Graphical framebuffer
* @brief HelenOS graphical framebuffer.
* @brief HelenOS graphical framebuffer.
* @ingroup fbs
* @{
*/
68,7 → 68,7
#define DEFAULT_BGCOLOR 0xf0f0f0
#define DEFAULT_FGCOLOR 0x000000
 
#define GLYPH_UNAVAIL '?'
#define GLYPH_UNAVAIL '?'
 
#define MAX_ANIM_LEN 8
#define MAX_ANIMATIONS 4
78,6 → 78,9
/** Function to render a pixel from a RGB value. */
typedef void (*rgb_conv_t)(void *, uint32_t);
 
/** Function to render a bit mask. */
typedef void (*mask_conv_t)(void *, bool);
 
/** Function to draw a glyph. */
typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
93,11 → 96,12
unsigned int pixelbytes;
unsigned int glyphbytes;
 
/** Pre-rendered mask for rendering glyphs. Specific for the visual. */
uint8_t *glyphs;
rgb_conv_t rgb_conv;
mask_conv_t mask_conv;
} screen;
 
/** Backbuffer character cell. */
121,12 → 125,12
/*
* Style and glyphs for text printing
*/
 
/** Current attributes. */
attr_rgb_t attr;
 
uint8_t *bgpixel;
 
/**
* Glyph drawing function for this viewport. Different viewports
* might use different drawing functions depending on whether their
170,23 → 174,23
static bool client_connected = false; /**< Allow only 1 connection */
 
static uint32_t color_table[16] = {
[COLOR_BLACK] = 0x000000,
[COLOR_BLUE] = 0x0000f0,
[COLOR_GREEN] = 0x00f000,
[COLOR_CYAN] = 0x00f0f0,
[COLOR_RED] = 0xf00000,
[COLOR_MAGENTA] = 0xf000f0,
[COLOR_YELLOW] = 0xf0f000,
[COLOR_WHITE] = 0xf0f0f0,
 
[8 + COLOR_BLACK] = 0x000000,
[8 + COLOR_BLUE] = 0x0000ff,
[8 + COLOR_GREEN] = 0x00ff00,
[8 + COLOR_CYAN] = 0x00ffff,
[8 + COLOR_RED] = 0xff0000,
[8 + COLOR_MAGENTA] = 0xff00ff,
[8 + COLOR_YELLOW] = 0xffff00,
[8 + COLOR_WHITE] = 0xffffff,
[COLOR_BLACK] = 0x000000,
[COLOR_BLUE] = 0x0000f0,
[COLOR_GREEN] = 0x00f000,
[COLOR_CYAN] = 0x00f0f0,
[COLOR_RED] = 0xf00000,
[COLOR_MAGENTA] = 0xf000f0,
[COLOR_YELLOW] = 0xf0f000,
[COLOR_WHITE] = 0xf0f0f0,
[8 + COLOR_BLACK] = 0x000000,
[8 + COLOR_BLUE] = 0x0000ff,
[8 + COLOR_GREEN] = 0x00ff00,
[8 + COLOR_CYAN] = 0x00ffff,
[8 + COLOR_RED] = 0xff0000,
[8 + COLOR_MAGENTA] = 0xff00ff,
[8 + COLOR_YELLOW] = 0xffff00,
[8 + COLOR_WHITE] = 0xffffff,
};
 
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a);
226,10 → 230,15
*/
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0xffffff;
*((uint32_t *) dst) = rgb & 0x00ffffff;
}
 
static void mask_0888(void *dst, bool mask)
{
*((uint32_t *) dst) = (mask ? 0x00ffffff : 0);
}
 
 
/** ABGR 8:8:8:8 conversion
*
*/
250,7 → 259,20
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void mask_888(void *dst, bool mask)
{
if (mask) {
((uint8_t *) dst)[0] = 0xff;
((uint8_t *) dst)[1] = 0xff;
((uint8_t *) dst)[2] = 0xff;
} else {
((uint8_t *) dst)[0] = 0;
((uint8_t *) dst)[1] = 0;
((uint8_t *) dst)[2] = 0;
}
}
 
 
/** BGR 8:8:8 conversion
*
*/
271,7 → 293,12
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
}
 
static void mask_555(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0x7fff : 0);
}
 
 
/** RGB 5:6:5 conversion
*
*/
281,7 → 308,12
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
}
 
static void mask_565(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0xffff : 0);
}
 
 
/** RGB 3:2:3
*
*/
291,34 → 323,44
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
}
 
static void mask_323(void *dst, bool mask)
{
*((uint8_t *) dst) = (mask ? 0xff : 0);
}
 
/** Draw a filled rectangle.
*
* @note Need real implementation that does not access VRAM twice.
*
*/
static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1,
unsigned int y1, uint32_t color)
{
unsigned int x, y;
unsigned int x;
unsigned int y;
unsigned int copy_bytes;
 
uint8_t *sp, *dp;
uint8_t *sp;
uint8_t *dp;
uint8_t cbuf[4];
 
if (y0 >= y1 || x0 >= x1) return;
if ((y0 >= y1) || (x0 >= x1))
return;
screen.rgb_conv(cbuf, color);
 
sp = &screen.fb_addr[FB_POS(x0, y0)];
dp = sp;
 
/* Draw the first line. */
for (x = x0; x < x1; x++) {
memcpy(dp, cbuf, screen.pixelbytes);
dp += screen.pixelbytes;
}
 
dp = sp + screen.scanline;
copy_bytes = (x1 - x0) * screen.pixelbytes;
 
/* Draw the remaining lines by copying. */
for (y = y0 + 1; y < y1; y++) {
memcpy(dp, sp, copy_bytes);
333,14 → 375,15
*/
static void vport_redraw(viewport_t *vport)
{
unsigned int row, col;
 
unsigned int row;
unsigned int col;
for (row = 0; row < vport->rows; row++) {
for (col = 0; col < vport->cols; col++) {
draw_vp_glyph(vport, false, col, row);
}
}
 
if (COL2X(vport->cols) < vport->width) {
draw_filled_rect(
vport->x + COL2X(vport->cols), vport->y,
347,7 → 390,7
vport->x + vport->width, vport->y + vport->height,
vport->attr.bg_color);
}
 
if (ROW2Y(vport->rows) < vport->height) {
draw_filled_rect(
vport->x, vport->y + ROW2Y(vport->rows),
359,8 → 402,8
static void backbuf_clear(bb_cell_t *backbuf, size_t len, uint32_t fg_color,
uint32_t bg_color)
{
unsigned i;
 
size_t i;
for (i = 0; i < len; i++) {
backbuf[i].glyph = 0;
backbuf[i].fg_color = fg_color;
388,17 → 431,20
*/
static void vport_scroll(viewport_t *vport, int lines)
{
unsigned int row, col;
unsigned int x, y;
unsigned int row;
unsigned int col;
unsigned int x;
unsigned int y;
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
bb_cell_t *bbp, *xbp;
 
bb_cell_t *bbp;
bb_cell_t *xbp;
/*
* Redraw.
*/
 
y = vport->y;
for (row = 0; row < vport->rows; row++) {
x = vport->x;
406,14 → 452,14
if ((row + lines >= 0) && (row + lines < vport->rows)) {
xbp = &vport->backbuf[BB_POS(vport, col, row + lines)];
bbp = &vport->backbuf[BB_POS(vport, col, row)];
 
glyph = xbp->glyph;
fg_color = xbp->fg_color;
bg_color = xbp->bg_color;
 
if (bbp->glyph == glyph &&
bbp->fg_color == xbp->fg_color &&
bbp->bg_color == xbp->bg_color) {
if ((bbp->glyph == glyph)
&& (bbp->fg_color == xbp->fg_color)
&& (bbp->bg_color == xbp->bg_color)) {
x += FONT_WIDTH;
continue;
}
422,7 → 468,7
fg_color = vport->attr.fg_color;
bg_color = vport->attr.bg_color;
}
 
(*vport->dglyph)(x, y, false, screen.glyphs, glyph,
fg_color, bg_color);
x += FONT_WIDTH;
429,11 → 475,11
}
y += FONT_SCANLINES;
}
 
/*
* Scroll backbuffer.
*/
 
if (lines > 0) {
memmove(vport->backbuf, vport->backbuf + vport->cols * lines,
vport->cols * (vport->rows - lines) * sizeof(bb_cell_t));
451,31 → 497,29
*
* Convert glyphs from device independent font
* description to current visual representation.
*
*/
static void render_glyphs(void)
{
unsigned int glyph;
 
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
unsigned int y;
 
for (y = 0; y < FONT_SCANLINES; y++) {
unsigned int x;
 
for (x = 0; x < FONT_WIDTH; x++) {
screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x)))
? 0xffffff : 0x000000);
 
screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x)))
? 0x000000 : 0xffffff);
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? true : false);
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? false : true);
}
}
}
}
 
 
/** Create new viewport
*
* @param x Origin of the viewport (x).
495,6 → 539,7
if (!viewports[i].initialized)
break;
}
if (i == MAX_VIEWPORTS)
return ELIMIT;
512,7 → 557,7
free(backbuf);
return ENOMEM;
}
 
backbuf_clear(backbuf, cols * rows, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR);
memset(bgpixel, 0, screen.pixelbytes);
528,24 → 573,23
viewports[i].attr.fg_color = DEFAULT_FGCOLOR;
viewports[i].bgpixel = bgpixel;
 
/*
* Conditions necessary to select aligned version:
* Conditions necessary to select aligned version:
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*/
if ((word_size % screen.pixelbytes) == 0 &&
(FONT_WIDTH * screen.pixelbytes) % word_size == 0 &&
(x * screen.pixelbytes) % word_size == 0 &&
screen.scanline % word_size == 0) {
 
if (((word_size % screen.pixelbytes) == 0)
&& ((FONT_WIDTH * screen.pixelbytes) % word_size == 0)
&& ((x * screen.pixelbytes) % word_size == 0)
&& (screen.scanline % word_size == 0)) {
viewports[i].dglyph = draw_glyph_aligned;
} else {
viewports[i].dglyph = draw_glyph_fallback;
}
 
viewports[i].cur_col = 0;
viewports[i].cur_row = 0;
viewports[i].cursor_active = false;
574,45 → 618,53
static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual)
{
unsigned int glyphsize;
uint8_t *glyphs;
switch (visual) {
case VISUAL_INDIRECT_8:
screen.rgb_conv = rgb_323;
screen.mask_conv = mask_323;
screen.pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
screen.rgb_conv = rgb_555;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
screen.rgb_conv = rgb_565;
screen.mask_conv = mask_565;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_BGR_8_8_8:
screen.rgb_conv = bgr_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
screen.rgb_conv = rgb_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_0_8_8_8:
screen.rgb_conv = bgr_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
default:
return false;
}
 
screen.fb_addr = (unsigned char *) addr;
screen.xres = xres;
screen.yres = yres;
620,15 → 672,15
screen.glyphscanline = FONT_WIDTH * screen.pixelbytes;
screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES;
 
glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
glyphs = (uint8_t *) malloc(glyphsize);
size_t glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
uint8_t *glyphs = (uint8_t *) malloc(glyphsize);
if (!glyphs)
return false;
memset(glyphs, 0, glyphsize);
screen.glyphs = glyphs;
 
render_glyphs();
/* Create first viewport */
651,46 → 703,47
* making it very fast. Most notably this version is not applicable at 24 bits
* per pixel.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
unsigned int i, yd;
unsigned long fg_buf, bg_buf;
unsigned long *maskp, *dp;
unsigned int i;
unsigned int yd;
unsigned long fg_buf;
unsigned long bg_buf;
unsigned long mask;
unsigned int ww, d_add;
 
/*
* Prepare a pair of words, one filled with foreground-color
* pattern and the other filled with background-color pattern.
*/
for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) {
screen.rgb_conv(&((uint8_t *)&fg_buf)[i * screen.pixelbytes],
screen.rgb_conv(&((uint8_t *) &fg_buf)[i * screen.pixelbytes],
fg_color);
screen.rgb_conv(&((uint8_t *)&bg_buf)[i * screen.pixelbytes],
screen.rgb_conv(&((uint8_t *) &bg_buf)[i * screen.pixelbytes],
bg_color);
}
 
/* Pointer to the current position in the mask. */
maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];
 
unsigned long *maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];
/* Pointer to the current position on the screen. */
dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];
 
unsigned long *dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];
/* Width of the character cell in words. */
ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);
 
unsigned int ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);
/* Offset to add when moving to another screen scanline. */
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
 
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/*
* Now process the cell scanline, combining foreground
700,7 → 753,7
mask = *maskp++;
*dp++ = (fg_buf & mask) | (bg_buf & ~mask);
}
 
/* Move to the beginning of the next scanline of the cell. */
dp = (unsigned long *) ((uint8_t *) dp + d_add);
}
711,23 → 764,26
* This version does not make use of the pre-rendered mask, it uses
* the font bitmap directly. It works always, but it is slower.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
unsigned int i, j, yd;
uint8_t fg_buf[4], bg_buf[4];
uint8_t *dp, *sp;
unsigned int d_add;
unsigned int i;
unsigned int j;
unsigned int yd;
uint8_t fg_buf[4];
uint8_t bg_buf[4];
uint8_t *sp;
uint8_t b;
 
/* Pre-render 1x the foreground and background color pixels. */
if (cursor) {
screen.rgb_conv(fg_buf, bg_color);
736,26 → 792,26
screen.rgb_conv(fg_buf, fg_color);
screen.rgb_conv(bg_buf, bg_color);
}
 
/* Pointer to the current position on the screen. */
dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];
 
uint8_t *dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];
/* Offset to add when moving to another screen scanline. */
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
 
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/* Byte containing bits of the glyph scanline. */
b = fb_font[glyph][yd];
 
for (i = 0; i < FONT_WIDTH; i++) {
/* Choose color based on the current bit. */
sp = (b & 0x80) ? fg_buf : bg_buf;
 
/* Copy the pixel. */
for (j = 0; j < screen.pixelbytes; j++) {
*dp++ = *sp++;
}
 
/* Move to the next bit. */
b = b << 1;
}
765,7 → 821,7
}
}
 
/** Draw glyph at specified position in viewport.
/** Draw glyph at specified position in viewport.
*
* @param vport Viewport identification
* @param cursor Draw glyph with cursor
778,15 → 834,11
{
unsigned int x = vport->x + COL2X(col);
unsigned int y = vport->y + ROW2Y(row);
 
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
glyph = vport->backbuf[BB_POS(vport, col, row)].glyph;
fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color;
bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color;
 
uint32_t glyph = vport->backbuf[BB_POS(vport, col, row)].glyph;
uint32_t fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color;
uint32_t bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color;
(*vport->dglyph)(x, y, cursor, screen.glyphs, glyph,
fg_color, bg_color);
}
839,17 → 891,17
static void draw_char(viewport_t *vport, wchar_t c, unsigned int col, unsigned int row)
{
bb_cell_t *bbp;
 
/* Do not hide cursor if we are going to overwrite it */
if ((vport->cursor_active) && (vport->cursor_shown) &&
((vport->cur_col != col) || (vport->cur_row != row)))
cursor_hide(vport);
 
bbp = &vport->backbuf[BB_POS(vport, col, row)];
bbp->glyph = fb_font_glyph(c);
bbp->fg_color = vport->attr.fg_color;
bbp->bg_color = vport->attr.bg_color;
 
draw_vp_glyph(vport, false, col, row);
vport->cur_col = col;
870,33 → 922,35
*
* @param vport Viewport id
* @param data Text data.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
*
*/
static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x,
unsigned int y, unsigned int w, unsigned int h)
{
unsigned int i, j;
unsigned int i;
unsigned int j;
bb_cell_t *bbp;
attrs_t *a;
attr_rgb_t rgb;
 
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
unsigned int col = x + i;
unsigned int row = y + j;
 
bbp = &vport->backbuf[BB_POS(vport, col, row)];
 
a = &data[j * w + i].attrs;
rgb_from_attr(&rgb, a);
 
bbp->glyph = fb_font_glyph(data[j * w + i].character);
bbp->fg_color = rgb.fg_color;
bbp->bg_color = rgb.bg_color;
 
draw_vp_glyph(vport, false, col, row);
}
}
1192,7 → 1246,7
counts = (counts + 1) % 8;
if (counts)
return;
 
for (i = 0; i < MAX_ANIMATIONS; i++) {
if ((!animations[i].animlen) || (!animations[i].initialized) ||
(!animations[i].enabled))
1659,6 → 1713,10
mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
retval = EOK;
break;
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = ENOENT;
}
/branches/network/uspace/srv/fb/ega.c
391,7 → 391,10
}
retval = 0;
break;
 
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = EINVAL;
}
/branches/network/uspace/srv/fs/tmpfs/tmpfs.h
52,6 → 52,7
 
typedef struct tmpfs_dentry {
fs_index_t index; /**< TMPFS node index. */
dev_handle_t dev_handle;/**< Device handle. */
link_t dh_link; /**< Dentries hash table link. */
struct tmpfs_dentry *sibling;
struct tmpfs_dentry *child;
66,6 → 67,8
 
extern libfs_ops_t tmpfs_libfs_ops;
 
extern bool tmpfs_init(void);
 
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
/branches/network/uspace/srv/fs/tmpfs/tmpfs_dump.c
177,7 → 177,7
goto error;
tag[5] = 0;
if (strcmp(tag, "TMPFS") != 0)
if (str_cmp(tag, "TMPFS") != 0)
goto error;
if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos,
/branches/network/uspace/srv/fs/tmpfs/tmpfs.c
127,7 → 127,12
int main(int argc, char **argv)
{
printf(NAME ": HelenOS TMPFS file system server\n");
 
if (!tmpfs_init()) {
printf(NAME ": failed to initialize TMPFS\n");
return -1;
}
 
int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
if (vfs_phone < EOK) {
printf(NAME ": Unable to connect to VFS\n");
140,7 → 145,7
printf(NAME ": Failed to register file system (%d)\n", rc);
return rc;
}
 
printf(NAME ": Accepting connections\n");
async_manager();
/* not reached */
/branches/network/uspace/srv/fs/tmpfs/tmpfs_ops.c
58,14 → 58,11
 
#define NAMES_BUCKETS 4
 
/*
* For now, we don't distinguish between different dev_handles/instances. All
* requests resolve to the only instance, rooted in the following variable.
*/
static tmpfs_dentry_t *root;
/** All root nodes have index 0. */
#define TMPFS_SOME_ROOT 0
/** Global counter for assigning node indices. Shared by all instances. */
fs_index_t tmpfs_next_index = 1;
 
#define TMPFS_DEV 0 /**< Dummy device handle for TMPFS */
 
/*
* Implementation of the libfs interface.
*/
102,7 → 99,7
 
static void *tmpfs_root_get(dev_handle_t dev_handle)
{
return root;
return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
}
 
static char tmpfs_plb_get_char(unsigned pos)
142,18 → 139,22
/** Hash table of all directory entries. */
hash_table_t dentries;
 
#define DENTRIES_KEY_INDEX 0
#define DENTRIES_KEY_DEV 1
 
/* Implementation of hash table interface for the dentries hash table. */
static hash_index_t dentries_hash(unsigned long *key)
static hash_index_t dentries_hash(unsigned long key[])
{
return *key % DENTRIES_BUCKETS;
return key[DENTRIES_KEY_INDEX] % DENTRIES_BUCKETS;
}
 
static int dentries_compare(unsigned long *key, hash_count_t keys,
static int dentries_compare(unsigned long key[], hash_count_t keys,
link_t *item)
{
tmpfs_dentry_t *dentry = hash_table_get_instance(item, tmpfs_dentry_t,
dh_link);
return dentry->index == *key;
return (dentry->index == key[DENTRIES_KEY_INDEX] &&
dentry->dev_handle == key[DENTRIES_KEY_DEV]);
}
 
static void dentries_remove_callback(link_t *item)
167,8 → 168,6
.remove_callback = dentries_remove_callback
};
 
fs_index_t tmpfs_next_index = 1;
 
typedef struct {
char *name;
tmpfs_dentry_t *parent;
215,6 → 214,7
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
{
dentry->index = 0;
dentry->dev_handle = 0;
dentry->sibling = NULL;
dentry->child = NULL;
dentry->type = TMPFS_NONE;
226,15 → 226,21
&names_ops);
}
 
static bool tmpfs_init(void)
bool tmpfs_init(void)
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 2, &dentries_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(TMPFS_DEV, L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return true;
}
 
static bool tmpfs_instance_init(dev_handle_t dev_handle)
{
tmpfs_dentry_t *root;
root = (tmpfs_dentry_t *) tmpfs_create_node(dev_handle, L_DIRECTORY);
if (!root)
return false;
}
root->lnkcnt = 0; /* FS root is not linked */
return true;
}
255,7 → 261,7
link_t *hlp = hash_table_find(&childp->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
return !strcmp(namep->name, component);
return !str_cmp(namep->name, component);
}
 
void *tmpfs_match(void *prnt, const char *component)
272,8 → 278,11
void *
tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
{
unsigned long key = index;
link_t *lnk = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
link_t *lnk = hash_table_find(&dentries, key);
if (!lnk)
return NULL;
return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link);
296,7 → 305,11
free(node);
return NULL;
}
node->index = tmpfs_next_index++;
if (!tmpfs_root_get(dev_handle))
node->index = TMPFS_SOME_ROOT;
else
node->index = tmpfs_next_index++;
node->dev_handle = dev_handle;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
else
303,8 → 316,11
node->type = TMPFS_FILE;
 
/* Insert the new node into the dentry hash table. */
unsigned long key = node->index;
hash_table_insert(&dentries, &key, &node->dh_link);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = node->index,
[DENTRIES_KEY_DEV] = node->dev_handle
};
hash_table_insert(&dentries, key, &node->dh_link);
return (void *) node;
}
 
319,13 → 335,13
if (!namep)
return ENOMEM;
tmpfs_name_initialize(namep);
size_t len = strlen(nm);
namep->name = malloc(len + 1);
size_t size = str_size(nm);
namep->name = malloc(size + 1);
if (!namep->name) {
free(namep);
return ENOMEM;
}
strcpy(namep->name, nm);
str_cpy(namep->name, size + 1, nm);
namep->parent = parentp;
childp->lnkcnt++;
384,8 → 400,11
assert(!dentry->child);
assert(!dentry->sibling);
 
unsigned long key = dentry->index;
hash_table_remove(&dentries, &key, 1);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = dentry->index,
[DENTRIES_KEY_DEV] = dentry->dev_handle
};
hash_table_remove(&dentries, key, 2);
 
hash_table_destroy(&dentry->names);
 
399,13 → 418,36
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 
/* Initialize TMPFS. */
if (!root && !tmpfs_init()) {
/* accept the mount options */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *opts = malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(opts);
return;
}
opts[size] = '\0';
 
if (dev_handle >= 0) {
/* Initialize TMPFS instance. */
if (!tmpfs_instance_init(dev_handle)) {
ipc_answer_0(rid, ENOMEM);
return;
}
 
tmpfs_dentry_t *root = tmpfs_root_get(dev_handle);
if (str_cmp(opts, "restore") == 0) {
if (tmpfs_restore(dev_handle))
ipc_answer_3(rid, EOK, root->index, root->size,
root->lnkcnt);
441,8 → 483,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle,
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
454,8 → 499,8
* Receive the read request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_read_receive(&callid, &len)) {
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
463,7 → 508,7
 
size_t bytes;
if (dentry->type == TMPFS_FILE) {
bytes = max(0, min(dentry->size - pos, len));
bytes = max(0, min(dentry->size - pos, size));
(void) ipc_data_read_finalize(callid, dentry->data + pos,
bytes);
} else {
494,7 → 539,7
link);
 
(void) ipc_data_read_finalize(callid, namep->name,
strlen(namep->name) + 1);
str_size(namep->name) + 1);
bytes = 1;
}
 
514,8 → 559,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
527,8 → 575,8
* Receive the write request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_write_receive(&callid, &len)) {
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
537,13 → 585,13
/*
* Check whether the file needs to grow.
*/
if (pos + len <= dentry->size) {
if (pos + size <= dentry->size) {
/* The file size is not changing. */
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
(void) ipc_data_write_finalize(callid, dentry->data + pos, size);
ipc_answer_2(rid, EOK, size, dentry->size);
return;
}
size_t delta = (pos + len) - dentry->size;
size_t delta = (pos + size) - dentry->size;
/*
* At this point, we are deliberately extremely straightforward and
* simply realloc the contents of the file on every write that grows the
561,8 → 609,8
memset(newdata + dentry->size, 0, delta);
dentry->size += delta;
dentry->data = newdata;
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
(void) ipc_data_write_finalize(callid, dentry->data + pos, size);
ipc_answer_2(rid, EOK, size, dentry->size);
}
 
void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
575,8 → 623,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
610,8 → 661,11
int rc;
 
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
/branches/network/uspace/srv/fs/fat/fat_dentry.c
62,15 → 62,18
int fat_dentry_namecmp(char *name, const char *component)
{
int rc;
size_t size;
 
if (!(rc = stricmp(name, component)))
return rc;
if (!strchr(name, '.')) {
if (!str_chr(name, '.')) {
/*
* There is no '.' in the name, so we know that there is enough
* space for appending an extra '.' to name.
*/
name[strlen(name)] = '.';
name[strlen(name) + 1] = '\0';
size = str_size(name);
name[size] = '.';
name[size + 1] = '\0';
rc = stricmp(name, component);
}
return rc;
/branches/network/uspace/srv/fs/fat/fat_ops.c
487,10 → 487,10
b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE);
d = (fat_dentry_t *)b->data;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
strcmp(d->name, FAT_NAME_DOT) == 0) {
str_cmp(d->name, FAT_NAME_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
strcpy(d->name, FAT_NAME_DOT);
strcpy(d->ext, FAT_EXT_PAD);
str_cpy(d->name, 8, FAT_NAME_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = host2uint16_t_le(childp->firstc);
/* TODO: initialize also the date/time members. */
497,10 → 497,10
}
d++;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
strcmp(d->name, FAT_NAME_DOT_DOT) == 0) {
str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
strcpy(d->name, FAT_NAME_DOT_DOT);
strcpy(d->ext, FAT_EXT_PAD);
str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
host2uint16_t_le(FAT_CLST_RES0) :
755,6 → 755,28
uint16_t rde;
int rc;
 
/* accept the mount options */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *opts = malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(opts);
return;
}
opts[size] = '\0';
 
/* initialize libblock */
rc = block_init(dev_handle, BS_SIZE);
if (rc != EOK) {
937,7 → 959,7
ipc_answer_1(rid, ENOENT, 0);
return;
hit:
(void) ipc_data_read_finalize(callid, name, strlen(name) + 1);
(void) ipc_data_read_finalize(callid, name, str_size(name) + 1);
bytes = (pos - spos) + 1;
}
 
/branches/network/uspace/srv/pci/libpci/names.c
103,7 → 103,7
u32 id34 = id_pair(id3, id4);
unsigned int h = id_hash(cat, id12, id34);
struct id_entry *n = a->id_hash[h];
int len = strlen((char *) text);
int len = str_size((char *) text);
 
while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
n = n->next;
/branches/network/uspace/srv/devmap/devmap.c
563,7 → 563,7
ipc_answer_0(iid, EOK);
size_t name_size = strlen(device->name);
size_t name_size = str_size(device->name);
/* FIXME:
* We have no channel from DEVMAP to client, therefore
/branches/network/uspace/srv/vfs/vfs_ops.c
60,6 → 60,7
link_t link;
char *fs_name; /**< File system name */
char *mp; /**< Mount point */
char *opts; /**< Mount options. */
ipc_callid_t callid; /**< Call ID waiting for the mount */
ipc_callid_t rid; /**< Request ID */
dev_handle_t dev_handle; /**< Device handle */
80,18 → 81,21
};
 
static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle,
fs_handle_t fs_handle, char *mp)
fs_handle_t fs_handle, char *mp, char *opts)
{
/* Resolve the path to the mountpoint. */
vfs_lookup_res_t mp_res;
vfs_node_t *mp_node = NULL;
int rc;
ipcarg_t rc;
int phone;
aid_t msg;
ipc_call_t answer;
 
/* Resolve the path to the mountpoint. */
futex_down(&rootfs_futex);
if (rootfs.fs_handle) {
/* We already have the root FS. */
rwlock_write_lock(&namespace_rwlock);
if ((strlen(mp) == 1) && (mp[0] == '/')) {
if (str_cmp(mp, "/") == 0) {
/* Trying to mount root FS over root FS */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
124,12 → 128,12
rwlock_write_unlock(&namespace_rwlock);
} else {
/* We still don't have the root file system mounted. */
if ((strlen(mp) == 1) && (mp[0] == '/')) {
if (str_cmp(mp, "/") == 0) {
vfs_lookup_res_t mr_res;
vfs_node_t *mr_node;
ipcarg_t rindex;
ipcarg_t rsize;
ipcarg_t rlnkcnt;
fs_index_t rindex;
size_t rsize;
unsigned rlnkcnt;
/*
* For this simple, but important case,
138,8 → 142,19
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
rc = async_req_1_3(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt);
msg = async_send_1(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts,
str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
futex_up(&rootfs_futex);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc != EOK) {
147,12 → 162,16
ipc_answer_0(rid, rc);
return;
}
 
rindex = (fs_index_t) IPC_GET_ARG1(answer);
rsize = (size_t) IPC_GET_ARG2(answer);
rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
mr_res.triplet.fs_handle = fs_handle;
mr_res.triplet.dev_handle = dev_handle;
mr_res.triplet.index = (fs_index_t) rindex;
mr_res.size = (size_t) rsize;
mr_res.lnkcnt = (unsigned) rlnkcnt;
mr_res.triplet.index = rindex;
mr_res.size = rsize;
mr_res.lnkcnt = rlnkcnt;
mr_res.type = VFS_NODE_DIRECTORY;
rootfs.fs_handle = fs_handle;
183,11 → 202,23
*/
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
rc = async_req_4_0(phone, VFS_MOUNT,
msg = async_send_4(phone, VFS_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) fs_handle,
(ipcarg_t) dev_handle);
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc != EOK) {
216,10 → 247,12
ipc_answer_0(pr->callid, EOK);
/* Do the mount */
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp);
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp,
pr->opts);
free(pr->fs_name);
free(pr->mp);
free(pr->opts);
list_remove(cur);
free(pr);
goto loop;
272,12 → 305,47
/* Deliver the mount point. */
ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);
if (retval != EOK) {
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, retval);
free(mp);
return;
}
mp[size] = '\0';
/* Now we expect to receive the mount options. */
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Check the offered options size. */
if (size < 0 || size > MAX_MNTOPTS_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Allocate buffer for the mount options. */
char *opts = (char *) malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
return;
}
 
/* Deliver the mount options. */
retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(mp);
free(opts);
return;
}
opts[size] = '\0';
/*
* Now, we expect the client to send us data with the name of the file
* system.
286,6 → 354,7
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
297,6 → 366,7
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
306,8 → 376,9
char *fs_name = (char *) malloc(size + 1);
if (fs_name == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, ENOMEM);
free(mp);
free(opts);
return;
}
314,14 → 385,30
/* Deliver the file system name. */
retval = ipc_data_write_finalize(callid, fs_name, size);
if (retval != EOK) {
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, retval);
free(mp);
free(opts);
free(fs_name);
return;
}
fs_name[size] = '\0';
 
/*
* Wait for IPC_M_PING so that we can return an error if we don't know
* fs_name.
*/
ipc_call_t data;
callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_PING) {
ipc_answer_0(callid, ENOTSUP);
ipc_answer_0(rid, ENOTSUP);
free(mp);
free(opts);
free(fs_name);
return;
}
 
/*
* Check if we know a file system with the same name as is in fs_name.
* This will also give us its file system handle.
*/
328,18 → 415,22
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true);
if (!fs_handle) {
if (flags & IPC_FLAG_BLOCKING) {
pending_req_t *pr;
 
/* Blocking mount, add to pending list */
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t));
pr = (pending_req_t *) malloc(sizeof(pending_req_t));
if (!pr) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
free(fs_name);
free(opts);
return;
}
pr->fs_name = fs_name;
pr->mp = mp;
pr->opts = opts;
pr->callid = callid;
pr->rid = rid;
pr->dev_handle = dev_handle;
352,6 → 443,7
ipc_answer_0(rid, ENOENT);
free(mp);
free(fs_name);
free(opts);
return;
}
359,9 → 451,10
ipc_answer_0(callid, EOK);
/* Do the mount */
vfs_mount_internal(rid, dev_handle, fs_handle, mp);
vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts);
free(mp);
free(fs_name);
free(opts);
}
 
void vfs_open(ipc_callid_t rid, ipc_call_t *request)
804,37 → 897,37
 
void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
size_t olen, nlen;
ipc_callid_t callid;
int rc;
 
/* Retrieve the old path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &olen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *old = malloc(len + 1);
char *old = malloc(olen + 1);
if (!old) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
if ((rc = ipc_data_write_finalize(callid, old, len))) {
if ((rc = ipc_data_write_finalize(callid, old, olen))) {
ipc_answer_0(rid, rc);
free(old);
return;
}
old[len] = '\0';
old[olen] = '\0';
/* Retrieve the new path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &nlen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(old);
return;
}
char *new = malloc(len + 1);
char *new = malloc(nlen + 1);
if (!new) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
841,16 → 934,16
free(old);
return;
}
if ((rc = ipc_data_write_finalize(callid, new, len))) {
if ((rc = ipc_data_write_finalize(callid, new, nlen))) {
ipc_answer_0(rid, rc);
free(old);
free(new);
return;
}
new[len] = '\0';
new[nlen] = '\0';
 
char *oldc = canonify(old, &len);
char *newc = canonify(new, NULL);
char *oldc = canonify(old, &olen);
char *newc = canonify(new, &nlen);
if (!oldc || !newc) {
ipc_answer_0(rid, EINVAL);
free(old);
857,7 → 950,9
free(new);
return;
}
if (!strncmp(newc, oldc, len)) {
oldc[olen] = '\0';
newc[nlen] = '\0';
if (!str_lcmp(newc, oldc, str_length(oldc))) {
/* oldc is a prefix of newc */
ipc_answer_0(rid, EINVAL);
free(old);
/branches/network/uspace/srv/vfs/vfs_register.c
376,8 → 376,7
link_t *cur;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
if (strncmp(fs->vfs_info.name, name,
sizeof(fs->vfs_info.name)) == 0) {
if (str_cmp(fs->vfs_info.name, name) == 0) {
handle = fs->fs_handle;
break;
}
/branches/network/uspace/srv/vfs/vfs.h
254,6 → 254,8
extern uint8_t *plb; /**< Path Lookup Buffer */
extern link_t plb_head; /**< List of active PLB entries. */
 
#define MAX_MNTOPTS_LEN 256
 
/** Holding this rwlock prevents changes in file system namespace. */
extern rwlock_t namespace_rwlock;
 
/branches/network/HelenOS.config
332,7 → 332,7
% Input device class
@ "generic" Keyboard or serial line
@ "none" No input device
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
378,6 → 378,9
% Support for GXemul printer
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32] CONFIG_ARM_PRN (y/n)
 
% Support for VIA CUDA controller
! [CONFIG_HID_IN=generic&PLATFORM=ppc32] CONFIG_VIA_CUDA (y/n)
 
% Support for NS16550 controller
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic] CONFIG_NS16550 (y/n)
 
385,16 → 388,19
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
% Support for Z8530 controller
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboardl)&PLATFORM=sparc64&MACHINE=generic] CONFIG_Z8530 (y/n)
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic] CONFIG_Z8530 (y/n)
 
% Support for Serengeti console
! [(CONFIG_HID_IN=generic|CONFIG_HID_OUT=generic)&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN (y/n)
! [CONFIG_HID_OUT=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_PRN (y/n)
 
% Support for Serengeti keyboard
! [CONFIG_HID_IN=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_KBD (y/n)
 
% i8042 controller support
! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
 
% Sun keyboard support
! [PLATFORM=sparc64&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
 
% Dummy serial line input
! [CONFIG_MIPS_KBD=y|CONFIG_ARM_KBD=y] CONFIG_DSRLNIN (y)
403,7 → 409,7
! [CONFIG_MIPS_PRN=y|CONFIG_ARM_PRN=y] CONFIG_DSRLNOUT (y)
 
% Serial line input module
! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)] CONFIG_SRLN (y)
! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)] CONFIG_SRLN (y)
 
% EGA support
! [CONFIG_HID_OUT=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_EGA (y/n)
/branches/network/boot/arch/sparc64/Makefile.inc
51,7 → 51,7
ifeq ($(CONFIG_RD_EXTERNAL),y)
cp arch/$(BARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img
endif
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $(BASE)/image.iso $(TMP)/
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $@ $(TMP)/
 
depend:
-rm arch/$(BARCH)/loader/image.boot
/branches/network/boot/arch/sparc64/loader/asm.S
40,7 → 40,7
.global jump_to_kernel
 
halt:
b halt
ba %xcc, halt
nop
memcpy:
116,7 → 116,7
set subarchitecture, %g2
ldub [%g2], %g2
cmp %g2, 3
be 1f
be %xcc, 1f
nop
0:
call icache_flush
/branches/network/boot/arch/sparc64/loader/boot.S
43,7 → 43,7
 
.global start
start:
b 1f
ba %xcc, 1f
nop
 
/*
83,7 → 83,7
call ofw_init ! initialize OpenFirmware
stx %o4, [%l0]
b bootstrap
ba %xcc, bootstrap
nop
 
.align STACK_ALIGNMENT
/branches/network/boot/arch/ppc32/Makefile.inc
26,17 → 26,27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
build: $(BASE)/image.boot
TMP = distroot
 
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
build: $(BASE)/image.iso
 
$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot
mkdir -p $(TMP)/boot
mkdir -p $(TMP)/ppc
cp arch/$(BARCH)/loader/image.boot $(TMP)/boot/image.boot
cp arch/$(BARCH)/yaboot/ofboot.b $(TMP)/boot/ofboot.b
cp arch/$(BARCH)/yaboot/bootinfo.txt $(TMP)/ppc/bootinfo.txt
cp arch/$(BARCH)/yaboot/yaboot $(TMP)/boot/yaboot
cp arch/$(BARCH)/yaboot/yaboot.conf $(TMP)/boot/yaboot.conf
mkisofs -hfs -part -map arch/$(BARCH)/yaboot/maps -no-desktop -hfs-volid "HelenOS" -hfs-bless $(TMP)/boot -r -o $@ $(TMP)/
 
depend:
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(BARCH)/loader/image.boot:
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean: generic_clean
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -f $(BASE)/image.boot
$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/network/boot/arch/ppc32/loader/ofwarch.c
52,7 → 52,8
{
char device_name[BUF_SIZE];
if (ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
if ((ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
&& (ofw_get_property(ofw_aliases, "mac-io", device_name, sizeof(device_name)) <= 0))
return false;
phandle device = ofw_find_device(device_name);
/branches/network/boot/arch/ppc32/yaboot/yaboot.conf
0,0 → 1,5
device=cd:
timeout=0
 
image=/boot/image.boot
label=HelenOS
/branches/network/boot/arch/ppc32/yaboot/ofboot.b
0,0 → 1,13
<CHRP-BOOT>
<COMPATIBLE>
MacRISC
</COMPATIBLE>
<DESCRIPTION>
HelenOS
</DESCRIPTION>
<BOOT-SCRIPT>
" screen" output
load-base release-load-area
boot cd:,\boot\yaboot
</BOOT-SCRIPT>
</CHRP-BOOT>
/branches/network/boot/arch/ppc32/yaboot/bootinfo.txt
0,0 → 1,5
<chrp-boot>
<description>HelenOS</description>
<os-name>HelenOS</os-name>
<boot-script>boot cd:,\boot\yaboot</boot-script>
</chrp-boot>
/branches/network/boot/arch/ppc32/yaboot/COPYING
0,0 → 1,340
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/branches/network/boot/arch/ppc32/yaboot/README
0,0 → 1,5
For licensing terms of Yaboot boot loader see the file COPYING contained
in this directory. Full version of Yaboot, including its source code,
can be downloaded from Yaboot's project page:
 
http://yaboot.ozlabs.org/
/branches/network/boot/arch/ppc32/yaboot/maps
0,0 → 1,6
# EXTN XLate CREATOR TYPE Comment
.b Raw 'UNIX' 'tbxi' "bootstrap"
yaboot Raw 'UNIX' 'boot' "bootstrap"
image.boot Raw 'UNIX' 'boot' "kernel"
.conf Raw 'UNIX' 'conf' "bootstrap"
* Raw 'UNIX 'UNIX' "unix"
/branches/network/boot/arch/ppc32/yaboot/yaboot
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/network/boot/arch/amd64/Makefile.inc
26,6 → 26,8
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
TMP = distroot
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
58,17 → 60,17
build: $(BASE)/image.iso
 
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p arch/$(BARCH)/iso/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/iso/boot/grub/
mkdir -p $(TMP)/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
ifneq ($(RDFMT),tmpfs)
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(BARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" > $(TMP)/boot/grub/menu.lst
endif
ifneq ($(RDFMT),fat)
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" >arch/$(BARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" > $(TMP)/boot/grub/menu.lst
endif
cp $(KERNELDIR)/kernel.bin arch/$(BARCH)/iso/boot/
cp $(KERNELDIR)/kernel.bin $(TMP)/boot/
for task in $(INIT_TASKS) ; do \
cp $$task arch/$(BARCH)/iso/boot/ ; \
cp $$task $(TMP)/boot/ ; \
done
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
77,14 → 79,14
cp $$file $(USPACEDIR)/dist/app/ ; \
done
ifeq ($(RDFMT),tmpfs)
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
ifeq ($(RDFMT),fat)
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
$(BASE)/tools/mkhord.py 4096 arch/$(BARCH)/iso/boot/initrd.fs arch/$(BARCH)/iso/boot/initrd.img
rm arch/$(BARCH)/iso/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(BARCH)/iso/
$(BASE)/tools/mkhord.py 4096 $(TMP)/boot/initrd.fs $(TMP)/boot/initrd.img
rm $(TMP)/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ $(TMP)/
 
clean:
-for file in $(RD_SRVS) ; do \
93,5 → 95,5
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -fr arch/$(BARCH)/iso
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/network/boot/arch/ia32/grub/stage2_eltorito
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/network/boot/arch/ia32/grub/COPYING
File deleted
/branches/network/boot/arch/ia32/grub/README
File deleted
/branches/network/boot/arch/ia32/grub/menu.lst
File deleted
/branches/network/boot/arch/ia32/Makefile.inc
26,6 → 26,8
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
TMP = distroot
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
32,7 → 34,7
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
endif
41,16 → 43,17
endif
 
RD_SRVS = \
$(USPACEDIR)/srv/net/net/net \
$(USPACEDIR)/srv/net/net/start/netstart \
$(USPACEDIR)/srv/net/netif/lo/lo \
$(USPACEDIR)/srv/net/netif/dp8390/dp8390 \
$(USPACEDIR)/srv/net/nil/eth/eth \
$(USPACEDIR)/srv/pci/pci \
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/net/net/net \
$(USPACEDIR)/srv/net/net/start/netstart \
$(USPACEDIR)/srv/net/netif/lo/lo \
$(USPACEDIR)/srv/net/netif/dp8390/dp8390 \
$(USPACEDIR)/srv/net/nil/eth/eth
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
 
RD_APPS = \
$(USPACEDIR)/app/tetris/tetris \
72,17 → 75,17
build: $(BASE)/image.iso
 
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p arch/$(BARCH)/iso/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/iso/boot/grub/
mkdir -p $(TMP)/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
ifneq ($(RDFMT),tmpfs)
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(BARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" > $(TMP)/boot/grub/menu.lst
endif
ifneq ($(RDFMT),fat)
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" >arch/$(BARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" > $(TMP)/boot/grub/menu.lst
endif
cp $(KERNELDIR)/kernel.bin arch/$(BARCH)/iso/boot/
cp $(KERNELDIR)/kernel.bin $(TMP)/boot/
for task in $(INIT_TASKS) ; do \
cp $$task arch/$(BARCH)/iso/boot/ ; \
cp $$task $(TMP)/boot/ ; \
done
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
91,14 → 94,14
cp $$file $(USPACEDIR)/dist/app/ ; \
done
ifeq ($(RDFMT),tmpfs)
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
ifeq ($(RDFMT),fat)
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
$(BASE)/tools/mkhord.py 4096 arch/$(BARCH)/iso/boot/initrd.fs arch/$(BARCH)/iso/boot/initrd.img
rm arch/$(BARCH)/iso/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(BARCH)/iso/
$(BASE)/tools/mkhord.py 4096 $(TMP)/boot/initrd.fs $(TMP)/boot/initrd.img
rm $(TMP)/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ $(TMP)/
 
clean:
-for file in $(RD_SRVS) ; do \
107,5 → 110,5
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -fr arch/$(BARCH)/iso
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/network/defaults/ppc32/output
1,0 → 0,0
image.boot
image.iso
/branches/network/defaults/ppc32/Makefile.config
25,6 → 25,9
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic