From 188b43270e2328e8b3338441969b54a159ea0daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 22 Oct 2007 00:10:36 +0000 Subject: [PATCH] m68k arch files for libroot. Mostly ppc from r22648. Some atomic_* done. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22654 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/libroot/os/arch/m68k/atomic.S | 86 +++++++++++++++ src/system/libroot/os/arch/m68k/byteorder.S | 102 ++++++++++++++++++ .../libroot/os/arch/m68k/compatibility.c | 44 ++++++++ src/system/libroot/os/arch/m68k/system_time.c | 29 +++++ .../libroot/os/arch/m68k/system_time_asm.S | 21 ++++ src/system/libroot/os/arch/m68k/thread.c | 9 ++ src/system/libroot/os/arch/m68k/time.c | 42 ++++++++ src/system/libroot/os/arch/m68k/tls.c | 53 +++++++++ 8 files changed, 386 insertions(+) create mode 100644 src/system/libroot/os/arch/m68k/atomic.S create mode 100644 src/system/libroot/os/arch/m68k/byteorder.S create mode 100644 src/system/libroot/os/arch/m68k/compatibility.c create mode 100644 src/system/libroot/os/arch/m68k/system_time.c create mode 100644 src/system/libroot/os/arch/m68k/system_time_asm.S create mode 100644 src/system/libroot/os/arch/m68k/thread.c create mode 100644 src/system/libroot/os/arch/m68k/time.c create mode 100644 src/system/libroot/os/arch/m68k/tls.c diff --git a/src/system/libroot/os/arch/m68k/atomic.S b/src/system/libroot/os/arch/m68k/atomic.S new file mode 100644 index 0000000000..bbe0c428ca --- /dev/null +++ b/src/system/libroot/os/arch/m68k/atomic.S @@ -0,0 +1,86 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +/* + * gcc/config/m68k/m68k.h:CALL_USED_REGISTERS: + * d0,d1,a0,a1 are scratch regs, not to be saved. + */ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + +/* int atomic_add(int *value, int increment) + */ +FUNCTION(atomic_add): + move.l (4,%a7),%a0 + move.l (%a0),%d0 +miss1: move.l %d0,%d1 + add.l (8,%a7),%d1 + cas.l %d0,%d1,(%a0) + bne miss1 + // d0 = old value + rts + +/* int atomic_and(int *value, int andValue) + */ +FUNCTION(atomic_and): + move.l (4,%a7),%a0 + move.l (%a0),%d0 +miss2: move.l %d0,%d1 + and.l (8,%a7),%d1 + cas.l %d0,%d1,(%a0) + bne miss2 + // d0 = old value + rts + +/* int atomic_or(int *value, int orValue) + */ +FUNCTION(atomic_or): + move.l (4,%a7),%a0 + move.l (%a0),%d0 +miss3: move.l %d0,%d1 + or.l (8,%a7),%d1 + cas.l %d0,%d1,(%a0) + bne miss3 + rts + +/* int atomic_set(int *value, int setTo) + */ +FUNCTION(atomic_set): + move.l (4,%a7),%a0 + move.l (%a0),%d0 +miss4: move.l %d0,%d1 + move.l (8,%a7),%d1 + cas.l %d0,%d1,(%a0) + bne miss4 + rts + +/* int atomic_test_and_set(int *value, int setTo, int testValue) + */ +FUNCTION(atomic_test_and_set): + move.l (4,%a7),%a0 + move.l (8,%a7),%d1 + move.l (12,%a7),%d0 + cas.l %d0,%d1,(%a0) +//XXX: + rts + +lost5: lwarx %r6, 0, %r3 + cmpw %r6, %r5 + bne out5 + stwcx. %r4, 0, %r3 +out5: mr %r3, %r6 + blr + +/* int atomic_get(int *value) + * r3 + */ +FUNCTION(atomic_get): +lost6: lwarx %r5, 0, %r3 + stwcx. %r5, 0, %r3 + bne- lost6 + mr %r3, %r5 + blr diff --git a/src/system/libroot/os/arch/m68k/byteorder.S b/src/system/libroot/os/arch/m68k/byteorder.S new file mode 100644 index 0000000000..8f1b1536b8 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/byteorder.S @@ -0,0 +1,102 @@ +/* +** Copyright 2003, Axel D�fler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + +/* uint16 __swap_int16(uint16 value) + * r3 + */ +FUNCTION(__swap_int16): + rlwinm %r4, %r3, 8, 16, 23 // byte 4 -> byte 3 (clear other bits) + rlwimi %r4, %r3, 24, 24, 31 // byte 3 -> byte 4 (copy into) + mr %r3, %r4 // copy to result register + blr + + +/* uint32 __swap_int32(uint32 value) + * r3 + */ +FUNCTION(__swap_int32): + rlwinm %r4, %r3, 24, 0, 31 // byte 4 to 1, byte 2 to 3 + rlwimi %r4, %r3, 8, 8, 15 // byte 3 to 2 + rlwimi %r4, %r3, 8, 24, 31 // byte 1 to 4 + mr %r3, %r4 + blr + + +/* uint64 __swap_int64(uint64 value) + * r3/r4 + */ +FUNCTION(__swap_int64): + rlwinm %r5, %r3, 24, 0, 31 // byte 4 to 5, byte 2 to 7 + rlwimi %r5, %r3, 8, 8, 15 // byte 3 to 6 + rlwimi %r5, %r3, 8, 24, 31 // byte 1 to 8 + rlwinm %r3, %r4, 24, 0, 31 // byte 8 to 1, byte 6 to 3 + rlwimi %r3, %r4, 8, 8, 15 // byte 7 to 2 + rlwimi %r3, %r4, 8, 24, 31 // byte 5 to 4 + mr %r4, %r5 // copy lower 32 bits + blr + + +/* TODO: The following functions can surely be optimized. A simple optimization + * would be to define macros with the contents of the __swap_int{32,64} + * functions and use those instead of calling the functions. + */ + +/* float __swap_float(float value) + * f1 + */ +FUNCTION(__swap_float): + // push a stack frame + stwu %r1, -32(%r1) + mflr %r0 + stw %r0, 36(%r1) + + // %f1 -> %r3 + stfs %f1, 20(%r1) + lwz %r3, 20(%r1) + + // let __swap_int32 convert %r3 + bl __swap_int32 + + // %r3 -> %f1 + stw %r3, 20(%r1) + lfs %f1, 20(%r1) + + // pop the stack frame + lwz %r0, 36(%r1) + mtlr %r0 + addi %r1, %r1, 32 + blr + +/* double __swap_double(double value) + * f1 + */ +FUNCTION(__swap_double): + // push a stack frame + stwu %r1, -32(%r1) + mflr %r0 + stw %r0, 36(%r1) + + // %f1 -> (%r3:%r4) + stfd %f1, 20(%r1) + lwz %r3, 20(%r1) + lwz %r4, 24(%r1) + + // let __swap_int64 convert %r3:%r4 + bl __swap_int64 + + // (%r3:%r4) -> %f1 + stw %r3, 20(%r1) + stw %r4, 24(%r1) + lfd %f1, 20(%r1) + + // pop the stack frame + lwz %r0, 36(%r1) + mtlr %r0 + addi %r1, %r1, 32 + blr diff --git a/src/system/libroot/os/arch/m68k/compatibility.c b/src/system/libroot/os/arch/m68k/compatibility.c new file mode 100644 index 0000000000..1411ca6560 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/compatibility.c @@ -0,0 +1,44 @@ +/* + * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +// This file includes some known R5 syscalls +// ToDo: maybe they should indeed do something... + +#include + + +int _kset_mon_limit_(int num); +int _kset_fd_limit_(int num); +int _kget_cpu_state_(int cpuNum); +int _kset_cpu_state_(int cpuNum, int state); + + +int +_kset_mon_limit_(int num) +{ + return B_ERROR; +} + + +int +_kset_fd_limit_(int num) +{ + return B_ERROR; +} + + +int +_kget_cpu_state_(int cpuNum) +{ + return 1; +} + + +int +_kset_cpu_state_(int cpuNum, int state) +{ + return state ? B_OK : B_ERROR; +} + diff --git a/src/system/libroot/os/arch/m68k/system_time.c b/src/system/libroot/os/arch/m68k/system_time.c new file mode 100644 index 0000000000..ce8aa13425 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/system_time.c @@ -0,0 +1,29 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include +#include +#include + + +static vint32 *sConversionFactor; + +void +__ppc_setup_system_time(vint32 *cvFactor) +{ + sConversionFactor = cvFactor; +} + + +bigtime_t +system_time(void) +{ + uint64 timeBase = __ppc_get_time_base(); + + uint32 cv = *sConversionFactor; + return (timeBase >> 32) * cv + (((timeBase & 0xffffffff) * cv) >> 32); +} diff --git a/src/system/libroot/os/arch/m68k/system_time_asm.S b/src/system/libroot/os/arch/m68k/system_time_asm.S new file mode 100644 index 0000000000..d425d756b2 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/system_time_asm.S @@ -0,0 +1,21 @@ +/* +** Copyright 2003, Axel D�fler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + +/* int64 __ppc_get_time_base(void) + * r3/r4 + */ +FUNCTION(__ppc_get_time_base): + /* get TB (time base) register */ +carry: mftbu %r3 + mftb %r4 + mftbu %r5 // read the upper half again + cmpw %r3, %r5 // and check if the values have changed + bne carry // try again, if they had + blr + diff --git a/src/system/libroot/os/arch/m68k/thread.c b/src/system/libroot/os/arch/m68k/thread.c new file mode 100644 index 0000000000..df90b6ad6a --- /dev/null +++ b/src/system/libroot/os/arch/m68k/thread.c @@ -0,0 +1,9 @@ +#include +#include "syscalls.h" + + +thread_id +find_thread(const char *name) +{ + return _kern_find_thread(name); +} diff --git a/src/system/libroot/os/arch/m68k/time.c b/src/system/libroot/os/arch/m68k/time.c new file mode 100644 index 0000000000..3b568e5bf3 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/time.c @@ -0,0 +1,42 @@ +/* + * Copyright 2006, Ingo Weinhold . + * Distributed under the terms of the MIT License. + */ + +#include + +#include +#include +#include + + +static struct arch_real_time_data *sRealTimeData; + +void +__arch_init_time(struct real_time_data *data, bool setDefaults) +{ + sRealTimeData = &data->arch_data; + + if (setDefaults) { + sRealTimeData->data[0].system_time_offset = 0; + sRealTimeData->system_time_conversion_factor = 1000000000LL; + sRealTimeData->version = 0; + } + + __ppc_setup_system_time(&sRealTimeData->system_time_conversion_factor); +} + + +bigtime_t +__arch_get_system_time_offset(struct real_time_data *data) +{ + int32 version; + bigtime_t offset; + do { + version = sRealTimeData->version; + offset = sRealTimeData->data[version % 2].system_time_offset; + } while (version != sRealTimeData->version); + + return offset; +} + diff --git a/src/system/libroot/os/arch/m68k/tls.c b/src/system/libroot/os/arch/m68k/tls.c new file mode 100644 index 0000000000..4ffd760532 --- /dev/null +++ b/src/system/libroot/os/arch/m68k/tls.c @@ -0,0 +1,53 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +// ToDo: this is a dummy implementation - I've not yet gained enough knowledge +// to decide how this should be done, so it's just broken now (okay for single +// threaded apps, though). + +// we don't want to have the inline assembly included here +#ifndef _NO_INLINE_ASM +# define _NO_INLINE_ASM 1 +#endif + +#include "support/TLS.h" +#include "tls.h" + + +static int32 gNextSlot = TLS_FIRST_FREE_SLOT; +static void *gSlots[TLS_MAX_KEYS]; + + +int32 +tls_allocate(void) +{ + int32 next = atomic_add(&gNextSlot, 1); + if (next >= TLS_MAX_KEYS) + return B_NO_MEMORY; + + return next; +} + + +void * +tls_get(int32 index) +{ + return gSlots[index]; +} + + +void ** +tls_address(int32 index) +{ + return &gSlots[index]; +} + + +void +tls_set(int32 index, void *value) +{ + gSlots[index] = value; +} +