Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4717 → Rev 4718

/branches/network/kernel/genarch/include/kbrd/scanc_mac.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* 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
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#ifndef KERN_SCANC_MAC_H_
#define KERN_SCANC_MAC_H_
 
#define SC_LSHIFT 0x38
#define SC_RSHIFT 0xfd /* Not used */
#define SC_CAPSLOCK 0xfe /* Not used */
#define SC_SCAN_ESCAPE 0xff /* Not used */
 
#endif
 
/** @}
*/
/branches/network/kernel/genarch/include/kbrd/scanc_pl050.h
0,0 → 1,58
/*
* Copyright (c) 2009 Vineeth Pillai
* 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
* @brief Scan codes for pl050 keyboards.
*/
 
#ifndef KERN_SCANC_PL050_H_
#define KERN_SCANC_PL050_H_
 
#define SC_SCAN_ESCAPE 0xE0
#define SC_ESC 0x76
#define SC_BACKSPACE 0x66
#define SC_LSHIFT 0x12
#define SC_RSHIFT 0x59
#define SC_CAPSLOCK 0x58
#define SC_SPEC_ESCAPE 0xe0
#define SC_LEFTARR 0x6b
#define SC_RIGHTARR 0x74
#define SC_UPARR 0x75
#define SC_DOWNARR 0x72
#define SC_DELETE 0x70
#define SC_HOME 0x6C
#define SC_END 0x69
 
#endif
 
/** @}
*/
/branches/network/kernel/genarch/include/fb/visuals.h
35,17 → 35,20
#ifndef KERN_VISUALS_H_
#define KERN_VISUALS_H_
 
#define VISUAL_INDIRECT_8 0
typedef enum {
VISUAL_INDIRECT_8,
VISUAL_RGB_5_5_5_LE,
VISUAL_RGB_5_5_5_BE,
VISUAL_RGB_5_6_5_LE,
VISUAL_RGB_5_6_5_BE,
VISUAL_BGR_8_8_8,
VISUAL_BGR_0_8_8_8,
VISUAL_BGR_8_8_8_0,
VISUAL_RGB_8_8_8,
VISUAL_RGB_0_8_8_8,
VISUAL_RGB_8_8_8_0
} visual_t;
 
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
 
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8 7
 
#endif
 
/** @}
/branches/network/kernel/genarch/include/drivers/pl050/pl050.h
0,0 → 1,105
/*
* Copyright (c) 2009 Vineeth Pillai
* 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
* @brief Describes the pl050 keyboard/mouse controller
*/
 
/**
* This file implements pl050 specific functions for keyboard and mouse
*/
 
#ifndef KERN_genarch_PL050_H
#define KERN_genarch_PL050_H
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
 
/*
* pl050 register offsets from the base address
*/
#define PL050_CR 0x00
#define PL050_STAT 0x04
#define PL050_DATA 0x08
#define PL050_CLOCKDIV 0x0C
#define PL050_INTRSTAT 0x10
 
/*
* Control Register Bits
*/
#define PL050_CR_TYPE (1 << 5) /* Type 0: PS2/AT mode, 1: No Line control bit mode */
#define PL050_CR_RXINTR (1 << 4) /* Recieve Interrupt Enable */
#define PL050_CR_TXINTR (1 << 3) /* Transmit Interrupt Enable */
#define PL050_CR_INTR (1 << 2) /* Interrupt Enable */
#define PL050_CR_FKMID (1 << 1) /* Force KMI Data Low */
#define PL050_CR_FKMIC 1 /* Force KMI Clock Low */
 
/*
* Status register bits
*/
#define PL050_STAT_TXEMPTY (1 << 6) /* 1: Transmit register empty */
#define PL050_STAT_TXBUSY (1 << 5) /* 1: Busy, sending data */
#define PL050_STAT_RXFULL (1 << 4) /* 1: register Full */
#define PL050_STAT_RXBUSY (1 << 3) /* 1: Busy, recieving Data */
#define PL050_STAT_RXPARITY (1 << 2) /* odd parity of the last bit recieved */
#define PL050_STAT_KMIC (1 << 1) /* status of KMICLKIN */
#define PL050_STAT_KMID 1 /* status of KMIDATAIN */
 
/*
* Interrupt status register bits.
*/
#define PL050_TX_INTRSTAT (1 << 1) /* Transmit intr asserted */
#define PL050_RX_INTRSTAT 1 /* Recieve intr asserted */
 
typedef struct {
ioport8_t *base;
ioport8_t *data;
ioport8_t *status;
ioport8_t *ctrl;
} pl050_t;
 
typedef struct {
irq_t irq;
pl050_t *pl050;
indev_t *kbrdin;
} pl050_instance_t;
 
extern pl050_instance_t *pl050_init(pl050_t *, inr_t);
extern void pl050_wire(pl050_instance_t *, indev_t *);
 
 
#endif
 
/** @}
*/
/branches/network/kernel/genarch/include/drivers/via-cuda/cuda.h
38,14 → 38,80
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <synch/spinlock.h>
 
typedef struct {
uint8_t b;
uint8_t pad0[0x1ff];
 
uint8_t a;
uint8_t pad1[0x1ff];
 
uint8_t dirb;
uint8_t pad2[0x1ff];
 
uint8_t dira;
uint8_t pad3[0x1ff];
 
uint8_t t1cl;
uint8_t pad4[0x1ff];
 
uint8_t t1ch;
uint8_t pad5[0x1ff];
 
uint8_t t1ll;
uint8_t pad6[0x1ff];
 
uint8_t t1lh;
uint8_t pad7[0x1ff];
 
uint8_t t2cl;
uint8_t pad8[0x1ff];
 
uint8_t t2ch;
uint8_t pad9[0x1ff];
 
uint8_t sr;
uint8_t pad10[0x1ff];
 
uint8_t acr;
uint8_t pad11[0x1ff];
 
uint8_t pcr;
uint8_t pad12[0x1ff];
 
uint8_t ifr;
uint8_t pad13[0x1ff];
 
uint8_t ier;
uint8_t pad14[0x1ff];
 
uint8_t anh;
uint8_t pad15[0x1ff];
} cuda_t;
 
enum {
CUDA_RCV_BUF_SIZE = 5
};
 
enum cuda_xfer_state {
cx_listen,
cx_receive,
cx_rcv_end,
cx_send_start,
cx_send
};
 
typedef struct {
irq_t irq;
cuda_t *cuda;
indev_t *kbrdin;
uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
uint8_t snd_buf[CUDA_RCV_BUF_SIZE];
size_t bidx;
size_t snd_bytes;
enum cuda_xfer_state xstate;
SPINLOCK_DECLARE(dev_lock);
} cuda_instance_t;
 
extern cuda_instance_t *cuda_init(cuda_t *, inr_t, cir_t, void *);
/branches/network/kernel/genarch/Makefile.inc
110,6 → 110,18
genarch/src/kbrd/scanc_sun.c
endif
 
ifeq ($(CONFIG_PL050),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd_pl050.c \
genarch/src/kbrd/scanc_pl050.c
endif
 
ifeq ($(CONFIG_MAC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_mac.c
endif
 
ifeq ($(CONFIG_SRLN),y)
GENARCH_SOURCES += \
genarch/src/srln/srln.c
/branches/network/kernel/genarch/src/kbrd/kbrd.c
45,6 → 45,10
#include <genarch/kbrd/scanc_sun.h>
#endif
 
#ifdef CONFIG_MAC_KBD
#include <genarch/kbrd/scanc_mac.h>
#endif
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
/branches/network/kernel/genarch/src/kbrd/kbrd_pl050.c
0,0 → 1,209
/*
* Copyright (c) 2009 Vineeth Pillai
* 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
* @brief pl050 Keyboard processing.
*/
 
#include <genarch/kbrd/kbrd.h>
#include <genarch/kbrd/scanc.h>
 
#include <genarch/kbrd/scanc_pl050.h>
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <macros.h>
 
#define PRESSED_SHIFT (1 << 0)
#define PRESSED_CAPSLOCK (1 << 1)
#define LOCKED_CAPSLOCK (1 << 0)
 
#define PL050_KEY_RELEASE 0xF0
#define PL050_ESC_KEY 0xE0
#define PL050_CAPS_SCAN_CODE 0x58
#define PL050_NUM_SCAN_CODE 0x77
#define PL050_SCROLL_SCAN_CODE 0x7E
 
static bool is_lock_key(wchar_t);
 
static indev_operations_t kbrd_raw_ops = {
.poll = NULL
};
 
/** Process release of key.
*
* @param sc Scancode of the key being released.
*/
static void key_released(kbrd_instance_t *instance, wchar_t sc)
{
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags &= ~PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags &= ~PRESSED_CAPSLOCK;
if (instance->lockflags & LOCKED_CAPSLOCK)
instance->lockflags &= ~LOCKED_CAPSLOCK;
else
instance->lockflags |= LOCKED_CAPSLOCK;
break;
default:
break;
}
spinlock_unlock(&instance->keylock);
}
 
/** Process keypress.
*
* @param sc Scancode of the key being pressed.
*/
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
{
bool letter;
bool shift;
bool capslock;
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SCAN_ESCAPE:
break;
default:
letter = islower(sc_primary_map[sc]);
shift = instance->keyflags & PRESSED_SHIFT;
capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
(instance->lockflags & LOCKED_CAPSLOCK);
if ((letter) && (capslock))
shift = !shift;
if (shift)
indev_push_character(instance->sink, sc_secondary_map[sc]);
else
indev_push_character(instance->sink, sc_primary_map[sc]);
break;
}
spinlock_unlock(&instance->keylock);
}
 
static void kkbrd(void *arg)
{
static int key_released_flag = 0;
static int is_locked = 0;
kbrd_instance_t *instance = (kbrd_instance_t *) arg;
while (true) {
wchar_t sc = indev_pop_character(&instance->raw);
 
if (sc == PL050_KEY_RELEASE) {
key_released_flag = 1;
} else {
if (key_released_flag) {
key_released_flag = 0;
if (is_lock_key(sc)) {
if (!is_locked) {
is_locked = 1;
} else {
is_locked = 0;
continue;
}
}
key_released(instance, sc);
 
} else {
if (is_lock_key(sc) && is_locked)
continue;
key_pressed(instance, sc);
}
}
}
}
 
kbrd_instance_t *kbrd_init(void)
{
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;
}
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;
}
 
static bool is_lock_key(wchar_t sc)
{
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
(sc == PL050_SCROLL_SCAN_CODE));
}
 
/** @}
*/
/branches/network/kernel/genarch/src/kbrd/scanc_mac.c
0,0 → 1,306
/*
* Copyright (c) 2009 Jiri Svoboda
* 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
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = 'a',
[0x01] = 's',
[0x02] = 'd',
[0x03] = 'f',
[0x04] = 'h',
[0x05] = 'g',
[0x06] = 'z',
[0x07] = 'x',
[0x08] = 'c',
[0x09] = 'v',
[0x0a] = U_SPECIAL,
[0x0b] = 'b',
[0x0c] = 'q',
[0x0d] = 'w',
[0x0e] = 'e',
[0x0f] = 'r',
[0x10] = 'y',
[0x11] = 't',
[0x12] = '1',
[0x13] = '2',
[0x14] = '3',
[0x15] = '4',
[0x16] = '6',
[0x17] = '5',
[0x18] = '=',
[0x19] = '9',
[0x1a] = '7',
[0x1b] = '-',
[0x1c] = '8',
[0x1d] = '0',
[0x1e] = ']',
[0x1f] = 'o',
[0x20] = 'u',
[0x21] = '[',
[0x22] = 'i',
[0x23] = 'p',
[0x24] = '\n', /* Enter */
[0x25] = 'l',
[0x26] = 'j',
[0x27] = '\'',
[0x28] = 'k',
[0x29] = ';',
[0x2a] = '\\',
[0x2b] = ',',
[0x2c] = '/',
[0x2d] = 'n',
[0x2e] = 'm',
[0x2f] = '.',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '`',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_ESCAPE,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_LEFT_ARROW,
[0x3c] = U_RIGHT_ARROW,
[0x3d] = U_DOWN_ARROW,
[0x3e] = U_UP_ARROW,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_HOME_ARROW,
[0x74] = U_PAGE_UP,
[0x75] = U_DELETE,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_PAGE_DOWN,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = 'A',
[0x01] = 'S',
[0x02] = 'D',
[0x03] = 'F',
[0x04] = 'H',
[0x05] = 'G',
[0x06] = 'Z',
[0x07] = 'X',
[0x08] = 'C',
[0x09] = 'V',
[0x0a] = U_SPECIAL,
[0x0b] = 'B',
[0x0c] = 'Q',
[0x0d] = 'W',
[0x0e] = 'E',
[0x0f] = 'R',
[0x10] = 'Y',
[0x11] = 'T',
[0x12] = '!',
[0x13] = '@',
[0x14] = '#',
[0x15] = '$',
[0x16] = '^',
[0x17] = '%',
[0x18] = '+',
[0x19] = '(',
[0x1a] = '&',
[0x1b] = '_',
[0x1c] = '*',
[0x1d] = ')',
[0x1e] = '}',
[0x1f] = 'O',
[0x20] = 'U',
[0x21] = '{',
[0x22] = 'I',
[0x23] = 'P',
[0x24] = '\n', /* Enter */
[0x25] = 'L',
[0x26] = 'J',
[0x27] = '"',
[0x28] = 'K',
[0x29] = ':',
[0x2a] = '|',
[0x2b] = '<',
[0x2c] = '?',
[0x2d] = 'N',
[0x2e] = 'M',
[0x2f] = '>',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '~',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_SPECIAL,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_SPECIAL,
[0x3c] = U_SPECIAL,
[0x3d] = U_SPECIAL,
[0x3e] = U_SPECIAL,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_SPECIAL,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/network/kernel/genarch/src/kbrd/scanc_pl050.c
0,0 → 1,234
/*
* Copyright (c) 2009 Vineeth Pillai
* 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, U_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
* @brief Scan codes for pl050 keyboards.
*/
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[] = {
U_NULL, /* 0x00 */
U_SPECIAL, /* 0x01 - F9 */
U_SPECIAL, /* 0x02 - F7 */
U_SPECIAL, /* 0x03 - F5 */
U_SPECIAL, /* 0x04 - F3 */
U_SPECIAL, /* 0x05 - F1 */
U_SPECIAL, /* 0x06 - F2 */
U_SPECIAL, /* 0x07 - F12 */
U_SPECIAL, /* 0x08 - */
U_SPECIAL, /* 0x09 - F10 */
U_SPECIAL, /* 0x0A - F8 */
U_SPECIAL, /* 0x0B - F10 */
U_SPECIAL, /* 0x0C - F4 */
'\t', /* 0x0D - Tab */
'`',
U_SPECIAL, /* 0x0F */
U_SPECIAL, /* 0x10 */
U_SPECIAL, /* 0x11 - LAlt */
U_SPECIAL, /* 0x12 - LShift */
U_SPECIAL, /* ox13 */
U_SPECIAL, /* 0x14 Ctrl */
'q', '1',
U_SPECIAL, /* 0x17 */
U_SPECIAL, /* 0x18 */
U_SPECIAL, /* 0x19 */
'z', 's', 'a', 'w', '2',
U_SPECIAL, /* 0x1F */
U_SPECIAL, /* 0x20 */
'c', 'x', 'd', 'e', '4', '3',
U_SPECIAL, /* 0x27 */
U_SPECIAL, /* 0x28 */
' ', 'v', 'f', 't', 'r', '5',
U_SPECIAL, /* 0x2F */
U_SPECIAL, /* 0x30 */
'n', 'b', 'h', 'g', 'y', '6',
U_SPECIAL, /* 0x37 */
U_SPECIAL, /* 0x38 */
U_SPECIAL, /* 0x39 */
'm', 'j', 'u', '7', '8',
U_SPECIAL, /* 0x3F */
U_SPECIAL, /* 0x40 */
',', 'k', 'i', 'o', '0', '9',
U_SPECIAL, /* 0x47 */
U_SPECIAL, /* 0x48 */
'.', '/', 'l', ';', 'p', '-',
U_SPECIAL, /* 0x4F */
U_SPECIAL, /* 0x50 */
U_SPECIAL, /* 0x51 */
'\'',
U_SPECIAL, /* 0x53 */
'[', '=',
U_SPECIAL, /* 0x56 */
U_SPECIAL, /* 0x57 */
U_SPECIAL, /* 0x58 - Caps Lock */
U_SPECIAL, /* 0x59 - RShift */
'\n', ']',
U_SPECIAL, /* 0x5C */
'\\',
U_SPECIAL, /* 0x5E */
U_SPECIAL, /* 0x5F */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
'\b', /* 0x66 - backspace*/
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_END_ARROW, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_LEFT_ARROW, /* 0x6b - Left Arrow */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_DELETE, /* 0x71 - Del*/
U_DOWN_ARROW, /* 0x72 Down Arrow */
U_SPECIAL, /* 0x73 */
U_RIGHT_ARROW, /* 0x74 - Right Arrow */
U_UP_ARROW, /* 0x75 Up Arrow */
U_ESCAPE, /* 0x76 Esc */
U_SPECIAL, /* 0x77 - NumLock*/
U_SPECIAL, /* 0x78 F11*/
U_SPECIAL, /* 0x79 */
U_PAGE_DOWN, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_PAGE_UP, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[] = {
U_NULL, /* 0x00 */
U_SPECIAL, /* 0x01 - F9 */
U_SPECIAL, /* 0x02 - F7 */
U_SPECIAL, /* 0x03 - F5 */
U_SPECIAL, /* 0x04 - F3 */
U_SPECIAL, /* 0x05 - F1 */
U_SPECIAL, /* 0x06 - F2 */
U_SPECIAL, /* 0x07 - F12 */
U_SPECIAL, /* 0x08 - */
U_SPECIAL, /* 0x09 - F10 */
U_SPECIAL, /* 0x0A - F8 */
U_SPECIAL, /* 0x0B - F10 */
U_SPECIAL, /* 0x0C - F4 */
'\t', /* 0x0D - Tab */
'~',
U_SPECIAL, /* 0x0F */
U_SPECIAL, /* 0x10 */
U_SPECIAL, /* 0x11 - LAlt */
U_SPECIAL, /* 0x12 - LShift */
U_SPECIAL, /* ox13 */
U_SPECIAL, /* 0x14 Ctrl */
'Q', '!',
U_SPECIAL, /* 0x17 */
U_SPECIAL, /* 0x18 */
U_SPECIAL, /* 0x19 */
'Z', 'S', 'A', 'W', '@',
U_SPECIAL, /* 0x1F */
U_SPECIAL, /* 0x20 */
'C', 'X', 'D', 'E', '$', '#',
U_SPECIAL, /* 0x27 */
U_SPECIAL, /* 0x28 */
' ', 'V', 'F', 'T', 'R', '%',
U_SPECIAL, /* 0x2F */
U_SPECIAL, /* 0x30 */
'N', 'B', 'H', 'G', 'Y', '^',
U_SPECIAL, /* 0x37 */
U_SPECIAL, /* 0x38 */
U_SPECIAL, /* 0x39 */
'M', 'J', 'U', '&', '*',
U_SPECIAL, /* 0x3F */
U_SPECIAL, /* 0x40 */
'<', 'K', 'I', 'O', ')', '(',
U_SPECIAL, /* 0x47 */
U_SPECIAL, /* 0x48 */
'>', '?', 'L', ':', 'P', '_',
U_SPECIAL, /* 0x4F */
U_SPECIAL, /* 0x50 */
U_SPECIAL, /* 0x51 */
'"',
U_SPECIAL, /* 0x53 */
'{', '+',
U_SPECIAL, /* 0x56 */
U_SPECIAL, /* 0x57 */
U_SPECIAL, /* 0x58 - Caps Lock */
U_SPECIAL, /* 0x59 - RShift */
'\n', '}',
U_SPECIAL, /* 0x5C */
'|',
U_SPECIAL, /* 0x5E */
U_SPECIAL, /* 0x5F */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
'\b', /* 0x66 - backspace*/
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_END_ARROW, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_LEFT_ARROW, /* 0x6b - Left Arrow */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_DELETE, /* 0x71 - Del*/
U_DOWN_ARROW, /* 0x72 Down Arrow */
U_SPECIAL, /* 0x73 */
U_RIGHT_ARROW, /* 0x74 - Right Arrow */
U_UP_ARROW, /* 0x75 Up Arrow */
U_ESCAPE, /* 0x76 Esc */
U_SPECIAL, /* 0x77 - NumLock*/
U_SPECIAL, /* 0x78 F11*/
U_SPECIAL, /* 0x79 */
U_PAGE_DOWN, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_PAGE_UP, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** @}
*/
/branches/network/kernel/genarch/src/fb/fb.c
50,6 → 50,7
#include <string.h>
#include <ddi/ddi.h>
#include <arch/types.h>
#include <byteorder.h>
 
SPINLOCK_INITIALIZE(fb_lock);
 
80,9 → 81,9
#define FG_COLOR 0xffff00
#define INV_COLOR 0xaaaaaa
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
 
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
97,69 → 98,79
 
static void (*rgb_conv)(void *, uint32_t);
 
 
/** ARGB 8:8:8:8 conversion
/*
* RGB conversion functions.
*
* These functions write an RGB value to some memory in some predefined format.
* The naming convention corresponds to the format created by these functions.
* The functions use the so called network order (i.e. big endian) with respect
* to their names.
*/
 
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0xffffff;
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(RED(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (BLUE(rgb, 8)));
}
 
 
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (RED(rgb, 8)));
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((RED(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8) | 0);
}
 
/** RGB 8:8:8 conversion
*
*/
static void bgr_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((BLUE(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (RED(rgb, 8) << 8) | 0);
}
 
static void rgb_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
 
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void rgb_555_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
static void rgb_555_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
static void rgb_565_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
static void rgb_565_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 3:2:3
/** BGR 3:2:3
*
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer
* will most likely use a color palette. The color appearance
176,7 → 187,7
* 0 and 255 to other colors.
*
*/
static void rgb_323(void *dst, uint32_t rgb)
static void bgr_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
450,17 → 461,25
{
switch (props->visual) {
case VISUAL_INDIRECT_8:
rgb_conv = rgb_323;
rgb_conv = bgr_323;
pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
rgb_conv = rgb_555;
case VISUAL_RGB_5_5_5_LE:
rgb_conv = rgb_555_le;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
rgb_conv = rgb_565;
case VISUAL_RGB_5_5_5_BE:
rgb_conv = rgb_555_be;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_LE:
rgb_conv = rgb_565_le;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_BE:
rgb_conv = rgb_565_be;
pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
rgb_conv = rgb_888;
pixelbytes = 3;
470,7 → 489,7
pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
rgb_conv = rgb_888;
rgb_conv = rgb_8880;
pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
481,6 → 500,10
rgb_conv = bgr_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
rgb_conv = bgr_8880;
pixelbytes = 4;
break;
default:
panic("Unsupported visual.");
}
/branches/network/kernel/genarch/src/mm/page_ht.c
192,6 → 192,8
t->k = !(flags & PAGE_USER);
t->c = (flags & PAGE_CACHEABLE) != 0;
t->p = !(flags & PAGE_NOT_PRESENT);
t->a = false;
t->d = false;
 
t->as = as;
t->page = ALIGN_DOWN(page, PAGE_SIZE);
/branches/network/kernel/genarch/src/drivers/pl050/pl050.c
0,0 → 1,117
/*
* Copyright (c) 2009 Vineeth Pillai
* 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
* @brief pl050 keyboard/mouse driver.
*
* It takes care of low-level keyboard functions.
*/
 
#include <genarch/drivers/pl050/pl050.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define PL050_KEY_RELEASE 0xF0
#define PL050_ESC_KEY 0xE0
#define PL050_CAPS_SCAN_CODE 0x58
 
/** Structure for pl050's IRQ. */
static pl050_t *pl050;
 
static irq_ownership_t pl050_claim(irq_t *irq)
{
uint8_t status;
if ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL)
return IRQ_ACCEPT;
else {
return IRQ_DECLINE;
}
}
 
static void pl050_irq_handler(irq_t *irq)
{
uint8_t data;
uint8_t status;
pl050_instance_t *instance = irq->instance;
while ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL) {
data = pio_read_8(pl050->data);
indev_push_character(instance->kbrdin, data);
 
}
}
 
/** Initialize pl050. */
pl050_instance_t *pl050_init(pl050_t *dev, inr_t inr)
{
 
pl050_instance_t *instance =
malloc(sizeof(pl050_instance_t), FRAME_ATOMIC);
 
pl050 = dev;
 
if (instance) {
instance->pl050 = dev;
instance->kbrdin = NULL;
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = pl050_claim;
instance->irq.handler = pl050_irq_handler;
instance->irq.instance = instance;
}
 
return instance;
}
 
void pl050_wire(pl050_instance_t *instance, indev_t *kbrdin)
{
uint8_t val;
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
val = PL050_CR_RXINTR | PL050_CR_INTR;
 
pio_write_8(pl050->ctrl, val);
 
/* reset the data buffer */
pio_read_8(pl050->data);
}
 
 
/** @}
*/
/branches/network/kernel/genarch/src/drivers/via-cuda/cuda.c
1,5 → 1,6
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
38,16 → 39,53
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
#include <synch/spinlock.h>
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
return IRQ_DECLINE;
}
static irq_ownership_t cuda_claim(irq_t *irq);
static void cuda_irq_handler(irq_t *irq);
 
static void cuda_irq_handler(irq_t *irq)
{
}
static void cuda_irq_listen(irq_t *irq);
static void cuda_irq_receive(irq_t *irq);
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len);
static void cuda_irq_send_start(irq_t *irq);
static void cuda_irq_send(irq_t *irq);
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *buf, size_t len);
static void cuda_send_start(cuda_instance_t *instance);
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable);
 
/** B register fields */
enum {
TREQ = 0x08,
TACK = 0x10,
TIP = 0x20
};
 
/** IER register fields */
enum {
IER_CLR = 0x00,
IER_SET = 0x80,
 
SR_INT = 0x04,
ALL_INT = 0x7f
};
 
/** ACR register fields */
enum {
SR_OUT = 0x10
};
 
/** Packet types */
enum {
PT_ADB = 0x00,
PT_CUDA = 0x01
};
 
/** CUDA packet types */
enum {
CPT_AUTOPOLL = 0x01
};
 
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
cuda_instance_t *instance
55,7 → 93,15
if (instance) {
instance->cuda = dev;
instance->kbrdin = NULL;
instance->xstate = cx_listen;
instance->bidx = 0;
instance->snd_bytes = 0;
 
spinlock_initialize(&instance->dev_lock, "cuda_dev");
 
/* Disable all interrupts from CUDA. */
pio_write_8(&dev->ier, IER_CLR | ALL_INT);
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
64,15 → 110,251
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
instance->irq.preack = true;
}
return instance;
}
 
#include <print.h>
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance);
ASSERT(kbrdin);
 
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
/* Enable SR interrupt. */
pio_write_8(&dev->ier, TIP | TREQ);
pio_write_8(&dev->ier, IER_SET | SR_INT);
 
/* Enable ADB autopolling. */
cuda_autopoll_set(instance, true);
}
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t ifr;
 
spinlock_lock(&instance->dev_lock);
ifr = pio_read_8(&dev->ifr);
spinlock_unlock(&instance->dev_lock);
 
if ((ifr & SR_INT) == 0)
return IRQ_DECLINE;
 
return IRQ_ACCEPT;
}
 
static void cuda_irq_handler(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
uint8_t rbuf[CUDA_RCV_BUF_SIZE];
size_t len;
bool handle;
 
handle = false;
len = 0;
 
spinlock_lock(&instance->dev_lock);
 
/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
pio_write_8(&instance->cuda->ifr, SR_INT);
 
switch (instance->xstate) {
case cx_listen: cuda_irq_listen(irq); break;
case cx_receive: cuda_irq_receive(irq); break;
case cx_rcv_end: cuda_irq_rcv_end(irq, rbuf, &len);
handle = true; break;
case cx_send_start: cuda_irq_send_start(irq); break;
case cx_send: cuda_irq_send(irq); break;
}
 
spinlock_unlock(&instance->dev_lock);
 
/* Handle an incoming packet. */
if (handle)
cuda_packet_handle(instance, rbuf, len);
}
 
/** Interrupt in listen state.
*
* Start packet reception.
*/
static void cuda_irq_listen(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) != 0) {
printf("cuda_irq_listen: no TREQ?!\n");
return;
}
 
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
instance->xstate = cx_receive;
}
 
/** Interrupt in receive state.
*
* Receive next byte of packet.
*/
static void cuda_irq_receive(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b, data;
 
data = pio_read_8(&dev->sr);
if (instance->bidx < CUDA_RCV_BUF_SIZE)
instance->rcv_buf[instance->bidx++] = data;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
pio_write_8(&dev->b, b ^ TACK);
} else {
pio_write_8(&dev->b, b | TACK | TIP);
instance->xstate = cx_rcv_end;
}
}
 
/** Interrupt in rcv_end state.
*
* Terminate packet reception. Either go back to listen state or start
* receiving another packet if CUDA has one for us.
*/
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t data, b;
 
b = pio_read_8(&dev->b);
data = pio_read_8(&dev->sr);
 
if ((b & TREQ) == 0) {
instance->xstate = cx_receive;
pio_write_8(&dev->b, b & ~TIP);
} else {
instance->xstate = cx_listen;
cuda_send_start(instance);
}
 
memcpy(buf, instance->rcv_buf, instance->bidx);
*len = instance->bidx;
instance->bidx = 0;
}
 
/** Interrupt in send_start state.
*
* Process result of sending first byte (and send second on success).
*/
static void cuda_irq_send_start(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
/* Collision */
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
instance->xstate = cx_listen;
return;
}
 
pio_write_8(&dev->sr, instance->snd_buf[1]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
instance->bidx = 2;
 
instance->xstate = cx_send;
}
 
/** Interrupt in send state.
*
* Send next byte or terminate transmission.
*/
static void cuda_irq_send(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
 
if (instance->bidx < instance->snd_bytes) {
/* Send next byte. */
pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
return;
}
 
/* End transfer. */
instance->snd_bytes = 0;
instance->bidx = 0;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
 
instance->xstate = cx_listen;
/* TODO: Match reply with request. */
}
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *data, size_t len)
{
if (data[0] != 0x00 || data[1] != 0x40 || (data[2] != 0x2c
&& data[2] != 0x8c))
return;
 
/* The packet contains one or two scancodes. */
if (data[3] != 0xff)
indev_push_character(instance->kbrdin, data[3]);
if (data[4] != 0xff)
indev_push_character(instance->kbrdin, data[4]);
}
 
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable)
{
instance->snd_buf[0] = PT_CUDA;
instance->snd_buf[1] = CPT_AUTOPOLL;
instance->snd_buf[2] = enable ? 0x01 : 0x00;
instance->snd_bytes = 3;
instance->bidx = 0;
 
cuda_send_start(instance);
}
 
static void cuda_send_start(cuda_instance_t *instance)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance->xstate == cx_listen);
 
if (instance->snd_bytes == 0)
return;
 
/* Check for incoming data. */
if ((pio_read_8(&dev->b) & TREQ) == 0)
return;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
pio_write_8(&dev->sr, instance->snd_buf[0]);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
 
instance->xstate = cx_send_start;
}
 
 
/** @}
*/
/branches/network/kernel/generic/include/string.h
88,7 → 88,7
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);
extern char *str_chr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
/branches/network/kernel/generic/include/context.h
45,7 → 45,7
(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
#endif /* context_set */
 
extern int context_save_arch(context_t *c);
extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
 
/** Save register context.
76,10 → 76,6
* corresponding call to context_save(), the only
* difference being return value.
*
* Note that content of any local variable defined by
* the caller of context_save() is undefined after
* context_restore().
*
* @param c Context structure.
*/
static inline void context_restore(context_t *c)
/branches/network/kernel/generic/src/main/uinit.c
79,6 → 79,14
uarg.uspace_thread_arg = NULL;
 
free((uspace_arg_t *) arg);
/*
* Disable interrupts so that the execution of userspace() is not
* disturbed by any interrupts as some of the userspace()
* implementations will switch to the userspace stack before switching
* the mode.
*/
(void) interrupts_disable();
userspace(&uarg);
}
 
/branches/network/kernel/generic/src/lib/string.c
637,7 → 637,7
* @return Pointer to character in @a str or NULL if not found.
*
*/
const char *str_chr(const char *str, wchar_t ch)
char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
645,7 → 645,7
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
return (char *) (str + last);
last = off;
}
/branches/network/kernel/generic/src/ipc/event.c
140,9 → 140,11
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
ipl_t ipl = interrupts_disable();
spinlock_lock(&events[evno].answerbox->irq_lock);
list_append(&call->link, &events[evno].answerbox->irq_notifs);
spinlock_unlock(&events[evno].answerbox->irq_lock);
interrupts_restore(ipl);
waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
}
/branches/network/kernel/arch/sparc64/include/atomic.h
123,7 → 123,7
"ldx %0, %2\n"
"brz %2, 0b\n"
"nop\n"
"ba %xcc, 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/context.h
39,7 → 39,7
#include <arch/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/network/kernel/arch/sparc64/src/asm.S
277,7 → 277,7
*/
.global switch_to_userspace
switch_to_userspace:
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
/branches/network/kernel/arch/sparc64/src/drivers/scr.c
133,11 → 133,11
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_BE;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
visual = VISUAL_BGR_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
177,11 → 177,11
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_BE;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
visual = VISUAL_BGR_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
/branches/network/kernel/arch/ia64/include/atomic.h
52,12 → 52,12
return v;
}
 
 
static inline uint64_t test_and_set(atomic_t *val) {
static inline uint64_t test_and_set(atomic_t *val)
{
uint64_t v;
asm volatile (
"movl %0 = 0x01;;\n"
"movl %0 = 0x1;;\n"
"xchg8 %0 = %1, %0;;\n"
: "=r" (v), "+m" (val->count)
);
65,6 → 65,13
return v;
}
 
static inline void atomic_lock_arch(atomic_t *val)
{
do {
while (val->count)
;
} while (test_and_set(val));
}
 
static inline void atomic_inc(atomic_t *val)
{
/branches/network/kernel/arch/ia64/include/mm/tlb.h
92,6 → 92,7
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate);
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_rights_fault(uint64_t vector, istate_t *istate);
extern void page_not_present(uint64_t vector, istate_t *istate);
 
#endif
/branches/network/kernel/arch/ia64/src/ivt.S
536,7 → 536,7
HEAVYWEIGHT_HANDLER 0x5000 page_not_present
HEAVYWEIGHT_HANDLER 0x5100
HEAVYWEIGHT_HANDLER 0x5200
HEAVYWEIGHT_HANDLER 0x5300
HEAVYWEIGHT_HANDLER 0x5300 data_access_rights_fault
HEAVYWEIGHT_HANDLER 0x5400 general_exception
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register
HEAVYWEIGHT_HANDLER 0x5600
/branches/network/kernel/arch/ia64/src/mm/tlb.c
710,6 → 710,37
page_table_unlock(AS, true);
}
 
/** Data access rights fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_access_rights_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
/*
* Assume a write to a read-only page.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
ASSERT(!t->w);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
page_table_unlock(AS, true);
}
 
/** Page not present fault handler.
*
* @param vector Interruption vector.
/branches/network/kernel/arch/arm32/include/exception.h
136,6 → 136,13
extern void install_exception_handlers(void);
extern void exception_init(void);
extern void print_istate(istate_t *istate);
extern void reset_exception_entry(void);
extern void irq_exception_entry(void);
extern void fiq_exception_entry(void);
extern void undef_instr_exception_entry(void);
extern void prefetch_abort_exception_entry(void);
extern void data_abort_exception_entry(void);
extern void swi_exception_entry(void);
 
 
#endif
/branches/network/kernel/arch/arm32/include/machine_func.h
0,0 → 1,132
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32
* @{
*/
/** @file
* @brief Declarations of machine specific functions.
*
* These functions enable to differentiate more kinds of ARM emulators
* or CPUs. It's the same concept as "arch" functions on the architecture
* level.
*/
 
#ifndef KERN_arm32_MACHINE_FUNC_H_
#define KERN_arm32_MACHINE_FUNC_H_
 
#include <console/console.h>
#include <arch/types.h>
#include <arch/exception.h>
 
#define MACHINE_GENFUNC machine_genfunc
 
struct arm_machine_ops {
void (*machine_grab_console)(void);
void (*machine_release_console)(void);
void (*machine_init)(void);
void (*machine_timer_irq_start)(void);
void (*machine_cpu_halt)(void);
uintptr_t (*machine_get_memory_size)(void);
void (*machine_fb_init)(void);
void (*machine_irq_exception)(int, istate_t*);
uintptr_t (*machine_get_fb_address)(void);
void (*machine_frame_init)(void);
void (*machine_output_init)(void);
void (*machine_input_init)(void);
};
 
extern struct arm_machine_ops machine_ops;
 
 
/** Acquire console back for kernel. */
extern void machine_grab_console(void);
 
/** Return console to userspace. */
extern void machine_release_console(void);
 
 
/** Maps HW devices to the kernel address space using #hw_map. */
extern void machine_init(void);
 
 
/** Starts timer. */
extern void machine_timer_irq_start(void);
 
 
/** Halts CPU. */
extern void machine_cpu_halt(void);
 
 
/** Returns size of available memory.
*
* @return Size of available memory.
*/
extern uintptr_t machine_get_memory_size(void);
 
/** Initializes the Frame Buffer
*
*/
extern void machine_fb_init(void);
 
 
/** Interrupt exception handler.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
extern void machine_irq_exception(int exc_no, istate_t *istate);
 
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
extern uintptr_t machine_get_fb_address(void);
 
/*
* Machine specific frame initialization
*/
extern void machine_frame_init(void);
 
/*
* configure the serial line output device.
*/
extern void machine_output_init(void);
 
/*
* configure the serial line input device.
*/
extern void machine_input_init(void);
 
extern void machine_genfunc(void);
#endif
 
/** @}
*/
/branches/network/kernel/arch/arm32/include/mach/testarm/testarm.h
0,0 → 1,87
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32gxemul GXemul
* @brief GXemul machine specific parts.
* @ingroup arm32
* @{
*/
/** @file
* @brief GXemul peripheries drivers declarations.
*/
 
#ifndef KERN_arm32_MACHINE_H_
#define KERN_arm32_MACHINE_H_
 
#include <arch/machine_func.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
/** Timer frequency */
#define GXEMUL_TIMER_FREQ 100
 
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_MP_ADDRESS 0x11000000
#define GXEMUL_FB_ADDRESS 0x12000000
#define GXEMUL_RTC_ADDRESS 0x15000000
#define GXEMUL_IRQC_ADDRESS 0x16000000
 
extern void *gxemul_kbd;
extern void *gxemul_rtc;
extern void *gxemul_irqc;
 
#define GXEMUL_HALT_OFFSET 0x010
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090
#define GXEMUL_RTC_ACK_OFFSET 0x110
 
extern void gxemul_init(void);
extern void gxemul_fb_init(void);
extern void gxemul_output_init(void);
extern void gxemul_input_init(void);
extern void gxemul_release_console(void);
extern void gxemul_grab_console(void);
extern void gxemul_timer_irq_start(void);
extern void gxemul_cpu_halt(void);
extern void gxemul_irq_exception(int exc_no, istate_t *istate);
extern uintptr_t gxemul_get_memory_size(void);
extern uintptr_t gxemul_get_fb_address(void);
extern void gxemul_fb_init(void);
extern void gxemul_frame_init(void);
 
 
#endif
 
/** @}
*/
/branches/network/kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
0,0 → 1,116
/*
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32integratorcp
* @brief Integratorcp machine specific parts.
* @ingroup arm32
* @{
*/
/** @file
* @brief Integratorcp peripheries drivers declarations.
*/
 
#ifndef KERN_arm32_MACHINE_H_
#define KERN_arm32_MACHINE_H_
 
#include <arch/machine_func.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define ICP_IRQC_MAX_IRQ 8
#define ICP_KBD_IRQ 3
#define ICP_TIMER_IRQ 6
 
/** Timer frequency */
#define ICP_TIMER_FREQ 10000
 
#define ICP_UART 0x16000000
#define ICP_KBD 0x18000000
#define ICP_KBD_STAT 0x04
#define ICP_KBD_DATA 0x08
#define ICP_KBD_INTR_STAT 0x10
#define ICP_RTC 0x13000000
#define ICP_RTC1_LOAD_OFFSET 0x100
#define ICP_RTC1_READ_OFFSET 0x104
#define ICP_RTC1_CTL_OFFSET 0x108
#define ICP_RTC1_INTRCLR_OFFSET 0x10C
#define ICP_RTC1_INTRSTAT_OFFSET 0x114
#define ICP_RTC1_BGLOAD_OFFSET 0x118
#define ICP_RTC_CTL_VALUE 0x00E2
#define ICP_IRQC 0x14000000
#define ICP_IRQC_MASK_OFFSET 0xC
#define ICP_IRQC_UNMASK_OFFSET 0x8
#define ICP_FB 0x00800000
#define ICP_FB_FRAME (ICP_FB >> 12)
#define ICP_FB_NUM_FRAME 512
#define ICP_VGA 0xC0000000
#define ICP_CMCR 0x10000000
#define ICP_SDRAM_MASK 0x1C
#define ICP_SDRAMCR_OFFSET 0x20
 
typedef struct {
uintptr_t uart;
uintptr_t kbd_ctrl;
uintptr_t kbd_stat;
uintptr_t kbd_data;
uintptr_t kbd_intstat;
uintptr_t rtc;
uintptr_t rtc1_load;
uintptr_t rtc1_read;
uintptr_t rtc1_ctl;
uintptr_t rtc1_intrclr;
uintptr_t rtc1_intrstat;
uintptr_t rtc1_bgload;
uintptr_t irqc;
uintptr_t irqc_mask;
uintptr_t irqc_unmask;
uintptr_t vga;
uintptr_t cmcr;
uintptr_t sdramcr;
} icp_hw_map_t;
 
 
extern void icp_init(void);
extern void icp_fb_init(void);
extern void icp_output_init(void);
extern void icp_input_init(void);
extern void icp_release_console(void);
extern void icp_grab_console(void);
extern void icp_timer_irq_start(void);
extern void icp_cpu_halt(void);
extern void icp_irq_exception(int exc_no, istate_t *istate);
extern uintptr_t icp_get_memory_size(void);
extern uintptr_t icp_get_fb_address(void);
extern void icp_fb_init(void);
extern void icp_frame_init(void);
 
#endif
 
/** @}
*/
/branches/network/kernel/arch/arm32/include/drivers/gxemul.h
File deleted
/branches/network/kernel/arch/arm32/Makefile.inc
45,7 → 45,9
ARCH_SOURCES = \
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/exc_handler.S \
arch/$(KARCH)/src/arm32.c \
arch/$(KARCH)/src/machine_func.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/dummy.S \
arch/$(KARCH)/src/panic.S \
58,5 → 60,16
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/page_fault.c \
arch/$(KARCH)/src/drivers/gxemul.c
arch/$(KARCH)/src/mm/page_fault.c
 
ifeq ($(MACHINE),testarm)
ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c
endif
 
ifeq ($(MACHINE),integratorcp)
ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c
endif
 
ifeq ($(CONFIG_PL050),y)
ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c
endif
/branches/network/kernel/arch/arm32/src/exception.c
39,10 → 39,17
#include <interrupt.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <syscall/syscall.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** Offset used in calculation of exception handler's relative address.
*
* @see install_handler()
58,159 → 65,6
/** Size of memory block occupied by exception vectors. */
#define EXC_VECTORS_SIZE (EXC_VECTORS * 4)
 
/** Switches to kernel stack and saves all registers there.
*
* Temporary exception stack is used to save a few registers
* before stack switch takes place.
*
*/
inline static void setup_stack_and_save_regs()
{
asm volatile (
"ldr r13, =exc_stack\n"
"stmfd r13!, {r0}\n"
"mrs r0, spsr\n"
"and r0, r0, #0x1f\n"
"cmp r0, #0x10\n"
"bne 1f\n"
/* prev mode was usermode */
"ldmfd r13!, {r0}\n"
"ldr r13, =supervisor_sp\n"
"ldr r13, [r13]\n"
"stmfd r13!, {lr}\n"
"stmfd r13!, {r0-r12}\n"
"stmfd r13!, {r13, lr}^\n"
"mrs r0, spsr\n"
"stmfd r13!, {r0}\n"
"b 2f\n"
/* mode was not usermode */
"1:\n"
"stmfd r13!, {r1, r2, r3}\n"
"mrs r1, cpsr\n"
"mov r2, lr\n"
"bic r1, r1, #0x1f\n"
"orr r1, r1, r0\n"
"mrs r0, cpsr\n"
"msr cpsr_c, r1\n"
"mov r3, r13\n"
"stmfd r13!, {r2}\n"
"mov r2, lr\n"
"stmfd r13!, {r4-r12}\n"
"mov r1, r13\n"
/* the following two lines are for debugging */
"mov sp, #0\n"
"mov lr, #0\n"
"msr cpsr_c, r0\n"
"ldmfd r13!, {r4, r5, r6, r7}\n"
"stmfd r1!, {r4, r5, r6}\n"
"stmfd r1!, {r7}\n"
"stmfd r1!, {r2}\n"
"stmfd r1!, {r3}\n"
"mrs r0, spsr\n"
"stmfd r1!, {r0}\n"
"mov r13, r1\n"
"2:\n"
);
}
 
/** Returns from exception mode.
*
* Previously saved state of registers (including control register)
* is restored from the stack.
*/
inline static void load_regs()
{
asm volatile(
"ldmfd r13!, {r0} \n"
"msr spsr, r0 \n"
"and r0, r0, #0x1f \n"
"cmp r0, #0x10 \n"
"bne 1f \n"
 
/* return to user mode */
"ldmfd r13!, {r13, lr}^ \n"
"b 2f \n"
 
/* return to non-user mode */
"1:\n"
"ldmfd r13!, {r1, r2} \n"
"mrs r3, cpsr \n"
"bic r3, r3, #0x1f \n"
"orr r3, r3, r0 \n"
"mrs r0, cpsr \n"
"msr cpsr_c, r3 \n"
 
"mov r13, r1 \n"
"mov lr, r2 \n"
"msr cpsr_c, r0 \n"
 
/* actual return */
"2:\n"
"ldmfd r13, {r0-r12, pc}^\n"
);
}
 
 
/** Switch CPU to mode in which interrupts are serviced (currently it
* is Undefined mode).
*
* The default mode for interrupt servicing (Interrupt Mode)
* can not be used because of nested interrupts (which can occur
* because interrupts are enabled in higher levels of interrupt handler).
*/
inline static void switch_to_irq_servicing_mode()
{
/* switch to Undefined mode */
asm volatile(
/* save regs used during switching */
"stmfd sp!, {r0-r3} \n"
 
/* save stack pointer and link register to r1, r2 */
"mov r1, sp \n"
"mov r2, lr \n"
 
/* mode switch */
"mrs r0, cpsr \n"
"bic r0, r0, #0x1f \n"
"orr r0, r0, #0x1b \n"
"msr cpsr_c, r0 \n"
 
/* restore saved sp and lr */
"mov sp, r1 \n"
"mov lr, r2 \n"
 
/* restore original regs */
"ldmfd sp!, {r0-r3} \n"
);
}
 
/** Calls exception dispatch routine. */
#define CALL_EXC_DISPATCH(exception) \
asm volatile ( \
"mov r0, %[exc]\n" \
"mov r1, r13\n" \
"bl exc_dispatch\n" \
:: [exc] "i" (exception) \
);\
 
/** General exception handler.
*
* Stores registers, dispatches the exception,
* and finally restores registers and returns from exception processing.
*
* @param exception Exception number.
*/
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
load_regs();
 
/** Updates specified exception vector to jump to given handler.
*
* Addresses of handlers are stored in memory following exception vectors.
232,71 → 86,6
 
}
 
/** Low-level Reset Exception handler. */
static void reset_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_RESET);
}
 
/** Low-level Software Interrupt Exception handler. */
static void swi_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_SWI);
}
 
/** Low-level Undefined Instruction Exception handler. */
static void undef_instr_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
}
 
/** Low-level Fast Interrupt Exception handler. */
static void fiq_exception_entry(void)
{
PROCESS_EXCEPTION(EXC_FIQ);
}
 
/** Low-level Prefetch Abort Exception handler. */
static void prefetch_abort_exception_entry(void)
{
asm volatile (
"sub lr, lr, #4"
);
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
}
 
/** Low-level Data Abort Exception handler. */
static void data_abort_exception_entry(void)
{
asm volatile (
"sub lr, lr, #8"
);
PROCESS_EXCEPTION(EXC_DATA_ABORT);
}
 
/** Low-level Interrupt Exception handler.
*
* CPU is switched to Undefined mode before further interrupt processing
* because of possible occurence of nested interrupt exception, which
* would overwrite (and thus spoil) stack pointer.
*/
static void irq_exception_entry(void)
{
asm volatile (
"sub lr, lr, #4"
);
setup_stack_and_save_regs();
switch_to_irq_servicing_mode();
CALL_EXC_DISPATCH(EXC_IRQ)
 
load_regs();
}
 
/** Software Interrupt handler.
*
* Dispatches the syscall.
307,37 → 96,6
istate->r3, istate->r4, istate->r5, istate->r6);
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
static void irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Fills exception vectors with appropriate exception handlers. */
void install_exception_handlers(void)
{
384,6 → 142,15
}
#endif
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
static void irq_exception(int exc_no, istate_t *istate)
{
machine_irq_exception(exc_no, istate);
}
 
/** Initializes exception handling.
*
* Installs low-level exception handlers and then registers
/branches/network/kernel/arch/arm32/src/start.S
35,11 → 35,33
.global supervisor_sp
 
kernel_image_start:
 
# initialize Stack pointer for exception modes
mrs r4, cpsr
bic r4, r4, #0x1f
 
#FIQ Mode
orr r3, r4, #0x11
msr cpsr_c, r3
ldr sp, =exc_stack
 
#IRQ Mode
orr r3, r4, #0x12
msr cpsr_c, r3
ldr sp, =exc_stack
 
#ABORT Mode
orr r3, r4, #0x17
msr cpsr_c, r3
ldr sp, =exc_stack
 
#UNDEFINED Mode
orr r3, r4, #0x1b
msr cpsr_c, r3
ldr sp, =exc_stack
 
# switch to supervisor mode
mrs r3, cpsr
bic r3, r3, #0x1f
orr r3, r3, #0x13
orr r3, r4, #0x13
msr cpsr_c, r3
ldr sp, =temp_stack
/branches/network/kernel/arch/arm32/src/machine_func.c
0,0 → 1,147
/*
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32
* @{
*/
/** @file
* @brief Definitions of machine specific functions.
*
* These functions enable to differentiate more kinds of ARM emulators
* or CPUs. It's the same concept as "arch" functions on the architecture
* level.
*/
 
#include <arch/machine_func.h>
 
 
/** Acquire console back for kernel. */
void machine_grab_console(void)
{
(machine_ops.machine_grab_console)();
}
 
/** Return console to userspace. */
void machine_release_console(void)
{
(machine_ops.machine_release_console)();
}
 
 
/** Maps HW devices to the kernel address space using #hw_map. */
void machine_init(void)
{
(machine_ops.machine_init)();
}
 
 
/** Starts timer. */
void machine_timer_irq_start(void)
{
(machine_ops.machine_timer_irq_start)();
}
 
 
/** Halts CPU. */
void machine_cpu_halt(void)
{
(machine_ops.machine_cpu_halt)();
}
 
 
/** Returns size of available memory.
*
* @return Size of available memory.
*/
uintptr_t machine_get_memory_size(void)
{
return (machine_ops.machine_get_memory_size)();
}
 
/** Initializes the Frame Buffer
*
*/
void machine_fb_init(void)
{
(machine_ops.machine_fb_init)();
}
 
 
/** Interrupt exception handler.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void machine_irq_exception(int exc_no, istate_t *istate)
{
(machine_ops.machine_irq_exception)(exc_no, istate);
}
 
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t machine_get_fb_address(void)
{
return (machine_ops.machine_get_fb_address)();
}
 
/*
* Machine specific frame initialization
*/
void machine_frame_init(void)
{
(machine_ops.machine_frame_init)();
}
 
/*
* configure the output device.
*/
void machine_output_init(void)
{
(machine_ops.machine_output_init)();
}
 
/*
* configure the input device.
*/
void machine_input_init(void)
{
(machine_ops.machine_input_init)();
}
 
/*
* Generic function to use, if sepcific function doesn't define any of the above functions.
*/
void machine_genfunc()
{
}
 
/** @}
*/
/branches/network/kernel/arch/arm32/src/arm32.c
37,13 → 37,9
#include <config.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#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>
#include <config.h>
#include <interrupt.h>
52,6 → 48,15
#include <macros.h>
#include <string.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
 
/** Performs arm32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
77,7 → 82,7
/** Performs arm32 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
gxemul_init();
machine_init();
/* Initialize exception dispatch table */
exception_init();
84,18 → 89,10
interrupt_init();
#ifdef CONFIG_FB
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
machine_fb_init();
#else
#ifdef CONFIG_ARM_PRN
dsrlnout_init((ioport8_t *) gxemul_kbd);
machine_output_init();
#endif /* CONFIG_ARM_PRN */
#endif /* CONFIG_FB */
}
126,30 → 123,7
*/
void arch_post_smp_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
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
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
machine_input_init();
}
 
 
156,7 → 130,6
/** Performs arm32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
tlb_invalidate_all();
}
 
 
168,6 → 141,7
{
uint8_t *stck;
tlb_invalidate_all();
stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
supervisor_sp = (uintptr_t) stck;
}
183,8 → 157,7
/** Halts CPU. */
void cpu_halt(void)
{
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
machine_cpu_halt();
}
 
/** Reboot. */
211,6 → 184,7
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
machine_grab_console();
#ifdef CONFIG_FB
fb_redraw();
#endif
219,6 → 193,7
/** Return console to userspace. */
void arch_release_console(void)
{
machine_release_console();
}
 
/** @}
/branches/network/kernel/arch/arm32/src/mach/testarm/testarm.c
0,0 → 1,242
/*
* Copyright (c) 2007 Michal Kebrt, Petr Stepan
* 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 arm32gxemul
* @{
*/
/** @file
* @brief GXemul drivers.
*/
 
#include <arch/exception.h>
#include <arch/mach/testarm/testarm.h>
#include <mm/page.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <config.h>
#include <sysinfo/sysinfo.h>
#include <interrupt.h>
#include <print.h>
 
 
void *gxemul_kbd;
void *gxemul_rtc;
void *gxemul_irqc;
static irq_t gxemul_timer_irq;
 
struct arm_machine_ops machine_ops = {
MACHINE_GENFUNC,
MACHINE_GENFUNC,
gxemul_init,
gxemul_timer_irq_start,
gxemul_cpu_halt,
gxemul_get_memory_size,
gxemul_fb_init,
gxemul_irq_exception,
gxemul_get_fb_address,
gxemul_frame_init,
gxemul_output_init,
gxemul_input_init
};
 
void gxemul_init(void)
{
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
}
 
void gxemul_fb_init(void)
{
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_RGB_8_8_8,
};
fb_init(&prop);
}
 
void gxemul_output_init(void)
{
dsrlnout_init((ioport8_t *) gxemul_kbd);
}
 
void gxemul_input_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
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
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initializes and registers timer interrupt handler. */
static void gxemul_timer_irq_init(void)
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
 
irq_register(&gxemul_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void gxemul_timer_irq_start(void)
{
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
uintptr_t gxemul_get_memory_size(void)
{
return *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
}
 
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
*/
void gxemul_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
 
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
void gxemul_cpu_halt(void)
{
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET)) = 0;
}
 
void gxemul_frame_init(void)
{
}
 
uintptr_t gxemul_get_fb_address()
{
return ((uintptr_t)GXEMUL_FB_ADDRESS);
}
 
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/network/kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
0,0 → 1,360
/*
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32integratorcp
* @{
*/
/** @file
* @brief ICP drivers.
*/
 
#include <interrupt.h>
#include <ipc/irq.h>
#include <console/chardev.h>
#include <genarch/drivers/pl050/pl050.h>
#include <genarch/kbrd/kbrd.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/mach/integratorcp/integratorcp.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <ddi/ddi.h>
#include <print.h>
 
#define SDRAM_SIZE (sdram[((*(uint32_t *)(ICP_CMCR+ICP_SDRAMCR_OFFSET) & ICP_SDRAM_MASK) >> 2)])
static parea_t fb_parea;
static icp_hw_map_t icp_hw_map;
static irq_t icp_timer_irq;
struct arm_machine_ops machine_ops = {
MACHINE_GENFUNC,
MACHINE_GENFUNC,
icp_init,
icp_timer_irq_start,
icp_cpu_halt,
icp_get_memory_size,
icp_fb_init,
icp_irq_exception,
icp_get_fb_address,
icp_frame_init,
icp_output_init,
icp_input_init
};
 
static bool hw_map_init_called = false;
static bool vga_init = false;
uint32_t sdram[8] = {
16777216, /* 16mb */
33554432, /* 32mb */
67108864, /* 64mb */
134217728, /* 128mb */
268435456, /* 256mb */
0, /* Reserverd */
0, /* Reserverd */
0 /* Reserverd */
};
 
void icp_vga_init(void);
 
/** Initializes the vga
*
*/
void icp_vga_init(void)
{
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x14) = 0xA05F0000;
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x1C) = 0x12C11000;
*(uint32_t*)icp_hw_map.vga = 0x3F1F3F9C;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x4) = 0x080B61DF;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x8) = 0x067F3800;
*(uint32_t*)((char *)(icp_hw_map.vga) + 0x10) = ICP_FB;
*(uint32_t *)((char *)(icp_hw_map.vga) + 0x1C) = 0x182B;
*(uint32_t*)((char *)(icp_hw_map.cmcr)+0xC) = 0x33805000;
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t icp_irqc_get_sources(void)
{
return *((uint32_t *) icp_hw_map.irqc);
}
 
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
static inline void icp_irqc_mask(uint32_t irq)
{
*((uint32_t *) icp_hw_map.irqc_mask) = (1 << irq);
}
 
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
static inline void icp_irqc_unmask(uint32_t irq)
{
*((uint32_t *) icp_hw_map.irqc_unmask) |= (1 << irq);
}
 
/** Initializes the icp frame buffer */
void icp_fb_init(void)
{
fb_properties_t prop = {
.addr = 0,
.offset = 0,
.x = 640,
.y = 480,
.scan = 2560,
.visual = VISUAL_BGR_0_8_8_8,
};
prop.addr = icp_get_fb_address();
fb_init(&prop);
fb_parea.pbase = ICP_FB;
fb_parea.frames = 300;
ddi_parea_register(&fb_parea);
}
 
/** Initializes icp_hw_map. */
void icp_init(void)
{
icp_hw_map.uart = hw_map(ICP_UART, PAGE_SIZE);
icp_hw_map.kbd_ctrl = hw_map(ICP_KBD, PAGE_SIZE);
icp_hw_map.kbd_stat = icp_hw_map.kbd_ctrl + ICP_KBD_STAT;
icp_hw_map.kbd_data = icp_hw_map.kbd_ctrl + ICP_KBD_DATA;
icp_hw_map.kbd_intstat = icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT;
icp_hw_map.rtc = hw_map(ICP_RTC, PAGE_SIZE);
icp_hw_map.rtc1_load = icp_hw_map.rtc + ICP_RTC1_LOAD_OFFSET;
icp_hw_map.rtc1_read = icp_hw_map.rtc + ICP_RTC1_READ_OFFSET;
icp_hw_map.rtc1_ctl = icp_hw_map.rtc + ICP_RTC1_CTL_OFFSET;
icp_hw_map.rtc1_intrclr = icp_hw_map.rtc + ICP_RTC1_INTRCLR_OFFSET;
icp_hw_map.rtc1_bgload = icp_hw_map.rtc + ICP_RTC1_BGLOAD_OFFSET;
icp_hw_map.rtc1_intrstat = icp_hw_map.rtc + ICP_RTC1_INTRSTAT_OFFSET;
 
icp_hw_map.irqc = hw_map(ICP_IRQC, PAGE_SIZE);
icp_hw_map.irqc_mask = icp_hw_map.irqc + ICP_IRQC_MASK_OFFSET;
icp_hw_map.irqc_unmask = icp_hw_map.irqc + ICP_IRQC_UNMASK_OFFSET;
icp_hw_map.cmcr = hw_map(ICP_CMCR, PAGE_SIZE);
icp_hw_map.sdramcr = icp_hw_map.cmcr + ICP_SDRAMCR_OFFSET;
icp_hw_map.vga = hw_map(ICP_VGA, PAGE_SIZE);
 
hw_map_init_called = true;
}
 
 
/** Acquire console back for kernel. */
void icp_grab_console(void)
{
}
 
/** Return console to userspace. */
void icp_release_console(void)
{
}
 
/** Starts icp Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void icp_timer_start(uint32_t frequency)
{
icp_irqc_mask(ICP_TIMER_IRQ);
*((uint32_t*) icp_hw_map.rtc1_load) = frequency;
*((uint32_t*) icp_hw_map.rtc1_bgload) = frequency;
*((uint32_t*) icp_hw_map.rtc1_ctl) = ICP_RTC_CTL_VALUE;
icp_irqc_unmask(ICP_TIMER_IRQ);
}
 
static irq_ownership_t icp_timer_claim(irq_t *irq)
{
if (icp_hw_map.rtc1_intrstat) {
*((uint32_t*) icp_hw_map.rtc1_intrclr) = 1;
return IRQ_ACCEPT;
} else
return IRQ_DECLINE;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void icp_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
 
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
}
 
/** Initializes and registers timer interrupt handler. */
static void icp_timer_irq_init(void)
{
irq_initialize(&icp_timer_irq);
icp_timer_irq.devno = device_assign_devno();
icp_timer_irq.inr = ICP_TIMER_IRQ;
icp_timer_irq.claim = icp_timer_claim;
icp_timer_irq.handler = icp_timer_irq_handler;
 
irq_register(&icp_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void icp_timer_irq_start(void)
{
icp_timer_irq_init();
icp_timer_start(ICP_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
size_t icp_get_memory_size(void)
{
if (hw_map_init_called) {
return (sdram[((*(uint32_t *)icp_hw_map.sdramcr & ICP_SDRAM_MASK) >> 2)]);
} else {
return SDRAM_SIZE;
}
}
 
/** Stops icp. */
void icp_cpu_halt(void)
{
while (1);
}
 
/** interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void icp_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = icp_irqc_get_sources();
int i;
for (i = 0; i < ICP_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t icp_get_fb_address(void)
{
if (!vga_init) {
icp_vga_init();
vga_init = true;
}
return (uintptr_t) ICP_FB;
}
 
/*
* Integrator specific frame initialization
*/
void
icp_frame_init(void)
{
frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
frame_mark_unavailable(0, 256);
}
 
void icp_output_init(void)
{
}
 
void icp_input_init(void)
{
 
pl050_t *pl050 = malloc(sizeof(pl050_t), FRAME_ATOMIC);
pl050->status = (ioport8_t *)icp_hw_map.kbd_stat;
pl050->data = (ioport8_t *)icp_hw_map.kbd_data;
pl050->ctrl = (ioport8_t *)icp_hw_map.kbd_ctrl;
pl050_instance_t *pl050_instance = pl050_init(pl050, ICP_KBD_IRQ);
if (pl050_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
icp_irqc_mask(ICP_KBD_IRQ);
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
pl050_wire(pl050_instance, kbrd);
icp_irqc_unmask(ICP_KBD_IRQ);
}
}
 
/*
* 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.inr", NULL, ICP_KBD_IRQ);
sysinfo_set_item_val("kbd.address.status", NULL,
(uintptr_t) icp_hw_map.kbd_stat);
sysinfo_set_item_val("kbd.address.data", NULL,
(uintptr_t) icp_hw_map.kbd_data);
 
}
 
 
/** @}
*/
/branches/network/kernel/arch/arm32/src/mm/frame.c
35,9 → 35,16
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/drivers/gxemul.h>
#include <config.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
 
44,7 → 51,7
/** Creates memory zones. */
void frame_arch_init(void)
{
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
last_frame = machine_get_memory_size();
/* All memory as one zone */
zone_create(0, ADDR2PFN(last_frame),
53,6 → 60,8
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
 
machine_frame_init();
}
 
/** Frees the boot page table. */
/branches/network/kernel/arch/arm32/src/interrupt.c
35,16 → 35,21
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <interrupt.h>
 
#ifdef MACHINE_testarm
#include <arch/mach/testarm/testarm.h>
#endif
 
#ifdef MACHINE_integratorcp
#include <arch/mach/integratorcp/integratorcp.h>
#endif
 
/** Initial size of a table holding interrupt handlers. */
#define IRQ_COUNT 8
 
static irq_t gxemul_timer_irq;
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
52,7 → 57,7
ipl_t interrupts_disable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
return ipl;
65,7 → 70,7
ipl_t interrupts_enable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
return ipl;
91,41 → 96,6
return current_status_reg_read();
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
132,16 → 102,7
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
gxemul_timer_start(GXEMUL_TIMER_FREQ);
machine_timer_irq_start();
}
 
/** @}
/branches/network/kernel/arch/arm32/src/exc_handler.S
0,0 → 1,199
#
# Copyright (c) 2009 Vineeth Pillai
# 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.
#
 
.text
 
.global irq_exception_entry
.global fiq_exception_entry
.global data_abort_exception_entry
.global prefetch_abort_exception_entry
.global undef_instr_exception_entry
.global swi_exception_entry
.global reset_exception_entry
 
 
# Switches to kernel stack and saves all registers there.
#
# The stack frame created by the function looks like:
#
# |_________________|
# | |
# | SPSR |
# | |
# |_________________|
# | Stack Pointer |
# | of |
# | Previous Mode |
# |_________________|
# | Return address |
# | of |
# | Previous Mode |
# |_________________|
# | R0 - R12 |
# | of |
# | Previous Mode |
# |_________________|
# | Return address |
# | from |
# |Exception Handler|
# |_________________|
# | |
#
#
 
.macro SAVE_REGS_TO_STACK
stmfd r13!, {r0-r3}
mov r3, sp
add sp, sp, #16
mrs r1, cpsr
bic r1, r1, #0x1f
mrs r2, spsr
and r0, r2, #0x1f
cmp r0, #0x10
bne 1f
 
# prev mode was usermode
mov r0, lr
 
# Switch to supervisor mode
orr r1, r1, #0x13
msr cpsr_c, r1
 
# Load sp with [supervisor_sp]
ldr r13, =supervisor_sp
ldr r13, [r13]
 
# Populate the stack frame
msr spsr, r2
mov lr, r0
stmfd r13!, {lr}
stmfd r13!, {r4-r12}
ldmfd r3!, {r4-r7}
stmfd r13!, {r4-r7}
stmfd r13!, {r13, lr}^
stmfd r13!, {r2}
b 2f
 
# mode was not usermode
1:
# Switch to previous mode which is undoubtedly the supervisor mode
orr r1, r1, r0
mov r0, lr
msr cpsr_c, r1
 
# Populate the stack frame
mov r1, sp
stmfd r13!, {r0}
stmfd r13!, {r4-r12}
 
# Store r0-r3 in r4-r7 and then push it on to stack
ldmfd r3!, {r4-r7}
stmfd r13!, {r4-r7}
 
# Push return address and stack pointer on to stack
stmfd r13!, {lr}
stmfd r13!, {r1}
mov lr, r0
msr spsr, r2
stmfd r13!, {r2}
2:
.endm
 
.macro LOAD_REGS_FROM_STACK
ldmfd r13!, {r0}
msr spsr, r0
and r0, r0, #0x1f
cmp r0, #0x10
bne 1f
 
# return to user mode
ldmfd r13!, {r13, lr}^
b 2f
 
# return to non-user mode
1:
ldmfd r13!, {r1, lr}
 
2:
ldmfd r13!, {r0-r12, pc}^
.endm
 
reset_exception_entry:
SAVE_REGS_TO_STACK
mov r0, #0
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
irq_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #5
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
fiq_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #6
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
undef_instr_exception_entry:
SAVE_REGS_TO_STACK
mov r0, #1
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
prefetch_abort_exception_entry:
sub lr, lr, #4
SAVE_REGS_TO_STACK
mov r0, #3
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
data_abort_exception_entry:
sub lr, lr, #8
SAVE_REGS_TO_STACK
mov r0, #4
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
swi_exception_entry:
ldr r13, =exc_stack
SAVE_REGS_TO_STACK
mov r0, #2
mov r1, r13
bl exc_dispatch
LOAD_REGS_FROM_STACK
 
/branches/network/kernel/arch/arm32/src/drivers/gxemul.c
File deleted
/branches/network/kernel/arch/ppc32/src/ppc32.c
36,6 → 36,7
#include <arch.h>
#include <arch/boot/boot.h>
#include <genarch/drivers/via-cuda/cuda.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
91,10 → 92,10
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
visual = VISUAL_RGB_5_5_5_BE;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
visual = VISUAL_BGR_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
117,31 → 118,6
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
if (bootinfo.macio.addr) {
/* Initialize PIC */
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_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
indev_t *sink = stdin_wire();
cuda_wire(cuda_instance, sink);
}
#endif
}
/* Merge all zones to 1 big zone */
zone_merge_all();
}
157,6 → 133,35
 
void arch_post_smp_init(void)
{
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
 
#ifdef CONFIG_MAC_KBD
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_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
cuda_wire(cuda_instance, kbrd);
pic_enable_interrupt(IRQ_CUDA);
}
}
#endif
}
}
 
void calibrate_delay_loop(void)
/branches/network/kernel/arch/mips32/include/context_offset.h
86,7 → 86,7
#define EOFFSET_STATUS 0x58
#define EOFFSET_EPC 0x5c
#define EOFFSET_K1 0x60
#define REGISTER_SPACE 100
#define REGISTER_SPACE 104 /* respect stack alignment */
 
#ifdef __ASM__
 
/branches/network/kernel/arch/mips32/include/atomic.h
88,6 → 88,13
return v;
}
 
static inline void atomic_lock_arch(atomic_t *val) {
do {
while (val->count)
;
} while (test_and_set(val));
}
 
#endif
 
/** @}
/branches/network/kernel/arch/mips32/src/mips32.c
141,7 → 141,7
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
.visual = VISUAL_RGB_8_8_8,
};
fb_init(&gxemul_prop);
#else
/branches/network/kernel/arch/ia32/src/drivers/vesa.c
85,15 → 85,15
if ((vesa_red_mask == 5) && (vesa_red_pos == 10)
&& (vesa_green_mask == 5) && (vesa_green_pos == 5)
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0))
visual = VISUAL_RGB_5_5_5;
visual = VISUAL_RGB_5_5_5_LE;
else
visual = VISUAL_RGB_5_6_5;
visual = VISUAL_RGB_5_6_5_LE;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
visual = VISUAL_BGR_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
visual = VISUAL_BGR_8_8_8_0;
break;
default:
panic("Unsupported bits per pixel.");
/branches/network/uspace/app/bdsh/cmds/modules/cp/cp.c
172,7 → 172,8
 
int cmd_cp(char **argv)
{
unsigned int argc, buffer = 0, verbose = 0;
unsigned int argc, verbose = 0;
int buffer = 0;
int c, opt_ind;
int64_t ret;
 
/branches/network/uspace/app/bdsh/cmds/modules/rm/rm.c
209,7 → 209,7
}
}
 
if (optind == argc) {
if ((unsigned) optind == argc) {
cli_error(CL_EFAIL,
"%s: insufficient arguments. Try %s --help", cmdname, cmdname);
rm_end(&rm);
/branches/network/uspace/app/bdsh/cmds/modules/ls/ls.c
50,48 → 50,9
 
static char *cmdname = "ls";
 
static inline off_t flen(const char *f)
{
int fd;
off_t size;
 
fd = open(f, O_RDONLY);
if (fd == -1)
return 0;
 
size = lseek(fd, 0, SEEK_END);
close(fd);
 
if (size < 0)
size = 0;
 
return size;
}
 
static unsigned int ls_scope(const char *path)
{
int fd;
DIR *dirp;
 
dirp = opendir(path);
if (dirp) {
closedir(dirp);
return LS_DIR;
}
 
fd = open(path, O_RDONLY);
if (fd > 0) {
close(fd);
return LS_FILE;
}
 
return LS_BOGUS;
}
 
static void ls_scan_dir(const char *d, DIR *dirp)
{
struct dirent *dp;
unsigned int scope;
char *buff;
 
if (! dirp)
108,20 → 69,7
/* Don't worry if inserting a double slash, this will be fixed by
* absolutize() later with subsequent calls to open() or readdir() */
snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
scope = ls_scope(buff);
switch (scope) {
case LS_DIR:
ls_print_dir(dp->d_name);
break;
case LS_FILE:
ls_print_file(dp->d_name, buff);
break;
case LS_BOGUS:
/* Odd chance it was deleted from the time readdir() found
* it and the time that it was scoped */
printf("ls: skipping bogus node %s\n", dp->d_name);
break;
}
ls_print(dp->d_name, buff);
}
 
free(buff);
129,7 → 77,7
return;
}
 
/* ls_print_* currently does nothing more than print the entry.
/* ls_print currently does nothing more than print the entry.
* in the future, we will likely pass the absolute path, and
* some sort of ls_options structure that controls how each
* entry is printed and what is printed about it.
136,17 → 84,24
*
* Now we just print basic DOS style lists */
 
static void ls_print_dir(const char *d)
static void ls_print(const char *name, const char *pathname)
{
printf("%-40s\t<dir>\n", d);
struct stat s;
int rc;
 
return;
}
rc = stat(pathname, &s);
if (rc != 0) {
/* Odd chance it was deleted from the time readdir() found it */
printf("ls: skipping bogus node %s\n", pathname);
printf("rc=%d\n", rc);
return;
}
if (s.is_file)
printf("%-40s\t%llu\n", name, (long long) s.size);
else
printf("%-40s\n", name);
 
static void ls_print_file(const char *name, const char *pathname)
{
printf("%-40s\t%llu\n", name, (long long) flen(pathname));
 
return;
}
 
166,7 → 121,7
int cmd_ls(char **argv)
{
unsigned int argc;
unsigned int scope;
struct stat s;
char *buff;
DIR *dirp;
 
184,19 → 139,17
else
str_cpy(buff, PATH_MAX, argv[1]);
 
scope = ls_scope(buff);
 
switch (scope) {
case LS_BOGUS:
if (stat(buff, &s)) {
cli_error(CL_ENOENT, buff);
free(buff);
return CMD_FAILURE;
case LS_FILE:
ls_print_file(buff, buff);
break;
case LS_DIR:
}
 
if (s.is_file) {
ls_print(buff, buff);
} else {
dirp = opendir(buff);
if (! dirp) {
if (!dirp) {
/* May have been deleted between scoping it and opening it */
cli_error(CL_EFAIL, "Could not stat %s", buff);
free(buff);
204,7 → 157,6
}
ls_scan_dir(buff, dirp);
closedir(dirp);
break;
}
 
free(buff);
/branches/network/uspace/app/bdsh/cmds/modules/ls/ls.h
6,11 → 6,8
#define LS_FILE 1
#define LS_DIR 2
 
 
static unsigned int ls_scope(const char *);
static void ls_scan_dir(const char *, DIR *);
static void ls_print_dir(const char *);
static void ls_print_file(const char *, const char *);
static void ls_print(const char *, const char *);
 
#endif /* LS_H */
 
/branches/network/uspace/app/bdsh/util.c
53,14 → 53,6
* string */
unsigned int cli_set_prompt(cliuser_t *usr)
{
usr->prompt = (char *) realloc(usr->prompt, PATH_MAX);
if (NULL == usr->prompt) {
cli_error(CL_ENOMEM, "Can not allocate prompt");
cli_errno = CL_ENOMEM;
return 1;
}
memset(usr->prompt, 0, sizeof(usr->prompt));
 
usr->cwd = (char *) realloc(usr->cwd, PATH_MAX);
if (NULL == usr->cwd) {
cli_error(CL_ENOMEM, "Can not allocate cwd");
67,13 → 59,11
cli_errno = CL_ENOMEM;
return 1;
}
memset(usr->cwd, 0, sizeof(usr->cwd));
 
usr->cwd = getcwd(usr->cwd, PATH_MAX - 1);
 
if (NULL == usr->cwd)
if (!getcwd(usr->cwd, PATH_MAX))
snprintf(usr->cwd, PATH_MAX, "(unknown)");
 
if (usr->prompt)
free(usr->prompt);
asprintf(&usr->prompt, "%s # ", usr->cwd);
 
return 0;
/branches/network/uspace/app/bdsh/exec.c
112,7 → 112,9
unsigned int try_exec(char *cmd, char **argv)
{
task_id_t tid;
task_exit_t texit;
char *tmp;
int retval;
 
tmp = str_dup(find_command(cmd));
free(found);
125,6 → 127,12
return 1;
}
task_wait(tid);
task_wait(tid, &texit, &retval);
if (texit != TASK_EXIT_NORMAL) {
printf("Command failed (unexpectedly terminated).\n");
} else if (retval != 0) {
printf("Command failed (return value %d).\n", retval);
}
 
return 0;
}
/branches/network/uspace/app/init/init.c
41,11 → 41,13
#include <bool.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <task.h>
#include <malloc.h>
#include <macros.h>
#include <string.h>
#include <devmap.h>
#include <config.h>
#include "init.h"
 
static void info_print(void)
55,31 → 57,31
 
static bool mount_root(const char *fstype)
{
int rc = -1;
char *opts = "";
const char *root_dev = "initrd";
if (str_cmp(fstype, "tmpfs") == 0)
opts = "restore";
 
while (rc < 0) {
rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Root filesystem mounted, %s at %s\n",
fstype, root_dev);
break;
case EBUSY:
printf(NAME ": Root filesystem already mounted\n");
break;
case ELIMIT:
printf(NAME ": Unable to mount root filesystem\n");
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (%s)\n", fstype);
return false;
}
int rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Root filesystem mounted, %s at %s\n",
fstype, root_dev);
break;
case EBUSY:
printf(NAME ": Root filesystem already mounted\n");
return false;
case ELIMIT:
printf(NAME ": Unable to mount root filesystem\n");
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (%s)\n", fstype);
return false;
default:
printf(NAME ": Error mounting root filesystem (%d)\n", rc);
return false;
}
return true;
87,27 → 89,39
 
static bool mount_devfs(void)
{
int rc = -1;
char null[MAX_DEVICE_NAME];
int null_id = devmap_null_create();
while (rc < 0) {
rc = mount("devfs", "/dev", "null", "", IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Device filesystem mounted\n");
break;
case EBUSY:
printf(NAME ": Device filesystem already mounted\n");
break;
case ELIMIT:
printf(NAME ": Unable to mount device filesystem\n");
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (devfs)\n");
return false;
}
if (null_id == -1) {
printf(NAME ": Unable to create null device\n");
return false;
}
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Device filesystem mounted\n");
break;
case EBUSY:
printf(NAME ": Device filesystem already mounted\n");
devmap_null_destroy(null_id);
return false;
case ELIMIT:
printf(NAME ": Unable to mount device filesystem\n");
devmap_null_destroy(null_id);
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (devfs)\n");
devmap_null_destroy(null_id);
return false;
default:
printf(NAME ": Error mounting device filesystem (%d)\n", rc);
devmap_null_destroy(null_id);
return false;
}
return true;
}
 
114,7 → 128,11
static void spawn(char *fname)
{
char *argv[2];
struct stat s;
if (stat(fname, &s) == ENOENT)
return;
printf(NAME ": Spawning %s\n", fname);
argv[0] = fname;
124,6 → 142,40
printf(NAME ": Error spawning %s\n", fname);
}
 
static void srv_start(char *fname)
{
char *argv[2];
task_id_t id;
task_exit_t texit;
int rc, retval;
struct stat s;
if (stat(fname, &s) == ENOENT)
return;
printf(NAME ": Starting %s\n", fname);
argv[0] = fname;
argv[1] = NULL;
id = task_spawn(fname, argv);
if (!id) {
printf(NAME ": Error spawning %s\n", fname);
return;
}
 
rc = task_wait(id, &texit, &retval);
if (rc != EOK) {
printf(NAME ": Error waiting for %s\n", fname);
return;
}
 
if (texit != TASK_EXIT_NORMAL || retval != 0) {
printf(NAME ": Server %s failed to start (returned %d)\n",
fname, retval);
}
}
 
static void getvc(char *dev, char *app)
{
char *argv[4];
150,7 → 202,7
}
}
 
void mount_data(void)
static void mount_data(void)
{
int rc;
 
186,12 → 238,24
spawn("/srv/console");
spawn("/srv/fhc");
spawn("/srv/obio");
spawn("/srv/ata_bd");
spawn("/srv/gxe_bd");
 
usleep(250000);
mount_data();
/*
* Start these synchronously so that mount_data() can be
* non-blocking.
*/
#ifdef CONFIG_START_BD
srv_start("/srv/ata_bd");
srv_start("/srv/gxe_bd");
#else
(void) srv_start;
#endif
 
#ifdef CONFIG_MOUNT_DATA
mount_data();
#else
(void) mount_data;
#endif
 
getvc("vc0", "/app/bdsh");
getvc("vc1", "/app/bdsh");
getvc("vc2", "/app/bdsh");
/branches/network/uspace/app/init/Makefile
34,6 → 34,7
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../..
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
/branches/network/uspace/app/tester/devmap/devmap1.def
File deleted
/branches/network/uspace/app/tester/devmap/devmap1.c
File deleted
/branches/network/uspace/app/tester/console/console1.c
46,78 → 46,78
[COLOR_WHITE] = "white"
};
 
char * test_console1(bool quiet)
char *test_console1(void)
{
int i, j;
 
printf("Style test: ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf("normal ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_EMPHASIS);
printf("emphasized");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf(".\n");
 
printf("Foreground color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
if (!test_quiet) {
printf("Style test: ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf("normal ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_EMPHASIS);
printf("emphasized");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf(".\n");
unsigned int i;
unsigned int j;
printf("\nForeground color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
fflush(stdout);
console_set_color(fphone(stdout), i, COLOR_WHITE,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
}
fflush(stdout);
console_set_color(fphone(stdout), i, COLOR_WHITE,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
printf("\nBackground color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
fflush(stdout);
console_set_color(fphone(stdout), COLOR_WHITE, i,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
printf("\nRGB colors test:\n");
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 16);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
 
printf("Background color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_color(fphone(stdout), COLOR_WHITE, i,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 8);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
 
printf("Now let's test RGB colors:\n");
 
for (i = 0; i < 255; i += 16) {
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i);
putchar('X');
}
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 16);
putchar('X');
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
 
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 8);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
 
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
 
printf("[press a key]\n");
getchar();
 
return NULL;
}
/branches/network/uspace/app/tester/stdio/stdio1.c
31,55 → 31,60
#include <errno.h>
#include "../tester.h"
 
#define BUF_SIZE 32
#define BUF_SIZE 32
 
static char buf[BUF_SIZE + 1];
 
char * test_stdio1(bool quiet)
char *test_stdio1(void)
{
FILE *f;
FILE *file;
char *file_name = "/readme";
size_t n;
int c;
 
printf("Open file '%s'\n", file_name);
TPRINTF("Open file \"%s\"...", file_name);
errno = 0;
f = fopen(file_name, "rt");
 
if (f == NULL) printf("errno = %d\n", errno);
 
if (f == NULL)
return "Failed opening file.";
 
n = fread(buf, 1, BUF_SIZE, f);
if (ferror(f)) {
fclose(f);
return "Failed reading file.";
}
 
printf("Read %d bytes.\n", n);
 
buf[n] = '\0';
printf("Read string '%s'.\n", buf);
 
printf("Seek to beginning.\n");
if (fseek(f, 0, SEEK_SET) != 0) {
fclose(f);
return "Failed seeking.";
}
 
printf("Read using fgetc().\n");
file = fopen(file_name, "rt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("Read file...");
size_t cnt = fread(buf, 1, BUF_SIZE, file);
if (ferror(file)) {
TPRINTF("errno = %d\n", errno);
fclose(file);
return "Failed reading file";
} else
TPRINTF("OK\n");
buf[cnt] = '\0';
TPRINTF("Read %u bytes, string \"%s\"\n", cnt, buf);
TPRINTF("Seek to beginning...");
if (fseek(file, 0, SEEK_SET) != 0) {
TPRINTF("errno = %d\n", errno);
fclose(file);
return "Failed seeking in file";
} else
TPRINTF("OK\n");
TPRINTF("Read using fgetc()...");
while (true) {
c = fgetc(f);
if (c == EOF) break;
 
printf("'%c'", c);
int c = fgetc(file);
if (c == EOF)
break;
TPRINTF(".");
}
 
printf("[EOF]\n");
printf("Closing.\n");
 
if (fclose(f) != 0)
return "Failed closing.";
 
TPRINTF("[EOF]\n");
TPRINTF("Close...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
return NULL;
}
/branches/network/uspace/app/tester/stdio/stdio2.c
31,38 → 31,53
#include <errno.h>
#include "../tester.h"
 
char * test_stdio2(bool quiet)
char *test_stdio2(void)
{
FILE *f;
FILE *file;
char *file_name = "/test";
int c;
 
printf("Open file '%s' for writing\n", file_name);
TPRINTF("Open file \"%s\" for writing...", file_name);
errno = 0;
f = fopen(file_name, "wt");
 
if (f == NULL)
return "Failed opening file.";
 
fprintf(f, "Integer: %d, string: '%s'\n", 42, "Hello!");
if (fclose(f) != 0)
return "Failed closing file.";
 
printf("Open file '%s' for reading\n", file_name);
 
f = fopen(file_name, "rt");
if (f == NULL)
return "Failed opening file.";
 
printf("File contains:\n");
file = fopen(file_name, "wt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("Write to file...");
fprintf(file, "integer: %u, string: \"%s\"", 42, "Hello!");
TPRINTF("OK\n");
TPRINTF("Close...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
TPRINTF("Open file \"%s\" for reading...", file_name);
file = fopen(file_name, "rt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("File contains:\n");
while (true) {
c = fgetc(f);
if (c == EOF) break;
putchar(c);
int c = fgetc(file);
if (c == EOF)
break;
TPRINTF("%c", c);
}
 
if (fclose(f) != 0)
return "Failed closing file.";
 
TPRINTF("\nClose...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
return NULL;
}
/branches/network/uspace/app/tester/tester.c
27,10 → 27,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup tester User space Tester
* @brief User space testing infrastructure.
/** @addtogroup tester User space tester
* @brief User space testing infrastructure.
* @{
*/
*/
/**
* @file
*/
37,48 → 37,44
 
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "tester.h"
 
int myservice = 0;
int phones[MAX_PHONES];
int connections[MAX_CONNECTIONS];
ipc_callid_t callids[MAX_CONNECTIONS];
bool test_quiet;
int test_argc;
char **test_argv;
 
test_t tests[] = {
#include "thread/thread1.def"
#include "print/print1.def"
#include "print/print2.def"
#include "print/print3.def"
#include "print/print4.def"
#include "console/console1.def"
#include "stdio/stdio1.def"
#include "stdio/stdio2.def"
#include "fault/fault1.def"
#include "fault/fault2.def"
#include "vfs/vfs1.def"
#include "ipc/ping_pong.def"
#include "ipc/register.def"
#include "ipc/connect.def"
#include "ipc/send_async.def"
#include "ipc/send_sync.def"
#include "ipc/answer.def"
#include "ipc/hangup.def"
#include "ipc/ping_pong.def"
#include "devmap/devmap1.def"
#include "loop/loop1.def"
#include "vfs/vfs1.def"
#include "console/console1.def"
#include "stdio/stdio1.def"
#include "stdio/stdio2.def"
{NULL, NULL, NULL}
#include "mm/malloc1.def"
{NULL, NULL, NULL, false}
};
 
static bool run_test(test_t *test)
{
printf("%s\t\t%s\n", test->name, test->desc);
/* Execute the test */
char * ret = test->entry(false);
char *ret = test->entry();
if (ret == NULL) {
printf("Test passed\n\n");
printf("\nTest passed\n");
return true;
}
 
printf("%s\n\n", ret);
printf("\n%s\n", ret);
return false;
}
 
87,11 → 83,12
test_t *test;
unsigned int i = 0;
unsigned int n = 0;
 
printf("\n*** Running all safe tests ***\n\n");
 
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
printf("%s (%s)\n", test->name, test->desc);
if (run_test(test))
i++;
else
98,64 → 95,52
n++;
}
}
 
printf("\nSafe tests completed, %u tests run, %u passed.\n\n", i + n, i);
printf("\nCompleted, %u tests run, %u passed.\n", i + n, i);
}
 
static void list_tests(void)
{
size_t len = 0;
test_t *test;
char c = 'a';
for (test = tests; test->name != NULL; test++) {
if (str_length(test->name) > len)
len = str_length(test->name);
}
for (test = tests; test->name != NULL; test++, c++)
printf("%c\t%s\t\t%s%s\n", c, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
for (test = tests; test->name != NULL; test++)
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("*\t\t\tRun all safe tests\n");
printf("%-*s Run all safe tests\n", len, "*");
}
 
int main(int argc, char **argv)
int main(int argc, char *argv[])
{
printf("Number of arguments: %d\n", argc);
if (argv) {
printf("Arguments:");
while (*argv) {
printf(" '%s'", *argv++);
}
printf("\n");
if (argc < 2) {
printf("Usage:\n\n");
printf("%s <test> [args ...]\n\n", argv[0]);
list_tests();
return 0;
}
 
while (1) {
char c;
test_t *test;
list_tests();
printf("> ");
fflush(stdout);
c = getchar();
printf("%c\n", c);
if ((c >= 'a') && (c <= 'z')) {
for (test = tests; test->name != NULL; test++, c--)
if (c == 'a')
break;
if (test->name == NULL)
printf("Unknown test\n\n");
else
run_test(test);
} else if (c == '*') {
run_safe_tests();
} else if (c < 0) {
/* got EOF */
break;
} else {
printf("Invalid test\n\n");
test_quiet = false;
test_argc = argc - 2;
test_argv = argv + 2;
if (str_cmp(argv[1], "*") == 0) {
run_safe_tests();
return 0;
}
test_t *test;
for (test = tests; test->name != NULL; test++) {
if (str_cmp(argv[1], test->name) == 0) {
return (run_test(test) ? 0 : -1);
}
}
 
return 0;
printf("Unknown test \"%s\"\n", argv[1]);
return -2;
}
 
/** @}
/branches/network/uspace/app/tester/thread/thread1.c
27,7 → 27,8
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#define THREADS 5
#define THREADS 20
#define DELAY 10
 
#include <atomic.h>
#include <thread.h>
37,45 → 38,42
 
static atomic_t finish;
static atomic_t threads_finished;
static bool sh_quiet;
 
static void threadtest(void *data)
{
thread_detach(thread_get_id());
 
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%llu ", thread_get_id());
while (atomic_get(&finish))
usleep(100000);
}
atomic_inc(&threads_finished);
}
 
char * test_thread1(bool quiet)
char *test_thread1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
unsigned int i;
int total = 0;
atomic_set(&finish, 1);
atomic_set(&threads_finished, 0);
 
for (i = 0; i < THREADS; i++) {
TPRINTF("Creating threads");
for (i = 0; i < THREADS; i++) {
if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("\nCould not create thread %u\n", i);
break;
}
TPRINTF(".");
total++;
}
if (!quiet)
printf("Running threads for 10 seconds...\n");
sleep(10);
TPRINTF("\nRunning threads for %u seconds...", DELAY);
sleep(DELAY);
TPRINTF("\n");
atomic_set(&finish, 0);
while (atomic_get(&threads_finished) < total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_finished));
TPRINTF("Threads left: %u\n", total - atomic_get(&threads_finished));
sleep(1);
}
/branches/network/uspace/app/tester/loop/loop1.c
30,12 → 30,11
#include <stdlib.h>
#include "../tester.h"
 
char *test_loop1(bool quiet)
char *test_loop1(void)
{
printf("Looping...\n");
while (1);
printf("Survived endless loop?!!\n");
 
return NULL;
TPRINTF("Looping...");
while (true);
TPRINTF("\n");
return "Survived endless loop";
}
 
/branches/network/uspace/app/tester/mm/malloc1.def
0,0 → 1,6
{
"malloc1",
"Memory allocator test",
&test_malloc1,
true
},
/branches/network/uspace/app/tester/mm/malloc1.c
0,0 → 1,651
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Tomas Bures
* Copyright (c) 2009 Lubomir Bulej
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <malloc.h>
#include "../tester.h"
 
/*
* The test consists of several phases which differ in the size of blocks
* they allocate. The size of blocks is given as a range of minimum and
* maximum allowed size. Each of the phases is divided into 3 subphases which
* differ in the probability of free and alloc actions. Second subphase is
* started when malloc returns 'out of memory' or when MAX_ALLOC is reached.
* Third subphase is started after a given number of cycles. The third subphase
* as well as the whole phase ends when all memory blocks are released.
*/
 
/**
* sizeof_array
* @array array to determine the size of
*
* Returns the size of @array in array elements.
*/
#define sizeof_array(array) \
(sizeof(array) / sizeof((array)[0]))
 
#define MAX_ALLOC (16 * 1024 * 1024)
 
/*
* Subphase control structures: subphase termination conditions,
* probabilities of individual actions, subphase control structure.
*/
 
typedef struct {
unsigned int max_cycles;
unsigned int no_memory;
unsigned int no_allocated;
} sp_term_cond_s;
 
typedef struct {
unsigned int alloc;
unsigned int free;
} sp_action_prob_s;
 
typedef struct {
char *name;
sp_term_cond_s cond;
sp_action_prob_s prob;
} subphase_s;
 
 
/*
* Phase control structures: The minimum and maximum block size that
* can be allocated during the phase execution, phase control structure.
*/
 
typedef struct {
size_t min_block_size;
size_t max_block_size;
} ph_alloc_size_s;
 
typedef struct {
char *name;
ph_alloc_size_s alloc;
subphase_s *subphases;
} phase_s;
 
 
/*
* Subphases are defined separately here. This is for two reasons:
* 1) data are not duplicated, 2) we don't have to state beforehand
* how many subphases a phase contains.
*/
static subphase_s subphases_32B[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 200,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 90,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 200,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 10,
.free = 100
}
}
};
 
static subphase_s subphases_128K[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 0,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 70,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 30,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 30,
.free = 100
}
}
};
 
static subphase_s subphases_default[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 0,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 90,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 200,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 10,
.free = 100
}
}
};
 
 
/*
* Phase definitions.
*/
static phase_s phases[] = {
{
.name = "32 B memory blocks",
.alloc = {
.min_block_size = 32,
.max_block_size = 32
},
.subphases = subphases_32B
},
{
.name = "128 KB memory blocks",
.alloc = {
.min_block_size = 128 * 1024,
.max_block_size = 128 * 1024
},
.subphases = subphases_128K
},
{
.name = "2500 B memory blocks",
.alloc = {
.min_block_size = 2500,
.max_block_size = 2500
},
.subphases = subphases_default
},
{
.name = "1 B .. 250000 B memory blocks",
.alloc = {
.min_block_size = 1,
.max_block_size = 250000
},
.subphases = subphases_default
}
};
 
 
/*
* Global error flag. The flag is set if an error
* is encountered (overlapping blocks, inconsistent
* block data, etc.)
*/
static bool error_flag = false;
 
/*
* Memory accounting: the amount of allocated memory and the
* number and list of allocated blocks.
*/
static size_t mem_allocated;
static size_t mem_blocks_count;
 
static LIST_INITIALIZE(mem_blocks);
 
typedef struct {
/* Address of the start of the block */
void *addr;
/* Size of the memory block */
size_t size;
/* link to other blocks */
link_t link;
} mem_block_s;
 
typedef mem_block_s *mem_block_t;
 
 
/** init_mem
*
* Initializes the memory accounting structures.
*
*/
static void init_mem(void)
{
mem_allocated = 0;
mem_blocks_count = 0;
}
 
 
static bool overlap_match(link_t *entry, void *addr, size_t size)
{
mem_block_t mblk = list_get_instance(entry, mem_block_s, link);
/* Entry block control structure <mbeg, mend) */
uint8_t *mbeg = (uint8_t *) mblk;
uint8_t *mend = (uint8_t *) mblk + sizeof(mem_block_s);
/* Entry block memory <bbeg, bend) */
uint8_t *bbeg = (uint8_t *) mblk->addr;
uint8_t *bend = (uint8_t *) mblk->addr + mblk->size;
/* Data block <dbeg, dend) */
uint8_t *dbeg = (uint8_t *) addr;
uint8_t *dend = (uint8_t *) addr + size;
/* Check for overlaps */
if (((mbeg >= dbeg) && (mbeg < dend)) ||
((mend > dbeg) && (mend <= dend)) ||
((bbeg >= dbeg) && (bbeg < dend)) ||
((bend > dbeg) && (bend <= dend)))
return true;
return false;
}
 
 
/** test_overlap
*
* Test whether a block starting at @addr overlaps with another, previously
* allocated memory block or its control structure.
*
* @param addr Initial address of the block
* @param size Size of the block
*
* @return false if the block does not overlap.
*
*/
static int test_overlap(void *addr, size_t size)
{
link_t *entry;
bool fnd = false;
for (entry = mem_blocks.next; entry != &mem_blocks; entry = entry->next) {
if (overlap_match(entry, addr, size)) {
fnd = true;
break;
}
}
return fnd;
}
 
 
/** checked_malloc
*
* Allocate @size bytes of memory and check whether the chunk comes
* from the non-mapped memory region and whether the chunk overlaps
* with other, previously allocated, chunks.
*
* @param size Amount of memory to allocate
*
* @return NULL if the allocation failed. Sets the global error_flag to
* true if the allocation succeeded but is illegal.
*
*/
static void *checked_malloc(size_t size)
{
void *data;
/* Allocate the chunk of memory */
data = malloc(size);
if (data == NULL)
return NULL;
/* Check for overlaps with other chunks */
if (test_overlap(data, size)) {
TPRINTF("\nError: Allocated block overlaps with another "
"previously allocated block.\n");
error_flag = true;
}
return data;
}
 
 
/** alloc_block
*
* Allocate a block of memory of @size bytes and add record about it into
* the mem_blocks list. Return a pointer to the block holder structure or
* NULL if the allocation failed.
*
* If the allocation is illegal (e.g. the memory does not come from the
* right region or some of the allocated blocks overlap with others),
* set the global error_flag.
*
* @param size Size of the memory block
*
*/
static mem_block_t alloc_block(size_t size)
{
/* Check for allocation limit */
if (mem_allocated >= MAX_ALLOC)
return NULL;
/* Allocate the block holder */
mem_block_t block = (mem_block_t) checked_malloc(sizeof(mem_block_s));
if (block == NULL)
return NULL;
link_initialize(&block->link);
/* Allocate the block memory */
block->addr = checked_malloc(size);
if (block->addr == NULL) {
free(block);
return NULL;
}
block->size = size;
/* Register the allocated block */
list_append(&block->link, &mem_blocks);
mem_allocated += size + sizeof(mem_block_s);
mem_blocks_count++;
return block;
}
 
 
/** free_block
*
* Free the block of memory and the block control structure allocated by
* alloc_block. Set the global error_flag if an error occurs.
*
* @param block Block control structure
*
*/
static void free_block(mem_block_t block)
{
/* Unregister the block */
list_remove(&block->link);
mem_allocated -= block->size + sizeof(mem_block_s);
mem_blocks_count--;
/* Free the memory */
free(block->addr);
free(block);
}
 
 
/** expected_value
*
* Compute the expected value of a byte located at @pos in memory
* block described by @blk.
*
* @param blk Memory block control structure
* @param pos Position in the memory block data area
*
*/
static inline uint8_t expected_value(mem_block_t blk, uint8_t *pos)
{
return ((unsigned long) blk ^ (unsigned long) pos) & 0xff;
}
 
 
/** fill_block
*
* Fill the memory block controlled by @blk with data.
*
* @param blk Memory block control structure
*
*/
static void fill_block(mem_block_t blk)
{
uint8_t *pos;
uint8_t *end;
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++)
*pos = expected_value(blk, pos);
}
 
 
/** check_block
*
* Check whether the block @blk contains the data it was filled with.
* Set global error_flag if an error occurs.
*
* @param blk Memory block control structure
*
*/
static void check_block(mem_block_t blk)
{
uint8_t *pos;
uint8_t *end;
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++) {
if (*pos != expected_value (blk, pos)) {
TPRINTF("\nError: Corrupted content of a data block.\n");
error_flag = true;
return;
}
}
}
 
 
static link_t *list_get_nth(link_t *list, unsigned int i)
{
unsigned int cnt = 0;
link_t *entry;
for (entry = list->next; entry != list; entry = entry->next) {
if (cnt == i)
return entry;
cnt++;
}
return NULL;
}
 
 
/** get_random_block
*
* Select a random memory block from the list of allocated blocks.
*
* @return Block control structure or NULL if the list is empty.
*
*/
static mem_block_t get_random_block(void)
{
if (mem_blocks_count == 0)
return NULL;
unsigned int blkidx = rand() % mem_blocks_count;
link_t *entry = list_get_nth(&mem_blocks, blkidx);
if (entry == NULL) {
TPRINTF("\nError: Corrupted list of allocated memory blocks.\n");
error_flag = true;
}
return list_get_instance(entry, mem_block_s, link);
}
 
 
#define RETURN_IF_ERROR \
{ \
if (error_flag) \
return; \
}
 
 
static void do_subphase(phase_s *phase, subphase_s *subphase)
{
unsigned int cycles;
for (cycles = 0; /* always */; cycles++) {
if (subphase->cond.max_cycles &&
cycles >= subphase->cond.max_cycles) {
/*
* We have performed the required number of
* cycles. End the current subphase.
*/
break;
}
/*
* Decide whether we alloc or free memory in this step.
*/
unsigned int rnd = rand() % 100;
if (rnd < subphase->prob.alloc) {
/* Compute a random number lying in interval <min_block_size, max_block_size> */
int alloc = phase->alloc.min_block_size +
(rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
mem_block_t blk = alloc_block(alloc);
RETURN_IF_ERROR;
if (blk == NULL) {
TPRINTF("F(A)");
if (subphase->cond.no_memory) {
/* We filled the memory. Proceed to next subphase */
break;
}
} else {
TPRINTF("A");
fill_block(blk);
}
} else if (rnd < subphase->prob.free) {
mem_block_t blk = get_random_block();
if (blk == NULL) {
TPRINTF("F(R)");
if (subphase->cond.no_allocated) {
/* We free all the memory. Proceed to next subphase. */
break;
}
} else {
TPRINTF("R");
check_block(blk);
RETURN_IF_ERROR;
free_block(blk);
RETURN_IF_ERROR;
}
}
}
TPRINTF("\n.. finished.\n");
}
 
 
static void do_phase(phase_s *phase)
{
unsigned int subno;
for (subno = 0; subno < 3; subno++) {
subphase_s *subphase = & phase->subphases [subno];
TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
do_subphase(phase, subphase);
RETURN_IF_ERROR;
}
}
 
char *test_malloc1(void)
{
init_mem();
unsigned int phaseno;
for (phaseno = 0; phaseno < sizeof_array(phases); phaseno++) {
phase_s *phase = &phases[phaseno];
TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
do_phase(phase);
if (error_flag)
break;
TPRINTF("Phase finished.\n");
}
if (error_flag)
return "Test failed";
return NULL;
}
/branches/network/uspace/app/tester/fault/fault1.c
29,7 → 29,7
 
#include "../tester.h"
 
char * test_fault1(bool quiet)
char *test_fault1(void)
{
((int *)(0))[1] = 0;
/branches/network/uspace/app/tester/fault/fault2.c
29,7 → 29,7
 
#include "../tester.h"
 
char * test_fault2(bool quiet)
char *test_fault2(void)
{
volatile long long var;
volatile int var1;
/branches/network/uspace/app/tester/ipc/send_sync.def
File deleted
/branches/network/uspace/app/tester/ipc/answer.def
File deleted
/branches/network/uspace/app/tester/ipc/send_async.def
File deleted
/branches/network/uspace/app/tester/ipc/answer.c
File deleted
/branches/network/uspace/app/tester/ipc/hangup.def
File deleted
/branches/network/uspace/app/tester/ipc/send_async.c
File deleted
/branches/network/uspace/app/tester/ipc/send_sync.c
File deleted
/branches/network/uspace/app/tester/ipc/hangup.c
File deleted
/branches/network/uspace/app/tester/ipc/ping_pong.c
37,20 → 37,23
#define DURATION_SECS 10
#define COUNT_GRANULARITY 100
 
char *test_ping_pong(bool quiet)
char *test_ping_pong(void)
{
printf("Pinging ns server for %d seconds...\n", DURATION_SECS);
TPRINTF("Pinging ns server for %d seconds...", DURATION_SECS);
struct timeval start;
if (gettimeofday(&start, NULL) != 0)
return "Failed getting the time.";
if (gettimeofday(&start, NULL) != 0) {
TPRINTF("\n");
return "Failed getting the time";
}
uint64_t count = 0;
while (true) {
struct timeval now;
if (gettimeofday(&now, NULL) != 0)
return "Failed getting the time.";
if (gettimeofday(&now, NULL) != 0) {
TPRINTF("\n");
return "Failed getting the time";
}
if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L)
break;
59,14 → 62,16
for (i = 0; i < COUNT_GRANULARITY; i++) {
int retval = async_req_0_0(PHONE_NS, NS_PING);
if (retval != EOK)
return "Failed to send ping message.";
if (retval != EOK) {
TPRINTF("\n");
return "Failed to send ping message";
}
}
count += COUNT_GRANULARITY;
}
printf("Completed %lu round trips in %u seconds, %lu RT/s.\n",
TPRINTF("OK\nCompleted %llu round trips in %u seconds, %llu rt/s.\n",
count, DURATION_SECS, count / DURATION_SECS);
return NULL;
/branches/network/uspace/app/tester/ipc/register.c
32,58 → 32,58
#include <errno.h>
#include "../tester.h"
 
#define MAX_CONNECTIONS 50
 
static int connections[MAX_CONNECTIONS];
 
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t phonehash = icall->in_phone_hash;
int retval;
int i;
 
printf("Connected phone: %P, accepting\n", icall->in_phone_hash);
unsigned int i;
TPRINTF("Connected phone %#x accepting\n", icall->in_phone_hash);
ipc_answer_0(iid, EOK);
for (i = 0; i < 1024; i++)
for (i = 0; i < MAX_CONNECTIONS; i++) {
if (!connections[i]) {
connections[i] = phonehash;
connections[i] = icall->in_phone_hash;
break;
}
}
while (1) {
callid = async_get_call(&call);
while (true) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
int retval;
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
printf("Phone (%P) hung up.\n", phonehash);
TPRINTF("Phone %#x hung up\n", icall->in_phone_hash);
retval = 0;
break;
case IPC_TEST_METHOD:
TPRINTF("Received well known message from %#x: %#x\n",
icall->in_phone_hash, callid);
ipc_answer_0(callid, EOK);
break;
default:
printf("Received message from %P: %X\n", phonehash,
callid);
for (i = 0; i < 1024; i++)
if (!callids[i]) {
callids[i] = callid;
break;
}
continue;
TPRINTF("Received unknown message from %#x: %#x\n",
icall->in_phone_hash, callid);
ipc_answer_0(callid, ENOENT);
break;
}
ipc_answer_0(callid, retval);
}
}
 
char * test_register(bool quiet)
char *test_register(void)
{
int i;
async_set_client_connection(client_connection);
 
for (i = IPC_TEST_START; i < IPC_TEST_START + 10; i++) {
ipcarg_t phonead;
int res = ipc_connect_to_me(PHONE_NS, i, 0, 0, &phonead);
if (!res)
break;
printf("Failed registering as %d..:%d\n", i, res);
}
printf("Registered as service: %d\n", i);
myservice = i;
ipcarg_t phonead;
int res = ipc_connect_to_me(PHONE_NS, IPC_TEST_SERVICE, 0, 0, &phonead);
if (res != 0)
return "Failed registering IPC service";
TPRINTF("Registered as service %u, accepting connections\n", IPC_TEST_SERVICE);
async_manager();
return NULL;
}
/branches/network/uspace/app/tester/ipc/connect.c
28,32 → 28,46
 
#include <stdio.h>
#include <unistd.h>
#include <atomic.h>
#include "../tester.h"
 
char * test_connect(bool quiet)
static atomic_t finish;
 
static void callback(void *priv, int retval, ipc_call_t *data)
{
char c;
int svc;
int phid;
atomic_set(&finish, 1);
}
 
printf("Choose one service: 0:10000....9:10009 (q to skip)\n");
do {
c = getchar();
if ((c == 'Q') || (c == 'q'))
return TEST_SKIPPED;
} while (c < '0' || c > '9');
char *test_connect(void)
{
TPRINTF("Connecting to %u...", IPC_TEST_SERVICE);
int phone = ipc_connect_me_to(PHONE_NS, IPC_TEST_SERVICE, 0, 0);
if (phone > 0) {
TPRINTF("phoneid %d\n", phone);
} else {
TPRINTF("\n");
return "ipc_connect_me_to() failed";
}
svc = IPC_TEST_START + c - '0';
if (svc == myservice)
return "Currently cannot connect to myself, update test";
printf("Sending synchronous message...\n");
int retval = ipc_call_sync_0_0(phone, IPC_TEST_METHOD);
TPRINTF("Received response to synchronous message\n");
printf("Connecting to %d..", svc);
phid = ipc_connect_me_to(PHONE_NS, svc, 0, 0);
if (phid > 0) {
printf("phoneid: %d\n", phid);
phones[phid] = 1;
} else
return "Error";
TPRINTF("Sending asynchronous message...\n");
atomic_set(&finish, 0);
ipc_call_async_0(phone, IPC_TEST_METHOD, NULL, callback, 1);
while (atomic_get(&finish) != 1)
TPRINTF(".");
TPRINTF("Received response to asynchronous message\n");
TPRINTF("Hanging up...");
retval = ipc_hangup(phone);
if (retval == 0) {
TPRINTF("OK\n");
} else {
TPRINTF("\n");
return "ipc_hangup() failed";
}
return NULL;
}
/branches/network/uspace/app/tester/print/print2.c
0,0 → 1,52
/*
* Copyright (c) 2005 Josef Cejka
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
char *test_print2(void)
{
TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
TPRINTF("Expected output: [a] [ b] [c ] [ d] [e ]\n");
TPRINTF("Real output: [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
TPRINTF("Expected output: [1] [ 02] [03 ] [004] [005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", 1, 2, 3, 4, 5);
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", -1, -2, -3, -4, -5):\n");
TPRINTF("Expected output: [-1] [-02] [-03] [-004] [-005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", -1, -2, -3, -4, -5);
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n");
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n");
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
return NULL;
}
/branches/network/uspace/app/tester/print/print3.c
0,0 → 1,62
/*
* Copyright (c) 2005 Josef Cejka
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <macros.h>
#include "../tester.h"
 
#define BUFFER_SIZE 32
 
char *test_print3(void)
{
char buffer[BUFFER_SIZE];
int retval;
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short text without parameters.\"):\n");
TPRINTF("Expected result: retval=30 buffer=\"Short text without parameters.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very very very long text without parameters.\"):\n");
TPRINTF("Expected result: retval=44 buffer=\"Very very very long text withou\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short %%s.\", \"text\"):\n");
TPRINTF("Expected result: retval=11 buffer=\"Short text.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short %s.", "text");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very long %%s. This text's length is more than %%d. We are interested in the result.\", \"text\", " STRING(BUFFER_SIZE) "):\n");
TPRINTF("Expected result: retval=84 buffer=\"Very long text. This text's len\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text's length is more than %d. We are interested in the result.", "text", BUFFER_SIZE);
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
return NULL;
}
/branches/network/uspace/app/tester/print/print4.c
30,63 → 30,54
#include <unistd.h>
#include "../tester.h"
 
#define PRIx8 "x"
 
char *test_print4(bool quiet)
char *test_print4(void)
{
if (!quiet) {
printf("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n");
TPRINTF("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n");
uint8_t group;
for (group = 1; group < 4; group++) {
TPRINTF("%#x: ", group << 5);
uint8_t group;
for (group = 1; group < 4; group++) {
printf("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
printf("%c", (char) ((group << 5) + index));
printf(" ");
for (index = 0; index < 32; index++)
printf("%lc", (wchar_t) ((group << 5) + index));
printf("\n");
}
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%c", (char) ((group << 5) + index));
printf("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n");
TPRINTF(" ");
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
for (group = 4; group < 8; group++) {
printf("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
printf("%lc", (wchar_t) ((group << 5) + index));
printf("\n");
}
TPRINTF("\n");
}
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n");
for (group = 4; group < 8; group++) {
TPRINTF("%#x: ", group << 5);
printf("\nUTF-8 strings using printf(\"%%s\"):\n");
printf("English: %s\n", "Quick brown fox jumps over the lazy dog");
printf("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy");
printf("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
printf("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה");
printf("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي");
printf("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой");
printf("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական");
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
printf("\nUTF-32 strings using printf(\"%%ls\"):\n");
printf("English: %ls\n", L"Quick brown fox jumps over the lazy dog");
printf("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy");
printf("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
printf("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה");
printf("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي");
printf("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой");
printf("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական");
 
printf("Test: [%d] '%lc'\n", L'\x0161', L'\x0161');
TPRINTF("\n");
}
 
printf("[Press a key]\n");
getchar();
TPRINTF("\nUTF-8 strings using printf(\"%%s\"):\n");
TPRINTF("English: %s\n", "Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական");
TPRINTF("\nUTF-32 strings using printf(\"%%ls\"):\n");
TPRINTF("English: %ls\n", L"Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական");
return NULL;
}
/branches/network/uspace/app/tester/print/print1.def
1,6 → 1,6
{
"print1",
"Printf test",
"String printf test",
&test_print1,
true
},
/branches/network/uspace/app/tester/print/print2.def
0,0 → 1,6
{
"print2",
"Numeric printf test",
&test_print2,
true
},
/branches/network/uspace/app/tester/print/print3.def
0,0 → 1,6
{
"print3",
"Buffered printf test",
&test_print3,
true
},
/branches/network/uspace/app/tester/print/print1.c
30,44 → 30,27
#include <unistd.h>
#include "../tester.h"
 
#define BUFFER_SIZE 32
 
char * test_print1(bool quiet)
char *test_print1(void)
{
if (!quiet) {
int retval;
unsigned int nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' );
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 );
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 );
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 );
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n", NULL);
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
}
TPRINTF("Testing printf(\"%%*.*s\", 5, 3, \"text\"):\n");
TPRINTF("Expected output: \" tex\"\n");
TPRINTF("Real output: \"%*.*s\"\n\n", 5, 3, "text");
TPRINTF("Testing printf(\"%%10.8s\", \"very long text\"):\n");
TPRINTF("Expected output: \" very lon\"\n");
TPRINTF("Real output: \"%10.8s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n");
TPRINTF("Expected output: \"text\"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "text");
TPRINTF("Testing printf(\"%%8.10s\", \"very long text\"):\n");
TPRINTF("Expected output: \"very long \"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%s\", NULL):\n");
TPRINTF("Expected output: \"(NULL)\"\n");
TPRINTF("Real output: \"%s\"\n\n", NULL);
return NULL;
}
/branches/network/uspace/app/tester/tester.h
39,43 → 39,45
#include <bool.h>
#include <ipc/ipc.h>
 
#define IPC_TEST_START 10000
#define MAX_PHONES 20
#define MAX_CONNECTIONS 50
#define TEST_SKIPPED "Test Skipped"
#define IPC_TEST_SERVICE 10240
#define IPC_TEST_METHOD 2000
 
extern int myservice;
extern int phones[MAX_PHONES];
extern int connections[MAX_CONNECTIONS];
extern ipc_callid_t callids[MAX_CONNECTIONS];
extern bool test_quiet;
extern int test_argc;
extern char **test_argv;
 
typedef char * (* test_entry_t)(bool);
#define TPRINTF(format, ...) \
{ \
if (!test_quiet) { \
fprintf(stderr, format, ##__VA_ARGS__); \
} \
}
 
typedef char *(*test_entry_t)(void);
 
typedef struct {
char * name;
char * desc;
char *name;
char *desc;
test_entry_t entry;
bool safe;
} test_t;
 
extern char * test_thread1(bool quiet);
extern char * test_print1(bool quiet);
extern char * test_print4(bool quiet);
extern char * test_fault1(bool quiet);
extern char * test_fault2(bool quiet);
extern char * test_register(bool quiet);
extern char * test_connect(bool quiet);
extern char * test_send_async(bool quiet);
extern char * test_send_sync(bool quiet);
extern char * test_answer(bool quiet);
extern char * test_hangup(bool quiet);
extern char * test_ping_pong(bool quiet);
extern char * test_devmap1(bool quiet);
extern char * test_loop1(bool quiet);
extern char * test_vfs1(bool quiet);
extern char * test_console1(bool quiet);
extern char * test_stdio1(bool quiet);
extern char * test_stdio2(bool quiet);
extern char *test_thread1(void);
extern char *test_print1(void);
extern char *test_print2(void);
extern char *test_print3(void);
extern char *test_print4(void);
extern char *test_console1(void);
extern char *test_stdio1(void);
extern char *test_stdio2(void);
extern char *test_fault1(void);
extern char *test_fault2(void);
extern char *test_vfs1(void);
extern char *test_ping_pong(void);
extern char *test_register(void);
extern char *test_connect(void);
extern char *test_loop1(void);
extern char *test_malloc1(void);
 
extern test_t tests[];
 
/branches/network/uspace/app/tester/Makefile
45,22 → 45,20
SOURCES = tester.c \
thread/thread1.c \
print/print1.c \
print/print2.c \
print/print3.c \
print/print4.c \
console/console1.c \
stdio/stdio1.c \
stdio/stdio2.c \
fault/fault1.c \
fault/fault2.c \
vfs/vfs1.c \
ipc/ping_pong.c \
ipc/register.c \
ipc/connect.c \
ipc/send_async.c \
ipc/send_sync.c \
ipc/answer.c \
ipc/hangup.c \
ipc/ping_pong.c \
loop/loop1.c \
devmap/devmap1.c \
console/console1.c \
stdio/stdio1.c \
stdio/stdio2.c \
vfs/vfs1.c
mm/malloc1.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
/branches/network/uspace/app/tester/vfs/vfs1.c
34,109 → 34,118
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <devmap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../tester.h"
 
char text[] = "O xein', angellein Lakedaimoniois hoti teide "
"keimetha tois keinon rhemasi peithomenoi.";
#define FS_TYPE "tmpfs"
#define MOUNT_POINT "/tmp"
#define OPTIONS ""
#define FLAGS 0
 
char *test_vfs1(bool quiet)
#define TEST_DIRECTORY MOUNT_POINT "/testdir"
#define TEST_FILE TEST_DIRECTORY "/testfile"
#define TEST_FILE2 TEST_DIRECTORY "/nextfile"
 
#define MAX_DEVICE_NAME 32
#define BUF_SIZE 16
 
static char text[] = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
 
static char *read_root(void)
{
int rc;
TPRINTF("Opening the root directory...");
DIR *dirp = opendir("/");
if (!dirp) {
TPRINTF("\n");
return "opendir() failed";
} else
TPRINTF("OK\n");
struct dirent *dp;
while ((dp = readdir(dirp)))
TPRINTF(" node \"%s\"\n", dp->d_name);
closedir(dirp);
return NULL;
}
 
rc = mount("tmpfs", "/", "nulldev0", "", 0);
char *test_vfs1(void)
{
if (mkdir(MOUNT_POINT, 0) != 0)
return "mkdir() failed";
TPRINTF("Created directory %s\n", MOUNT_POINT);
char null[MAX_DEVICE_NAME];
int null_id = devmap_null_create();
if (null_id == -1)
return "Unable to create null device";
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS);
switch (rc) {
case EOK:
if (!quiet)
printf("mounted tmpfs on /\n");
TPRINTF("Mounted /dev/%s as %s on %s\n", null, FS_TYPE, MOUNT_POINT);
break;
case EBUSY:
if (!quiet)
printf("(INFO) something is already mounted on /\n");
TPRINTF("(INFO) Filesystem already mounted on %s\n", MOUNT_POINT);
break;
default:
if (!quiet)
printf("(INFO) IPC returned errno %d\n", rc);
return "mount() failed.";
TPRINTF("(ERR) IPC returned errno %d (is tmpfs loaded?)\n", rc);
return "mount() failed";
}
 
if (mkdir("/mydir", 0) != 0)
return "mkdir() failed.\n";
if (!quiet)
printf("created directory /mydir\n");
int fd0 = open("/mydir/myfile", O_CREAT);
if (mkdir(TEST_DIRECTORY, 0) != 0)
return "mkdir() failed";
TPRINTF("Created directory %s\n", TEST_DIRECTORY);
int fd0 = open(TEST_FILE, O_CREAT);
if (fd0 < 0)
return "open() failed.\n";
if (!quiet)
printf("created file /mydir/myfile, fd=%d\n", fd0);
 
ssize_t cnt;
return "open() failed";
TPRINTF("Created file %s (fd=%d)\n", TEST_FILE, fd0);
size_t size = sizeof(text);
cnt = write(fd0, text, size);
ssize_t cnt = write(fd0, text, size);
if (cnt < 0)
return "write() failed.\n";
if (!quiet)
printf("written %d bytes, fd=%d\n", cnt, fd0);
return "write() failed";
TPRINTF("Written %d bytes\n", cnt);
if (lseek(fd0, 0, SEEK_SET) != 0)
return "lseek() failed.\n";
if (!quiet)
printf("sought to position 0, fd=%d\n", fd0);
 
char buf[10];
 
while ((cnt = read(fd0, buf, sizeof(buf)))) {
return "lseek() failed";
TPRINTF("Sought to position 0\n");
char buf[BUF_SIZE];
while ((cnt = read(fd0, buf, BUF_SIZE))) {
if (cnt < 0)
return "read() failed.\n";
if (!quiet)
printf("read %d bytes: \"%.*s\", fd=%d\n", cnt, cnt,
buf, fd0);
return "read() failed";
TPRINTF("Read %d bytes: \".*s\"\n", cnt, cnt, buf);
}
 
close(fd0);
 
DIR *dirp;
struct dirent *dp;
 
if (!quiet)
printf("scanning the root directory...\n");
 
dirp = opendir("/");
if (!dirp)
return "opendir() failed\n";
while ((dp = readdir(dirp)))
printf("discovered node %s in /\n", dp->d_name);
closedir(dirp);
 
if (rename("/mydir/myfile", "/mydir/yourfile"))
return "rename() failed.\n";
 
if (!quiet)
printf("renamed /mydir/myfile to /mydir/yourfile\n");
 
if (unlink("/mydir/yourfile"))
return "unlink() failed.\n";
if (!quiet)
printf("unlinked file /mydir/yourfile\n");
 
if (rmdir("/mydir"))
return "rmdir() failed.\n";
 
if (!quiet)
printf("removed directory /mydir\n");
char *rv = read_root();
if (rv != NULL)
return rv;
if (!quiet)
printf("scanning the root directory...\n");
 
dirp = opendir("/");
if (!dirp)
return "opendir() failed\n";
while ((dp = readdir(dirp)))
printf("discovered node %s in /\n", dp->d_name);
closedir(dirp);
 
if (rename(TEST_FILE, TEST_FILE2))
return "rename() failed";
TPRINTF("Renamed %s to %s\n", TEST_FILE, TEST_FILE2);
if (unlink(TEST_FILE2))
return "unlink() failed";
TPRINTF("Unlinked %s\n", TEST_FILE2);
if (rmdir(TEST_DIRECTORY))
return "rmdir() failed";
TPRINTF("Removed directory %s\n", TEST_DIRECTORY);
rv = read_root();
if (rv != NULL)
return rv;
return NULL;
}
 
/branches/network/uspace/app/getvc/getvc.c
73,6 → 73,9
 
int main(int argc, char *argv[])
{
task_exit_t texit;
int retval;
 
if (argc < 3) {
usage();
return -1;
97,7 → 100,7
version_print(argv[1]);
task_id_t id = spawn(argv[2]);
task_wait(id);
task_wait(id, &texit, &retval);
return 0;
}
/branches/network/uspace/app/tetris/screen.c
62,6 → 62,8
static int curscore;
static int isset; /* true => terminal is in game mode */
 
static int use_color; /* true => use colors */
 
static const struct shape *lastshape;
 
 
78,7 → 80,8
static void start_standout(uint32_t color)
{
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xf0f0f0, color);
console_set_rgb_color(fphone(stdout), 0xf0f0f0,
use_color ? color : 0x000000);
}
 
static void resume_normal(void)
127,6 → 130,18
return console_get_size(fphone(stdout), &ws->ws_col, &ws->ws_row);
}
 
static int get_display_color_sup(void)
{
int rc;
int ccap;
 
rc = console_get_color_cap(fphone(stdout), &ccap);
if (rc != 0)
return 0;
 
return (ccap >= CONSOLE_CCAP_RGB);
}
 
/*
* Set up screen mode.
*/
141,6 → 156,8
Rows = ws.ws_row;
Cols = ws.ws_col;
}
 
use_color = get_display_color_sup();
if ((Rows < MINROWS) || (Cols < MINCOLS)) {
char smallscr[55];
/branches/network/uspace/app/tetris/shapes.c
87,7 → 87,7
*/
int fits_in(const struct shape *shape, int pos)
{
int *o = shape->off;
const int *o = shape->off;
if ((board[pos]) || (board[pos + *o++]) || (board[pos + *o++]) ||
(board[pos + *o]))
102,7 → 102,7
*/
void place(const struct shape *shape, int pos, int onoff)
{
int *o = shape->off;
const int *o = shape->off;
board[pos] = onoff ? shape->color : 0x000000;
board[pos + *o++] = onoff ? shape->color : 0x000000;
/branches/network/uspace/app/tetris/tetris.c
237,7 → 237,7
{
int pos;
int c;
char *keys;
const char *keys;
int level = 2;
char key_write[6][10];
int i;
/branches/network/uspace/app/trace/trace.c
43,7 → 43,11
#include <task.h>
#include <mem.h>
#include <string.h>
#include <bool.h>
#include <loader/loader.h>
#include <io/console.h>
#include <io/keycode.h>
#include <fibril_sync.h>
 
#include <libc.h>
 
64,22 → 68,31
 
int next_thread_id;
 
ipc_call_t thread_ipc_req[THBUF_SIZE];
 
int phoneid;
int abort_trace;
bool abort_trace;
 
uintptr_t thash;
volatile int paused;
static bool paused;
static fibril_condvar_t state_cv;
static fibril_mutex_t state_lock;
 
static bool cev_valid;
static console_event_t cev;
 
void thread_trace_start(uintptr_t thread_hash);
 
static proto_t *proto_console;
static task_id_t task_id;
static loader_t *task_ldr;
static bool task_wait_for;
 
/** Combination of events/data to print. */
display_mask_t display_mask;
 
static int program_run_fibril(void *arg);
static int cev_fibril(void *arg);
 
static void program_run(void)
{
94,6 → 107,19
fibril_add_ready(fid);
}
 
static void cev_fibril_start(void)
{
fid_t fid;
 
fid = fibril_create(cev_fibril, NULL);
if (fid == 0) {
printf("Error creating fibril\n");
exit(1);
}
 
fibril_add_ready(fid);
}
 
static int program_run_fibril(void *arg)
{
int rc;
180,6 → 206,10
 
void val_print(sysarg_t val, val_type_t v_type)
{
long sval;
 
sval = (long) val;
 
switch (v_type) {
case V_VOID:
printf("<void>");
186,7 → 216,7
break;
 
case V_INTEGER:
printf("%ld", val);
printf("%ld", sval);
break;
 
case V_HASH:
195,29 → 225,29
break;
 
case V_ERRNO:
if (val >= -15 && val <= 0) {
printf("%ld %s (%s)", val,
err_desc[-val].name,
err_desc[-val].desc);
if (sval >= -15 && sval <= 0) {
printf("%ld %s (%s)", sval,
err_desc[-sval].name,
err_desc[-sval].desc);
} else {
printf("%ld", val);
printf("%ld", sval);
}
break;
case V_INT_ERRNO:
if (val >= -15 && val < 0) {
printf("%ld %s (%s)", val,
err_desc[-val].name,
err_desc[-val].desc);
if (sval >= -15 && sval < 0) {
printf("%ld %s (%s)", sval,
err_desc[-sval].name,
err_desc[-sval].desc);
} else {
printf("%ld", val);
printf("%ld", sval);
}
break;
 
case V_CHAR:
if (val >= 0x20 && val < 0x7f) {
printf("'%c'", val);
if (sval >= 0x20 && sval < 0x7f) {
printf("'%c'", sval);
} else {
switch (val) {
switch (sval) {
case '\a': printf("'\\a'"); break;
case '\b': printf("'\\b'"); break;
case '\n': printf("'\\n'"); break;
256,7 → 286,8
ipc_call_t call;
ipcarg_t phoneid;
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
if (sc_rc == (sysarg_t) IPC_CALLRET_FATAL ||
sc_rc == (sysarg_t) IPC_CALLRET_TEMPORARY)
return;
 
phoneid = sc_args[0];
276,7 → 307,8
ipc_call_t call;
int rc;
 
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
if (sc_rc == (sysarg_t) IPC_CALLRET_FATAL ||
sc_rc == (sysarg_t) IPC_CALLRET_TEMPORARY)
return;
 
memset(&call, 0, sizeof(call));
315,22 → 347,38
ipcp_call_sync(phoneidx, &question, &reply);
}
 
static void sc_ipc_call_sync_slow(sysarg_t *sc_args)
static void sc_ipc_call_sync_slow_b(unsigned thread_id, sysarg_t *sc_args)
{
ipc_call_t question, reply;
ipc_call_t question;
int rc;
 
memset(&question, 0, sizeof(question));
rc = udebug_mem_read(phoneid, &question.args, sc_args[1], sizeof(question.args));
printf("dmr->%d\n", rc);
if (rc < 0) return;
rc = udebug_mem_read(phoneid, &question.args, sc_args[1],
sizeof(question.args));
 
if (rc < 0) {
printf("Error: mem_read->%d\n", rc);
return;
}
 
thread_ipc_req[thread_id] = question;
}
 
static void sc_ipc_call_sync_slow_e(unsigned thread_id, sysarg_t *sc_args)
{
ipc_call_t reply;
int rc;
 
memset(&reply, 0, sizeof(reply));
rc = udebug_mem_read(phoneid, &reply.args, sc_args[2], sizeof(reply.args));
printf("dmr->%d\n", rc);
if (rc < 0) return;
rc = udebug_mem_read(phoneid, &reply.args, sc_args[2],
sizeof(reply.args));
 
ipcp_call_sync(sc_args[0], &question, &reply);
if (rc < 0) {
printf("Error: mem_read->%d\n", rc);
return;
}
 
ipcp_call_sync(sc_args[0], &thread_ipc_req[thread_id], &reply);
}
 
static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc)
375,6 → 423,14
print_sc_args(sc_args, syscall_desc[sc_id].n_args);
}
 
switch (sc_id) {
case SYS_IPC_CALL_SYNC_SLOW:
sc_ipc_call_sync_slow_b(thread_id, sc_args);
break;
default:
break;
}
 
async_serialize_end();
}
 
415,7 → 471,7
sc_ipc_call_sync_fast(sc_args);
break;
case SYS_IPC_CALL_SYNC_SLOW:
sc_ipc_call_sync_slow(sc_args);
sc_ipc_call_sync_slow_e(thread_id, sc_args);
break;
case SYS_IPC_WAIT:
sc_ipc_wait(sc_args, sc_rc);
446,20 → 502,26
 
thread_hash = (uintptr_t)thread_hash_arg;
thread_id = next_thread_id++;
if (thread_id >= THBUF_SIZE) {
printf("Too many threads.\n");
return ELIMIT;
}
 
printf("Start tracing thread [%d] (hash 0x%lx).\n", thread_id, thread_hash);
 
while (!abort_trace) {
 
fibril_mutex_lock(&state_lock);
if (paused) {
printf("Press R to resume (and be patient).\n");
while (paused) {
usleep(1000000);
fibril_yield();
printf(".");
}
printf("Resumed\n");
printf("Thread [%d] paused. Press R to resume.\n",
thread_id);
 
while (paused)
fibril_condvar_wait(&state_cv, &state_lock);
 
printf("Thread [%d] resumed.\n", thread_id);
}
fibril_mutex_unlock(&state_lock);
 
/* Run thread until an event occurs */
rc = udebug_go(phoneid, thread_hash,
481,6 → 543,9
break;
case UDEBUG_EVENT_STOP:
printf("Stop event\n");
fibril_mutex_lock(&state_lock);
paused = true;
fibril_mutex_unlock(&state_lock);
break;
case UDEBUG_EVENT_THREAD_B:
event_thread_b(val0);
487,7 → 552,10
break;
case UDEBUG_EVENT_THREAD_E:
printf("Thread 0x%lx exited.\n", val0);
abort_trace = 1;
fibril_mutex_lock(&state_lock);
abort_trace = true;
fibril_condvar_broadcast(&state_cv);
fibril_mutex_unlock(&state_lock);
break;
default:
printf("Unknown event type %d.\n", ev_type);
540,6 → 608,33
if (rc != EOK)
goto error;
 
/* Send default files */
fdi_node_t *files[4];
fdi_node_t stdin_node;
fdi_node_t stdout_node;
fdi_node_t stderr_node;
if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
files[0] = &stdin_node;
else
files[0] = NULL;
if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
files[1] = &stdout_node;
else
files[1] = NULL;
if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
files[2] = &stderr_node;
else
files[2] = NULL;
files[3] = NULL;
rc = loader_set_files(ldr, files);
if (rc != EOK)
goto error;
 
/* Load the program. */
rc = loader_load_program(ldr);
if (rc != EOK)
555,11 → 650,32
return NULL;
}
 
static int cev_fibril(void *arg)
{
(void) arg;
 
while (true) {
fibril_mutex_lock(&state_lock);
while (cev_valid)
fibril_condvar_wait(&state_cv, &state_lock);
fibril_mutex_unlock(&state_lock);
 
if (!console_get_event(fphone(stdin), &cev))
return -1;
 
fibril_mutex_lock(&state_lock);
cev_valid = true;
fibril_condvar_broadcast(&state_cv);
fibril_mutex_unlock(&state_lock);
}
}
 
static void trace_task(task_id_t task_id)
{
console_event_t ev;
bool done;
int i;
int rc;
int c;
 
ipcp_init();
 
575,29 → 691,55
return;
}
 
abort_trace = 0;
abort_trace = false;
 
for (i = 0; i < n_threads; i++) {
thread_trace_start(thread_hash_buf[i]);
}
 
while(1) {
c = getchar();
if (c == 'q') break;
if (c == 'p') {
done = false;
 
while (!done) {
fibril_mutex_lock(&state_lock);
while (!cev_valid && !abort_trace)
fibril_condvar_wait(&state_cv, &state_lock);
fibril_mutex_unlock(&state_lock);
 
ev = cev;
 
fibril_mutex_lock(&state_lock);
cev_valid = false;
fibril_condvar_broadcast(&state_cv);
fibril_mutex_unlock(&state_lock);
 
if (abort_trace)
break;
 
if (ev.type != KEY_PRESS)
continue;
 
switch (ev.key) {
case KC_Q:
done = true;
break;
case KC_P:
printf("Pause...\n");
paused = 1;
rc = udebug_stop(phoneid, thash);
printf("stop -> %d\n", rc);
}
if (c == 'r') {
paused = 0;
if (rc != EOK)
printf("Error: stop -> %d\n", rc);
break;
case KC_R:
fibril_mutex_lock(&state_lock);
paused = false;
fibril_condvar_broadcast(&state_cv);
fibril_mutex_unlock(&state_lock);
printf("Resume...\n");
break;
}
}
 
printf("\nTerminate debugging session...\n");
abort_trace = 1;
abort_trace = true;
udebug_end(phoneid);
ipc_hangup(phoneid);
 
629,37 → 771,53
};
 
next_thread_id = 1;
paused = 0;
paused = false;
cev_valid = false;
 
fibril_mutex_initialize(&state_lock);
fibril_condvar_initialize(&state_cv);
 
proto_init();
 
p = proto_new("vfs");
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_OPEN, o);
o = oper_new("open_node", 4, arg_def, V_INT_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_OPEN_NODE, o);
o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def);
proto_add_oper(p, VFS_READ, o);
proto_add_oper(p, VFS_IN_READ, o);
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def);
proto_add_oper(p, VFS_WRITE, o);
proto_add_oper(p, VFS_IN_WRITE, o);
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_SEEK, o);
o = oper_new("truncate", 5, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_TRUNCATE, o);
proto_add_oper(p, VFS_IN_TRUNCATE, o);
o = oper_new("fstat", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_FSTAT, o);
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_CLOSE, o);
o = oper_new("mount", 2, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_MOUNT, o);
proto_add_oper(p, VFS_IN_MOUNT, o);
/* o = oper_new("unmount", 0, arg_def);
proto_add_oper(p, VFS_UNMOUNT, o);*/
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_OPEN, o);
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_CLOSE, o);
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_SEEK, o);
proto_add_oper(p, VFS_IN_UNMOUNT, o);*/
o = oper_new("sync", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_SYNC, o);
o = oper_new("mkdir", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_MKDIR, o);
proto_add_oper(p, VFS_IN_MKDIR, o);
o = oper_new("unlink", 0, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_UNLINK, o);
proto_add_oper(p, VFS_IN_UNLINK, o);
o = oper_new("rename", 0, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_RENAME, o);
proto_add_oper(p, VFS_IN_RENAME, o);
o = oper_new("stat", 0, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_STAT, o);
 
proto_register(SERVICE_VFS, p);
 
p = proto_new("console");
 
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def);
proto_add_oper(p, VFS_IN_WRITE, o);
 
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER;
resp_def[2] = V_INTEGER; resp_def[3] = V_CHAR;
o = oper_new("getkey", 0, arg_def, V_ERRNO, 4, resp_def);
752,6 → 910,7
--argc; ++argv;
task_id = strtol(*argv, &err_p, 10);
task_ldr = NULL;
task_wait_for = false;
if (*err_p) {
printf("Task ID syntax error\n");
print_syntax();
789,6 → 948,7
while (*cp) printf("'%s'\n", *cp++);
}
task_ldr = preload_task(*argv, argv, &task_id);
task_wait_for = true;
 
return 0;
}
796,6 → 956,8
int main(int argc, char *argv[])
{
int rc;
task_exit_t texit;
int retval;
 
printf("System Call / IPC Tracer\n");
printf("Controls: Q - Quit, P - Pause, R - Resume\n");
815,12 → 977,29
 
printf("Connected to task %lld.\n", task_id);
 
if (task_ldr != NULL) {
if (task_ldr != NULL)
program_run();
}
 
cev_fibril_start();
trace_task(task_id);
 
if (task_wait_for) {
printf("Waiting for task to exit.\n");
 
rc = task_wait(task_id, &texit, &retval);
if (rc != EOK) {
printf("Failed waiting for task.\n");
return -1;
}
 
if (texit == TASK_EXIT_NORMAL) {
printf("Task exited normally, return value %d.\n",
retval);
} else {
printf("Task exited unexpectedly.\n");
}
}
 
return 0;
}
 
/branches/network/uspace/app/trace/proto.c
46,7 → 46,7
hash_table_t srv_proto;
 
typedef struct {
int srv;
unsigned srv;
proto_t *proto;
link_t link;
} srv_proto_t;
/branches/network/uspace/lib/libfs/libfs.c
43,6 → 43,7
#include <assert.h>
#include <dirent.h>
#include <mem.h>
#include <sys/stat.h>
 
/** Register file system server.
*
69,7 → 70,7
* out-of-order, when it knows that the operation succeeded or failed.
*/
ipc_call_t answer;
aid_t req = async_send_0(vfs_phone, VFS_REGISTER, &answer);
aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
 
/*
* Send our VFS info structure to VFS.
104,7 → 105,7
}
/*
* Pick up the answer for the request to the VFS_REQUEST call.
* Pick up the answer for the request to the VFS_IN_REQUEST call.
*/
async_wait_for(req, NULL);
reg->fs_handle = (int) IPC_GET_ARG1(answer);
186,7 → 187,7
}
ipc_call_t answer;
aid_t msg = async_send_1(mountee_phone, VFS_MOUNTED, mr_dev_handle,
aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
&answer);
ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
213,8 → 214,8
* file system implementation
* @param fs_handle File system handle of the file system where to perform
* the lookup.
* @param rid Request ID of the VFS_LOOKUP request.
* @param request VFS_LOOKUP request data itself.
* @param rid Request ID of the VFS_OUT_LOOKUP request.
* @param request VFS_OUT_LOOKUP request data itself.
*
*/
void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
237,7 → 238,7
fs_node_t *tmp = NULL;
 
if (cur->mp_data.mp_active) {
ipc_forward_slow(rid, cur->mp_data.phone, VFS_LOOKUP,
ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
next, last, cur->mp_data.dev_handle, lflag, index,
IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
272,9 → 273,9
else
next--;
ipc_forward_slow(rid, tmp->mp_data.phone, VFS_LOOKUP,
next, last, tmp->mp_data.dev_handle, lflag, index,
IPC_FF_ROUTE_FROM_ME);
ipc_forward_slow(rid, tmp->mp_data.phone,
VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
lflag, index, IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
ops->node_put(tmp);
if (par)
428,12 → 429,42
ops->node_put(tmp);
}
 
void libfs_stat(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
fs_node_t *fn = ops->node_get(dev_handle, index);
 
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size != sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat stat;
memset(&stat, 0, sizeof(struct stat));
stat.fs_handle = fs_handle;
stat.dev_handle = dev_handle;
stat.index = index;
stat.lnkcnt = ops->lnkcnt_get(fn);
stat.is_file = ops->is_file(fn);
stat.size = ops->size_get(fn);
 
ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
}
 
/** Open VFS triplet.
*
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param rid Request ID of the VFS_OPEN_NODE request.
* @param request VFS_OPEN_NODE request data itself.
* @param rid Request ID of the VFS_OUT_OPEN_NODE request.
* @param request VFS_OUT_OPEN_NODE request data itself.
*
*/
void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
/branches/network/uspace/lib/libfs/libfs.h
84,6 → 84,7
 
extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
ipc_call_t *);
 
/branches/network/uspace/lib/libblock/libblock.c
63,6 → 63,7
fibril_mutex_t lock;
size_t block_size; /**< Block size. */
unsigned block_count; /**< Total number of blocks. */
unsigned blocks_cached; /**< Number of cached blocks. */
hash_table_t block_hash;
link_t free_head;
enum cache_mode mode;
72,6 → 73,7
link_t link;
dev_handle_t dev_handle;
int dev_phone;
fibril_mutex_t com_area_lock;
void *com_area;
size_t com_size;
void *bb_buf;
80,8 → 82,8
cache_t *cache;
} devcon_t;
 
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
const void *src);
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
 
static devcon_t *devcon_search(dev_handle_t dev_handle)
{
112,6 → 114,7
link_initialize(&devcon->link);
devcon->dev_handle = dev_handle;
devcon->dev_phone = dev_phone;
fibril_mutex_initialize(&devcon->com_area_lock);
devcon->com_area = com_area;
devcon->com_size = com_size;
devcon->bb_buf = NULL;
211,14 → 214,16
if (!bb_buf)
return ENOMEM;
off_t bufpos = 0;
size_t buflen = 0;
rc = block_read(dev_handle, &bufpos, &buflen, &off,
bb_buf, size, size);
fibril_mutex_lock(&devcon->com_area_lock);
rc = read_block(devcon, 0, size);
if (rc != EOK) {
fibril_mutex_unlock(&devcon->com_area_lock);
free(bb_buf);
return rc;
}
memcpy(bb_buf, devcon->com_area, size);
fibril_mutex_unlock(&devcon->com_area_lock);
 
devcon->bb_buf = bb_buf;
devcon->bb_off = off;
devcon->bb_size = size;
271,6 → 276,7
list_initialize(&cache->free_head);
cache->block_size = size;
cache->block_count = blocks;
cache->blocks_cached = 0;
cache->mode = mode;
 
if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
283,8 → 289,14
return EOK;
}
 
#define CACHE_LO_WATERMARK 10
#define CACHE_HI_WATERMARK 20
static bool cache_can_grow(cache_t *cache)
{
if (cache->blocks_cached < CACHE_LO_WATERMARK)
return true;
if (!list_empty(&cache->free_head))
return false;
return true;
}
 
315,6 → 327,7
block_t *b;
link_t *l;
unsigned long key = boff;
bn_t oboff;
devcon = devcon_search(dev_handle);
 
339,9 → 352,6
* The block was not found in the cache.
*/
int rc;
off_t bufpos = 0;
size_t buflen = 0;
off_t pos = boff * cache->block_size;
bool sync = false;
 
if (cache_can_grow(cache)) {
358,6 → 368,7
free(b);
goto recycle;
}
cache->blocks_cached++;
} else {
/*
* Try to recycle a block from the free list.
367,8 → 378,9
assert(!list_empty(&cache->free_head));
l = cache->free_head.next;
list_remove(l);
b = hash_table_get_instance(l, block_t, hash_link);
b = list_get_instance(l, block_t, free_link);
sync = b->dirty;
oboff = b->boff;
temp_key = b->boff;
hash_table_remove(&cache->block_hash, &temp_key, 1);
}
392,7 → 404,11
* The block is dirty and needs to be written back to
* the device before we can read in the new contents.
*/
abort(); /* TODO: block_write() */
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, b->data, b->size);
rc = write_block(devcon, oboff, cache->block_size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
}
if (!(flags & BLOCK_FLAGS_NOREAD)) {
/*
399,9 → 415,11
* The block contains old or no data. We need to read
* the new contents from the device.
*/
rc = block_read(dev_handle, &bufpos, &buflen, &pos,
b->data, cache->block_size, cache->block_size);
fibril_mutex_lock(&devcon->com_area_lock);
rc = read_block(devcon, b->boff, cache->block_size);
assert(rc == EOK);
memcpy(b->data, devcon->com_area, cache->block_size);
fibril_mutex_unlock(&devcon->com_area_lock);
}
 
fibril_mutex_unlock(&b->lock);
429,14 → 447,43
fibril_mutex_lock(&block->lock);
if (!--block->refcnt) {
/*
* Last reference to the block was dropped, put the block on the
* free list.
* Last reference to the block was dropped. Either free the
* block or put it on the free list.
*/
if (cache->blocks_cached > CACHE_HI_WATERMARK) {
/*
* Currently there are too many cached blocks.
*/
if (block->dirty) {
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, block->data,
block->size);
rc = write_block(devcon, block->boff,
block->size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
}
/*
* Take the block out of the cache and free it.
*/
unsigned long key = block->boff;
hash_table_remove(&cache->block_hash, &key, 1);
free(block);
free(block->data);
cache->blocks_cached--;
fibril_mutex_unlock(&cache->lock);
return;
}
/*
* Put the block on the free list.
*/
list_append(&block->free_link, &cache->free_head);
if (cache->mode != CACHE_MODE_WB && block->dirty) {
rc = write_block(devcon, block->boff, block->size,
block->data);
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, block->data, block->size);
rc = write_block(devcon, block->boff, block->size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
 
block->dirty = false;
}
445,7 → 492,7
fibril_mutex_unlock(&cache->lock);
}
 
/** Read data from a block device.
/** Read sequential data from a block device.
*
* @param dev_handle Device handle of the block device.
* @param bufpos Pointer to the first unread valid offset within the
459,9 → 506,8
*
* @return EOK on success or a negative return code on failure.
*/
int
block_read(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, off_t *pos,
void *dst, size_t size, size_t block_size)
int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
off_t *pos, void *dst, size_t size, size_t block_size)
{
off_t offset = 0;
size_t left = size;
468,6 → 514,7
devcon_t *devcon = devcon_search(dev_handle);
assert(devcon);
fibril_mutex_lock(&devcon->com_area_lock);
while (left > 0) {
size_t rd;
490,20 → 537,46
if (*bufpos == (off_t) *buflen) {
/* Refill the communication buffer with a new block. */
ipcarg_t retval;
int rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK,
*pos / block_size, block_size, &retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
int rc;
 
rc = read_block(devcon, *pos / block_size, block_size);
if (rc != EOK) {
fibril_mutex_unlock(&devcon->com_area_lock);
return rc;
}
*bufpos = 0;
*buflen = block_size;
}
}
fibril_mutex_unlock(&devcon->com_area_lock);
return EOK;
}
 
/** Read block from block device.
*
* @param devcon Device connection.
* @param boff Block index.
* @param block_size Block size.
* @param src Buffer for storing the data.
*
* @return EOK on success or negative error code on failure.
*/
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
{
ipcarg_t retval;
int rc;
 
assert(devcon);
rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
&retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
 
return EOK;
}
 
/** Write block to block device.
*
* @param devcon Device connection.
513,17 → 586,14
*
* @return EOK on success or negative error code on failure.
*/
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
const void *src)
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
{
ipcarg_t retval;
int rc;
 
assert(devcon);
memcpy(devcon->com_area, src, block_size);
rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK,
boff, block_size, &retval);
rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
&retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
 
/branches/network/uspace/lib/libblock/libblock.h
100,11 → 100,11
 
extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
 
extern block_t *block_get(dev_handle_t, bn_t, int flags);
extern block_t *block_get(dev_handle_t, bn_t, int);
extern void block_put(block_t *);
 
extern int block_read(dev_handle_t, off_t *, size_t *, off_t *, void *, size_t,
size_t);
extern int block_seqread(dev_handle_t, off_t *, size_t *, off_t *, void *,
size_t, size_t);
 
#endif
 
/branches/network/uspace/lib/libc/malloc/malloc.c
File deleted
/branches/network/uspace/lib/libc/include/getopt.h
58,7 → 58,7
};
 
/* HelenOS Port - These need to be exposed for legacy getopt() */
extern char *optarg;
extern const char *optarg;
extern int optind, opterr, optopt;
extern int optreset;
 
/branches/network/uspace/lib/libc/include/string.h
74,8 → 74,8
 
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 char *str_chr(const char *str, wchar_t ch);
extern char *str_rchr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
/branches/network/uspace/lib/libc/include/malloc.h
1,537 → 1,51
/*
Default header file for malloc-2.8.x, written by Doug Lea
and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain.
last update: Mon Aug 15 08:55:52 2005 Doug Lea (dl at gee)
* 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.
*/
 
This header is for ANSI C/C++ only. You can set any of
the following #defines before including:
 
* If USE_DL_PREFIX is defined, it is assumed that malloc.c
was also compiled with this option, so all routines
have names starting with "dl".
 
* If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this
file will be #included AFTER <malloc.h>. This is needed only if
your system defines a struct mallinfo that is incompatible with the
standard one declared here. Otherwise, you can include this file
INSTEAD of your system system <malloc.h>. At least on ANSI, all
declarations should be compatible with system versions
 
* If MSPACES is defined, declarations for mspace versions are included.
*/
 
#ifndef MALLOC_280_H
#define MALLOC_280_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include <stddef.h> /* for size_t */
 
#if !ONLY_MSPACES
 
#ifndef USE_DL_PREFIX
#define dlcalloc calloc
#define dlfree free
#define dlmalloc malloc
#define dlmemalign memalign
#define dlrealloc realloc
#define dlvalloc valloc
#define dlpvalloc pvalloc
#define dlmallinfo mallinfo
#define dlmallopt mallopt
#define dlmalloc_trim malloc_trim
#define dlmalloc_stats malloc_stats
#define dlmalloc_usable_size malloc_usable_size
#define dlmalloc_footprint malloc_footprint
#define dlmalloc_max_footprint malloc_max_footprint
#define dlindependent_calloc independent_calloc
#define dlindependent_comalloc independent_comalloc
#endif /* USE_DL_PREFIX */
 
 
/*
malloc(size_t n)
Returns a pointer to a newly allocated chunk of at least n bytes, or
null if no space is available, in which case errno is set to ENOMEM
on ANSI C systems.
 
If n is zero, malloc returns a minimum-sized chunk. (The minimum
size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
systems.) Note that size_t is an unsigned type, so calls with
arguments that would be negative if signed are interpreted as
requests for huge amounts of space, which will often fail. The
maximum supported value of n differs across systems, but is in all
cases less than the maximum representable value of a size_t.
*/
void* dlmalloc(size_t);
 
/*
free(void* p)
Releases the chunk of memory pointed to by p, that had been previously
allocated using malloc or a related routine such as realloc.
It has no effect if p is null. If p was not malloced or already
freed, free(p) will by default cuase the current program to abort.
*/
void dlfree(void*);
 
/*
calloc(size_t n_elements, size_t element_size);
Returns a pointer to n_elements * element_size bytes, with all locations
set to zero.
*/
void* dlcalloc(size_t, size_t);
 
/*
realloc(void* p, size_t n)
Returns a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available.
 
The returned pointer may or may not be the same as p. The algorithm
prefers extending p in most cases when possible, otherwise it
employs the equivalent of a malloc-copy-free sequence.
 
If p is null, realloc is equivalent to malloc.
 
If space is not available, realloc returns null, errno is set (if on
ANSI) and p is NOT freed.
 
if n is for fewer bytes than already held by p, the newly unused
space is lopped off and freed if possible. realloc with a size
argument of zero (re)allocates a minimum-sized chunk.
 
The old unix realloc convention of allowing the last-free'd chunk
to be used as an argument to realloc is not supported.
*/
 
void* dlrealloc(void*, size_t);
 
/*
memalign(size_t alignment, size_t n);
Returns a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument.
 
The alignment argument should be a power of two. If the argument is
not a power of two, the nearest greater power is used.
8-byte alignment is guaranteed by normal malloc calls, so don't
bother calling memalign with an argument of 8 or less.
 
Overreliance on memalign is a sure way to fragment space.
*/
void* dlmemalign(size_t, size_t);
 
/*
valloc(size_t n);
Equivalent to memalign(pagesize, n), where pagesize is the page
size of the system. If the pagesize is unknown, 4096 is used.
*/
void* dlvalloc(size_t);
 
/*
mallopt(int parameter_number, int parameter_value)
Sets tunable parameters The format is to provide a
(parameter-number, parameter-value) pair. mallopt then sets the
corresponding parameter to the argument value if it can (i.e., so
long as the value is meaningful), and returns 1 if successful else
0. SVID/XPG/ANSI defines four standard param numbers for mallopt,
normally defined in malloc.h. None of these are use in this malloc,
so setting them has no effect. But this malloc also supports other
options in mallopt:
 
Symbol param # default allowed param values
M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming)
M_GRANULARITY -2 page size any power of 2 >= page size
M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support)
*/
int dlmallopt(int, int);
 
#define M_TRIM_THRESHOLD (-1)
#define M_GRANULARITY (-2)
#define M_MMAP_THRESHOLD (-3)
 
 
/*
malloc_footprint();
Returns the number of bytes obtained from the system. The total
number of bytes allocated by malloc, realloc etc., is less than this
value. Unlike mallinfo, this function returns only a precomputed
result, so can be called frequently to monitor memory consumption.
Even if locks are otherwise defined, this function does not use them,
so results might not be up to date.
*/
size_t dlmalloc_footprint(void);
size_t dlmalloc_max_footprint(void);
 
#if !NO_MALLINFO
/*
mallinfo()
Returns (by copy) a struct containing various summary statistics:
 
arena: current total non-mmapped bytes allocated from system
ordblks: the number of free chunks
smblks: always zero.
hblks: current number of mmapped regions
hblkhd: total bytes held in mmapped regions
usmblks: the maximum total allocated space. This will be greater
than current total if trimming has occurred.
fsmblks: always zero
uordblks: current total allocated space (normal or mmapped)
fordblks: total free space
keepcost: the maximum number of bytes that could ideally be released
back to system via malloc_trim. ("ideally" means that
it ignores page restrictions etc.)
 
Because these fields are ints, but internal bookkeeping may
be kept as longs, the reported values may wrap around zero and
thus be inaccurate.
*/
#ifndef HAVE_USR_INCLUDE_MALLOC_H
#ifndef _MALLOC_H
#ifndef MALLINFO_FIELD_TYPE
#define MALLINFO_FIELD_TYPE size_t
#endif /* MALLINFO_FIELD_TYPE */
struct mallinfo {
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
MALLINFO_FIELD_TYPE smblks; /* always 0 */
MALLINFO_FIELD_TYPE hblks; /* always 0 */
MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */
MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */
MALLINFO_FIELD_TYPE fsmblks; /* always 0 */
MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
MALLINFO_FIELD_TYPE fordblks; /* total free space */
MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
};
#endif /* _MALLOC_H */
#endif /* HAVE_USR_INCLUDE_MALLOC_H */
 
struct mallinfo dlmallinfo(void);
#endif /* NO_MALLINFO */
 
/*
independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
 
independent_calloc is similar to calloc, but instead of returning a
single cleared space, it returns an array of pointers to n_elements
independent elements that can hold contents of size elem_size, each
of which starts out cleared, and can be independently freed,
realloc'ed etc. The elements are guaranteed to be adjacently
allocated (this is not guaranteed to occur with multiple callocs or
mallocs), which may also improve cache locality in some
applications.
 
The "chunks" argument is optional (i.e., may be null, which is
probably the most typical usage). If it is null, the returned array
is itself dynamically allocated and should also be freed when it is
no longer needed. Otherwise, the chunks array must be of at least
n_elements in length. It is filled in with the pointers to the
chunks.
 
In either case, independent_calloc returns this pointer array, or
null if the allocation failed. If n_elements is zero and "chunks"
is null, it returns a chunk representing an array with zero elements
(which should be freed if not wanted).
 
Each element must be individually freed when it is no longer
needed. If you'd like to instead be able to free all at once, you
should instead use regular calloc and assign pointers into this
space to represent elements. (In this case though, you cannot
independently free elements.)
 
independent_calloc simplifies and speeds up implementations of many
kinds of pools. It may also be useful when constructing large data
structures that initially have a fixed number of fixed-sized nodes,
but the number is not known at compile time, and some of the nodes
may later need to be freed. For example:
 
struct Node { int item; struct Node* next; };
 
struct Node* build_list() {
struct Node** pool;
int n = read_number_of_nodes_needed();
if (n <= 0) return 0;
pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
if (pool == 0) die();
// organize into a linked list...
struct Node* first = pool[0];
for (i = 0; i < n-1; ++i)
pool[i]->next = pool[i+1];
free(pool); // Can now free the array (or not, if it is needed later)
return first;
}
*/
void** dlindependent_calloc(size_t, size_t, void**);
 
/*
independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
 
independent_comalloc allocates, all at once, a set of n_elements
chunks with sizes indicated in the "sizes" array. It returns
an array of pointers to these elements, each of which can be
independently freed, realloc'ed etc. The elements are guaranteed to
be adjacently allocated (this is not guaranteed to occur with
multiple callocs or mallocs), which may also improve cache locality
in some applications.
 
The "chunks" argument is optional (i.e., may be null). If it is null
the returned array is itself dynamically allocated and should also
be freed when it is no longer needed. Otherwise, the chunks array
must be of at least n_elements in length. It is filled in with the
pointers to the chunks.
 
In either case, independent_comalloc returns this pointer array, or
null if the allocation failed. If n_elements is zero and chunks is
null, it returns a chunk representing an array with zero elements
(which should be freed if not wanted).
 
Each element must be individually freed when it is no longer
needed. If you'd like to instead be able to free all at once, you
should instead use a single regular malloc, and assign pointers at
particular offsets in the aggregate space. (In this case though, you
cannot independently free elements.)
 
independent_comallac differs from independent_calloc in that each
element may have a different size, and also that it does not
automatically clear elements.
 
independent_comalloc can be used to speed up allocation in cases
where several structs or objects must always be allocated at the
same time. For example:
 
struct Head { ... }
struct Foot { ... }
 
void send_message(char* msg) {
int msglen = strlen(msg);
size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
void* chunks[3];
if (independent_comalloc(3, sizes, chunks) == 0)
die();
struct Head* head = (struct Head*)(chunks[0]);
char* body = (char*)(chunks[1]);
struct Foot* foot = (struct Foot*)(chunks[2]);
// ...
}
 
In general though, independent_comalloc is worth using only for
larger values of n_elements. For small values, you probably won't
detect enough difference from series of malloc calls to bother.
 
Overuse of independent_comalloc can increase overall memory usage,
since it cannot reuse existing noncontiguous small chunks that
might be available for some of the elements.
*/
void** dlindependent_comalloc(size_t, size_t*, void**);
 
 
/*
pvalloc(size_t n);
Equivalent to valloc(minimum-page-that-holds(n)), that is,
round up n to nearest pagesize.
/** @addtogroup libc
* @{
*/
void* dlpvalloc(size_t);
/** @file
*/
 
/*
malloc_trim(size_t pad);
#ifndef LIBC_MALLOC_H_
#define LIBC_MALLOC_H_
 
If possible, gives memory back to the system (via negative arguments
to sbrk) if there is unused memory at the `high' end of the malloc
pool or in unused MMAP segments. You can call this after freeing
large blocks of memory to potentially reduce the system-level memory
requirements of a program. However, it cannot guarantee to reduce
memory. Under some allocation patterns, some large free blocks of
memory will be locked between two used chunks, so they cannot be
given back to the system.
#include <sys/types.h>
 
The `pad' argument to malloc_trim represents the amount of free
trailing space to leave untrimmed. If this argument is zero, only
the minimum amount of memory to maintain internal data structures
will be left. Non-zero arguments can be supplied to maintain enough
trailing space to service future expected allocations without having
to re-obtain memory from the system.
extern void __heap_init(void);
extern uintptr_t get_max_heap_addr(void);
 
Malloc_trim returns 1 if it actually released any memory, else 0.
*/
int dlmalloc_trim(size_t);
extern void *malloc(const size_t size);
extern void *memalign(const size_t align, const size_t size);
extern void *realloc(const void *addr, const size_t size);
extern void free(const void *addr);
 
/*
malloc_usable_size(void* p);
 
Returns the number of bytes you can actually use in
an allocated chunk, which may be more than you requested (although
often not) due to alignment and minimum size constraints.
You can use this many bytes without worrying about
overwriting other allocated objects. This is not a particularly great
programming practice. malloc_usable_size can be more useful in
debugging and assertions, for example:
 
p = malloc(n);
assert(malloc_usable_size(p) >= 256);
*/
size_t dlmalloc_usable_size(void*);
 
/*
malloc_stats();
Prints on stderr the amount of space obtained from the system (both
via sbrk and mmap), the maximum amount (which may be more than
current if malloc_trim and/or munmap got called), and the current
number of bytes allocated via malloc (or realloc, etc) but not yet
freed. Note that this is the number of bytes allocated, not the
number requested. It will be larger than the number requested
because of alignment and bookkeeping overhead. Because it includes
alignment wastage as being in use, this figure may be greater than
zero even when no user-level chunks are allocated.
 
The reported current and maximum system memory can be inaccurate if
a program makes other calls to system memory allocation functions
(normally sbrk) outside of malloc.
 
malloc_stats prints only the most commonly interesting statistics.
More information can be obtained by calling mallinfo.
*/
void dlmalloc_stats(void);
 
#endif /* !ONLY_MSPACES */
 
#if MSPACES
 
/*
mspace is an opaque type representing an independent
region of space that supports mspace_malloc, etc.
*/
typedef void* mspace;
 
/*
create_mspace creates and returns a new independent space with the
given initial capacity, or, if 0, the default granularity size. It
returns null if there is no system memory available to create the
space. If argument locked is non-zero, the space uses a separate
lock to control access. The capacity of the space will grow
dynamically as needed to service mspace_malloc requests. You can
control the sizes of incremental increases of this space by
compiling with a different DEFAULT_GRANULARITY or dynamically
setting with mallopt(M_GRANULARITY, value).
*/
mspace create_mspace(size_t capacity, int locked);
 
/*
destroy_mspace destroys the given space, and attempts to return all
of its memory back to the system, returning the total number of
bytes freed. After destruction, the results of access to all memory
used by the space become undefined.
*/
size_t destroy_mspace(mspace msp);
 
/*
create_mspace_with_base uses the memory supplied as the initial base
of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
space is used for bookkeeping, so the capacity must be at least this
large. (Otherwise 0 is returned.) When this initial space is
exhausted, additional memory will be obtained from the system.
Destroying this space will deallocate all additionally allocated
space (if possible) but not the initial base.
*/
mspace create_mspace_with_base(void* base, size_t capacity, int locked);
 
/*
mspace_malloc behaves as malloc, but operates within
the given space.
*/
void* mspace_malloc(mspace msp, size_t bytes);
 
/*
mspace_free behaves as free, but operates within
the given space.
 
If compiled with FOOTERS==1, mspace_free is not actually needed.
free may be called instead of mspace_free because freed chunks from
any space are handled by their originating spaces.
*/
void mspace_free(mspace msp, void* mem);
 
/*
mspace_realloc behaves as realloc, but operates within
the given space.
 
If compiled with FOOTERS==1, mspace_realloc is not actually
needed. realloc may be called instead of mspace_realloc because
realloced chunks from any space are handled by their originating
spaces.
*/
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
 
/*
mspace_calloc behaves as calloc, but operates within
the given space.
*/
void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
 
/*
mspace_memalign behaves as memalign, but operates within
the given space.
*/
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
 
/*
mspace_independent_calloc behaves as independent_calloc, but
operates within the given space.
*/
void** mspace_independent_calloc(mspace msp, size_t n_elements,
size_t elem_size, void* chunks[]);
 
/*
mspace_independent_comalloc behaves as independent_comalloc, but
operates within the given space.
*/
void** mspace_independent_comalloc(mspace msp, size_t n_elements,
size_t sizes[], void* chunks[]);
 
/*
mspace_footprint() returns the number of bytes obtained from the
system for this space.
*/
size_t mspace_footprint(mspace msp);
 
 
#if !NO_MALLINFO
/*
mspace_mallinfo behaves as mallinfo, but reports properties of
the given space.
*/
struct mallinfo mspace_mallinfo(mspace msp);
#endif /* NO_MALLINFO */
 
/*
mspace_malloc_stats behaves as malloc_stats, but reports
properties of the given space.
*/
void mspace_malloc_stats(mspace msp);
 
/*
mspace_trim behaves as malloc_trim, but
operates within the given space.
*/
int mspace_trim(mspace msp, size_t pad);
 
/*
An alias for mallopt.
*/
int mspace_mallopt(int, int);
 
#endif /* MSPACES */
 
#ifdef __cplusplus
}; /* end of extern "C" */
#endif
 
#endif /* MALLOC_280_H */
 
 
/** @}
/** @}
*/
/branches/network/uspace/lib/libc/include/vfs/vfs.h
55,8 → 55,8
extern int mount(const char *, const char *, const char *, const char *,
unsigned int);
 
extern void stdio_init(int filc, fdi_node_t *filv[]);
extern void stdio_done(void);
extern void __stdio_init(int filc, fdi_node_t *filv[]);
extern void __stdio_done(void);
 
extern int open_node(fdi_node_t *, int);
extern int fd_phone(int);
/branches/network/uspace/lib/libc/include/async.h
46,11 → 46,7
 
extern atomic_t async_futex;
 
static inline void async_manager(void)
{
fibril_switch(FIBRIL_TO_MANAGER);
}
 
extern int __async_init(void);
extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
 
static inline ipc_callid_t async_get_call(ipc_call_t *data)
58,6 → 54,11
return async_get_call_timeout(data, 0);
}
 
static inline void async_manager(void)
{
fibril_switch(FIBRIL_TO_MANAGER);
}
 
/*
* User-friendly wrappers for async_send_fast() and async_send_slow(). The
* macros are in the form async_send_m(), where m denotes the number of payload
94,7 → 95,6
extern void async_usleep(suseconds_t timeout);
extern void async_create_manager(void);
extern void async_destroy_manager(void);
extern int _async_init(void);
 
extern void async_set_client_connection(async_client_conn_t conn);
extern void async_set_interrupt_received(async_client_conn_t conn);
/branches/network/uspace/lib/libc/include/stdlib.h
38,10 → 38,10
#include <unistd.h>
#include <malloc.h>
 
#define abort() _exit(1)
#define exit(status) _exit((status))
#define abort() _exit(1)
#define exit(status) _exit((status))
 
#define RAND_MAX 714025
#define RAND_MAX 714025
 
extern long int random(void);
extern void srandom(unsigned int seed);
50,6 → 50,7
{
return random();
}
 
static inline void srand(unsigned int seed)
{
srandom(seed);
/branches/network/uspace/lib/libc/include/stdio.h
37,20 → 37,21
 
#include <sys/types.h>
#include <stdarg.h>
#include <string.h>
#include <adt/list.h>
 
#define EOF (-1)
 
/** Default size for stream I/O buffers */
#define BUFSIZ 4096
#define BUFSIZ 4096
 
#define DEBUG(fmt, ...) \
{ \
char buf[256]; \
int n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \
if (n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, str_size(buf)); \
}
{ \
char _buf[256]; \
int _n = snprintf(_buf, sizeof(_buf), fmt, ##__VA_ARGS__); \
if (_n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) _buf, str_size(_buf)); \
}
 
#ifndef SEEK_SET
#define SEEK_SET 0
/branches/network/uspace/lib/libc/include/bitops.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
42,10 → 42,10
*
* If number is zero, it returns 0
*/
static inline int fnzb32(uint32_t arg)
static inline unsigned int fnzb32(uint32_t arg)
{
int n = 0;
 
unsigned int n = 0;
if (arg >> 16) {
arg >>= 16;
n += 16;
74,19 → 74,22
return n;
}
 
static inline int fnzb64(uint64_t arg)
static inline unsigned int fnzb64(uint64_t arg)
{
int n = 0;
 
unsigned int n = 0;
if (arg >> 32) {
arg >>= 32;
n += 32;
}
return n + fnzb32((uint32_t) arg);
return (n + fnzb32((uint32_t) arg));
}
 
#define fnzb(x) fnzb32(x)
static inline unsigned int fnzb(size_t arg)
{
return fnzb64(arg);
}
 
#endif
 
/branches/network/uspace/lib/libc/include/task.h
39,11 → 39,18
 
typedef uint64_t task_id_t;
 
typedef enum {
TASK_EXIT_NORMAL,
TASK_EXIT_UNEXPECTED
} task_exit_t;
 
extern task_id_t task_get_id(void);
extern int task_set_name(const char *name);
extern task_id_t task_spawn(const char *path, char *const argv[]);
extern int task_wait(task_id_t id);
extern int task_wait(task_id_t id, task_exit_t *texit, int *retval);
extern int task_retval(int val);
 
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/unistd.h
65,7 → 65,6
extern int chdir(const char *);
 
extern void _exit(int status) __attribute__ ((noreturn));
extern void *sbrk(ssize_t incr);
extern int usleep(unsigned long usec);
extern unsigned int sleep(unsigned int seconds);
 
/branches/network/uspace/lib/libc/include/fibril.h
75,7 → 75,7
/** Fibril-local variable specifier */
#define fibril_local __thread
 
extern int context_save(context_t *c);
extern int context_save(context_t *c) __attribute__ ((returns_twice));
extern void context_restore(context_t *c) __attribute__ ((noreturn));
 
extern fid_t fibril_create(int (*func)(void *), void *arg);
/branches/network/uspace/lib/libc/include/devmap.h
47,6 → 47,9
extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
extern int devmap_device_connect(dev_handle_t, unsigned int);
 
extern int devmap_null_create(void);
extern void devmap_null_destroy(int);
 
extern ipcarg_t devmap_device_get_count(void);
extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
 
/branches/network/uspace/lib/libc/include/mem.h
39,9 → 39,9
 
#define bzero(ptr, len) memset((ptr), 0, (len))
 
extern void * memset(void *, int, size_t);
extern void * memcpy(void *, const void *, size_t);
extern void * memmove(void *, const void *, size_t);
extern void *memset(void *, int, size_t);
extern void *memcpy(void *, const void *, size_t);
extern void *memmove(void *, const void *, size_t);
 
extern int bcmp(const char *, const char *, size_t);
 
/branches/network/uspace/lib/libc/include/io/console.h
43,6 → 43,13
KEY_RELEASE
} console_ev_type_t;
 
enum {
CONSOLE_CCAP_NONE = 0,
CONSOLE_CCAP_STYLE,
CONSOLE_CCAP_INDEXED,
CONSOLE_CCAP_RGB
};
 
/** Console event structure. */
typedef struct {
/** Press or release event. */
68,6 → 75,7
extern void console_set_rgb_color(int phone, int fg_color, int bg_color);
 
extern void console_cursor_visibility(int phone, bool show);
extern int console_get_color_cap(int phone, int *ccap);
extern void console_kcon_enable(int phone);
 
extern bool console_get_event(int phone, console_event_t *event);
/branches/network/uspace/lib/libc/include/adt/gcdlcm.h
0,0 → 1,73
/*
* 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 libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_GCDLCM_H_
#define LIBC_GCDLCM_H_
 
#include <sys/types.h>
 
#define DECLARE_GCD(type, name) \
static inline type name(type a, type b) \
{ \
if (a == 0) \
return b; \
\
while (b != 0) { \
if (a > b) \
a -= b; \
else \
b -= a; \
} \
\
return a; \
}
 
#define DECLARE_LCM(type, name, gcd) \
static inline type name(type a, type b) \
{ \
return (a * b) / gcd(a, b); \
}
 
DECLARE_GCD(uint32_t, gcd32);
DECLARE_GCD(uint64_t, gcd64);
DECLARE_GCD(size_t, gcd);
 
DECLARE_LCM(uint32_t, lcm32, gcd32);
DECLARE_LCM(uint64_t, lcm64, gcd64);
DECLARE_LCM(size_t, lcm, gcd);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/macros.h
35,6 → 35,9
#ifndef LIBC_MACROS_H_
#define LIBC_MACROS_H_
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
/branches/network/uspace/lib/libc/include/ipc/devmap.h
28,7 → 28,7
 
/** @addtogroup devmap
* @{
*/
*/
 
#ifndef DEVMAP_DEVMAP_H_
#define DEVMAP_DEVMAP_H_
48,6 → 48,8
DEVMAP_DEVICE_UNREGISTER,
DEVMAP_DEVICE_GET_NAME,
DEVMAP_DEVICE_GET_HANDLE,
DEVMAP_DEVICE_NULL_CREATE,
DEVMAP_DEVICE_NULL_DESTROY,
DEVMAP_DEVICE_GET_COUNT,
DEVMAP_DEVICE_GET_DEVICES
} devmap_request_t;
/branches/network/uspace/lib/libc/include/ipc/vfs.h
57,36 → 57,40
} vfs_info_t;
 
typedef enum {
VFS_OPEN_NODE = IPC_FIRST_USER_METHOD,
VFS_READ,
VFS_WRITE,
VFS_TRUNCATE,
VFS_MOUNT,
VFS_UNMOUNT,
VFS_DEVICE,
VFS_SYNC,
VFS_CLOSE,
VFS_LAST_CMN /* keep this the last member of this enum */
} vfs_request_cmn_t;
VFS_IN_OPEN = IPC_FIRST_USER_METHOD,
VFS_IN_OPEN_NODE,
VFS_IN_READ,
VFS_IN_WRITE,
VFS_IN_SEEK,
VFS_IN_TRUNCATE,
VFS_IN_FSTAT,
VFS_IN_CLOSE,
VFS_IN_MOUNT,
VFS_IN_UNMOUNT,
VFS_IN_SYNC,
VFS_IN_REGISTER,
VFS_IN_MKDIR,
VFS_IN_UNLINK,
VFS_IN_RENAME,
VFS_IN_STAT
} vfs_in_request_t;
 
typedef enum {
VFS_LOOKUP = VFS_LAST_CMN,
VFS_MOUNTED,
VFS_DESTROY,
VFS_LAST_CLNT /* keep this the last member of this enum */
} vfs_request_clnt_t;
VFS_OUT_OPEN_NODE = IPC_FIRST_USER_METHOD,
VFS_OUT_READ,
VFS_OUT_WRITE,
VFS_OUT_TRUNCATE,
VFS_OUT_CLOSE,
VFS_OUT_MOUNT,
VFS_OUT_MOUNTED,
VFS_OUT_UNMOUNT,
VFS_OUT_SYNC,
VFS_OUT_STAT,
VFS_OUT_LOOKUP,
VFS_OUT_DESTROY,
VFS_OUT_LAST
} vfs_out_request_t;
 
typedef enum {
VFS_REGISTER = VFS_LAST_CMN,
VFS_OPEN,
VFS_SEEK,
VFS_MKDIR,
VFS_UNLINK,
VFS_RENAME,
VFS_NODE,
VFS_LAST_SRV /* keep this the last member of this enum */
} vfs_request_srv_t;
 
/*
* Lookup flags.
*/
/branches/network/uspace/lib/libc/include/ipc/ns.h
39,7 → 39,9
 
typedef enum {
NS_PING = IPC_FIRST_USER_METHOD,
NS_TASK_WAIT
NS_TASK_WAIT,
NS_ID_INTRO,
NS_RETVAL
} ns_request_t;
 
#endif
/branches/network/uspace/lib/libc/include/ipc/console.h
39,7 → 39,8
#include <ipc/vfs.h>
 
typedef enum {
CONSOLE_GET_SIZE = VFS_LAST_SRV,
CONSOLE_GET_SIZE = VFS_OUT_LAST,
CONSOLE_GET_COLOR_CAP,
CONSOLE_GET_EVENT,
CONSOLE_GOTO,
CONSOLE_CLEAR,
/branches/network/uspace/lib/libc/include/ipc/fb.h
41,6 → 41,7
FB_PUTCHAR = IPC_FIRST_USER_METHOD,
FB_CLEAR,
FB_GET_CSIZE,
FB_GET_COLOR_CAP,
FB_CURSOR_VISIBILITY,
FB_CURSOR_GOTO,
FB_SCROLL,
71,6 → 72,13
FB_SCREEN_RECLAIM
} fb_request_t;
 
enum {
FB_CCAP_NONE = 0,
FB_CCAP_STYLE,
FB_CCAP_INDEXED,
FB_CCAP_RGB
};
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/errno.h
35,12 → 35,13
#ifndef LIBC_ERRNO_H_
#define LIBC_ERRNO_H_
 
/* TODO: support threads/fibrils */
#include <kernel/errno.h>
#include <fibril.h>
 
extern int _errno;
 
#define errno _errno
 
#include <kernel/errno.h>
 
#define EMFILE (-17)
#define ENAMETOOLONG (-256)
#define EISDIR (-257)
/branches/network/uspace/lib/libc/include/sys/stat.h
36,7 → 36,26
#define LIBC_SYS_STAT_H_
 
#include <sys/types.h>
#include <bool.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
 
struct stat {
fs_handle_t fs_handle;
dev_handle_t dev_handle;
fs_index_t index;
unsigned lnkcnt;
bool is_file;
off_t size;
union {
struct {
dev_handle_t device;
} devfs_stat;
};
};
 
extern int fstat(int, struct stat *);
extern int stat(const char *, struct stat *);
extern int mkdir(const char *, mode_t);
 
#endif
/branches/network/uspace/lib/libc/generic/task.c
148,10 → 148,23
return 0;
}
 
int task_wait(task_id_t id)
int task_wait(task_id_t id, task_exit_t *texit, int *retval)
{
return (int) async_req_2_0(PHONE_NS, NS_TASK_WAIT, LOWER32(id), UPPER32(id));
ipcarg_t te, rv;
int rc;
 
rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
UPPER32(id), &te, &rv);
*texit = te;
*retval = rv;
 
return rc;
}
 
int task_retval(int val)
{
return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/getopt.c
47,7 → 47,7
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
const char *optarg; /* argument associated with option */
 
 
#define IGNORE_FIRST (*options == '-' || *options == '+')
162,7 → 162,7
char **nargv;
const char *options;
{
char *oli; /* option letter list index */
const char *oli; /* option letter list index */
int optchar;
 
assert(nargv != NULL);
275,7 → 275,7
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = *place;
optarg = place;
/* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
353,7 → 353,8
 
retval = getopt_internal(nargc, (char **)nargv, options);
if (retval == -2) {
char *current_argv, *has_equal;
char *current_argv;
const char *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
 
/branches/network/uspace/lib/libc/generic/as.c
38,23 → 38,23
#include <align.h>
#include <sys/types.h>
#include <bitops.h>
#include <malloc.h>
 
/**
* Either 4*256M on 32-bit architecures or 16*256M on 64-bit architectures.
*/
#define MAX_HEAP_SIZE (sizeof(uintptr_t)<<28)
/** Last position allocated by as_get_mappable_page */
static uintptr_t last_allocated = 0;
 
/** Create address space area.
*
* @param address Virtual address where to place new address space area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
*
* @return address on success, (void *) -1 otherwise.
*
*/
void *as_area_create(void *address, size_t size, int flags)
{
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t ) address,
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
61,15 → 61,16
/** Resize address space area.
*
* @param address Virtual address pointing into already existing address space
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_resize(void *address, size_t size, int flags)
{
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address,
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
76,22 → 77,24
/** Destroy address space area.
*
* @param address Virtual address pointing into the address space area being
* destroyed.
* destroyed.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_destroy(void *address)
{
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t) address);
}
 
/** Change address-space area flags.
*
* @param address Virtual address pointing into the address space area being
* modified.
* @param flags New flags describing type of the area.
* modified.
* @param flags New flags describing type of the area.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_change_flags(void *address, int flags)
{
99,101 → 102,29
(sysarg_t) flags);
}
 
static size_t heapsize = 0;
static size_t maxheapsize = (size_t) (-1);
 
static void *last_allocated = 0;
 
/* Start of heap linker symbol */
extern char _heap;
 
/** Sbrk emulation
*
* @param incr New area that should be allocated or negative,
if it should be shrinked
* @return Pointer to newly allocated area
*/
void *sbrk(ssize_t incr)
{
int rc;
void *res;
/* Check for invalid values */
if ((incr < 0) && (((size_t) -incr) > heapsize))
return NULL;
/* Check for too large value */
if ((incr > 0) && (incr + heapsize < heapsize))
return NULL;
/* Check for too small values */
if ((incr < 0) && (incr + heapsize > heapsize))
return NULL;
/* Check for user limit */
if ((maxheapsize != (size_t) (-1)) && (heapsize + incr) > maxheapsize)
return NULL;
rc = as_area_resize(&_heap, heapsize + incr, 0);
if (rc != 0)
return NULL;
/* Compute start of new area */
res = (void *) &_heap + heapsize;
 
heapsize += incr;
 
return res;
}
 
/** Set maximum heap size and return pointer just after the heap */
void *set_maxheapsize(size_t mhs)
{
maxheapsize = mhs;
/* Return pointer to area not managed by sbrk */
return ((void *) &_heap + maxheapsize);
}
 
/** Return pointer to some unmapped area, where fits new as_area
*
* @param sz Requested size of the allocation.
* @param size Requested size of the allocation.
*
* @return Pointer to the beginning
* @return pointer to the beginning
*
* TODO: make some first_fit/... algorithm, we are now just incrementing
* the pointer to last area
*/
void *as_get_mappable_page(size_t sz)
void *as_get_mappable_page(size_t size)
{
void *res;
uint64_t asz;
int i;
if (size == 0)
return NULL;
if (!sz)
return NULL;
 
asz = 1 << (fnzb64(sz - 1) + 1);
 
/* Set heapsize to some meaningful value */
if (maxheapsize == (size_t) -1)
set_maxheapsize(MAX_HEAP_SIZE);
size_t sz = 1 << (fnzb(size - 1) + 1);
if (last_allocated == 0)
last_allocated = get_max_heap_addr();
/*
* Make sure we allocate from naturally aligned address.
*/
i = 0;
if (!last_allocated) {
last_allocated = (void *) ALIGN_UP((void *) &_heap +
maxheapsize, asz);
} else {
last_allocated = (void *) ALIGN_UP(((uintptr_t)
last_allocated) + (int) (i > 0), asz);
}
 
res = last_allocated;
last_allocated += ALIGN_UP(sz, PAGE_SIZE);
 
return res;
uintptr_t res = ALIGN_UP(last_allocated, sz);
last_allocated = res + ALIGN_UP(size, PAGE_SIZE);
return ((void *) res);
}
 
/** @}
/branches/network/uspace/lib/libc/generic/string.c
589,7 → 589,7
*
* @return Pointer to character in @a str or NULL if not found.
*/
const char *str_chr(const char *str, wchar_t ch)
char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
597,7 → 597,7
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
return (char *) (str + last);
last = off;
}
611,7 → 611,7
*
* @return Pointer to character in @a str or NULL if not found.
*/
const char *str_rchr(const char *str, wchar_t ch)
char *str_rchr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
624,7 → 624,7
last = off;
}
return res;
return (char *) res;
}
 
/** Insert a wide character into a wide string.
/branches/network/uspace/lib/libc/generic/malloc.c
0,0 → 1,475
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Petr Tuma
* 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 libc
* @{
*/
/** @file
*/
 
#include <malloc.h>
#include <bool.h>
#include <as.h>
#include <align.h>
#include <macros.h>
#include <assert.h>
#include <errno.h>
#include <bitops.h>
#include <mem.h>
#include <adt/gcdlcm.h>
 
/* Magic used in heap headers. */
#define HEAP_BLOCK_HEAD_MAGIC 0xBEEF0101
 
/* Magic used in heap footers. */
#define HEAP_BLOCK_FOOT_MAGIC 0xBEEF0202
 
/** Allocation alignment (this also covers the alignment of fields
in the heap header and footer) */
#define BASE_ALIGN 16
 
/**
* Either 4 * 256M on 32-bit architecures or 16 * 256M on 64-bit architectures
*/
#define MAX_HEAP_SIZE (sizeof(uintptr_t) << 28)
 
/**
*
*/
#define STRUCT_OVERHEAD (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
 
/**
* Calculate real size of a heap block (with header and footer)
*/
#define GROSS_SIZE(size) ((size) + STRUCT_OVERHEAD)
 
/**
* Calculate net size of a heap block (without header and footer)
*/
#define NET_SIZE(size) ((size) - STRUCT_OVERHEAD)
 
 
/** Header of a heap block
*
*/
typedef struct {
/* Size of the block (including header and footer) */
size_t size;
/* Indication of a free block */
bool free;
/* A magic value to detect overwrite of heap header */
uint32_t magic;
} heap_block_head_t;
 
/** Footer of a heap block
*
*/
typedef struct {
/* Size of the block (including header and footer) */
size_t size;
/* A magic value to detect overwrite of heap footer */
uint32_t magic;
} heap_block_foot_t;
 
/** Linker heap symbol */
extern char _heap;
 
/** Address of heap start */
static void *heap_start = 0;
 
/** Address of heap end */
static void *heap_end = 0;
 
/** Maximum heap size */
static size_t max_heap_size = (size_t) -1;
 
/** Current number of pages of heap area */
static size_t heap_pages = 0;
 
/** Initialize a heap block
*
* Fills in the structures related to a heap block.
*
* @param addr Address of the block.
* @param size Size of the block including the header and the footer.
* @param free Indication of a free block.
*
*/
static void block_init(void *addr, size_t size, bool free)
{
/* Calculate the position of the header and the footer */
heap_block_head_t *head = (heap_block_head_t *) addr;
heap_block_foot_t *foot =
(heap_block_foot_t *) (addr + size - sizeof(heap_block_foot_t));
head->size = size;
head->free = free;
head->magic = HEAP_BLOCK_HEAD_MAGIC;
foot->size = size;
foot->magic = HEAP_BLOCK_FOOT_MAGIC;
}
 
/** Check a heap block
*
* Verifies that the structures related to a heap block still contain
* the magic constants. This helps detect heap corruption early on.
*
* @param addr Address of the block.
*
*/
static void block_check(void *addr)
{
heap_block_head_t *head = (heap_block_head_t *) addr;
assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
heap_block_foot_t *foot =
(heap_block_foot_t *) (addr + head->size - sizeof(heap_block_foot_t));
assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
assert(head->size == foot->size);
}
 
static bool grow_heap(size_t size)
{
if (size == 0)
return false;
size_t heap_size = (size_t) (heap_end - heap_start);
if ((max_heap_size != (size_t) -1) && (heap_size + size > max_heap_size))
return false;
size_t pages = (size - 1) / PAGE_SIZE + 1;
if (as_area_resize((void *) &_heap, (heap_pages + pages) * PAGE_SIZE, 0)
== EOK) {
void *end = (void *) ALIGN_DOWN(((uintptr_t) &_heap) +
(heap_pages + pages) * PAGE_SIZE, BASE_ALIGN);
block_init(heap_end, end - heap_end, true);
heap_pages += pages;
heap_end = end;
return true;
}
return false;
}
 
static void shrink_heap(void)
{
// TODO
}
 
/** Initialize the heap allocator
*
* Finds how much physical memory we have and creates
* the heap management structures that mark the whole
* physical memory as a single free block.
*
*/
void __heap_init(void)
{
if (as_area_create((void *) &_heap, PAGE_SIZE,
AS_AREA_WRITE | AS_AREA_READ)) {
heap_pages = 1;
heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
heap_end =
(void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
/* Make the entire area one large block. */
block_init(heap_start, heap_end - heap_start, true);
}
}
 
uintptr_t get_max_heap_addr(void)
{
if (max_heap_size == (size_t) -1)
max_heap_size =
max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
return ((uintptr_t) heap_start + max_heap_size);
}
 
static void split_mark(heap_block_head_t *cur, const size_t size)
{
assert(cur->size >= size);
/* See if we should split the block. */
size_t split_limit = GROSS_SIZE(size);
if (cur->size > split_limit) {
/* Block big enough -> split. */
void *next = ((void *) cur) + size;
block_init(next, cur->size - size, true);
block_init(cur, size, false);
} else {
/* Block too small -> use as is. */
cur->free = false;
}
}
 
/** Allocate a memory block
*
* @param size The size of the block to allocate.
* @param align Memory address alignment.
*
* @return the address of the block or NULL when not enough memory.
*
*/
static void *malloc_internal(const size_t size, const size_t align)
{
if (align == 0)
return NULL;
size_t falign = lcm(align, BASE_ALIGN);
size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
bool grown = false;
void *result;
loop:
result = NULL;
heap_block_head_t *cur = (heap_block_head_t *) heap_start;
while ((result == NULL) && ((void *) cur < heap_end)) {
block_check(cur);
/* Try to find a block that is free and large enough. */
if ((cur->free) && (cur->size >= real_size)) {
/* We have found a suitable block.
Check for alignment properties. */
void *addr = ((void *) cur) + sizeof(heap_block_head_t);
void *aligned = (void *) ALIGN_UP(addr, falign);
if (addr == aligned) {
/* Exact block start including alignment. */
split_mark(cur, real_size);
result = addr;
} else {
/* Block start has to be aligned */
size_t excess = (size_t) (aligned - addr);
if (cur->size >= real_size + excess) {
/* The current block is large enough to fit
data in including alignment */
if ((void *) cur > heap_start) {
/* There is a block before the current block.
This previous block can be enlarged to compensate
for the alignment excess */
heap_block_foot_t *prev_foot =
((void *) cur) - sizeof(heap_block_foot_t);
heap_block_head_t *prev_head =
(heap_block_head_t *) (((void *) cur) - prev_foot->size);
block_check(prev_head);
size_t reduced_size = cur->size - excess;
heap_block_head_t *next_head = ((void *) cur) + excess;
if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) {
/* The previous block is not free and there is enough
space to fill in a new free block between the previous
and current block */
block_init(cur, excess, true);
} else {
/* The previous block is free (thus there is no need to
induce additional fragmentation to the heap) or the
excess is small, thus just enlarge the previous block */
block_init(prev_head, prev_head->size + excess, prev_head->free);
}
block_init(next_head, reduced_size, true);
split_mark(next_head, real_size);
result = aligned;
cur = next_head;
} else {
/* The current block is the first block on the heap.
We have to make sure that the alignment excess
is large enough to fit a new free block just
before the current block */
while (excess < STRUCT_OVERHEAD) {
aligned += falign;
excess += falign;
}
/* Check for current block size again */
if (cur->size >= real_size + excess) {
size_t reduced_size = cur->size - excess;
cur = (heap_block_head_t *) (heap_start + excess);
block_init(heap_start, excess, true);
block_init(cur, reduced_size, true);
split_mark(cur, real_size);
result = aligned;
}
}
}
}
}
/* Advance to the next block. */
cur = (heap_block_head_t *) (((void *) cur) + cur->size);
}
if ((result == NULL) && (!grown)) {
if (grow_heap(real_size)) {
grown = true;
goto loop;
}
}
return result;
}
 
void *malloc(const size_t size)
{
return malloc_internal(size, BASE_ALIGN);
}
 
void *memalign(const size_t align, const size_t size)
{
if (align == 0)
return NULL;
size_t palign =
1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
return malloc_internal(size, palign);
}
 
void *realloc(const void *addr, const size_t size)
{
if (addr == NULL)
return malloc(size);
/* Calculate the position of the header. */
heap_block_head_t *head =
(heap_block_head_t *) (addr - sizeof(heap_block_head_t));
assert((void *) head >= heap_start);
assert((void *) head < heap_end);
block_check(head);
assert(!head->free);
void *ptr = NULL;
size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
size_t orig_size = head->size;
if (orig_size > real_size) {
/* Shrink */
if (orig_size - real_size >= STRUCT_OVERHEAD) {
/* Split the original block to a full block
and a tailing free block */
block_init((void *) head, real_size, false);
block_init((void *) head + real_size,
orig_size - real_size, true);
shrink_heap();
}
ptr = ((void *) head) + sizeof(heap_block_head_t);
} else {
/* Look at the next block. If it is free and the size is
sufficient then merge the two. */
heap_block_head_t *next_head =
(heap_block_head_t *) (((void *) head) + head->size);
if (((void *) next_head < heap_end) &&
(head->size + next_head->size >= real_size) &&
(next_head->free)) {
block_check(next_head);
block_init(head, head->size + next_head->size, false);
split_mark(head, real_size);
ptr = ((void *) head) + sizeof(heap_block_head_t);
} else {
ptr = malloc(size);
if (ptr != NULL) {
memcpy(ptr, addr, NET_SIZE(orig_size));
free(addr);
}
}
}
return ptr;
}
 
/** Free a memory block
*
* @param addr The address of the block.
*/
void free(const void *addr)
{
/* Calculate the position of the header. */
heap_block_head_t *head
= (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
assert((void *) head >= heap_start);
assert((void *) head < heap_end);
block_check(head);
assert(!head->free);
/* Mark the block itself as free. */
head->free = true;
/* Look at the next block. If it is free, merge the two. */
heap_block_head_t *next_head
= (heap_block_head_t *) (((void *) head) + head->size);
if ((void *) next_head < heap_end) {
block_check(next_head);
if (next_head->free)
block_init(head, head->size + next_head->size, true);
}
/* Look at the previous block. If it is free, merge the two. */
if ((void *) head > heap_start) {
heap_block_foot_t *prev_foot =
(heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
heap_block_head_t *prev_head =
(heap_block_head_t *) (((void *) head) - prev_foot->size);
block_check(prev_head);
if (prev_head->free)
block_init(prev_head, prev_head->size + head->size, true);
}
shrink_heap();
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/libc.c
52,11 → 52,8
#include <as.h>
#include <loader/pcb.h>
 
extern char _heap;
extern int main(int argc, char *argv[]);
 
int _errno;
 
void _exit(int status)
{
thread_exit(status);
64,9 → 61,10
 
void __main(void *pcb_ptr)
{
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
_async_init();
int retval;
 
__heap_init();
__async_init();
fibril_t *fibril = fibril_setup();
__tcb_set(fibril->tcb);
79,15 → 77,17
if (__pcb == NULL) {
argc = 0;
argv = NULL;
stdio_init(0, NULL);
__stdio_init(0, NULL);
} else {
argc = __pcb->argc;
argv = __pcb->argv;
stdio_init(__pcb->filc, __pcb->filv);
__stdio_init(__pcb->filc, __pcb->filv);
}
main(argc, argv);
stdio_done();
retval = main(argc, argv);
 
__stdio_done();
(void) task_retval(retval);
}
 
void __exit(void)
/branches/network/uspace/lib/libc/generic/devmap.c
218,6 → 218,31
return phone;
}
 
int devmap_null_create(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return -1;
ipcarg_t null_id;
int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
if (retval != EOK)
return -1;
return (int) null_id;
}
 
void devmap_null_destroy(int null_id)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return;
async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
}
 
ipcarg_t devmap_device_get_count(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
/branches/network/uspace/lib/libc/generic/async.c
738,7 → 738,7
*
* @return Zero on success or an error code.
*/
int _async_init(void)
int __async_init(void)
{
if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
&conn_hash_table_ops)) {
/branches/network/uspace/lib/libc/generic/vfs/vfs.c
38,8 → 38,8
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
137,7 → 137,7
async_serialize_start();
vfs_connect();
req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL);
req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
198,7 → 198,7
async_serialize_start();
vfs_connect();
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
230,7 → 230,7
vfs_connect();
ipc_call_t answer;
aid_t req = async_send_4(vfs_phone, VFS_OPEN_NODE, node->fs_handle,
aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
node->dev_handle, node->index, oflag, &answer);
ipcarg_t rc;
252,7 → 252,7
async_serialize_start();
vfs_connect();
rc = async_req_1_0(vfs_phone, VFS_CLOSE, fildes);
rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
270,7 → 270,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_READ, fildes, &answer);
req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
297,7 → 297,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer);
req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
314,95 → 314,115
return -1;
}
 
int fd_phone(int fildes)
int fsync(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t device;
ipcarg_t rc = async_req_1_1(vfs_phone, VFS_DEVICE, fildes, &device);
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc != EOK)
return -1;
return devmap_device_connect((dev_handle_t) device, 0);
return (int) rc;
}
 
int fd_node(int fildes, fdi_node_t *node)
off_t lseek(int fildes, off_t offset, int whence)
{
ipcarg_t rc;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t fs_handle;
ipcarg_t dev_handle;
ipcarg_t index;
ipcarg_t rc = async_req_1_3(vfs_phone, VFS_NODE, fildes, &fs_handle,
&dev_handle, &index);
ipcarg_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
&newoffs);
 
async_serialize_end();
futex_up(&vfs_phone_futex);
 
if (rc != EOK)
return (off_t) -1;
if (rc == EOK) {
node->fs_handle = (fs_handle_t) fs_handle;
node->dev_handle = (dev_handle_t) dev_handle;
node->index = (fs_index_t) index;
}
return rc;
return (off_t) newoffs;
}
 
int fsync(int fildes)
int ftruncate(int fildes, off_t length)
{
ipcarg_t rc;
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_SYNC, fildes);
rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
 
off_t lseek(int fildes, off_t offset, int whence)
int fstat(int fildes, struct stat *stat)
{
ipcarg_t rc;
aid_t req;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence,
&newoffs);
 
req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (ssize_t) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
 
if (rc != EOK)
return (off_t) -1;
return (off_t) newoffs;
return rc;
}
 
int ftruncate(int fildes, off_t length)
int stat(const char *path, struct stat *stat)
{
ipcarg_t rc;
aid_t req;
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length);
req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
free(pa);
return rc;
}
 
DIR *opendir(const char *dirname)
452,7 → 472,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
482,7 → 502,7
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
529,7 → 549,7
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_RENAME, NULL);
req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
rc = ipc_data_write_start(vfs_phone, olda, olda_size);
if (rc != EOK) {
async_wait_for(req, NULL);
598,5 → 618,34
return buf;
}
 
int fd_phone(int fildes)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
 
if (!stat.devfs_stat.device)
return -1;
return devmap_device_connect(stat.devfs_stat.device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
if (rc == EOK) {
node->fs_handle = stat.fs_handle;
node->dev_handle = stat.dev_handle;
node->index = stat.index;
}
return rc;
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/errno.c
0,0 → 1,41
/*
* 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 libc
* @{
*/
/** @file
*/
 
#include <errno.h>
#include <fibril.h>
 
int _errno;
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/io/console.c
69,6 → 69,17
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
}
 
int console_get_color_cap(int phone, int *ccap)
{
ipcarg_t ccap_tmp;
int rc;
 
rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp);
*ccap = ccap_tmp;
 
return rc;
}
 
void console_kcon_enable(int phone)
{
async_msg_0(phone, CONSOLE_KCON_ENABLE);
/branches/network/uspace/lib/libc/generic/io/io.c
89,7 → 89,7
 
static LIST_INITIALIZE(files);
 
void stdio_init(int filc, fdi_node_t *filv[])
void __stdio_init(int filc, fdi_node_t *filv[])
{
if (filc > 0) {
stdin = fopen_node(filv[0], "r");
113,7 → 113,7
}
}
 
void stdio_done(void)
void __stdio_done(void)
{
link_t *link = files.next;
180,17 → 180,34
stream->buf_head = stream->buf;
}
 
static void _setvbuf(FILE *stream)
{
/* FIXME: Use more complex rules for setting buffering options. */
switch (stream->fd) {
case 1:
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
break;
case 0:
case 2:
setvbuf(stream, NULL, _IONBF, 0);
break;
default:
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
}
}
 
/** Allocate stream buffer. */
static int _fallocbuf(FILE *stream)
{
assert(stream->buf == NULL);
 
stream->buf = malloc(stream->buf_size);
if (stream->buf == NULL) {
errno = ENOMEM;
return -1;
}
 
stream->buf_head = stream->buf;
return 0;
}
225,9 → 242,7
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
_setvbuf(stream);
list_append(&stream->link, &files);
248,9 → 263,7
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
_setvbuf(stream);
list_append(&stream->link, &files);
281,9 → 294,7
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
_setvbuf(stream);
list_append(&stream->link, &files);
331,10 → 342,10
{
size_t left = size * nmemb;
size_t done = 0;
 
/* Make sure no data is pending write. */
_fflushbuf(stream);
 
while ((left > 0) && (!stream->error) && (!stream->eof)) {
ssize_t rd = read(stream->fd, buf + done, left);
379,14 → 390,14
static void _fflushbuf(FILE *stream)
{
size_t bytes_used;
 
if (!stream->buf || stream->btype == _IONBF || stream->error)
if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error))
return;
 
bytes_used = stream->buf_head - stream->buf;
if (bytes_used == 0)
return;
 
(void) _fwrite(stream->buf, 1, bytes_used, stream);
stream->buf_head = stream->buf;
}
409,44 → 420,46
size_t i;
uint8_t b;
bool need_flush;
 
/* If not buffered stream, write out directly. */
if (stream->btype == _IONBF)
return _fwrite(buf, size, nmemb, stream);
 
if (stream->btype == _IONBF) {
now = _fwrite(buf, size, nmemb, stream);
fflush(stream);
return now;
}
/* Perform lazy allocation of stream buffer. */
if (stream->buf == NULL) {
if (_fallocbuf(stream) != 0)
return 0; /* Errno set by _fallocbuf(). */
}
 
data = (uint8_t *) buf;
bytes_left = size * nmemb;
total_written = 0;
need_flush = false;
 
while (!stream->error && bytes_left > 0) {
 
while ((!stream->error) && (bytes_left > 0)) {
buf_free = stream->buf_size - (stream->buf_head - stream->buf);
if (bytes_left > buf_free)
now = buf_free;
else
now = bytes_left;
 
for (i = 0; i < now; i++) {
b = data[i];
stream->buf_head[i] = b;
 
if (b == '\n' && stream->btype == _IOLBF)
if ((b == '\n') && (stream->btype == _IOLBF))
need_flush = true;
}
 
buf += now;
stream->buf_head += now;
buf_free -= now;
bytes_left -= now;
total_written += now;
 
if (buf_free == 0) {
/* Only need to drain buffer. */
_fflushbuf(stream);
453,10 → 466,10
need_flush = false;
}
}
 
if (need_flush)
fflush(stream);
 
return (total_written / size);
}
 
495,13 → 508,13
int fgetc(FILE *stream)
{
char c;
 
/* This could be made faster by only flushing when needed. */
if (stdout)
fflush(stdout);
if (stderr)
fflush(stderr);
 
if (fread(&c, sizeof(char), 1, stream) < sizeof(char))
return EOF;
534,7 → 547,7
int fflush(FILE *stream)
{
_fflushbuf(stream);
 
if (stream->klog) {
klog_update();
return EOK;
/branches/network/uspace/lib/libc/generic/mman.c
37,17 → 37,18
#include <as.h>
#include <unistd.h>
 
void *mmap(void *start, size_t length, int prot, int flags, int fd,
void *mmap(void *start, size_t length, int prot, int flags, int fd,
off_t offset)
{
if (!start)
start = as_get_mappable_page(length);
// if (! ((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// if (!((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// return MAP_FAILED;
if (! (flags & MAP_ANONYMOUS))
if (!(flags & MAP_ANONYMOUS))
return MAP_FAILED;
 
return as_area_create(start, length, prot);
}
 
/branches/network/uspace/lib/libc/Makefile
49,6 → 49,7
generic/cap.c \
generic/devmap.c \
generic/event.c \
generic/errno.c \
generic/mem.c \
generic/string.c \
generic/fibril.c \
68,7 → 69,7
generic/io/vsnprintf.c \
generic/io/printf_core.c \
generic/io/console.c \
malloc/malloc.c \
generic/malloc.c \
generic/sysinfo.c \
generic/ipc.c \
generic/async.c \
105,7 → 106,7
 
clean:
-rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend
find generic/ arch/$(UARCH)/ malloc -name '*.o' -follow -exec rm \{\} \;
find generic/ arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \;
 
depend: kerninc
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
/branches/network/uspace/lib/libc/arch/sparc64/include/stack.h
45,6 → 45,11
*/
#define STACK_WINDOW_SAVE_AREA_SIZE (16 * STACK_ITEM_SIZE)
 
/*
* Six extended words for first six arguments.
*/
#define STACK_ARG_SAVE_AREA_SIZE (6 * STACK_ITEM_SIZE)
 
/**
* By convention, the actual top of the stack is %sp + STACK_BIAS.
*/
/branches/network/uspace/lib/libc/arch/sparc64/include/fibril.h
39,7 → 39,7
#include <sys/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/network/uspace/lib/libc/arch/ia64/Makefile.inc
37,7 → 37,7
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/ddi.c
 
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16
CFLAGS += -fno-unwind-tables
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
 
ENDIANESS = LE
/branches/network/uspace/srv/kbd/ctl/pl050.c
0,0 → 1,262
/*
* Copyright (c) 2009 Vineeth Pillai
* 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_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief PL050 keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stdio.h>
 
#define PL050_CAPS_SCAN_CODE 0x58
#define PL050_NUM_SCAN_CODE 0x77
#define PL050_SCROLL_SCAN_CODE 0x7E
 
static bool is_lock_key(int);
enum dec_state {
ds_s,
ds_e
};
 
static enum dec_state ds;
 
static int scanmap_simple[] = {
 
[0x0e] = KC_BACKTICK,
 
[0x16] = KC_1,
[0x1e] = KC_2,
[0x26] = KC_3,
[0x25] = KC_4,
[0x2e] = KC_5,
[0x36] = KC_6,
[0x3d] = KC_7,
[0x3e] = KC_8,
[0x46] = KC_9,
[0x45] = KC_0,
 
[0x4e] = KC_MINUS,
[0x55] = KC_EQUALS,
[0x66] = KC_BACKSPACE,
 
[0x0d] = KC_TAB,
 
[0x15] = KC_Q,
[0x1d] = KC_W,
[0x24] = KC_E,
[0x2d] = KC_R,
[0x2c] = KC_T,
[0x35] = KC_Y,
[0x3c] = KC_U,
[0x43] = KC_I,
[0x44] = KC_O,
[0x4d] = KC_P,
 
[0x54] = KC_LBRACKET,
[0x5b] = KC_RBRACKET,
 
[0x58] = KC_CAPS_LOCK,
 
[0x1c] = KC_A,
[0x1b] = KC_S,
[0x23] = KC_D,
[0x2b] = KC_F,
[0x34] = KC_G,
[0x33] = KC_H,
[0x3b] = KC_J,
[0x42] = KC_K,
[0x4b] = KC_L,
 
[0x4c] = KC_SEMICOLON,
[0x52] = KC_QUOTE,
[0x5d] = KC_BACKSLASH,
 
[0x12] = KC_LSHIFT,
 
[0x1a] = KC_Z,
[0x22] = KC_X,
[0x21] = KC_C,
[0x2a] = KC_V,
[0x32] = KC_B,
[0x31] = KC_N,
[0x3a] = KC_M,
 
[0x41] = KC_COMMA,
[0x49] = KC_PERIOD,
[0x4a] = KC_SLASH,
 
[0x59] = KC_RSHIFT,
 
[0x14] = KC_LCTRL,
[0x11] = KC_LALT,
[0x29] = KC_SPACE,
 
[0x76] = KC_ESCAPE,
 
[0x05] = KC_F1,
[0x06] = KC_F2,
[0x04] = KC_F3,
[0x0c] = KC_F4,
[0x03] = KC_F5,
[0x0b] = KC_F6,
[0x02] = KC_F7,
 
[0x0a] = KC_F8,
[0x01] = KC_F9,
[0x09] = KC_F10,
 
[0x78] = KC_F11,
[0x07] = KC_F12,
 
[0x60] = KC_SCROLL_LOCK,
 
[0x5a] = KC_ENTER,
 
[0x77] = KC_NUM_LOCK,
[0x7c] = KC_NTIMES,
[0x7b] = KC_NMINUS,
[0x79] = KC_NPLUS,
[0x6c] = KC_N7,
[0x75] = KC_N8,
[0x7d] = KC_N9,
[0x6b] = KC_N4,
[0x73] = KC_N5,
[0x74] = KC_N6,
[0x69] = KC_N1,
[0x72] = KC_N2,
[0x7a] = KC_N3,
[0x70] = KC_N0,
[0x71] = KC_NPERIOD
};
 
static int scanmap_e0[] = {
[0x65] = KC_RALT,
[0x59] = KC_RSHIFT,
 
[0x64] = KC_PRTSCR,
 
[0x70] = KC_INSERT,
[0x6c] = KC_HOME,
[0x7d] = KC_PAGE_UP,
 
[0x71] = KC_DELETE,
[0x69] = KC_END,
[0x7a] = KC_PAGE_DOWN,
 
[0x75] = KC_UP,
[0x6b] = KC_LEFT,
[0x72] = KC_DOWN,
[0x74] = KC_RIGHT,
 
[0x4a] = KC_NSLASH,
[0x5a] = KC_NENTER
};
 
int kbd_ctl_init(void)
{
ds = ds_s;
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
static int key_release_flag = 0;
static int is_locked = 0;
console_ev_type_t type;
unsigned int key;
int *map;
size_t map_length;
 
if (scancode == 0xe0) {
ds = ds_e;
return;
}
 
switch (ds) {
case ds_s:
map = scanmap_simple;
map_length = sizeof(scanmap_simple) / sizeof(int);
break;
case ds_e:
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
if (scancode == 0xf0) {
key_release_flag = 1;
return;
} else {
if (key_release_flag) {
type = KEY_RELEASE;
key_release_flag = 0;
if (is_lock_key(scancode)) {
if (!is_locked) {
is_locked = 1;
} else {
is_locked = 0;
return;
}
}
} else {
if (is_lock_key(scancode) && is_locked)
return;
type = KEY_PRESS;
}
}
 
if (scancode < 0)
return;
 
key = map[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
static bool is_lock_key(int sc)
{
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
(sc == PL050_SCROLL_SCAN_CODE));
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/ctl/pc.c
207,6 → 207,9
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
218,7 → 221,7
type = KEY_PRESS;
}
 
if (scancode < 0 || scancode >= map_length)
if ((scancode < 0) || ((size_t) scancode >= map_length))
return;
 
key = map[scancode];
/branches/network/uspace/srv/kbd/port/pl050.c
0,0 → 1,114
/*
* Copyright (c) 2009 Vineeth Pillai
* 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 pl050 port driver.
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <ipc/ipc.h>
#include <async.h>
#include <unistd.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
#include <stdio.h>
 
#define PL050_STAT_RXFULL (1 << 4)
static irq_cmd_t pl050_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = NULL,
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = PL050_STAT_RXFULL,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t pl050_kbd = {
sizeof(pl050_cmds) / sizeof(irq_cmd_t),
pl050_cmds
};
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
 
pl050_kbd.cmds[0].addr = (void *) sysinfo_value("kbd.address.status");
pl050_kbd.cmds[3].addr = (void *) sysinfo_value("kbd.address.data");
 
async_set_interrupt_received(pl050_irq_handler);
 
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &pl050_kbd);
 
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
return;
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/i8042.c
135,8 → 135,8
(void) pio_read_8(&i8042->data);
/* Enable kbd */
i8042_kbd.cmds[0].addr = &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = &((i8042_t *) i8042_kernel)->data;
i8042_kbd.cmds[0].addr = (void *) &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = (void *) &((i8042_t *) i8042_kernel)->data;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &i8042_kbd);
 
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
/branches/network/uspace/srv/kbd/genarch/gsp.c
244,7 → 244,7
key[0] = t->old_state;
key[1] = t->input;
 
hash_table_insert(&p->trans, &key, &t->link);
hash_table_insert(&p->trans, key, &t->link);
}
 
/** Allocate transition structure. */
276,7 → 276,8
gsp_trans_t *t;
 
t = hash_table_get_instance(item, gsp_trans_t, link);
return (key[0] == t->old_state && key[1] == t->input);
return ((key[0] == (unsigned long) t->old_state)
&& (key[1] == (unsigned long) t->input));
}
 
static void trans_op_remove_callback(link_t *item)
/branches/network/uspace/srv/kbd/Makefile
61,6 → 61,7
endif
 
ifeq ($(UARCH), arm32)
ifeq ($(MACHINE), testarm)
GENARCH_SOURCES += \
port/gxemul.c
72,6 → 73,12
ctl/stty.c
endif
endif
ifeq ($(MACHINE), integratorcp)
GENARCH_SOURCES += \
port/pl050.c \
ctl/pl050.c
endif
endif
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
/branches/network/uspace/srv/kbd/layout/us_qwerty.c
27,7 → 27,7
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @brief US QWERTY layout.
* @{
*/
 
/branches/network/uspace/srv/kbd/layout/cz.c
27,7 → 27,7
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @brief Czech QWERTZ layout.
* @{
*/
 
399,6 → 399,8
case ms_carka:
return parse_ms_carka(ev);
}
return 0;
}
 
/**
/branches/network/uspace/srv/ns/ns.c
108,13 → 108,6
task_id_t id;
ipcarg_t retval;
if (callid & IPC_CALLID_NOTIFICATION) {
id = (task_id_t)
MERGE_LOUP32(IPC_GET_ARG2(call), IPC_GET_ARG3(call));
wait_notification((wait_type_t) IPC_GET_ARG1(call), id);
continue;
}
switch (IPC_GET_METHOD(call)) {
case IPC_M_SHARE_IN:
switch (IPC_GET_ARG3(call)) {
133,7 → 126,7
}
continue;
case IPC_M_PHONE_HUNGUP:
retval = EOK;
retval = ns_task_disconnect(&call);
break;
case IPC_M_CONNECT_TO_ME:
/*
170,6 → 163,12
MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
wait_for_task(id, &call, callid);
continue;
case NS_ID_INTRO:
retval = ns_task_id_intro(&call);
break;
case NS_RETVAL:
retval = ns_task_retval(&call);
break;
default:
retval = ENOENT;
break;
/branches/network/uspace/srv/ns/task.c
1,5 → 1,6
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
41,20 → 42,13
#include "ns.h"
 
#define TASK_HASH_TABLE_CHAINS 256
#define P2I_HASH_TABLE_CHAINS 256
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id);
 
/* TODO:
*
* The current implementation of waiting on a task is not perfect. If somebody
* wants to wait on a task which has already finished before the NS asked
* the kernel to receive notifications, it would block indefinitively.
*
* A solution to this is to fail immediately on a task for which no creation
* notification was received yet. However, there is a danger of a race condition
* in this solution -- the caller has to make sure that it is not trying to wait
* before the NS has a change to receive the task creation notification. This
* can be assured by waiting for this event in task_spawn().
*
* Finally, as there is currently no convention that each task has to be waited
* As there is currently no convention that each task has to be waited
* for, the NS can leak memory because of the zombie tasks.
*
*/
62,8 → 56,10
/** Task hash table item. */
typedef struct {
link_t link;
task_id_t id; /**< Task ID. */
bool destroyed;
task_id_t id; /**< Task ID. */
bool finished; /**< Task is done. */
bool have_rval; /**< Task returned a value. */
int retval; /**< The return value. */
} hashed_task_t;
 
/** Compute hash index into task hash table.
83,7 → 79,7
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be lesser or equal to 2.
* @param keys Must be less than or equal to 2.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
125,6 → 121,65
/** Task hash table structure. */
static hash_table_t task_hash_table;
 
typedef struct {
link_t link;
ipcarg_t phash; /**< Task ID. */
task_id_t id; /**< Task ID. */
} p2i_entry_t;
 
/** Compute hash index into task hash table.
*
* @param key Array of keys.
* @return Hash index corresponding to key[0].
*
*/
static hash_index_t p2i_hash(unsigned long *key)
{
assert(key);
return (*key % TASK_HASH_TABLE_CHAINS);
}
 
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be less than or equal to 1.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
*
*/
static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
assert(key);
assert(keys == 1);
assert(item);
 
p2i_entry_t *e = hash_table_get_instance(item, p2i_entry_t, link);
 
return (key[0] == e->phash);
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*
*/
static void p2i_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, p2i_entry_t, link));
}
 
/** Operations for task hash table. */
static hash_table_operations_t p2i_ops = {
.hash = p2i_hash,
.compare = p2i_compare,
.remove_callback = p2i_remove
};
 
/** Map phone hash to task ID */
static hash_table_t phone_to_id;
 
/** Pending task wait structure. */
typedef struct {
link_t link;
141,10 → 196,13
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
 
if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS,
1, &p2i_ops)) {
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
if (event_subscribe(EVENT_WAIT, 0) != EOK)
printf(NAME ": Error registering wait notifications\n");
list_initialize(&pending_wait);
return EOK;
154,6 → 212,7
void process_pending_wait(void)
{
link_t *cur;
task_exit_t texit;
loop:
for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) {
169,12 → 228,16
continue;
hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
if (!ht->destroyed)
if (!ht->finished)
continue;
if (!(pr->callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(pr->callid, EOK);
if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL :
TASK_EXIT_UNEXPECTED;
ipc_answer_2(pr->callid, EOK, texit,
ht->retval);
}
 
hash_table_remove(&task_hash_table, keys, 2);
list_remove(cur);
free(pr);
182,66 → 245,27
}
}
 
static void fail_pending_wait(task_id_t id, int rc)
void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
{
link_t *cur;
loop:
for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) {
pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
if (pr->id == id) {
if (!(pr->callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(pr->callid, rc);
list_remove(cur);
free(pr);
goto loop;
}
}
}
ipcarg_t retval;
task_exit_t texit;
 
void wait_notification(wait_type_t et, task_id_t id)
{
unsigned long keys[2] = {
LOWER32(id),
UPPER32(id)
};
link_t *link = hash_table_find(&task_hash_table, keys);
if (link == NULL) {
hashed_task_t *ht =
(hashed_task_t *) malloc(sizeof(hashed_task_t));
if (ht == NULL) {
fail_pending_wait(id, ENOMEM);
return;
}
link_initialize(&ht->link);
ht->id = id;
ht->destroyed = (et == TASK_CREATE) ? false : true;
hash_table_insert(&task_hash_table, keys, &ht->link);
} else {
hashed_task_t *ht =
hash_table_get_instance(link, hashed_task_t, link);
ht->destroyed = (et == TASK_CREATE) ? false : true;
}
}
 
void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
{
ipcarg_t retval;
unsigned long keys[2] = {
LOWER32(id),
UPPER32(id)
};
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
if ((ht == NULL) || (!ht->destroyed)) {
 
if (ht == NULL) {
/* No such task exists. */
retval = ENOENT;
goto out;
}
 
if (!ht->finished) {
/* Add to pending list */
pending_wait_t *pr =
(pending_wait_t *) malloc(sizeof(pending_wait_t));
260,10 → 284,131
retval = EOK;
out:
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, retval);
if (!(callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED;
ipc_answer_2(callid, retval, texit, ht->retval);
}
}
 
int ns_task_id_intro(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
link_t *link;
p2i_entry_t *e;
hashed_task_t *ht;
 
id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
 
keys[0] = call->in_phone_hash;
 
link = hash_table_find(&phone_to_id, keys);
if (link != NULL)
return EEXISTS;
 
e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t));
if (e == NULL)
return ENOMEM;
 
ht = (hashed_task_t *) malloc(sizeof(hashed_task_t));
if (ht == NULL)
return ENOMEM;
 
/* Insert to phone-to-id map. */
 
link_initialize(&e->link);
e->phash = call->in_phone_hash;
e->id = id;
hash_table_insert(&phone_to_id, keys, &e->link);
 
/* Insert to main table. */
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_initialize(&ht->link);
ht->id = id;
ht->finished = false;
ht->have_rval = false;
ht->retval = -1;
hash_table_insert(&task_hash_table, keys, &ht->link);
 
return EOK;
}
 
int ns_task_retval(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
if ((ht == NULL) || ht->finished)
return EINVAL;
 
ht->finished = true;
ht->have_rval = true;
ht->retval = IPC_GET_ARG1(*call);
 
return EOK;
}
 
int ns_task_disconnect(ipc_call_t *call)
{
unsigned long keys[2];
task_id_t id;
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
/* Delete from phone-to-id map. */
keys[0] = call->in_phone_hash;
hash_table_remove(&phone_to_id, keys, 1);
 
/* Mark task as finished. */
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht =
hash_table_get_instance(link, hashed_task_t, link);
if (ht == NULL)
return EOK;
 
ht->finished = true;
 
return EOK;
}
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id)
{
unsigned long keys[1];
link_t *link;
p2i_entry_t *e;
 
keys[0] = phone_hash;
link = hash_table_find(&phone_to_id, keys);
if (link == NULL)
return ENOENT;
 
e = hash_table_get_instance(link, p2i_entry_t, link);
*id = e->id;
 
return EOK;
}
 
/**
* @}
*/
/branches/network/uspace/srv/ns/task.h
42,6 → 42,11
extern void wait_notification(wait_type_t et, task_id_t id);
extern void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid);
 
extern int ns_task_id_intro(ipc_call_t *call);
extern int ns_task_disconnect(ipc_call_t *call);
extern int ns_task_retval(ipc_call_t *call);
 
 
#endif
 
/**
/branches/network/uspace/srv/console/screenbuffer.h
135,6 → 135,8
return (a1.a.r.fg_color == a2.a.r.fg_color)
&& (a1.a.r.bg_color == a2.a.r.bg_color);
}
return 0;
}
 
 
/branches/network/uspace/srv/console/console.c
69,6 → 69,7
int phone; /**< Framebuffer phone */
ipcarg_t cols; /**< Framebuffer columns */
ipcarg_t rows; /**< Framebuffer rows */
int color_cap; /**< Color capabilities (FB_CCAP_xxx) */
} fb_info;
 
typedef struct {
172,6 → 173,19
}
}
 
static int ccap_fb_to_con(int ccap_fb, int *ccap_con)
{
switch (ccap_fb) {
case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break;
case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break;
case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break;
case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break;
default: return EINVAL;
}
 
return EOK;
}
 
/** Send an area of screenbuffer to the FB driver. */
static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
{
526,6 → 540,9
ipcarg_t arg1;
ipcarg_t arg2;
ipcarg_t arg3;
 
int cons_ccap;
int rc;
async_serialize_start();
if (cons->refcount == 0)
551,17 → 568,17
if (cons->refcount == 0)
gcons_notify_disconnect(cons->index);
return;
case VFS_READ:
case VFS_OUT_READ:
async_serialize_end();
cons_read(cons, callid, &call);
async_serialize_start();
continue;
case VFS_WRITE:
case VFS_OUT_WRITE:
async_serialize_end();
cons_write(cons, callid, &call);
async_serialize_start();
continue;
case VFS_SYNC:
case VFS_OUT_SYNC:
fb_pending_flush();
if (cons == active_console) {
async_req_0_0(fb_info.phone, FB_FLUSH);
588,6 → 605,14
arg1 = fb_info.cols;
arg2 = fb_info.rows;
break;
case CONSOLE_GET_COLOR_CAP:
rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap);
if (rc != EOK) {
ipc_answer_0(callid, rc);
continue;
}
arg1 = cons_ccap;
break;
case CONSOLE_SET_STYLE:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
639,6 → 664,8
 
static bool console_init(void)
{
ipcarg_t color_cap;
 
/* Connect to keyboard driver */
kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
if (kbd_phone < 0) {
674,6 → 701,8
/* Synchronize, the gcons could put something in queue */
async_req_0_0(fb_info.phone, FB_FLUSH);
async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap);
fb_info.color_cap = color_cap;
/* Set up shared memory buffer. */
size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
/branches/network/uspace/srv/bd/file_bd/file_bd.c
49,6 → 49,7
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#define NAME "file_bd"
 
86,6 → 87,7
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
/branches/network/uspace/srv/bd/gxe_bd/gxe_bd.c
46,6 → 46,7
#include <devmap.h>
#include <sys/types.h>
#include <errno.h>
#include <task.h>
 
#define NAME "gxe_bd"
 
110,6 → 111,7
return -1;
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
/branches/network/uspace/srv/bd/ata_bd/ata_bd.c
54,6 → 54,7
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#include "ata_bd.h"
 
95,7 → 96,9
return -1;
 
/* Put drives to reset, disable interrupts. */
printf("Reset drives...\n");
printf("Reset drives... ");
fflush(stdout);
 
pio_write_8(&ctl->device_control, DCR_SRST);
/* FIXME: Find out how to do this properly. */
async_usleep(100);
106,8 → 109,6
} while ((status & SR_BSY) != 0);
printf("Done\n");
 
printf("Status = 0x%x\n", pio_read_8(&cmd->status));
 
(void) drive_identify(0, &disk[0]);
(void) drive_identify(1, &disk[1]);
 
135,6 → 136,7
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
147,13 → 149,14
uint8_t status;
size_t i;
 
printf("Identify drive %d\n", disk_id);
printf("Identify drive %d... ", disk_id);
fflush(stdout);
 
pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
async_usleep(100);
pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
 
status = pio_read_8(&cmd->status);
printf("Status = 0x%x\n", status);
 
d->present = false;
 
/branches/network/uspace/srv/loader/main.c
52,6 → 52,8
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/loader.h>
#include <ipc/ns.h>
#include <macros.h>
#include <loader/pcb.h>
#include <errno.h>
#include <async.h>
437,16 → 439,24
int main(int argc, char *argv[])
{
ipcarg_t phonead;
task_id_t id;
int rc;
 
connected = false;
 
/* Introduce this task to the NS (give it our task ID). */
id = task_get_id();
rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
if (rc != EOK)
return -1;
 
/* Set a handler of incomming connections. */
async_set_client_connection(ldr_connection);
/* Register at naming service. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
return -1;
return -2;
 
async_manager();
/* Never reached */
/branches/network/uspace/srv/fb/serial_console.c
388,6 → 388,10
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, color ? FB_CCAP_INDEXED :
FB_CCAP_STYLE);
continue;
case FB_CLEAR:
serial_clrscr();
retval = 0;
/branches/network/uspace/srv/fb/fb.c
56,6 → 56,8
#include <async.h>
#include <fibril.h>
#include <bool.h>
#include <stdio.h>
#include <byteorder.h>
 
#include "font-8x16.h"
#include "fb.h"
211,9 → 213,9
unsigned int row);
 
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
 
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
225,36 → 227,58
#define BB_POS(vport, col, row) ((row) * vport->cols + (col))
#define GLYPH_POS(glyph, y, cursor) (((glyph) + (cursor) * FONT_GLYPHS) * screen.glyphbytes + (y) * screen.glyphscanline)
 
 
/** ARGB 8:8:8:8 conversion
/*
* RGB conversion and mask functions.
*
* These functions write an RGB value to some memory in some predefined format.
* The naming convention corresponds to the format created by these functions.
* The functions use the so called network order (i.e. big endian) with respect
* to their names.
*/
 
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0x00ffffff;
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(RED(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (BLUE(rgb, 8)));
}
 
static void bgr_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (RED(rgb, 8)));
}
 
static void mask_0888(void *dst, bool mask)
{
*((uint32_t *) dst) = (mask ? 0x00ffffff : 0);
bgr_0888(dst, mask ? 0xffffff : 0);
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((RED(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8) | 0);
}
 
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
static void bgr_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
*((uint32_t *) dst) = host2uint32_t_be((BLUE(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (RED(rgb, 8) << 8) | 0);
}
 
static void mask_8880(void *dst, bool mask)
{
bgr_8880(dst, mask ? 0xffffff : 0);
}
 
/** RGB 8:8:8 conversion
*
*/
static void rgb_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
static void bgr_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
262,63 → 286,44
 
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_888(dst, mask ? 0xffffff : 0);
}
 
static void rgb_555_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
static void rgb_555_le(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
static void rgb_565_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
static void mask_555(void *dst, bool mask)
static void rgb_565_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = (mask ? 0x7fff : 0);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
static void mask_555(void *dst, bool mask)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
rgb_555_be(dst, mask ? 0xffffff : 0);
}
 
static void mask_565(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0xffff : 0);
rgb_565_be(dst, mask ? 0xffffff : 0);
}
 
 
/** RGB 3:2:3
*
*/
static void rgb_323(void *dst, uint32_t rgb)
static void bgr_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
326,7 → 331,7
 
static void mask_323(void *dst, bool mask)
{
*((uint8_t *) dst) = (mask ? 0xff : 0);
bgr_323(dst, mask ? 0x0 : ~0x0);
}
 
/** Draw a filled rectangle.
620,24 → 625,32
static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual)
{
switch (visual) {
case VISUAL_INDIRECT_8:
screen.rgb_conv = rgb_323;
screen.rgb_conv = bgr_323;
screen.mask_conv = mask_323;
screen.pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
screen.rgb_conv = rgb_555;
case VISUAL_RGB_5_5_5_LE:
screen.rgb_conv = rgb_555_le;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
screen.rgb_conv = rgb_565;
case VISUAL_RGB_5_5_5_BE:
screen.rgb_conv = rgb_555_be;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_LE:
screen.rgb_conv = rgb_565_le;
screen.mask_conv = mask_565;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_BE:
screen.rgb_conv = rgb_565_be;
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;
649,8 → 662,8
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.rgb_conv = rgb_8880;
screen.mask_conv = mask_8880;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
663,6 → 676,11
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
screen.rgb_conv = bgr_8880;
screen.mask_conv = mask_8880;
screen.pixelbytes = 4;
break;
default:
return false;
}
1067,10 → 1085,11
if (IPC_GET_ARG1(*call) == shm_id) {
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
shm_size = IPC_GET_ARG2(*call);
if (!ipc_answer_1(callid, EOK, (sysarg_t) dest))
shm = dest;
else
if (ipc_answer_1(callid, EOK, (sysarg_t) dest)) {
shm_id = 0;
return false;
}
shm = dest;
if (shm[0] != 'P')
return false;
1645,6 → 1664,9
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, vport->cols, vport->rows);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_RGB);
continue;
case FB_SCROLL:
scroll = IPC_GET_ARG1(call);
if ((scroll > (int) vport->rows) || (scroll < (-(int) vport->rows))) {
1739,17 → 1761,17
unsigned int fb_height = sysinfo_value("fb.height");
unsigned int fb_scanline = sysinfo_value("fb.scanline");
unsigned int fb_visual = sysinfo_value("fb.visual");
 
unsigned int fbsize = fb_scanline * fb_height;
void *fb_addr = as_get_mappable_page(fbsize);
 
if (physmem_map(fb_ph_addr + fb_offset, fb_addr,
ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
 
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
return 0;
 
return -1;
}
 
/branches/network/uspace/srv/fb/ppm.c
89,7 → 89,7
{
unsigned int width, height;
unsigned int maxcolor;
unsigned i;
unsigned int i;
unsigned int color;
unsigned int coef;
/branches/network/uspace/srv/fb/ega.c
319,6 → 319,9
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_INDEXED);
continue;
case FB_CLEAR:
clrscr();
retval = 0;
/branches/network/uspace/srv/fs/devfs/devfs.c
67,37 → 67,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
devfs_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
devfs_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
devfs_lookup(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
devfs_open_node(callid, &call);
break;
case VFS_DEVICE:
devfs_device(callid, &call);
case VFS_OUT_STAT:
devfs_stat(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
devfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
devfs_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
devfs_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_CLOSE:
devfs_close(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
devfs_sync(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
devfs_destroy(callid, &call);
break;
default:
/branches/network/uspace/srv/fs/devfs/devfs_ops.c
43,6 → 43,7
#include <libfs.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <sys/stat.h>
#include "devfs.h"
#include "devfs_ops.h"
 
163,12 → 164,12
if (first >= last) {
/* Root entry */
if (lflag & L_DIRECTORY)
if (!(lflag & L_FILE))
ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0);
else
ipc_answer_0(rid, ENOENT);
} else {
if (lflag & L_FILE) {
if (!(lflag & L_DIRECTORY)) {
size_t len;
if (last >= first)
len = last - first + 1;
277,10 → 278,30
ipc_answer_3(rid, EOK, 0, 1, L_FILE);
}
 
void devfs_device(ipc_callid_t rid, ipc_call_t *request)
void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size != sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat stat;
memset(&stat, 0, sizeof(struct stat));
 
stat.fs_handle = devfs_reg.fs_handle;
stat.dev_handle = dev_handle;
stat.index = index;
stat.lnkcnt = 1;
stat.is_file = (index != 0);
stat.size = 0;
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
288,16 → 309,13
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
if (lnk != NULL)
stat.devfs_stat.device = (dev_handle_t)index;
fibril_mutex_unlock(&devices_mutex);
ipc_answer_1(rid, EOK, (ipcarg_t) index);
} else
ipc_answer_0(rid, ENOTSUP);
}
 
ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
}
 
void devfs_read(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/fs/devfs/devfs_ops.h
42,7 → 42,7
extern void devfs_mount(ipc_callid_t, ipc_call_t *);
extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
extern void devfs_device(ipc_callid_t, ipc_call_t *);
extern void devfs_stat(ipc_callid_t, ipc_call_t *);
extern void devfs_sync(ipc_callid_t, ipc_call_t *);
extern void devfs_read(ipc_callid_t, ipc_call_t *);
extern void devfs_write(ipc_callid_t, ipc_call_t *);
/branches/network/uspace/srv/fs/tmpfs/tmpfs.h
86,10 → 86,10
extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
extern void tmpfs_device(ipc_callid_t, ipc_call_t *);
extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
 
extern bool tmpfs_restore(dev_handle_t);
/branches/network/uspace/srv/fs/tmpfs/tmpfs_dump.c
67,8 → 67,8
tmpfs_node_t *nodep;
uint32_t size;
if (block_read(dev, bufpos, buflen, pos, &entry, sizeof(entry),
TMPFS_BLOCK_SIZE) != EOK)
if (block_seqread(dev, bufpos, buflen, pos, &entry,
sizeof(entry), TMPFS_BLOCK_SIZE) != EOK)
return false;
entry.len = uint32_t_le2host(entry.len);
87,7 → 87,7
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
103,7 → 103,7
}
free(fname);
if (block_read(dev, bufpos, buflen, pos, &size,
if (block_seqread(dev, bufpos, buflen, pos, &size,
sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
return false;
115,7 → 115,7
return false;
nodep->size = size;
if (block_read(dev, bufpos, buflen, pos, nodep->data,
if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
size, TMPFS_BLOCK_SIZE) != EOK)
return false;
131,7 → 131,7
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
174,7 → 174,7
off_t pos = 0;
char tag[6];
if (block_read(dev, &bufpos, &buflen, &pos, tag, 5,
if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE) != EOK)
goto error;
/branches/network/uspace/srv/fs/tmpfs/tmpfs.c
98,37 → 98,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
tmpfs_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
tmpfs_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
tmpfs_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
tmpfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
tmpfs_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
tmpfs_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_CLOSE:
tmpfs_close(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
tmpfs_destroy(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
tmpfs_open_node(callid, &call);
break;
case VFS_DEVICE:
tmpfs_device(callid, &call);
case VFS_OUT_STAT:
tmpfs_stat(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
tmpfs_sync(callid, &call);
break;
default:
152,7 → 152,7
printf(NAME ": Unable to connect to VFS\n");
return -1;
}
 
int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
tmpfs_connection);
if (rc != EOK) {
/branches/network/uspace/srv/fs/tmpfs/tmpfs_ops.c
628,9 → 628,9
libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_device(ipc_callid_t rid, ipc_call_t *request)
void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/fs/fat/fat.h
207,10 → 207,11
extern void fat_read(ipc_callid_t, ipc_call_t *);
extern void fat_write(ipc_callid_t, ipc_call_t *);
extern void fat_truncate(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_close(ipc_callid_t, ipc_call_t *);
extern void fat_destroy(ipc_callid_t, ipc_call_t *);
extern void fat_open_node(ipc_callid_t, ipc_call_t *);
extern void fat_device(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_sync(ipc_callid_t, ipc_call_t *);
 
extern fat_idx_t *fat_idx_get_new(dev_handle_t);
/branches/network/uspace/srv/fs/fat/fat.c
91,37 → 91,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
fat_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
fat_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
fat_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
fat_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
fat_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
fat_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_STAT:
fat_stat(callid, &call);
break;
case VFS_OUT_CLOSE:
fat_close(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
fat_destroy(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
fat_open_node(callid, &call);
break;
case VFS_DEVICE:
fat_device(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
fat_sync(callid, &call);
break;
default:
/branches/network/uspace/srv/fs/fat/fat_ops.c
402,7 → 402,7
fat_dentry_t *d;
fat_bs_t *bs;
block_t *b;
int i, j;
unsigned i, j;
uint16_t bps;
unsigned dps;
unsigned blocks;
1202,9 → 1202,9
libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_device(ipc_callid_t rid, ipc_call_t *request)
void fat_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_sync(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/pci/update-ids
1,6 → 1,6
#! /bin/bash
 
wget http://pciids.sourceforge.net/v2.2/pci.ids
wget -O pci.ids http://pciids.sourceforge.net/v2.2/pci.ids
 
cat > pci_ids.h <<EOF
/* DO NOT EDIT, THIS FILE IS AUTOMATICALLY GENERATED */
7,7 → 7,8
char *pci_ids[] = {
EOF
 
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | sed -n 's/\(.*\)/"\1",/p' >> pci_ids.h
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | \
sed -n 's/\(.*\)/"\1",/p' | sed 's/?/\\?/g' >> pci_ids.h
 
cat >> pci_ids.h <<EOF
""
/branches/network/uspace/srv/pci/libpci/i386-ports.c
79,14 → 79,14
d.func = 0;
for (d.dev = 0; d.dev < 32; d.dev++) {
u16 class, vendor;
if (m->read(&d, PCI_CLASS_DEVICE, (byte *) & class,
if ((m->read(&d, PCI_CLASS_DEVICE, (byte *) & class,
sizeof(class))
&& (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST)
|| class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA))
|| m->read(&d, PCI_VENDOR_ID, (byte *) & vendor,
|| class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)))
|| (m->read(&d, PCI_VENDOR_ID, (byte *) & vendor,
sizeof(vendor))
&& (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL)
|| vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) {
|| vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ)))) {
a->debug("...outside the Asylum at 0/%02x/0",
d.dev);
return 1;
/branches/network/uspace/srv/pci/libpci/pci_ids.h
386,7 → 386,7
" 1043 c01b A9600XT/TD (Secondary)",
" 174b 7c28 Sapphire Radeon 9600XT (Secondary)",
" 1787 4003 Radeon 9600 XT (Secondary)",
" 4173 RV350 ?? [Radeon 9550] (Secondary)",
" 4173 RV350 \?\? [Radeon 9550] (Secondary)",
" 4237 Radeon 7000 IGP",
" 4242 R200 BB [Radeon All in Wonder 8500DV]",
" 1002 02aa Radeon 8500 AIW DV Edition",
668,7 → 668,7
" 1002 002a Rage 128 Pro AIW AGP",
" 1002 0048 Rage Fury Pro",
" 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)",
" 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)",
" 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device\?!)",
" 5047 Rage 128 PG/PRO",
" 5048 Rage 128 PH/PRO AGP 2x",
" 5049 Rage 128 PI/PRO AGP 4x",
1635,7 → 1635,7
" 1028 0106 PowerEdge 4600",
" 1028 0121 PowerEdge 2650",
"102b Matrox Graphics, Inc.",
" 0010 MGA-I [Impression?]",
" 0010 MGA-I [Impression\?]",
" 0100 MGA 1064SG [Mystique]",
" 0518 MGA-II [Athena]",
" 0519 MGA 2064W [Millennium]",
2437,7 → 2437,7
" 9922 W99200F/W9922PF MPEG-1/2 Video Encoder",
" 9970 W9970CF",
"1051 Anigma, Inc.",
"1052 ?Young Micro Systems",
"1052 \?Young Micro Systems",
"1053 Young Micro Systems",
"1054 Hitachi, Ltd",
"1055 Efar Microsystems",
3048,7 → 3048,7
" 0369 Bt878 Video Capture",
" 1002 0001 TV-Wonder",
" 1002 0003 TV-Wonder/VE",
" 036c Bt879(??) Video Capture",
" 036c Bt879(\?\?) Video Capture",
" 13e9 0070 Win/TV (Video Section)",
" 036e Bt878 Video Capture",
" 0070 13eb WinTV Series",
4123,7 → 4123,7
" 01de Quadro FX 350",
" 10de 01dc Quadro FX Go350M",
" 01df GeForce 7300 GS",
" 01e0 nForce2 AGP (different version?)",
" 01e0 nForce2 AGP (different version\?)",
" 147b 1c09 NV7 Motherboard",
" 01e8 nForce2 AGP",
" 01ea nForce2 Memory Controller 0",
5096,7 → 5096,7
" 1113 1211 EN-1207D Fast Ethernet Adapter",
" 1216 EN-1216 Ethernet Adapter",
" 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card",
" 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]",
" 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX \?]",
" 1217 EN-1217 Ethernet Adapter",
" 5105 10Mbps Network card",
" 9211 EN-1207D Fast Ethernet Adapter",
6556,7 → 6556,7
"123e Simutech, Inc.",
"123f C-Cube Microsystems",
" 00e4 MPEG",
" 8120 E4?",
" 8120 E4\?",
" 11bd 0006 DV500 E4",
" 11bd 000a DV500 E4",
" 11bd 000f DV500 E4",
6632,7 → 6632,7
" 0640 Aries 16000P",
"125d ESS Technology",
" 0000 ES336H Fax Modem (Early Model)",
" 1948 Solo?",
" 1948 Solo\?",
" 1968 ES1968 Maestro 2",
" 1028 0085 ES1968 Maestro-2 PCI",
" 1033 8051 ES1968 Maestro-2 Audiodrive",
6922,7 → 6922,7
" 122d 4056 MSP3880SP-U",
" 122d 4057 MSP3880SP-A",
" 4311 Riptide HSF 56k PCI Modem",
" 127a 4311 Ring Modular? Riptide HSF RT HP Dom",
" 127a 4311 Ring Modular\? Riptide HSF RT HP Dom",
" 13e0 0210 HP-GVC",
" 4320 Riptide PCI Audio Controller",
" 1235 4320 Riptide PCI Audio Controller",
8382,7 → 8382,7
" 4325 BCM43xG 802.11b/g",
" 1414 0003 Wireless Notebook Adapter MN-720",
" 1414 0004 Wireless PCI Adapter MN-730",
" 4326 BCM4307 Chipcommon I/O Controller?",
" 4326 BCM4307 Chipcommon I/O Controller\?",
" 4401 BCM4401 100Base-T",
" 1043 80a8 A7V8X motherboard",
" 4402 BCM4402 Integrated 10/100BaseT",
8691,7 → 8691,7
"1504 KAISER Electronics",
"1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH",
"1506 CHAMELEON Systems Inc",
"1507 Motorola ?? / HTEC",
"1507 Motorola \?\? / HTEC",
" 0001 MPC105 [Eagle]",
" 0002 MPC106 [Grackle]",
" 0003 MPC8240 [Kahlua]",
9467,7 → 9467,7
"270b Xantel Corporation",
"270f Chaintech Computer Co. Ltd",
"2711 AVID Technology Inc.",
"2a15 3D Vision(???)",
"2a15 3D Vision(\?\?\?)",
"3000 Hansol Electronics Inc.",
"3142 Post Impression Systems.",
"3388 Hint Corp",
/branches/network/uspace/srv/pci/libpci/names.c
150,7 → 150,7
int cat = -1;
int nest;
static const char parse_error[] = "Parse error";
int i;
size_t i;
 
*lino = 0;
for (i = 0; i < sizeof(pci_ids) / sizeof(char *); i++) {
330,7 → 330,7
iv = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", iv);
else if (v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0))
else if ((v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0)) != 0)
return (char *) v->name;
else
res = snprintf(buf, size, "Unknown vendor %04x", iv);
340,7 → 340,7
id = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", id);
else if (d = id_lookup(a, ID_DEVICE, iv, id, 0, 0))
else if ((d = id_lookup(a, ID_DEVICE, iv, id, 0, 0)) != 0)
return (char *) d->name;
else if (synth)
res = snprintf(buf, size, "Unknown device %04x", id);
370,7 → 370,7
isv = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", isv);
else if (v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0))
else if ((v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0)) != 0)
return (char *) v->name;
else if (synth)
res = snprintf(buf, size, "Unknown vendor %04x", isv);
384,7 → 384,7
isd = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", isd);
else if (d = id_lookup_subsys(a, iv, id, isv, isd))
else if ((d = id_lookup_subsys(a, iv, id, isv, isd)) != 0)
return (char *) d->name;
else if (synth)
res = snprintf(buf, size, "Unknown device %04x", isd);
415,9 → 415,9
icls = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", icls);
else if (cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0))
else if ((cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0)) != 0)
return (char *) cls->name;
else if (cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0))
else if ((cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0)) != 0)
res = snprintf(buf, size, "%s [%04x]", cls->name, icls);
else if (synth)
res = snprintf(buf, size, "Class %04x", icls);
429,7 → 429,7
ipif = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%02x", ipif);
else if (pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0))
else if ((pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0)) != 0)
return (char *) pif->name;
else if (icls == 0x0101 && !(ipif & 0x70)) {
/* IDE controllers have complex prog-if semantics */
/branches/network/uspace/srv/pci/libpci/generic.c
29,7 → 29,7
for (dev = 0; dev < 32; dev++) {
t->dev = dev;
multi = 0;
for (t->func = 0; !t->func || multi && t->func < 8;
for (t->func = 0; !t->func || (multi && t->func < 8);
t->func++) {
u32 vd = pci_read_long(t, PCI_VENDOR_ID);
struct pci_dev *d;
/branches/network/uspace/srv/devmap/devmap.c
46,7 → 46,8
#include <string.h>
#include <ipc/devmap.h>
 
#define NAME "devmap"
#define NAME "devmap"
#define NULL_DEVICES 256
 
/** Representation of device driver.
*
97,8 → 98,10
static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv);
static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex);
static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex);
static FIBRIL_MUTEX_INITIALIZE(null_devices_mutex);
 
static dev_handle_t last_handle = 0;
static devmap_device_t *null_devices[NULL_DEVICES];
 
static dev_handle_t devmap_create_handle(void)
{
543,12 → 546,12
ipc_answer_0(iid, EOK);
size_t name_size = str_size(device->name);
/* FIXME:
* We have no channel from DEVMAP to client, therefore
* sending must be initiated by client.
*
* size_t name_size = str_size(device->name);
*
* int rc = ipc_data_write_send(phone, device->name, name_size);
* if (rc != EOK) {
* async_wait_for(req, NULL);
618,21 → 621,43
ipc_answer_1(iid, EOK, pos);
}
 
/** Initialize device mapper.
*
*
*/
static bool devmap_init(void)
static void devmap_null_create(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
bool fnd = false;
for (i = 0; i < NULL_DEVICES; i++) {
if (null_devices[i] == NULL) {
fnd = true;
break;
}
}
if (!fnd) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
/* Create NULL device entry */
devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
if (device == NULL)
return false;
if (device == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
device->name = str_dup("null");
char null[DEVMAP_NAME_MAXLEN];
snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);
device->name = str_dup(null);
if (device->name == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
free(device);
return false;
ipc_answer_0(iid, ENOMEM);
return;
}
list_initialize(&(device->devices));
644,11 → 669,50
device->handle = devmap_create_handle();
device->driver = NULL;
/* Insert device into list of all devices */
/* Insert device into list of all devices
and into null devices array */
list_append(&device->devices, &devices_list);
null_devices[i] = device;
fibril_mutex_unlock(&devices_list_mutex);
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_1(iid, EOK, (ipcarg_t) i);
}
 
static void devmap_null_destroy(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
ipcarg_t i = IPC_GET_ARG1(*icall);
if (null_devices[i] == NULL) {
ipc_answer_0(iid, ENOENT);
return;
}
devmap_device_unregister_core(null_devices[i]);
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, EOK);
}
 
/** Initialize device mapper.
*
*
*/
static bool devmap_init(void)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
for (i = 0; i < NULL_DEVICES; i++)
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
return true;
}
 
701,7 → 765,7
}
}
if (NULL != driver) {
if (driver != NULL) {
/*
* Unregister the device driver and all its devices.
*/
733,6 → 797,12
case DEVMAP_DEVICE_GET_NAME:
devmap_get_name(callid, &call);
break;
case DEVMAP_DEVICE_NULL_CREATE:
devmap_null_create(callid, &call);
break;
case DEVMAP_DEVICE_NULL_DESTROY:
devmap_null_destroy(callid, &call);
break;
case DEVMAP_DEVICE_GET_COUNT:
devmap_get_count(callid, &call);
break;
783,7 → 853,7
/* Set a handler of incomming connections */
async_set_client_connection(devmap_connection);
 
/* Register device mapper at naming service */
ipcarg_t phonead;
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
/branches/network/uspace/srv/vfs/vfs.c
79,52 → 79,52
case IPC_M_PHONE_HUNGUP:
keep_on_going = false;
break;
case VFS_REGISTER:
case VFS_IN_REGISTER:
vfs_register(callid, &call);
keep_on_going = false;
break;
case VFS_MOUNT:
case VFS_IN_MOUNT:
vfs_mount(callid, &call);
break;
case VFS_OPEN:
case VFS_IN_OPEN:
vfs_open(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_IN_OPEN_NODE:
vfs_open_node(callid, &call);
break;
case VFS_CLOSE:
case VFS_IN_CLOSE:
vfs_close(callid, &call);
break;
case VFS_READ:
case VFS_IN_READ:
vfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_IN_WRITE:
vfs_write(callid, &call);
break;
case VFS_SEEK:
case VFS_IN_SEEK:
vfs_seek(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_IN_TRUNCATE:
vfs_truncate(callid, &call);
break;
case VFS_MKDIR:
case VFS_IN_FSTAT:
vfs_fstat(callid, &call);
break;
case VFS_IN_STAT:
vfs_stat(callid, &call);
break;
case VFS_IN_MKDIR:
vfs_mkdir(callid, &call);
break;
case VFS_UNLINK:
case VFS_IN_UNLINK:
vfs_unlink(callid, &call);
break;
case VFS_RENAME:
case VFS_IN_RENAME:
vfs_rename(callid, &call);
break;
case VFS_DEVICE:
vfs_device(callid, &call);
break;
case VFS_SYNC:
case VFS_IN_SYNC:
vfs_sync(callid, &call);
break;
case VFS_NODE:
vfs_node(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
/branches/network/uspace/srv/vfs/vfs_ops.c
108,7 → 108,7
/*
* Now we hold a reference to mp_node.
* It will be dropped upon the corresponding VFS_UNMOUNT.
* It will be dropped upon the corresponding VFS_IN_UNMOUNT.
* This prevents the mount point from being deleted.
*/
} else {
121,7 → 121,7
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
msg = async_send_1(phone, VFS_MOUNTED,
msg = async_send_1(phone, VFS_OUT_MOUNTED,
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts,
183,7 → 183,7
assert(mountee_phone >= 0);
 
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
msg = async_send_4(phone, VFS_MOUNT,
msg = async_send_4(phone, VFS_OUT_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) fs_handle,
306,7 → 306,7
}
 
/* Check the offered options size. */
if (size < 0 || size > MAX_MNTOPTS_LEN) {
if (size > MAX_MNTOPTS_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
437,8 → 437,8
/*
* The POSIX interface is open(path, oflag, mode).
* We can receive oflags and mode along with the VFS_OPEN call; the path
* will need to arrive in another call.
* We can receive oflags and mode along with the VFS_IN_OPEN call;
* the path will need to arrive in another call.
*
* We also receive one private, non-POSIX set of flags called lflag
* used to pass information to vfs_lookup_internal().
447,6 → 447,9
int oflag = IPC_GET_ARG2(*request);
int mode = IPC_GET_ARG3(*request);
size_t len;
 
/* Ignore mode for now. */
(void) mode;
/*
* Make sure that we are called with exactly one of L_FILE and
555,7 → 558,7
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_CLOSE.
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
632,7 → 635,7
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_CLOSE.
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
641,55 → 644,6
ipc_answer_1(rid, EOK, fd);
}
 
void vfs_node(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
ipc_answer_3(rid, EOK, file->node->fs_handle, file->node->dev_handle,
file->node->index);
}
 
void vfs_device(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
/*
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_DEVICE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
 
vfs_release_phone(fs_phone);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer));
}
 
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
708,11 → 662,11
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_SYMC request at the destination FS server. */
/* Make a VFS_OUT_SYMC request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
742,11 → 696,11
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_CLOSE request at the destination FS server. */
/* Make a VFS_OUT_CLOSE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
832,7 → 786,7
ipc_call_t answer;
if (!read && file->append)
file->pos = file->node->size;
msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
file->node->dev_handle, file->node->index, file->pos, &answer);
/*
946,7 → 900,7
int fs_phone;
fs_phone = vfs_grab_phone(fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
(ipcarg_t)index, (ipcarg_t)size);
vfs_release_phone(fs_phone);
return (int)rc;
976,6 → 930,106
ipc_answer_0(rid, (ipcarg_t)rc);
}
 
void vfs_fstat(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
size_t size = IPC_GET_ARG2(*request);
ipcarg_t rc;
 
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
 
ipc_callid_t callid;
if (!ipc_data_read_receive(&callid, NULL)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fibril_mutex_lock(&file->lock);
 
int fs_phone = vfs_grab_phone(file->node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
file->node->index, true, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
 
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, rc);
}
 
void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
ipc_callid_t callid;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *path = malloc(len + 1);
if (!path) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
int rc;
if ((rc = ipc_data_write_finalize(callid, path, len))) {
ipc_answer_0(rid, rc);
free(path);
return;
}
path[len] = '\0';
 
if (!ipc_data_read_receive(&callid, NULL)) {
free(path);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
vfs_lookup_res_t lr;
fibril_rwlock_read_lock(&namespace_rwlock);
rc = vfs_lookup_internal(path, L_NONE, &lr, NULL);
free(path);
if (rc != EOK) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, rc);
ipc_answer_0(rid, rc);
return;
}
vfs_node_t *node = vfs_node_get(&lr);
if (!node) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
fibril_rwlock_read_unlock(&namespace_rwlock);
 
int fs_phone = vfs_grab_phone(node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle,
node->index, false, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
ipcarg_t rv;
async_wait_for(msg, &rv);
vfs_release_phone(fs_phone);
 
ipc_answer_0(rid, rv);
 
vfs_node_put(node);
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
{
int mode = IPC_GET_ARG1(*request);
1001,6 → 1055,9
return;
}
path[len] = '\0';
 
/* Ignore mode for now. */
(void) mode;
fibril_rwlock_write_lock(&namespace_rwlock);
int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
1050,7 → 1107,7
/*
* The name has already been unlinked by vfs_lookup_internal().
* We have to get and put the VFS node to ensure that it is
* VFS_DESTROY'ed after the last reference to it is dropped.
* VFS_OUT_DESTROY'ed after the last reference to it is dropped.
*/
vfs_node_t *node = vfs_node_get(&lr);
fibril_mutex_lock(&nodes_mutex);
/branches/network/uspace/srv/vfs/vfs.h
198,14 → 198,15
extern void vfs_mount(ipc_callid_t, ipc_call_t *);
extern void vfs_open(ipc_callid_t, ipc_call_t *);
extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
extern void vfs_device(ipc_callid_t, ipc_call_t *);
extern void vfs_sync(ipc_callid_t, ipc_call_t *);
extern void vfs_node(ipc_callid_t, ipc_call_t *);
extern void vfs_close(ipc_callid_t, ipc_call_t *);
extern void vfs_read(ipc_callid_t, ipc_call_t *);
extern void vfs_write(ipc_callid_t, ipc_call_t *);
extern void vfs_seek(ipc_callid_t, ipc_call_t *);
extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_stat(ipc_callid_t, ipc_call_t *);
extern void vfs_mkdir(ipc_callid_t, ipc_call_t *);
extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
extern void vfs_rename(ipc_callid_t, ipc_call_t *);
/branches/network/uspace/srv/vfs/vfs_node.c
129,7 → 129,7
*/
int phone = vfs_grab_phone(node->fs_handle);
ipcarg_t rc;
rc = async_req_2_0(phone, VFS_DESTROY,
rc = async_req_2_0(phone, VFS_OUT_DESTROY,
(ipcarg_t)node->dev_handle, (ipcarg_t)node->index);
assert(rc == EOK);
vfs_release_phone(phone);
/branches/network/uspace/srv/vfs/vfs_lookup.c
159,7 → 159,7
 
ipc_call_t answer;
int phone = vfs_grab_phone(root->fs_handle);
aid_t req = async_send_5(phone, VFS_LOOKUP, (ipcarg_t) first,
aid_t req = async_send_5(phone, VFS_OUT_LOOKUP, (ipcarg_t) first,
(ipcarg_t) (first + len - 1) % PLB_SIZE,
(ipcarg_t) root->dev_handle, (ipcarg_t) lflag, (ipcarg_t) index,
&answer);
204,7 → 204,7
int phone = vfs_grab_phone(result->triplet.fs_handle);
ipc_call_t answer;
aid_t req = async_send_2(phone, VFS_OPEN_NODE,
aid_t req = async_send_2(phone, VFS_OUT_OPEN_NODE,
(ipcarg_t) result->triplet.dev_handle,
(ipcarg_t) result->triplet.index, &answer);
/branches/network/HelenOS.config
55,6 → 55,11
@ "serengeti" Serengeti system
! [PLATFORM=sparc64] MACHINE (choice)
 
% Machine type
@ "testarm" GXEmul Testarm
@ "integratorcp" Integratorcp
! [PLATFORM=arm32] MACHINE (choice)
 
% CPU type
@ "pentium4" Pentium 4
@ "pentium3" Pentium 3
325,8 → 330,12
 
% Input device class
@ "generic" Keyboard or serial line
! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
@ "none" No input device
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
! [PLATFORM=ia32|(PLATFORM=arm32&MACHINE=testarm)|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
337,6 → 346,10
 
% Output device class
@ "generic" Monitor or serial line
! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_OUT (choice)
 
% Output device class
@ "generic" Monitor or serial line
@ "none" No output device
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ppc32|(PLATFORM=ia64&MACHINE=i460GX)|(PLATFORM=mips32&MACHINE=msim)] CONFIG_HID_OUT (choice)
 
352,7 → 365,7
@ "monitor" Monitor
@ "serial" Serial line
@ "none" No output device
! [PLATFORM=arm32] CONFIG_HID_OUT (choice)
! [PLATFORM=arm32&MACHINE=testarm] CONFIG_HID_OUT (choice)
 
% PC keyboard support
! [CONFIG_HID_IN=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_PC_KBD (y/n)
367,10 → 380,10
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=mips32] CONFIG_MIPS_PRN (y/n)
 
% Support for GXemul keyboard
! [CONFIG_HID_IN=generic&PLATFORM=arm32] CONFIG_ARM_KBD (y/n)
! [CONFIG_HID_IN=generic&PLATFORM=arm32&MACHINE=testarm] CONFIG_ARM_KBD (y/n)
 
% Support for GXemul printer
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32] CONFIG_ARM_PRN (y/n)
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=testarm] CONFIG_ARM_PRN (y/n)
 
% Support for VIA CUDA controller
! [CONFIG_HID_IN=generic&PLATFORM=ppc32] CONFIG_VIA_CUDA (y/n)
390,12 → 403,18
% Support for Serengeti keyboard
! [CONFIG_HID_IN=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_KBD (y/n)
 
% i8042 controller support
% Support for i8042 controller
! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
 
% Support for pl050 controller
! [CONFIG_HID_IN=generic&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_PL050 (y)
 
% Sun keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
 
% Macintosh ADB keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=ppc32&(CONFIG_VIA_CUDA=y)] CONFIG_MAC_KBD (y)
 
% Dummy serial line input
! [CONFIG_MIPS_KBD=y|CONFIG_ARM_KBD=y] CONFIG_DSRLNIN (y)
 
457,6 → 476,12
% External ramdisk
! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n)
 
% Load disk drivers on startup
! CONFIG_START_BD (n/y)
 
% Mount /data on startup
! [CONFIG_START_BD=y] CONFIG_MOUNT_DATA (n/y)
 
% Networking architecture
@ "modular" Modular
@ "module" One module
/branches/network/boot/arch/arm32/loader/_link.ld.in
17,6 → 17,9
*(COMMON); /* global variables */
*(.reginfo);
 
. = 0x2000;
*(ST); /* bootloader stack section */
 
. = 0x4000;
*(PT); /* page table placed at 0x4000 */
[[COMPONENTS]]
/branches/network/boot/arch/arm32/loader/boot.S
34,8 → 34,10
.global start
.global jump_to_kernel
.global page_table
.global boot_stack
 
start:
ldr sp, =boot_stack
b bootstrap
 
jump_to_kernel:
46,6 → 48,10
#
bx r0
 
#bootloader stack
.section ST
.space 4096
boot_stack:
 
# place page_table to PT section
.section PT
/branches/network/boot/arch/arm32/loader/main.c
67,7 → 67,7
/** Prints bootloader version information. */
static void version_print(void)
{
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2007 HelenOS project\n",
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2009 HelenOS project\n",
release, revision, timestamp);
}
 
91,8 → 91,6
bootinfo.cnt = 0;
unsigned int i, j;
for (i = 0; i < COMPONENTS; i++) {
printf(" %L: %s image (size %d bytes)\n",
components[i].start, components[i].name, components[i].size);
top = ALIGN_UP(top, KERNEL_PAGE_SIZE);
if (i > 0) {
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top;
106,18 → 104,17
j = bootinfo.cnt - 1;
 
printf("\nCopying components\n");
 
printf("Component\tAddress\t\tSize (Bytes)\n");
printf("============================================\n");
for (i = COMPONENTS - 1; i > 0; i--, j--) {
printf(" %s...", components[i].name);
printf("%s\t\t0x%x\t%d\n", components[i].name, bootinfo.tasks[j].addr, components[i].size);
memcpy((void *)bootinfo.tasks[j].addr, components[i].start,
components[i].size);
printf("done.\n");
}
printf("\nCopying kernel...");
printf("KERNEL\t\t0x%x\t%d\n", KERNEL_VIRTUAL_ADDRESS, components[0].size);
 
memcpy((void *)KERNEL_VIRTUAL_ADDRESS, components[0].start,
components[0].size);
printf("done.\n");
 
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo);
/branches/network/boot/arch/arm32/loader/print/gxemul.c
File deleted
/branches/network/boot/arch/arm32/loader/print/print.c
0,0 → 1,80
/*
* Copyright (c) 2007 Michal Kebrt
* Copyright (c) 2009 Vineeth Pillai
* 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 arm32boot
* @{
*/
/** @file
* @brief bootloader output logic
*/
 
 
#include <printf.h>
 
 
/** Address where characters to be printed are expected. */
#ifdef MACHINE_testarm
#define PUTC_ADDRESS 0x10000000
#endif
 
#ifdef MACHINE_integratorcp
#define PUTC_ADDRESS 0x16000000
#endif
 
 
 
/** Prints a character to the console.
*
* @param ch Character to be printed.
*/
static void putc(char ch)
{
if (ch == '\n')
*((volatile char *) PUTC_ADDRESS) = '\r';
*((volatile char *) PUTC_ADDRESS) = ch;
}
 
 
/** Prints a string to the console.
*
* @param str String to be printed.
* @param len Number of characters to be printed.
*/
void write(const char *str, const int len)
{
int i;
for (i = 0; i < len; ++i) {
putc(str[i]);
}
}
 
/** @}
*/
 
Property changes:
Added: svn:mergeinfo
/branches/network/boot/arch/arm32/loader/Makefile
64,7 → 64,7
boot.S \
asm.S \
mm.c \
print/gxemul.c \
print/print.c \
_components.c \
../../../generic/printf.c \
../../../generic/string.c \
92,8 → 92,11
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/file_bd/file_bd \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
$(USPACEDIR)/srv/bd/file_bd/file_bd
ifeq ($(MACHINE),testarm)
RD_SRVS += \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
endif
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
/branches/network/version
36,7 → 36,7
 
VERSION = 0
PATCHLEVEL = 4
SUBLEVEL = 0
SUBLEVEL = 1
 
ifdef EXTRAVERSION
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION)
44,4 → 44,4
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)
endif
 
NAME = Sinister Valentine
NAME = Escalopino
/branches/network/defaults/sparc64/Makefile.config
54,3 → 54,9
 
# External ramdisk
CONFIG_RD_EXTERNAL = y
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/ia64/Makefile.config
42,3 → 42,9
 
# Output device class
CONFIG_HID_OUT = generic
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/arm32/Makefile.config
30,3 → 30,9
 
# What is your output device?
CONFIG_HID_OUT = generic
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/arm32/GXemul/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = testarm
/branches/network/defaults/arm32/integratorcp/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = integratorcp
/branches/network/defaults/ppc32/Makefile.config
36,3 → 36,9
 
# Use Block Address Translation by the loader
CONFIG_BAT = y
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/amd64/Makefile.config
54,3 → 54,9
 
# Default framebuffer depth
CONFIG_VESA_BPP = 16
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/mips32/Makefile.config
36,3 → 36,9
 
# Output device class
CONFIG_HID_OUT = generic
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n
/branches/network/defaults/ia32/Makefile.config
60,3 → 60,9
 
# Default framebuffer depth
CONFIG_VESA_BPP = 16
 
# Load disk drivers on startup
CONFIG_START_BD = n
 
# Mount /data on startup
CONFIG_MOUNT_DATA = n