Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2464 → Rev 2465

/trunk/uspace/kbd/Makefile
32,6 → 32,7
LIBC_PREFIX = ../libc
SOFTINT_PREFIX = ../softint
include $(LIBC_PREFIX)/Makefile.toolchain
include ../../Makefile.config
 
CFLAGS += -Iinclude -I../libadt/include
 
70,6 → 71,12
GENARCH_SOURCES = \
genarch/src/kbd.c
endif
ifeq ($(ARCH), arm32)
ifeq ($(MACHINE), gxemul_testarm)
ARCH_SOURCES += \
arch/$(ARCH)/src/kbd_gxemul.c
endif
endif
 
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
/trunk/uspace/kbd/arch/arm32/include/kbd.h
1,5 → 1,5
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,12 → 26,11
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdarm32 arm32
* @brief HelenOS arm32 arch dependent parts of uspace keyboard handler.
* @ingroup kbd
/** @addtogroup kbdarm32
* @{
*/
/** @file
* @brief Empty.
*/
 
#ifndef KBD_arm32_KBD_H_
/trunk/uspace/kbd/arch/arm32/src/kbd.c
1,5 → 1,5
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
32,24 → 32,9
* @{
*/
/** @file
* @brief Empty, required by generic Makefile.
*/
 
#include <arch/kbd.h>
#include <ipc/ipc.h>
#include <sysinfo.h>
#include <kbd.h>
#include <keys.h>
 
int kbd_arch_init(void)
{
return 0;
}
 
 
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
{
return 1;
}
 
/** @}
*/
/trunk/uspace/kbd/arch/arm32/src/kbd_gxemul.c
0,0 → 1,424
/*
* Copyright (c) 2007 Michal Kebrt
* 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 kbdarm32gxemul GXemul
* @brief HelenOS arm32 GXEmul uspace keyboard handler.
* @ingroup kbdarm32
* @{
*/
/** @file
* @brief GXemul uspace keyboard handler.
*/
 
#include <ipc/ipc.h>
#include <sysinfo.h>
#include <kbd.h>
#include <keys.h>
#include <bool.h>
 
 
/* GXemul key codes in no-framebuffer mode. */
#define GXEMUL_KEY_F1 0x504f1bL
#define GXEMUL_KEY_F2 0x514f1bL
#define GXEMUL_KEY_F3 0x524f1bL
#define GXEMUL_KEY_F4 0x534f1bL
#define GXEMUL_KEY_F5 0x35315b1bL
#define GXEMUL_KEY_F6 0x37315b1bL
#define GXEMUL_KEY_F7 0x38315b1bL
#define GXEMUL_KEY_F8 0x39315b1bL
#define GXEMUL_KEY_F9 0x30325b1bL
#define GXEMUL_KEY_F10 0x31325b1bL
#define GXEMUL_KEY_F11 0x33325d1bL
#define GXEMUL_KEY_F12 0x34325b1bL
 
/** Start code of F5-F12 keys. */
#define GXEMUL_KEY_F5_F12_START_CODE 0x7e
 
/* GXemul key codes in framebuffer mode. */
#define GXEMUL_FB_KEY_F1 0x504f5b1bL
#define GXEMUL_FB_KEY_F2 0x514f5b1bL
#define GXEMUL_FB_KEY_F3 0x524f5b1bL
#define GXEMUL_FB_KEY_F4 0x534f5b1bL
#define GXEMUL_FB_KEY_F5 0x35315b1bL
#define GXEMUL_FB_KEY_F6 0x37315b1bL
#define GXEMUL_FB_KEY_F7 0x38315b1bL
#define GXEMUL_FB_KEY_F8 0x39315b1bL
#define GXEMUL_FB_KEY_F9 0x38325b1bL
#define GXEMUL_FB_KEY_F10 0x39325b1bL
#define GXEMUL_FB_KEY_F11 0x33325b1bL
#define GXEMUL_FB_KEY_F12 0x34325b1bL
 
 
/** Function keys start code (F1=0x101) */
#define FUNCTION_KEYS 0x100
 
static irq_cmd_t gxemul_cmds[] = {
{
CMD_MEM_READ_1,
(void *) 0,
0,
2
}
};
 
static irq_code_t gxemul_kbd = {
1,
gxemul_cmds
};
 
 
/** Framebuffer switched on. */
static bool fb;
 
 
/*
// Please preserve this code (it can be used to determine scancodes)
int to_hex(int v)
{
return "0123456789ABCDEF"[v];
}
*/
 
 
/** Process data sent when a key is pressed (in no-framebuffer mode).
*
* @param keybuffer Buffer of pressed key.
* @param scan_code Scan code.
*
* @return Always 1.
*/
static int gxemul_kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code)
{
// holds at most 4 latest scan codes
static unsigned long buf = 0;
 
// number of scan codes in #buf
static int count = 0;
 
/*
// Preserve for detecting scan codes.
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
keybuffer_push(keybuffer, to_hex(scan_code&0xf));
keybuffer_push(keybuffer, 'X');
keybuffer_push(keybuffer, 'Y');
return 1;
*/
 
if (scan_code == '\r') {
scan_code = '\n';
}
if (scan_code == GXEMUL_KEY_F5_F12_START_CODE) {
switch (buf) {
case GXEMUL_KEY_F5:
keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
buf = count = 0;
return 1;
case GXEMUL_KEY_F6:
keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
buf = count = 0;
return 1;
case GXEMUL_KEY_F7:
keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
buf = count = 0;
return 1;
case GXEMUL_KEY_F8:
keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
buf = count = 0;
return 1;
case GXEMUL_KEY_F9:
keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
buf = count = 0;
return 1;
case GXEMUL_KEY_F10:
keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
buf = count = 0;
return 1;
case GXEMUL_KEY_F11:
keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
buf = count = 0;
return 1;
case GXEMUL_KEY_F12:
keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
buf = count = 0;
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
keybuffer_push(keybuffer, (buf >> 24) & 0xff);
keybuffer_push(keybuffer, scan_code);
buf = count = 0;
return 1;
}
}
 
// add to buffer
buf |= ((unsigned long) scan_code) << (8 * (count++));
if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) {
keybuffer_push(keybuffer, buf);
buf = count = 0;
return 1;
}
 
if (count <= 1) {
return 1;
}
 
if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff)
&& (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
buf = count = 0;
return 1;
}
 
if (count <= 2) {
return 1;
}
 
switch (buf) {
case GXEMUL_KEY_F1:
keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
buf = count = 0;
return 1;
case GXEMUL_KEY_F2:
keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
buf = count = 0;
return 1;
case GXEMUL_KEY_F3:
keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
buf = count = 0;
return 1;
case GXEMUL_KEY_F4:
keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
buf = count = 0;
return 1;
}
 
 
if ((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff)
&& (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
buf = count = 0;
return 1;
}
 
if (count <= 3) {
return 1;
}
switch (buf) {
case GXEMUL_KEY_F5:
case GXEMUL_KEY_F6:
case GXEMUL_KEY_F7:
case GXEMUL_KEY_F8:
case GXEMUL_KEY_F9:
case GXEMUL_KEY_F10:
case GXEMUL_KEY_F11:
case GXEMUL_KEY_F12:
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
keybuffer_push(keybuffer, (buf >> 24) & 0xff);
buf = count = 0;
return 1;
}
 
return 1;
}
 
 
/** Process data sent when a key is pressed (in framebuffer mode).
*
* @param keybuffer Buffer of pressed keys.
* @param scan_code Scan code.
*
* @return Always 1.
*/
static int gxemul_kbd_process_fb(keybuffer_t *keybuffer, int scan_code)
{
// holds at most 4 latest scan codes
static unsigned long buf = 0;
 
// number of scan codes in #buf
static int count = 0;
 
/*
// Please preserve this code (it can be used to determine scancodes)
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
keybuffer_push(keybuffer, to_hex(scan_code&0xf));
keybuffer_push(keybuffer, ' ');
keybuffer_push(keybuffer, ' ');
return 1;
*/
if (scan_code == '\r') {
scan_code = '\n';
}
// add to buffer
buf |= ((unsigned long) scan_code) << (8*(count++));
if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) {
keybuffer_push(keybuffer, buf);
buf = count = 0;
return 1;
}
 
if (count <= 1) {
return 1;
}
 
if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) {
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) &0xff);
buf = count = 0;
return 1;
}
 
if (count <= 2) {
return 1;
}
 
if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff)
&& (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff)
&& (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) {
 
keybuffer_push(keybuffer, buf & 0xff);
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
buf = count = 0;
return 1;
}
 
if (count <= 3) {
return 1;
}
 
switch (buf) {
case GXEMUL_FB_KEY_F1:
keybuffer_push(keybuffer,FUNCTION_KEYS | 1 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F2:
keybuffer_push(keybuffer,FUNCTION_KEYS | 2 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F3:
keybuffer_push(keybuffer,FUNCTION_KEYS | 3 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F4:
keybuffer_push(keybuffer,FUNCTION_KEYS | 4 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F5:
keybuffer_push(keybuffer,FUNCTION_KEYS | 5 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F6:
keybuffer_push(keybuffer,FUNCTION_KEYS | 6 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F7:
keybuffer_push(keybuffer,FUNCTION_KEYS | 7 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F8:
keybuffer_push(keybuffer,FUNCTION_KEYS | 8 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F9:
keybuffer_push(keybuffer,FUNCTION_KEYS | 9 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F10:
keybuffer_push(keybuffer,FUNCTION_KEYS | 10 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F11:
keybuffer_push(keybuffer,FUNCTION_KEYS | 11 );
buf = count = 0;
return 1;
case GXEMUL_FB_KEY_F12:
keybuffer_push(keybuffer,FUNCTION_KEYS | 12 );
buf = count = 0;
return 1;
default:
keybuffer_push(keybuffer, buf & 0xff );
keybuffer_push(keybuffer, (buf >> 8) & 0xff);
keybuffer_push(keybuffer, (buf >> 16) & 0xff);
keybuffer_push(keybuffer, (buf >> 24) & 0xff);
buf = count = 0;
return 1;
}
 
return 1;
}
 
 
/** Initializes keyboard handler. */
int kbd_arch_init(void)
{
fb = (sysinfo_value("fb.kind") == 1);
gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd);
return 0;
}
 
 
/** Process data sent when a key is pressed.
*
* @param keybuffer Buffer of pressed keys.
* @param call IPC call.
*
* @return Always 1.
*/
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
if (fb) {
return gxemul_kbd_process_fb(keybuffer, scan_code);
} else {
return gxemul_kbd_process_no_fb(keybuffer, scan_code);
}
 
}
 
/** @}
*/
/trunk/uspace/softfloat/arch/arm32/include/functions.h
28,10 → 28,11
 
/** @addtogroup softfloatarm32 arm32
* @ingroup sfl
* @brief softfloat architecture dependent definitions
* @brief Softfloat architecture dependent definitions.
* @{
*/
/** @file
/** @file
* @brief Softfloat architecture dependent definitions.
*/
 
#ifndef __SOFTFLOAT_FUNCTIONS_H__
/trunk/uspace/libc/arch/arm32/_link.ld.in
7,46 → 7,46
}
 
SECTIONS {
. = 0x2000;
. = 0x1000;
 
.init ALIGN(0x2000): SUBALIGN(0x2000) {
.init ALIGN(0x1000): SUBALIGN(0x1000) {
*(.init);
} : text
.text : {
*(.text);
*(.rodata*);
*(.rodata*);
} :text
 
.got ALIGN(0x2000) : SUBALIGN(0x2000) {
_gp = .;
*(.got*);
} :data
.data : {
.data ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.opd);
*(.data .data.*);
*(.sdata);
} :data
 
.tdata : {
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
 
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
 
.bss : {
*(.sbss);
*(.scommon);
*(COMMON);
*(.bss);
*(COMMON);
*(.bss);
} :data
 
. = ALIGN(0x2000);
. = ALIGN(0x1000);
_heap = .;
/DISCARD/ : {
*(*);
}
}
 
}
/trunk/uspace/libc/arch/arm32/include/psthread.h
1,5 → 1,5
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
29,8 → 29,8
/** @addtogroup libcarm32
* @{
*/
/** @file
* @ingroup libcarm32
/** @file
* @brief psthread related declarations.
*/
 
#ifndef LIBC_arm32_PSTHREAD_H_
37,15 → 37,53
#define LIBC_arm32_PSTHREAD_H_
 
#include <types.h>
#include <align.h>
#include "thread.h"
 
#define SP_DELTA 0 /* TODO */
/** Size of a stack item */
#define STACK_ITEM_SIZE 4
 
/** Stack alignment - see <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for details */
#define STACK_ALIGNMENT 8
 
#define SP_DELTA (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 
/** Sets data to the context.
*
* @param c Context (#context_t).
* @param _pc Program counter.
* @param stack Stack address.
* @param size Stack size.
* @param ptls Pointer to the TCB.
*/
#define context_set(c, _pc, stack, size, ptls) \
(c)->pc = (sysarg_t) (_pc); \
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
(c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET;
 
 
/** Thread context.
*
* Only registers preserved accross function calls are included. r9 is used
* to store a TLS address. -ffixed-r9 gcc forces gcc not to use this
* register. -mtp=soft forces gcc to use #__aeabi_read_tp to obtain
* TLS address.
*/
typedef struct {
uint32_t sp;
uint32_t pc;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t tls;
uint32_t r10;
uint32_t r11;
} context_t;
 
 
#endif
 
/** @}
/trunk/uspace/libc/arch/arm32/include/syscall.h
1,5 → 1,5
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,11
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
/** @addtogroup libcarm32
* @{
*/
/**
* @file
/** @file
* @brief Empty.
*/
 
#ifndef LIBC_arm32_SYSCALL_H_
/trunk/uspace/libc/arch/arm32/include/atomic.h
1,5 → 1,5
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
30,6 → 30,7
* @{
*/
/** @file
* @brief Atomic operations.
*/
 
#ifndef LIBC_arm32_ATOMIC_H_
37,26 → 38,80
 
/** Atomic addition.
*
* @param val Atomic value.
* @param imm Value to add.
* @param val Where to add.
* @param i Value to be added.
*
* @return Value after addition.
*/
static inline long atomic_add(atomic_t *val, int imm)
static inline long atomic_add(atomic_t *val, int i)
{
/* TODO */
return (val->count += imm);
int ret;
volatile long * mem = &(val->count);
 
asm volatile (
"1: \n"
"ldr r2, [%1] \n"
"add r3, r2, %2 \n"
"str r3, %0 \n"
"swp r3, r3, [%1] \n"
"cmp r3, r2 \n"
"bne 1b \n"
 
: "=m" (ret)
: "r" (mem), "r" (i)
: "r3", "r2"
);
 
return ret;
}
 
 
/** Atomic increment.
*
* @param val Variable to be incremented.
*/
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
 
 
/** Atomic decrement.
*
* @param val Variable to be decremented.
*/
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
 
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
 
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
/** Atomic pre-increment.
*
* @param val Variable to be incremented.
* @return Value after incrementation.
*/
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1); }
 
 
/** Atomic pre-decrement.
*
* @param val Variable to be decremented.
* @return Value after decrementation.
*/
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1); }
 
 
/** Atomic post-increment.
*
* @param val Variable to be incremented.
* @return Value before incrementation.
*/
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1) - 1; }
 
 
/** Atomic post-decrement.
*
* @param val Variable to be decremented.
* @return Value before decrementation.
*/
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1) + 1; }
 
 
#endif
 
/** @}
/trunk/uspace/libc/arch/arm32/include/endian.h
29,7 → 29,8
/** @addtogroup libcarm32
* @{
*/
/** @file
/** @file
* @brief Endianness definition.
*/
 
#ifndef LIBC_arm32_ENDIAN_H_
/trunk/uspace/libc/arch/arm32/include/stackarg.h
1,5 → 1,5
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
30,6 → 30,7
* @{
*/
/** @file
* @brief Empty.
*/
 
#ifndef LIBC_arm32_STACKARG_H_
/trunk/uspace/libc/arch/arm32/include/faddr.h
1,5 → 1,5
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
29,7 → 29,8
/** @addtogroup libcarm32
* @{
*/
/** @file
/** @file
* @brief Function address conversion.
*/
 
#ifndef LIBC_arm32_FADDR_H_
37,13 → 38,9
 
#include <libarch/types.h>
 
/**
/** Calculate absolute address of function referenced by fptr pointer.
*
* Calculate absolute address of function
* referenced by fptr pointer.
*
* @param f Function pointer.
*
*/
#define FADDR(f) (f)
 
/trunk/uspace/libc/arch/arm32/include/limits.h
1,5 → 1,5
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
29,17 → 29,17
/** @addtogroup libcarm32
* @{
*/
/** @file
* @ingroup libcarm32
/** @file
* @brief Limits declarations.
*/
 
#ifndef LIBC_arm32__LIMITS_H_
#define LIBC_arm32__LIMITS_H_
 
# define LONG_MIN MIN_INT32
# define LONG_MAX MAX_INT32
# define ULONG_MIN MIN_UINT32
# define ULONG_MAX MAX_UINT32
#define LONG_MIN MIN_INT32
#define LONG_MAX MAX_INT32
#define ULONG_MIN MIN_UINT32
#define ULONG_MAX MAX_UINT32
 
#endif
 
/trunk/uspace/libc/arch/arm32/include/types.h
29,8 → 29,8
/** @addtogroup libcarm32
* @{
*/
/** @file
* @ingroup libcarm32
/** @file
* @brief Definitions of basic types like #uintptr_t.
*/
 
#ifndef LIBC_arm32_TYPES_H_
/trunk/uspace/libc/arch/arm32/include/config.h
29,7 → 29,8
/** @addtogroup libcarm32
* @{
*/
/** @file
/** @file
* @brief Configuration constants.
*/
 
#ifndef LIBC_arm32_CONFIG_H_
/trunk/uspace/libc/arch/arm32/include/thread.h
1,5 → 1,5
/*
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,10 → 26,11
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libcia64
/** @addtogroup libcarm32
* @{
*/
/** @file
* @brief Uspace threads and TLS.
*/
 
#ifndef LIBC_arm32_THREAD_H_
37,24 → 38,61
 
#include <unistd.h>
 
/** Stack initial size. */
#define THREAD_INITIAL_STACK_PAGES_NO 1
 
/** Offsets for accessing __thread variables are shifted 8 bytes higher. */
#define ARM_TP_OFFSET (-8)
 
/** TCB (Thread Control Block) struct.
*
* TLS starts just after this struct.
*/
typedef struct {
/** psthread data. */
void *pst_data;
/* TODO */
} tcb_t;
 
 
/** Sets TLS address to the r9 register.
*
* @param tcb TCB (TLS starts behind)
*/
static inline void __tcb_set(tcb_t *tcb)
{
/* TODO */
void *tls = (void *)tcb;
tls += sizeof(tcb_t) + ARM_TP_OFFSET;
asm volatile (
"mov r9, %0"
:
: "r"(tls)
);
}
 
 
/** Returns TCB address.
*
* @return TCB address (starts before TLS which address is stored in r9 register).
*/
static inline tcb_t *__tcb_get(void)
{
/* TODO */
return NULL;
void *ret;
asm volatile (
"mov %0, r9"
: "=r"(ret)
);
return (tcb_t *)(ret - ARM_TP_OFFSET - sizeof(tcb_t));
}
 
 
/** Returns TLS address stored.
*
* Implemented in assembly.
*
* @return TLS address stored in r9 register
*/
extern uintptr_t __aeabi_read_tp(void);
 
#endif
 
/** @}
/trunk/uspace/libc/arch/arm32/Makefile.inc
1,5 → 1,5
#
# Copyright (c) 2005 Martin Decky
# Copyright (c) 2007 Michal Kebrt, Pavel Jancik
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
31,7 → 31,7
 
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = /usr/local/arm/bin
CFLAGS +=
CFLAGS += -ffixed-r9 -mtp=soft
LFLAGS += -N ../softint/libsoftint.a
AFLAGS +=
 
38,7 → 38,7
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/psthread.S \
arch/$(ARCH)/src/thread.c \
arch/$(ARCH)/src/dummy.S
arch/$(ARCH)/src/eabi.S
 
BFD_NAME = elf32-little
BFD_ARCH = arm
/trunk/uspace/libc/arch/arm32/src/dummy.S
File deleted
/trunk/uspace/libc/arch/arm32/src/eabi.S
0,0 → 1,35
#
# Copyright (c) 2007 Pavel Jancik
# 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 __aeabi_read_tp
 
__aeabi_read_tp:
mov r0, r9
mov pc, lr
/trunk/uspace/libc/arch/arm32/src/entry.s
1,5 → 1,5
#
# Copyright (c) 2006 Jakub Jermar
# Copyright (c) 2007 Michal Kebrt, Pavel Jancik
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
28,6 → 28,8
 
.section .init, "ax"
 
.org 0
 
.global __entry
.global __entry_driver
 
35,7 → 37,13
#
#
__entry:
bl __main
bl __io_init
bl main
bl __exit
 
#
# TODO
#
__entry_driver:
bl __main
bl main
bl __exit
 
/trunk/uspace/libc/arch/arm32/src/thread.c
1,5 → 1,5
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2007 Pavel Jancik
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
32,25 → 32,35
* @{
*/
/** @file
* @brief Uspace threads and TLS.
*/
 
#include <thread.h>
#include <malloc.h>
 
/** Allocate TLS & TCB for initial module threads
/** Allocates TLS & TCB.
*
* @param data Start of data section
* @return pointer to tcb_t structure
* @param data Start of data section (output parameter).
* @param size Size of (tbss + tdata) sections.
* @return Pointer to the allocated #tcb_t structure.
*/
tcb_t * __alloc_tls(void **data, size_t size)
{
/* TODO */
return NULL;
tcb_t *result;
 
result = malloc(sizeof(tcb_t) + size);
*data = ((void *)result) + sizeof(tcb_t);
return result;
}
 
/** Deallocates TLS & TCB.
*
* @param tcb TCB structure to be deallocated (along with corresponding TLS).
* @param size Not used.
*/
void __free_tls_arch(tcb_t *tcb, size_t size)
{
/* TODO */
free(tcb);
}
 
/** @}
/trunk/uspace/libc/arch/arm32/src/thread_entry.s
34,7 → 34,4
#
#
__thread_entry:
 
#
# TODO
#
b __thread_main
/trunk/uspace/libc/arch/arm32/src/psthread.S
1,5 → 1,5
#
# Copyright (c) 2005 Jakub Jermar
# Copyright (c) 2007 Michal Kebrt
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
32,7 → 32,18
.global context_restore
 
context_save:
/* TODO */
stmia r0!, {sp, lr}
stmia r0!, {r4-r11}
 
# return 1
mov r0, #1
mov pc, lr
 
context_restore:
/* TODO */
ldmia r0!, {sp, lr}
ldmia r0!, {r4-r11}
 
#return 0
mov r0, #0
mov pc, lr
 
/trunk/uspace/libc/arch/arm32/src/syscall.c
1,5 → 1,5
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2007 Pavel Jancik
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
30,16 → 30,44
* @{
*/
/** @file
* @ingroup libcarm32
* @brief Syscall routine.
*/
 
#include <libc.h>
 
 
/** Syscall routine.
*
* Stores p1-p4, id to r0-r4 registers and calls <code>swi</code>
* instruction. Returned value is read from r0 register.
*
* @param p1 Parameter 1.
* @param p2 Parameter 2.
* @param p3 Parameter 3.
* @param p4 Parameter 4.
* @param id Number of syscall.
*
* @return Syscall return value.
*/
sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
const sysarg_t p4, const syscall_t id)
{
/* TODO */
return 0;
register sysarg_t __arm_reg_r0 asm("r0") = p1;
register sysarg_t __arm_reg_r1 asm("r1") = p2;
register sysarg_t __arm_reg_r2 asm("r2") = p3;
register sysarg_t __arm_reg_r3 asm("r3") = p4;
register sysarg_t __arm_reg_r4 asm("r4") = id;
 
asm volatile ( "swi"
: "=r" (__arm_reg_r0)
: "r" (__arm_reg_r0),
"r" (__arm_reg_r1),
"r" (__arm_reg_r2),
"r" (__arm_reg_r3),
"r" (__arm_reg_r4)
);
 
return __arm_reg_r0;
}
 
/** @}