diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2015-10-08 20:28:39 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2015-10-09 05:34:32 +0200 |
commit | 4d8e5484afb4978f672a8568ddd12e628fb02724 (patch) | |
tree | 58be2b52d5afb90974cee8303c6966fb0298f7a0 | |
parent | e78a0f58f23347c822c182d1c01f6eb9b9866d60 (diff) |
add new architecture support for or1k
Information about Openrisc:
http://opencores.org/or1k/Main_Page
Integrated from:
https://github.com/openrisc/uClibc-or1k
40 files changed, 2819 insertions, 2 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 5166efbf0..a9c01f130 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -34,6 +34,7 @@ choice default TARGET_mips if DESIRED_TARGET_ARCH = "mips" default TARGET_nios if DESIRED_TARGET_ARCH = "nios" default TARGET_nios2 if DESIRED_TARGET_ARCH = "nios2" + default TARGET_or1k if DESIRED_TARGET_ARCH = "or1k" default TARGET_powerpc if DESIRED_TARGET_ARCH = "powerpc" default TARGET_sh if DESIRED_TARGET_ARCH = "sh" default TARGET_sh64 if DESIRED_TARGET_ARCH = "sh64" @@ -107,6 +108,9 @@ config TARGET_mips config TARGET_nios2 bool "nios2" +config TARGET_or1k + bool "or1k" + config TARGET_powerpc bool "powerpc" @@ -208,6 +212,10 @@ if TARGET_mips source "extra/Configs/Config.mips" endif +if TARGET_or1k +source "extra/Configs/Config.or1k" +endif + if TARGET_powerpc source "extra/Configs/Config.powerpc" endif @@ -474,7 +482,7 @@ config LDSO_NO_CLEANUP Unless you know you need this, you should answer N. config UCLIBC_CTOR_DTOR - boolean + bool default y help If you wish to build uClibc with support for global constructor @@ -576,6 +584,7 @@ config UCLIBC_HAS_THREADS_NATIVE !TARGET_m68k && \ !TARGET_microblaze && \ !TARGET_nios2 && \ + !TARGET_or1k && \ !TARGET_vax help If you want to compile uClibc with NPTL support, then answer Y. diff --git a/extra/Configs/Config.or1k b/extra/Configs/Config.or1k new file mode 100644 index 000000000..45e6f0a57 --- /dev/null +++ b/extra/Configs/Config.or1k @@ -0,0 +1,35 @@ +# +# For a description of the syntax of this configuration file, +# see extra/config/Kconfig-language.txt +# + +config TARGET_ARCH + default "or1k" + +config ARCH_CFLAGS + string + +config ARCH_LDFLAGS + string + +config LIBGCC_CFLAGS + string + +choice + prompt "Target Architecture Type" + default CONFIG_OR1K + help + This is the architecture type of your CPU. This information is used for + optimizing purposes. + + These are the possible settings: + - or1k Generic support for OpenCores OpenRISC/or1k architecture. + +config CONFIG_OR1K + select ARCH_HAS_MMU + select UCLIBC_HAS_FPU + select ARCH_BIG_ENDIAN + select HAS_NO_THREADS + bool "or1k" + +endchoice diff --git a/extra/Configs/defconfigs/or1k/defconfig b/extra/Configs/defconfigs/or1k/defconfig new file mode 100644 index 000000000..f8b8d2b33 --- /dev/null +++ b/extra/Configs/defconfigs/or1k/defconfig @@ -0,0 +1,245 @@ +# +# Automatically generated make config: don't edit +# Version: 0.9.34-git +# Wed Oct 10 16:27:15 2012 +# +# TARGET_alpha is not set +# TARGET_arm is not set +# TARGET_avr32 is not set +# TARGET_bfin is not set +# TARGET_c6x is not set +# TARGET_cris is not set +# TARGET_e1 is not set +# TARGET_frv is not set +# TARGET_h8300 is not set +# TARGET_hppa is not set +# TARGET_i386 is not set +# TARGET_i960 is not set +# TARGET_ia64 is not set +# TARGET_m68k is not set +# TARGET_microblaze is not set +# TARGET_mips is not set +# TARGET_nios is not set +# TARGET_nios2 is not set +TARGET_or1k=y +# TARGET_powerpc is not set +# TARGET_sh is not set +# TARGET_sh64 is not set +# TARGET_sparc is not set +# TARGET_v850 is not set +# TARGET_vax is not set +# TARGET_x86_64 is not set +# TARGET_xtensa is not set + +# +# Target Architecture Features and Options +# +TARGET_ARCH="or1k" +CONFIG_OR1K=y +TARGET_SUBARCH="" + +# +# Using ELF file format +# +ARCH_BIG_ENDIAN=y + +# +# Using Big Endian +# +ARCH_HAS_MMU=y +ARCH_USE_MMU=y +UCLIBC_HAS_FLOATS=y +UCLIBC_HAS_FPU=y +DO_C99_MATH=y +# DO_XSI_MATH is not set +# UCLIBC_HAS_FENV is not set +KERNEL_HEADERS="${SYSROOT}/usr/include" +HAVE_DOT_CONFIG=y + +# +# General Library Settings +# +DOPIC=y +HAVE_SHARED=y +# FORCE_SHAREABLE_TEXT_SEGMENTS is not set +LDSO_LDD_SUPPORT=y +LDSO_CACHE_SUPPORT=y +LDSO_PRELOAD_ENV_SUPPORT=y +# LDSO_PRELOAD_FILE_SUPPORT is not set +LDSO_BASE_FILENAME="ld.so" +# LDSO_STANDALONE_SUPPORT is not set +# LDSO_PRELINK_SUPPORT is not set +UCLIBC_STATIC_LDCONFIG=y +LDSO_RUNPATH=y +LDSO_SEARCH_INTERP_PATH=y +LDSO_LD_LIBRARY_PATH=y +# LDSO_NO_CLEANUP is not set +UCLIBC_CTOR_DTOR=y +# LDSO_GNU_HASH_SUPPORT is not set +# HAS_NO_THREADS is not set +LINUXTHREADS_OLD=y +# LINUXTHREADS_NEW is not set +# UCLIBC_HAS_THREADS_NATIVE is not set +UCLIBC_HAS_THREADS=y +# PTHREADS_DEBUG_SUPPORT is not set +UCLIBC_HAS_SYSLOG=y +UCLIBC_HAS_LFS=y +# MALLOC is not set +# MALLOC_SIMPLE is not set +MALLOC_STANDARD=y +# MALLOC_GLIBC_COMPAT is not set +# UCLIBC_DYNAMIC_ATEXIT is not set +COMPAT_ATEXIT=y +UCLIBC_SUSV3_LEGACY=y +# UCLIBC_SUSV3_LEGACY_MACROS is not set +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_STRICT_HEADERS is not set +# UCLIBC_HAS_STUBS is not set +UCLIBC_HAS_SHADOW=y +UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y +UCLIBC_HAS___PROGNAME=y +UCLIBC_HAS_PTY=y +ASSUME_DEVPTS=y +UNIX98PTY_ONLY=y +# UCLIBC_HAS_GETPT is not set +# UCLIBC_HAS_LIBUTIL is not set +UCLIBC_HAS_TM_EXTENSIONS=y +UCLIBC_HAS_TZ_CACHING=y +UCLIBC_HAS_TZ_FILE=y +UCLIBC_HAS_TZ_FILE_READ_MANY=y +UCLIBC_TZ_FILE_PATH="/etc/TZ" +UCLIBC_FALLBACK_TO_ETC_LOCALTIME=y + +# +# Advanced Library Settings +# +UCLIBC_PWD_BUFFER_SIZE=256 +UCLIBC_GRP_BUFFER_SIZE=256 + +# +# Support various families of functions +# +UCLIBC_LINUX_MODULE_26=y +UCLIBC_LINUX_MODULE_24=y +UCLIBC_LINUX_SPECIFIC=y +UCLIBC_HAS_GNU_ERROR=y +UCLIBC_BSD_SPECIFIC=y +UCLIBC_HAS_BSD_ERR=y +# UCLIBC_HAS_OBSOLETE_BSD_SIGNAL is not set +# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set +# UCLIBC_NTP_LEGACY is not set +# UCLIBC_SV4_DEPRECATED is not set +UCLIBC_HAS_REALTIME=y +UCLIBC_HAS_ADVANCED_REALTIME=y +UCLIBC_HAS_EPOLL=y +UCLIBC_HAS_XATTR=y +UCLIBC_HAS_PROFILING=y +UCLIBC_HAS_CRYPT_IMPL=y +# UCLIBC_HAS_SHA256_CRYPT_IMPL is not set +# UCLIBC_HAS_SHA512_CRYPT_IMPL is not set +UCLIBC_HAS_CRYPT=y +UCLIBC_HAS_NETWORK_SUPPORT=y +UCLIBC_HAS_SOCKET=y +UCLIBC_HAS_IPV4=y +UCLIBC_HAS_IPV6=y +UCLIBC_HAS_RPC=y +UCLIBC_HAS_FULL_RPC=y +UCLIBC_HAS_REENTRANT_RPC=y +# UCLIBC_USE_NETLINK is not set +# UCLIBC_HAS_BSD_RES_CLOSE is not set +UCLIBC_HAS_COMPAT_RES_STATE=y +# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set +# UCLIBC_HAS_RESOLVER_SUPPORT is not set +# UCLIBC_HAS_LIBRESOLV_STUB is not set +# UCLIBC_HAS_LIBNSL_STUB is not set + +# +# String and Stdio Support +# +UCLIBC_HAS_STRING_GENERIC_OPT=y +UCLIBC_HAS_STRING_ARCH_OPT=y +UCLIBC_HAS_CTYPE_TABLES=y +UCLIBC_HAS_CTYPE_SIGNED=y +UCLIBC_HAS_CTYPE_UNSAFE=y +# UCLIBC_HAS_CTYPE_CHECKED is not set +# UCLIBC_HAS_CTYPE_ENFORCED is not set +UCLIBC_HAS_WCHAR=y +# UCLIBC_HAS_LOCALE is not set +# UCLIBC_HAS_HEXADECIMAL_FLOATS is not set +# UCLIBC_HAS_GLIBC_CUSTOM_PRINTF is not set +UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9 +# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set +# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set +UCLIBC_HAS_STDIO_BUFSIZ_4096=y +# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set +UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set +# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set +UCLIBC_HAS_STDIO_GETC_MACRO=y +UCLIBC_HAS_STDIO_PUTC_MACRO=y +UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y +# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set +# UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE is not set +# UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE is not set +# UCLIBC_HAS_GLIBC_CUSTOM_STREAMS is not set +# UCLIBC_HAS_PRINTF_M_SPEC is not set +UCLIBC_HAS_ERRNO_MESSAGES=y +# UCLIBC_HAS_SYS_ERRLIST is not set +UCLIBC_HAS_SIGNUM_MESSAGES=y +# UCLIBC_HAS_SYS_SIGLIST is not set +UCLIBC_HAS_GNU_GETOPT=y +UCLIBC_HAS_GNU_GETSUBOPT=y + +# +# Big and Tall +# +UCLIBC_HAS_REGEX=y +UCLIBC_HAS_REGEX_OLD=y +UCLIBC_HAS_FNMATCH=y +UCLIBC_HAS_FNMATCH_OLD=y +# UCLIBC_HAS_WORDEXP is not set +# UCLIBC_HAS_NFTW is not set +# UCLIBC_HAS_FTW is not set +# UCLIBC_HAS_FTS is not set +UCLIBC_HAS_GLOB=y +# UCLIBC_HAS_GNU_GLOB is not set +# UCLIBC_HAS_UTMPX is not set + +# +# Library Installation Options +# +RUNTIME_PREFIX="/" +DEVEL_PREFIX="/usr" +MULTILIB_DIR="lib" +HARDWIRED_ABSPATH=y + +# +# Security options +# +# UCLIBC_HAS_ARC4RANDOM is not set +# UCLIBC_HAS_SSP is not set +UCLIBC_BUILD_RELRO=y +# UCLIBC_BUILD_NOW is not set +UCLIBC_BUILD_NOEXECSTACK=y + +# +# Development/debugging options +# +CROSS_COMPILER_PREFIX="or1k-linux-uclibc-" +UCLIBC_EXTRA_CFLAGS="" +# DODEBUG is not set +# DODEBUG_PT is not set +# DOSTRIP is not set +# DOASSERTS is not set +# SUPPORT_LD_DEBUG is not set +# SUPPORT_LD_DEBUG_EARLY is not set +# UCLIBC_MALLOC_DEBUGGING is not set +# UCLIBC_HAS_BACKTRACE is not set +WARNINGS="-Wall" +# EXTRA_WARNINGS is not set +# DOMULTI is not set +# UCLIBC_MJN3_ONLY is not set diff --git a/include/elf.h b/include/elf.h index 18d286b03..ed952664f 100644 --- a/include/elf.h +++ b/include/elf.h @@ -257,7 +257,7 @@ typedef struct #define EM_MN10300 89 /* Matsushita MN10300 */ #define EM_MN10200 90 /* Matsushita MN10200 */ #define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_OR1K 92 /* OpenRISC 32-bit embedded processor */ #define EM_ARCOMPACT 93 /* ARCompact ISA based Cores: ARC 700 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_IP2K 101 /* Ubicom IP2022 micro controller */ @@ -3188,6 +3188,30 @@ typedef Elf32_Addr Elf32_Conflict; #define R_METAG_TLS_DTPMOD 57 #define R_METAG_TLS_DTPOFF 58 +/* OpenRISC 1000 specific relocs */ +#define R_OR1K_NONE 0 +#define R_OR1K_32 1 +#define R_OR1K_16 2 +#define R_OR1K_8 3 +#define R_OR1K_LO_16_IN_INSN 4 +#define R_OR1K_HI_16_IN_INSN 5 +#define R_OR1K_INSN_REL_26 6 +#define R_OR1K_GNU_VTENTRY 7 +#define R_OR1K_GNU_VTINHERIT 8 +#define R_OR1K_32_PCREL 9 +#define R_OR1K_16_PCREL 10 +#define R_OR1K_8_PCREL 11 +#define R_OR1K_GOTPC_HI16 12 +#define R_OR1K_GOTPC_LO16 13 +#define R_OR1K_GOT16 14 +#define R_OR1K_PLT26 15 +#define R_OR1K_GOTOFF_HI16 16 +#define R_OR1K_GOTOFF_LO16 17 +#define R_OR1K_COPY 18 +#define R_OR1K_GLOB_DAT 19 +#define R_OR1K_JMP_SLOT 20 +#define R_OR1K_RELATIVE 21 + /* ARCompact specific relocs */ #define R_ARC_NONE 0x0 #define R_ARC_8 0x1 diff --git a/ldso/ldso/or1k/dl-debug.h b/ldso/ldso/or1k/dl-debug.h new file mode 100644 index 000000000..d925577cd --- /dev/null +++ b/ldso/ldso/or1k/dl-debug.h @@ -0,0 +1,53 @@ +/* OpenRISC 1000 shared library loader suppport + * + * Copyright (C) 2012 Stefan Kristansson + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the above contributors may not be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``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 CONTRIBUTORS 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. + */ + +static const char * const _dl_reltypes_tab[] = + { + "R_OR1K_NONE", + "R_OR1K_32", + "R_OR1K_16", + "R_OR1K_8", + "R_OR1K_LO_16_IN_INSN", + "R_OR1K_HI_16_IN_INSN", + "R_OR1K_INSN_REL_26", + "R_OR1K_GNU_VTENTRY", + "R_OR1K_GNU_VTINHERIT", + "R_OR1K_32_PCREL", + "R_OR1K_16_PCREL", + "R_OR1K_8_PCREL", + "R_OR1K_GOTPC_HI16", + "R_OR1K_GOTPC_LO16", + "R_OR1K_GOT16", + "R_OR1K_PLT26", + "R_OR1K_GOTOFF_HI16", + "R_OR1K_GOTOFF_LO16", + "R_OR1K_COPY", + "R_OR1K_GLOB_DAT", + "R_OR1K_JMP_SLOT", + "R_OR1K_RELATIVE", + }; diff --git a/ldso/ldso/or1k/dl-startup.h b/ldso/ldso/or1k/dl-startup.h new file mode 100644 index 000000000..3c99bcd5c --- /dev/null +++ b/ldso/ldso/or1k/dl-startup.h @@ -0,0 +1,106 @@ +/* Startup code for the OpenRISC 1000 platform, + based on microblaze implementation */ +/* + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +__asm__ ("\ + .text\n\ + .globl _start\n\ + .type _start,@function\n\ + .hidden _start\n\ +_start:\n\ + l.ori r3, r9, 0\n\ + l.ori r3, r1, 0\n\ + l.movhi r11, 0\n\ +1:\n\ + l.addi r3, r3, 4\n\ + l.lwz r12, 0(r3)\n\ + l.sfnei r12, 0\n\ + l.addi r11, r11, 1\n\ + l.bf 1b\n\ + l.nop\n\ + l.ori r3, r11, 0\n\ + l.ori r3, r1, 0\n\ + l.addi r11, r11, -1\n\ + /* store argument counter to stack */\n\ + l.sw 0(r3), r11\n\ + l.addi r1, r1, -24\n\ + l.sw 0(r1), r9\n\ +\n\ + l.jal .LPC0\n\ +#ifndef __OR1K_NODELAY__\n\ + l.nop\n\ +#endif\n\ + /* Load the PIC register */\n\ +.LPC0:\n\ + l.movhi r16, gotpchi(_GLOBAL_OFFSET_TABLE_+(.-.LPC0))\n\ + l.ori r16, r16, gotpclo(_GLOBAL_OFFSET_TABLE_+(.-.LPC0))\n\ + l.add r16, r16, r9\n\ +\n\ + l.jal _dl_start\n\ + l.nop\n\ + /* FALLTHRU */\n\ +\n\ + .globl _dl_start_user\n\ + .type _dl_start_user,@function\n\ +_dl_start_user:\n\ + l.movhi r12, gotoffhi(_dl_skip_args)\n\ + l.ori r12, r12, gotofflo(_dl_skip_args)\n\ + l.add r12, r12, r16\n\ + l.lwz r12, 0(r12)\n\ + l.lwz r3, 24(r1)\n\ +\n\ + l.movhi r9, gotoffhi(_dl_fini)\n\ + l.ori r9, r9, gotofflo(_dl_fini)\n\ + l.add r9, r9, r16\n\ +\n\ + l.addi r9, r9, -8\n\ + l.addi r1, r1, 24\n\ + l.jr r11\n\ + l.nop\n\ + .size _dl_start_user, . - _dl_start_user\n\ + .previous\n\ +"); +/* + * Get a pointer to the argv array. On many platforms this can be just + * the address of the first argument, on other platforms we need to + * do something a little more subtle here. + */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1) + +/* The ld.so library requires relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + +static __always_inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, + attribute_unused Elf32_Sym *symtab) +{ + + switch (ELF_R_TYPE(rpnt->r_info)) + { + case R_OR1K_RELATIVE: + + *reloc_addr = load_addr + rpnt->r_addend; + break; + + default: + _dl_exit(1); + break; + + } + +} diff --git a/ldso/ldso/or1k/dl-syscalls.h b/ldso/ldso/or1k/dl-syscalls.h new file mode 100644 index 000000000..f40c4fd31 --- /dev/null +++ b/ldso/ldso/or1k/dl-syscalls.h @@ -0,0 +1 @@ +/* stub for arch-specific syscall issues */ diff --git a/ldso/ldso/or1k/dl-sysdep.h b/ldso/ldso/or1k/dl-sysdep.h new file mode 100644 index 000000000..21ca028c8 --- /dev/null +++ b/ldso/ldso/or1k/dl-sysdep.h @@ -0,0 +1,105 @@ +/* elf reloc code for the or1k platform, based on glibc 2.3.6, dl-machine.h */ + +/* + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Use reloca */ +#define ELF_USES_RELOCA + +#include <elf.h> + + +/* Initialise the GOT */ +#define INIT_GOT(GOT_BASE,MODULE) \ +do { \ + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ + GOT_BASE[1] = (unsigned long) MODULE; \ +} while(0) + +/* Here we define the magic numbers that this dynamic loader should accept */ + +#define MAGIC1 EM_OR1K +#undef MAGIC2 +/* Used for error messages */ +#define ELF_TARGET "or1k" + +#define elf_machine_type_class(type) \ + (((type) == R_OR1K_JMP_SLOT) * ELF_RTYPE_CLASS_PLT \ + | ((type) == R_OR1K_COPY) * ELF_RTYPE_CLASS_COPY) + +static inline Elf32_Addr * +or1k_get_got (void) +{ + Elf32_Addr *got; + Elf32_Addr linkreg; + __asm__("l.ori %0, r9, 0\n" + "l.jal .LPC1\n" +#ifndef __OR1K_NODELAY__ + "l.nop\n" +#endif + ".LPC1:\n" + "l.movhi %1, gotpchi(_GLOBAL_OFFSET_TABLE_+(.-.LPC1))\n" + "l.ori %1, %1, gotpclo(_GLOBAL_OFFSET_TABLE_+(.-.LPC1))\n" + "l.add %1, %1, r9\n" + "l.ori r9, %0, 0\n" + : "=r" (linkreg), "=r" (got)); + return got; +} + +/* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. */ +static inline Elf32_Addr +elf_machine_dynamic (void) +{ + Elf32_Addr *got = or1k_get_got(); + return *got; +} + + +/* Return the run-time load address of the shared object. */ +static inline Elf32_Addr +elf_machine_load_address (void) +{ + /* Compute the difference between the runtime address of _DYNAMIC as seen + by a GOTOFF reference, and the link-time address found in the special + unrelocated first GOT entry. */ + Elf32_Addr dyn; + Elf32_Addr *got = or1k_get_got(); + + __asm__ __volatile__ ( + "l.movhi %0, gotoffhi(_DYNAMIC);" + "l.ori %0, %0, gotofflo(_DYNAMIC);" + "l.add %0, %0, %1;" + : "=r"(dyn), "=r"(got) + ); + return dyn - *got; +} + + + +static __always_inline void +elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) +{ + Elf32_Rela * rpnt = (void *) rel_addr; + --rpnt; + do { + Elf32_Addr *const reloc_addr = (void *) (load_off + + (++rpnt)->r_offset); + + *reloc_addr += load_off; + } while (--relative_count); +} diff --git a/ldso/ldso/or1k/elfinterp.c b/ldso/ldso/or1k/elfinterp.c new file mode 100644 index 000000000..928e95ba1 --- /dev/null +++ b/ldso/ldso/or1k/elfinterp.c @@ -0,0 +1,333 @@ +/* vi: set sw=4 ts=4: */ +/* OpenRISC 1000 ELF shared library loader suppport + * + * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, + * David Engel, Hongjiu Lu and Mitch D'Souza + * Copyright (C) 2001-2004 Erik Andersen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the above contributors may not be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``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 CONTRIBUTORS 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 "ldso.h" + +/* Program to load an ELF binary on a linux system, and run it. + References to symbols in sharable libraries can be resolved by either + an ELF sharable library or a linux style of shared library. */ + +/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have + I ever taken any courses on internals. This program was developed using + information available through the book "UNIX SYSTEM V RELEASE 4, + Programmers guide: Ansi C and Programming Support Tools", which did + a more than adequate job of explaining everything required to get this + working. */ + +extern int _dl_linux_resolve(void); + +unsigned long +_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) +{ + ELF_RELOC *this_reloc; + char *strtab; + ElfW(Sym) *symtab; + int symtab_index; + char *rel_addr; + char *new_addr; + char **got_addr; + ElfW(Addr) instr_addr; + char *symname; + + rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; + this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry); + symtab_index = ELF_R_SYM(this_reloc->r_info); + + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB]; + strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; + symname = strtab + symtab[symtab_index].st_name; + + /* Address of the jump instruction to fix up. */ + instr_addr = (this_reloc->r_offset + tpnt->loadaddr); + got_addr = (char **)instr_addr; + + /* Get the address of the GOT entry. */ + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); + if (unlikely(!new_addr)) { + _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", + _dl_progname, symname, tpnt->libname); + _dl_exit(1); + } + +#if defined (__SUPPORT_LD_DEBUG__) + if ((unsigned long)got_addr < 0x40000000) { + if (_dl_debug_bindings) { + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); + if (_dl_debug_detail) + _dl_dprintf(_dl_debug_file, + "\tpatched: %x ==> %x @ %x\n", + *got_addr, new_addr, got_addr); + } + } + if (!_dl_debug_nofixups) +#endif + *got_addr = new_addr; + + return (unsigned long)new_addr; +} + +static int +_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, + unsigned long rel_addr, unsigned long rel_size, + int (*reloc_fnc)(struct elf_resolve *tpnt, struct r_scope_elem *scope, + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) +{ + unsigned int i; + char *strtab; + ElfW(Sym) *symtab; + ELF_RELOC *rpnt; + int symtab_index; + + /* Parse the relocation information. */ + rpnt = (ELF_RELOC *)rel_addr; + rel_size /= sizeof(ELF_RELOC); + + symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB]; + strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; + + for (i = 0; i < rel_size; i++, rpnt++) { + int res; + + symtab_index = ELF_R_SYM(rpnt->r_info); + + debug_sym(symtab, strtab, symtab_index); + debug_reloc(symtab, strtab, rpnt); + + res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab); + + if (res == 0) + continue; + + _dl_dprintf(2, "\n%s: ", _dl_progname); + + if (symtab_index) + _dl_dprintf(2, "symbol '%s': ", + strtab + symtab[symtab_index].st_name); + + if (unlikely(res < 0)) { + int reloc_type = ELF_R_TYPE(rpnt->r_info); + + _dl_dprintf(2, "can't handle reloc type " +#if defined (__SUPPORT_LD_DEBUG__) + "%s\n", _dl_reltypes(reloc_type)); +#else + "%x\n", reloc_type); +#endif + _dl_exit(-res); + } else if (unlikely(res > 0)) { + _dl_dprintf(2, "can't resolve symbol\n"); + return res; + } + } + + return 0; +} + +static int +_dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) +{ + int reloc_type; + int symtab_index; + char *symname; +#if defined USE_TLS && USE_TLS + struct elf_resolve *tls_tpnt; +#endif + struct symbol_ref sym_ref; + ElfW(Addr) *reloc_addr; + ElfW(Addr) symbol_addr; +#if defined (__SUPPORT_LD_DEBUG__) + ElfW(Addr) old_val; +#endif + + struct unaligned { + Elf32_Addr x; + } __attribute__ ((packed, may_alias)); + + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); + reloc_type = ELF_R_TYPE(rpnt->r_info); + symtab_index = ELF_R_SYM(rpnt->r_info); + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; + symbol_addr = 0; + symname = strtab + sym_ref.sym->st_name; + + if (symtab_index) { + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, + elf_machine_type_class(reloc_type), &sym_ref); + /* + * We want to allow undefined references to weak symbols - this + * might have been intentional. We should not be linking local + * symbols here, so all bases should be covered. + */ + if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym_ref.sym->st_info) != STT_TLS) + && (ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK))) { + /* This may be non-fatal if called from dlopen. */ + return 1; + } +#if defined USE_TLS && USE_TLS + tls_tpnt = sym_ref.tpnt; +#endif + } else { + /* Relocs against STN_UNDEF are usually treated as using a + * symbol value of zero, and using the module containing the + * reloc itself. */ + symbol_addr = sym_ref.sym->st_value; +#if defined USE_TLS && USE_TLS + tls_tpnt = tpnt; +#endif + } + + +#if defined (__SUPPORT_LD_DEBUG__) + if (reloc_addr) { + old_val = ((struct unaligned *)reloc_addr)->x; + } else { + old_val = 0; + } +#endif + + switch (reloc_type) { + case R_OR1K_NONE: + break; + + case R_OR1K_8: + case R_OR1K_16: + case R_OR1K_32: + /* Support relocations on mis-aligned offsets. */ + ((struct unaligned *)reloc_addr)->x = symbol_addr + + rpnt->r_addend; + break; + + case R_OR1K_8_PCREL: + case R_OR1K_16_PCREL: + case R_OR1K_32_PCREL: + case R_OR1K_INSN_REL_26: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; + + case R_OR1K_GLOB_DAT: + case R_OR1K_JMP_SLOT: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; +/* Handled by elf_machine_relative */ + case R_OR1K_RELATIVE: + *reloc_addr = (unsigned long)tpnt->loadaddr + rpnt->r_addend; + break; + + case R_OR1K_COPY: + if (symbol_addr) { +#if defined (__SUPPORT_LD_DEBUG__) + if (_dl_debug_move) + _dl_dprintf(_dl_debug_file, + "\t%s move %d bytes from %x to %x\n", + symname, sym_ref.sym->st_size, + symbol_addr, reloc_addr); +#endif + + _dl_memcpy((char *)reloc_addr, + (char *)symbol_addr, + sym_ref.sym->st_size); + } +#if defined (__SUPPORT_LD_DEBUG__) + else + _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); +#endif + break; + + default: + return -1; /* Calls _dl_exit(1). */ + } + +#if defined (__SUPPORT_LD_DEBUG__) + if (_dl_debug_reloc && _dl_debug_detail) + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", + old_val, ((struct unaligned *)reloc_addr)->x, + reloc_addr); +#endif + + return 0; +} + +static int +_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, + ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) +{ + int reloc_type; + int symtab_index; + ElfW(Addr) *reloc_addr; +#if defined (__SUPPORT_LD_DEBUG__) + ElfW(Addr) old_val; +#endif + + (void)scope; + symtab_index = ELF_R_SYM(rpnt->r_info); + (void)strtab; + + reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset); + reloc_type = ELF_R_TYPE(rpnt->r_info); + +#if defined (__SUPPORT_LD_DEBUG__) + old_val = *reloc_addr; +#endif + + switch (reloc_type) { + case R_OR1K_NONE: + break; + case R_OR1K_JMP_SLOT: + *reloc_addr += (unsigned long)tpnt->loadaddr; + break; + default: + _dl_exit(1); + } + +#if defined (__SUPPORT_LD_DEBUG__) + if (_dl_debug_reloc && _dl_debug_detail) + _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n", + old_val, *reloc_addr, reloc_addr); +#endif + + return 0; +} + +void +_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, + unsigned long rel_addr, unsigned long rel_size) +{ + (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); +} + +int +_dl_parse_relocation_information(struct dyn_elf *rpnt, + struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) +{ + return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); +} diff --git a/ldso/ldso/or1k/resolve.S b/ldso/ldso/or1k/resolve.S new file mode 100644 index 000000000..4a156d529 --- /dev/null +++ b/ldso/ldso/or1k/resolve.S @@ -0,0 +1,54 @@ +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ +/* We assume that R11 contain relocation offset and R12 contains + link_map (_DYNAMIC). This must be consistent with the JUMP_SLOT + layout generated by binutils. */ + +/* Based on microblaze implementation */ +/* + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +.text +.align 4 +.globl _dl_linux_resolver +.globl _dl_linux_resolve +.type _dl_linux_resolve,@function + +_dl_linux_resolve: + l.addi r1, r1, -32 + l.sw 0(r1), r9 + /* save function arguments */ + l.sw 8(r1), r3 + l.sw 12(r1), r4 + l.sw 16(r1), r5 + l.sw 20(r1), r6 + l.sw 24(r1), r7 + l.sw 28(r1), r8 + l.ori r3, r12, 0 + l.ori r4, r11, 0 + l.jal _dl_linux_resolver + l.nop + l.lwz r8, 28(r1) + l.lwz r7, 24(r1) + l.lwz r6, 20(r1) + l.lwz r5, 16(r1) + l.lwz r4, 12(r1) + l.lwz r3, 8(r1) + l.lwz r9, 0(r1) + l.addi r1, r1, 32 + l.jr r11 + l.nop + .size _dl_linux_resolve, . - _dl_linux_resolve diff --git a/libc/sysdeps/linux/or1k/Makefile b/libc/sysdeps/linux/or1k/Makefile new file mode 100644 index 000000000..633c91f3e --- /dev/null +++ b/libc/sysdeps/linux/or1k/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../../ +top_builddir=../../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.arch +include $(top_srcdir)Makerules diff --git a/libc/sysdeps/linux/or1k/Makefile.arch b/libc/sysdeps/linux/or1k/Makefile.arch new file mode 100644 index 000000000..53d4ed576 --- /dev/null +++ b/libc/sysdeps/linux/or1k/Makefile.arch @@ -0,0 +1,9 @@ +# Makefile for uClibc +# +# Copyright (C) 2010 Jonas Bonn <jonas@southpole.se> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +CSRC-y := __syscall_error.c __init_brk.c brk.c sbrk.c clone.c +SSRC-y := __longjmp.S setjmp.S diff --git a/libc/sysdeps/linux/or1k/__init_brk.c b/libc/sysdeps/linux/or1k/__init_brk.c new file mode 100644 index 000000000..4c6763fdd --- /dev/null +++ b/libc/sysdeps/linux/or1k/__init_brk.c @@ -0,0 +1,28 @@ +/* From libc-5.3.12 */ + +#include <errno.h> +#include <unistd.h> +#include <sys/syscall.h> + +void * ___brk_addr = 0; + +int __init_brk (void); +void *_brk(void *ptr); + +#define __NR__brk __NR_brk +_syscall1(void *, _brk, void *, ptr); + +int +__init_brk (void) +{ + if (___brk_addr == 0) + { + ___brk_addr = _brk(0); + if (___brk_addr == 0) + { + __set_errno(ENOMEM); + return -1; + } + } + return 0; +} diff --git a/libc/sysdeps/linux/or1k/__longjmp.S b/libc/sysdeps/linux/or1k/__longjmp.S new file mode 100644 index 000000000..1eb5bb403 --- /dev/null +++ b/libc/sysdeps/linux/or1k/__longjmp.S @@ -0,0 +1,81 @@ +/* longjmp for or1k + + Based on: + longjmp for PowerPC. + Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <jmpbuf-offsets.h> + +#ifdef __UCLIBC_HAS_FLOATS__ +#define FP(x...) x +#else +#define FP(x...) +#endif + +.globl __longjmp; +.type __longjmp,@function; +.align 2; + +__longjmp: +# l.lwz r11,(JB_SR*4)(r3) +# l.mtspr r0,r11,SPR_SR + l.lwz r1,((JB_GPRS+0)*4)(r3) + l.lwz r2,((JB_GPRS+1)*4)(r3) + /* pass through "value" to r11, then restore r4, for what it's worth" */ +#if 1 + /* if r4 is 0, something wrong, so set it to 1 */ + l.sfeqi r4, 0x0 + l.bnf 1f /* r4 != 0, longjmp value sensible */ + l.nop + l.ori r4, r0, 0x1 /* make nonzero */ +1: +#endif + l.addi r11, r4, 0 + l.lwz r4,((JB_GPRS+3)*4)(r3) + l.lwz r5,((JB_GPRS+4)*4)(r3) + l.lwz r6,((JB_GPRS+5)*4)(r3) + l.lwz r7,((JB_GPRS+6)*4)(r3) + l.lwz r8,((JB_GPRS+7)*4)(r3) + l.lwz r9,((JB_GPRS+8)*4)(r3) + l.lwz r10,((JB_GPRS+9)*4)(r3) + l.lwz r12,((JB_GPRS+11)*4)(r3) + l.lwz r13,((JB_GPRS+12)*4)(r3) + l.lwz r14,((JB_GPRS+13)*4)(r3) + l.lwz r15,((JB_GPRS+14)*4)(r3) + l.lwz r16,((JB_GPRS+15)*4)(r3) + l.lwz r17,((JB_GPRS+16)*4)(r3) + l.lwz r18,((JB_GPRS+17)*4)(r3) + l.lwz r19,((JB_GPRS+18)*4)(r3) + l.lwz r20,((JB_GPRS+19)*4)(r3) + l.lwz r21,((JB_GPRS+20)*4)(r3) + l.lwz r22,((JB_GPRS+21)*4)(r3) + l.lwz r23,((JB_GPRS+22)*4)(r3) + l.lwz r24,((JB_GPRS+23)*4)(r3) + l.lwz r25,((JB_GPRS+24)*4)(r3) + l.lwz r26,((JB_GPRS+25)*4)(r3) + l.lwz r27,((JB_GPRS+26)*4)(r3) + l.lwz r28,((JB_GPRS+27)*4)(r3) + l.lwz r29,((JB_GPRS+28)*4)(r3) + l.lwz r30,((JB_GPRS+29)*4)(r3) + l.lwz r31,((JB_GPRS+30)*4)(r3) + l.jr r9 + l.nop +.size __longjmp,.-__longjmp + +libc_hidden_def(__longjmp) diff --git a/libc/sysdeps/linux/or1k/__syscall_error.c b/libc/sysdeps/linux/or1k/__syscall_error.c new file mode 100644 index 000000000..ef8307893 --- /dev/null +++ b/libc/sysdeps/linux/or1k/__syscall_error.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> + +int __syscall_error (int err_no); + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int __syscall_error (int err_no) +{ + __set_errno (err_no); + return -1; +} + diff --git a/libc/sysdeps/linux/or1k/bits/endian.h b/libc/sysdeps/linux/or1k/bits/endian.h new file mode 100644 index 000000000..799e27a6b --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/endian.h @@ -0,0 +1,25 @@ +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* or1k can be little or big endian. Hopefully gcc will know... */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/libc/sysdeps/linux/or1k/bits/fcntl.h b/libc/sysdeps/linux/or1k/bits/fcntl.h new file mode 100644 index 000000000..b0813001b --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/fcntl.h @@ -0,0 +1,236 @@ +/* O_*, F_*, FD_* bit values for Linux. + Copyright (C) 1995-1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _FCNTL_H +# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." +#endif + + +#include <sys/types.h> +#ifdef __USE_GNU +# include <bits/uio.h> +#endif + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define O_FSYNC O_SYNC +#define O_ASYNC 020000 + +#ifdef __USE_GNU +# define O_DIRECT 040000 /* Direct disk access. */ +# define O_DIRECTORY 0200000 /* Must be a directory. */ +# define O_NOFOLLOW 0400000 /* Do not follow links. */ +# define O_NOATIME 01000000 /* Do not set atime. */ +# define O_CLOEXEC 02000000 /* Set close_on_exec. */ +#endif + +#ifdef __USE_LARGEFILE64 +# define O_LARGEFILE 0100000 +#endif + +/* For now Linux has synchronisity options for data and read operations. + We define the symbols here but let them do the same as O_SYNC since + this is a superset. */ +#if defined __USE_POSIX199309 || defined __USE_UNIX98 +# define O_DSYNC O_SYNC /* Synchronize data. */ +# define O_RSYNC O_SYNC /* Synchronize read operations. */ +#endif + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ + +#ifndef __USE_FILE_OFFSET64 +# define F_GETLK 5 /* Get record locking info. */ +# define F_SETLK 6 /* Set record locking info (non-blocking). */ +# define F_SETLKW 7 /* Set record locking info (blocking). */ +#else +# define F_GETLK F_GETLK64 /* Get record locking info. */ +# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/ +# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */ +#endif + +#define F_GETLK64 12 /* Get record locking info. */ +#define F_SETLK64 13 /* Set record locking info (non-blocking). */ +#define F_SETLKW64 14 /* Set record locking info (blocking). */ + +#if defined __USE_BSD || defined __USE_XOPEN2K +# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */ +# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */ +#endif + +#ifdef __USE_GNU +# define F_SETSIG 10 /* Set number of signal to be sent. */ +# define F_GETSIG 11 /* Get number of signal to be sent. */ +#endif + +#ifdef __USE_GNU +# define F_SETLEASE 1024 /* Set a lease. */ +# define F_GETLEASE 1025 /* Enquire what lease is active. */ +# define F_NOTIFY 1026 /* Request notfications on a directory. */ +#endif + +/* For F_[GET|SET]FL. */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ +#define F_RDLCK 0 /* Read lock. */ +#define F_WRLCK 1 /* Write lock. */ +#define F_UNLCK 2 /* Remove lock. */ + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +#ifdef __USE_BSD +/* Operations for bsd flock(), also used by the kernel implementation */ +# define LOCK_SH 1 /* shared lock */ +# define LOCK_EX 2 /* exclusive lock */ +# define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +# define LOCK_UN 8 /* remove lock */ +#endif + +#ifdef __USE_GNU +# define LOCK_MAND 32 /* This is a mandatory flock: */ +# define LOCK_READ 64 /* ... which allows concurrent read operations. */ +# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */ +# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */ +#endif + +#ifdef __USE_GNU +/* Types of directory notifications that may be requested with F_NOTIFY. */ +# define DN_ACCESS 0x00000001 /* File accessed. */ +# define DN_MODIFY 0x00000002 /* File modified. */ +# define DN_CREATE 0x00000004 /* File created. */ +# define DN_DELETE 0x00000008 /* File removed. */ +# define DN_RENAME 0x00000010 /* File renamed. */ +# define DN_ATTRIB 0x00000020 /* File changed attibutes. */ +# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */ +#endif + +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ +#ifndef __USE_FILE_OFFSET64 + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ +#else + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ +#endif + __pid_t l_pid; /* Process holding the lock. */ + }; + +#ifdef __USE_LARGEFILE64 +struct flock64 + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; +#endif + +/* Define some more compatibility macros to be backward compatible with + BSD systems which did not managed to hide these kernel macros. */ +#ifdef __USE_BSD +# define FAPPEND O_APPEND +# define FFSYNC O_FSYNC +# define FASYNC O_ASYNC +# define FNONBLOCK O_NONBLOCK +# define FNDELAY O_NDELAY +#endif /* Use BSD. */ + +/* Advise to `posix_fadvise'. */ +#ifdef __USE_XOPEN2K +# define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif + +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ +/* Flags for SYNC_FILE_RANGE. */ +# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages + in the range before performing the + write. */ +# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those + dirty pages in the range which are + not presently under writeback. */ +# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in + the range after performing the + write. */ + +/* Flags for SPLICE and VMSPLICE. */ +# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */ +# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing + (but we may still block on the fd + we splice from/to). */ +# define SPLICE_F_MORE 4 /* Expect more data. */ +# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */ +#endif + +__BEGIN_DECLS + +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ + +/* Provide kernel hint to read ahead. */ +extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) + __THROW; + + +/* Selective file content synch'ing. */ +extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to, + unsigned int __flags); + +/* Splice address range into a pipe. */ +extern ssize_t vmsplice (int __fdout, const struct iovec *__iov, + size_t __count, unsigned int __flags); + +/* Splice two files together. */ +extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout, + __off64_t *__offout, size_t __len, + unsigned int __flags); + +/* In-kernel implementation of tee for pipe buffers. */ +extern ssize_t tee (int __fdin, int __fdout, size_t __len, + unsigned int __flags); + +#endif +__END_DECLS diff --git a/libc/sysdeps/linux/or1k/bits/kernel_stat.h b/libc/sysdeps/linux/or1k/bits/kernel_stat.h new file mode 100644 index 000000000..9c8abf658 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/kernel_stat.h @@ -0,0 +1,59 @@ +/* taken from linux/include/asm-or1k/stat.h */ + +#ifndef _BITS_STAT_STRUCT_H +#define _BITS_STAT_STRUCT_H + +#ifndef _LIBC +#error bits/kernel_stat.h is for internal uClibc use only! +#endif + +struct kernel_stat { + unsigned long st_dev; /* Device. */ + unsigned long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long st_rdev; /* Device number, if device. */ + unsigned long __pad1; + long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + long st_blocks; /* Number 512-byte blocks allocated. */ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + /* + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + */ + unsigned int __unused4; + unsigned int __unused5; +}; + +/* This matches struct stat64 in glibc2.1. + */ +struct kernel_stat64 { + unsigned long long st_dev; /* Device. */ + unsigned long long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long long st_rdev; /* Device number, if device. */ + unsigned long long __pad1; + long long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + long long st_blocks; /* Number 512-byte blocks allocated. */ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned int __unused4; + unsigned int __unused5; +}; +#endif diff --git a/libc/sysdeps/linux/or1k/bits/kernel_types.h b/libc/sysdeps/linux/or1k/bits/kernel_types.h new file mode 100644 index 000000000..4c5fe3ea6 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/kernel_types.h @@ -0,0 +1 @@ +#include <asm/posix_types.h> diff --git a/libc/sysdeps/linux/or1k/bits/machine-gmon.h b/libc/sysdeps/linux/or1k/bits/machine-gmon.h new file mode 100644 index 000000000..15a1773d6 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/machine-gmon.h @@ -0,0 +1,31 @@ +/* or1k-specific implementation of profiling support. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* We need a special version of the `mcount' function because it has + to preserve more registers than your usual function. */ + +void __mcount_internal (unsigned long frompc, unsigned long selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +void __mcount_internal (unsigned long frompc, unsigned long selfpc) + + +/* Define MCOUNT as empty since we have the implementation in another + file. */ +#define MCOUNT diff --git a/libc/sysdeps/linux/or1k/bits/setjmp.h b/libc/sysdeps/linux/or1k/bits/setjmp.h new file mode 100644 index 000000000..ad93b1991 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/setjmp.h @@ -0,0 +1,32 @@ +/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Define the machine-dependent type `jmp_buf'. or1k version. */ + +#ifndef _BITS_SETJMP_H +#define _BITS_SETJMP_H 1 + +#ifndef _SETJMP_H +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +#ifndef _ASM +typedef long int __jmp_buf[32]; +#endif + +#endif diff --git a/libc/sysdeps/linux/or1k/bits/sigcontextinfo.h b/libc/sysdeps/linux/or1k/bits/sigcontextinfo.h new file mode 100644 index 000000000..369738a99 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/sigcontextinfo.h @@ -0,0 +1,24 @@ +/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <signal.h> + +#define SIGCONTEXT struct sigcontext * +#define SIGCONTEXT_EXTRA_ARGS +#define CALL_SIGHANDLER(handler, signo, ctx) \ + (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx)) diff --git a/libc/sysdeps/linux/or1k/bits/stackinfo.h b/libc/sysdeps/linux/or1k/bits/stackinfo.h new file mode 100644 index 000000000..12d46a026 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On or1k the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/libc/sysdeps/linux/or1k/bits/syscalls.h b/libc/sysdeps/linux/or1k/bits/syscalls.h new file mode 100644 index 000000000..6a08d3cd1 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/syscalls.h @@ -0,0 +1,101 @@ +/* + * Based on arm/bits/syscalls.h + */ + +#ifndef _BITS_SYSCALLS_H +#define _BITS_SYSCALLS_H +#ifndef _SYSCALL_H +# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." +#endif + +/* + Some of the sneaky macros in the code were taken from + glibc-2.3.2/sysdeps/unix/sysv/linux/arm/sysdep.h +*/ + +#ifdef __ASSEMBLER__ + +/* TODO: recheck this */ + +/* Call a given syscall, with arguments loaded. Unlike the DO_CALL + macro in glibc, this macro does not load syscall arguments. */ +#undef DO_CALL +#define DO_CALL(syscall_name) \ + l.lwz r11, =SYS_ify (syscall_name); \ + l.sys 1 \ + l.nop + +#else + +#include <errno.h> + +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ unsigned long __sys_result; \ + { \ + register long __sc_ret __asm__ ("r11") = name; \ + LOAD_ARGS_##nr (args) \ + __asm__ __volatile__ ("l.sys 1" \ + : "=r" (__sc_ret) ASM_ARGS_OUT_##nr \ + : "0" (__sc_ret) ASM_ARGS_IN_##nr \ + : ASM_CLOBBERS_##nr \ + "r12", "r13", "r15", "r17", "r19", \ + "r21", "r23", "r25", "r27", "r29", \ + "r31"); \ + __asm__ __volatile__ ("l.nop"); \ + __sys_result = __sc_ret; \ + } \ + (long) __sys_result; }) + +/* : "0", "1", "2", "3", "4", "5", "6", \ */ +/* : ASM_CLOBBERS_##nr, \ */ + +#define LOAD_ARGS_0() + +#define ASM_ARGS_OUT_0 +#define ASM_ARGS_IN_0 +#define ASM_CLOBBERS_0 "r3", ASM_CLOBBERS_1 + +#define LOAD_ARGS_1(a) \ + LOAD_ARGS_0 () \ + register long __a __asm__ ("r3") = (long)(a); +#define ASM_ARGS_OUT_1 ASM_ARGS_OUT_0, "=r" (__a) +#define ASM_ARGS_IN_1 ASM_ARGS_IN_0, "1" (__a) +#define ASM_CLOBBERS_1 "r4", ASM_CLOBBERS_2 + +#define LOAD_ARGS_2(a, b) \ + LOAD_ARGS_1 (a) \ + register long __b __asm__ ("r4") = (long)(b); +#define ASM_ARGS_OUT_2 ASM_ARGS_OUT_1, "=r" (__b) +#define ASM_ARGS_IN_2 ASM_ARGS_IN_1, "2" (__b) +#define ASM_CLOBBERS_2 "r5", ASM_CLOBBERS_3 + +#define LOAD_ARGS_3(a, b, c) \ + LOAD_ARGS_2 (a, b) \ + register long __c __asm__ ("r5") = (long)(c); +#define ASM_ARGS_OUT_3 ASM_ARGS_OUT_2, "=r" (__c) +#define ASM_ARGS_IN_3 ASM_ARGS_IN_2, "3" (__c) +#define ASM_CLOBBERS_3 "r6", ASM_CLOBBERS_4 + +#define LOAD_ARGS_4(a, b, c, d) \ + LOAD_ARGS_3 (a, b, c) \ + register long __d __asm__ ("r6") = (long)(d); +#define ASM_ARGS_OUT_4 ASM_ARGS_OUT_3, "=r" (__d) +#define ASM_ARGS_IN_4 ASM_ARGS_IN_3, "4" (__d) +#define ASM_CLOBBERS_4 "r7", ASM_CLOBBERS_5 + +#define LOAD_ARGS_5(a, b, c, d, e) \ + LOAD_ARGS_4 (a, b, c, d) \ + register long __e __asm__ ("r7") = (long)(e); +#define ASM_ARGS_OUT_5 ASM_ARGS_OUT_4, "=r" (__e) +#define ASM_ARGS_IN_5 ASM_ARGS_IN_4, "5" (__e) +#define ASM_CLOBBERS_5 "r8", ASM_CLOBBERS_6 + +#define LOAD_ARGS_6(a, b, c, d, e, f) \ + LOAD_ARGS_5 (a, b, c, d, e) \ + register long __f __asm__ ("r8") = (long)(f); +#define ASM_ARGS_OUT_6 ASM_ARGS_OUT_5, "=r" (__f) +#define ASM_ARGS_IN_6 ASM_ARGS_IN_5, "6" (__f) +#define ASM_CLOBBERS_6 + +#endif /* __ASSEMBLER__ */ +#endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/or1k/bits/uClibc_arch_features.h b/libc/sysdeps/linux/or1k/bits/uClibc_arch_features.h new file mode 100644 index 000000000..30ae44364 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/uClibc_arch_features.h @@ -0,0 +1,44 @@ +/* + * Track misc arch-specific features that aren't config options + */ + +#ifndef _BITS_UCLIBC_ARCH_FEATURES_H +#define _BITS_UCLIBC_ARCH_FEATURES_H + +#undef _ERRNO_H +#undef EDEADLOCK /*Use Linux*/ + +/* instruction used when calling abort() to kill yourself */ +#define __UCLIBC_ABORT_INSTRUCTION__ ".long 0xbfffffff" + +/* can your target use syscall6() for mmap ? */ +#define __UCLIBC_MMAP_HAS_6_ARGS__ + +/* does your target use syscall4() for truncate64 ? (32bit arches only) */ +#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__ + +/* does your target have a broken create_module() ? */ +#undef __UCLIBC_BROKEN_CREATE_MODULE__ + +/* does your target have to worry about older [gs]etrlimit() ? */ +#undef __UCLIBC_HANDLE_OLDER_RLIMIT__ + +/* does your target have an asm .set ? */ +#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__ + +/* define if target doesn't like .global */ +#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__ + +/* define if target supports .weak */ +#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__ + +/* define if target supports .weakext */ +#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__ + +/* needed probably only for ppc64 */ +#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__ + +/* define if target supports IEEE signed zero floats */ +#define __UCLIBC_HAVE_SIGNED_ZERO__ + +#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */ diff --git a/libc/sysdeps/linux/or1k/bits/uClibc_page.h b/libc/sysdeps/linux/or1k/bits/uClibc_page.h new file mode 100644 index 000000000..80c3bd9a1 --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/uClibc_page.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2004 Erik Andersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The GNU C Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the GNU C Library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA. + */ + +/* Supply an architecture specific value for PAGE_SIZE and friends. */ + +#ifndef _UCLIBC_PAGE_H +#define _UCLIBC_PAGE_H + +/* PAGE_SHIFT determines the page size -- in this case 4096 */ +#define PAGE_SHIFT 13 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* Some architectures always use 12 as page shift for mmap2() eventhough the + * real PAGE_SHIFT != 12. Other architectures use the same value as + * PAGE_SHIFT... + */ +#define MMAP2_PAGE_SHIFT PAGE_SHIFT + +#endif /* _UCLIBC_PAGE_H */ diff --git a/libc/sysdeps/linux/or1k/bits/wordsize.h b/libc/sysdeps/linux/or1k/bits/wordsize.h new file mode 100644 index 000000000..ba643b60a --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/wordsize.h @@ -0,0 +1,19 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define __WORDSIZE 32 diff --git a/libc/sysdeps/linux/or1k/brk.c b/libc/sysdeps/linux/or1k/brk.c new file mode 100644 index 000000000..f8183dbc1 --- /dev/null +++ b/libc/sysdeps/linux/or1k/brk.c @@ -0,0 +1,23 @@ +/* From libc-5.3.12 */ + +#include <errno.h> +#include <unistd.h> +#include <sys/syscall.h> +libc_hidden_proto(brk) +extern void * ___brk_addr; + +extern int __init_brk (void); +extern void *_brk(void *ptr); + +int brk(void * end_data_seg) +{ + if (__init_brk () == 0) + { + ___brk_addr = _brk(end_data_seg); + if (___brk_addr == end_data_seg) + return 0; + __set_errno(ENOMEM); + } + return -1; +} +libc_hidden_def(brk) diff --git a/libc/sysdeps/linux/or1k/clone.c b/libc/sysdeps/linux/or1k/clone.c new file mode 100644 index 000000000..ebb048ad4 --- /dev/null +++ b/libc/sysdeps/linux/or1k/clone.c @@ -0,0 +1,88 @@ +/* + * clone syscall for OpenRISC + * + * Copyright (c) 2010 Jonas Bonn <jonas@southpole.se> + * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au> + * Copyright (C) 2002,03 NEC Electronics Corporation + * Copyright (C) 2002,03 Miles Bader <miles@gnu.org> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License. See the file COPYING.LIB in the main + * directory of this archive for more details. + * + * OpenRISC port by Jonas Bonn <jonas@southpole.se> + */ + +#include <errno.h> +#include <sys/syscall.h> +#include <sched.h> +#include <unistd.h> + +/* The userland implementation is: + int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...) + the kernel entry is: + int clone (long flags, void *child_stack) +*/ + +int +clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...) +{ + int err; + + /* OK, here's the skinny on this one... + * OR1K GCC does weird things with varargs functions... the last + * parameter is NEVER passed on the stack -- i.e. arg, in this case. + * So we need to push at least 'arg' onto the child stack so that + * the new thread can find it. Just to be totally safe, we'll + * push both 'fn' and 'arg'; that way we don't need to care what + * GCC does with parameters, whether they are passed in registers + * or on stack. + */ + + /* Put 'fn' and 'arg' on child stack */ + __asm__ __volatile__ ( + "l.sw -4(%0),%1;" + "l.sw -8(%0),%2;" + : + : "r" (child_stack), "r" (fn), "r" (arg) + ); + + /* Sanity check the arguments */ + err = -EINVAL; + if (!fn) + goto syscall_error; + if (!child_stack) + goto syscall_error; + + err = INLINE_SYSCALL(clone, 2, flags, child_stack); + + /* NB: from here you are in child thread or parent thread. + * + * Do not use any functions here that may write data _up_ + * onto the stack because they will overwrite the child's + * thread descriptor... i.e. don't use printf + */ + + if (err < 0) + goto syscall_error; + else if (err != 0) { + return err; + } + + /* NB: from here you exclusively in child thread */ + + /* Grab 'fn' and 'arg' from child stack */ + __asm__ __volatile__ ( + "l.lwz %0,-4(%2);" + "l.lwz %1,-8(%2);" + : "=&r" (fn), "=r" (arg) + : "r" (child_stack) + : "0", "1" + ); + + _exit(fn(arg)); + +syscall_error: + __set_errno (-err); + return -1; +} diff --git a/libc/sysdeps/linux/or1k/crt1.S b/libc/sysdeps/linux/or1k/crt1.S new file mode 100644 index 000000000..c1926bef2 --- /dev/null +++ b/libc/sysdeps/linux/or1k/crt1.S @@ -0,0 +1,144 @@ +/* Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002, 2005 + Free Software Foundation, Inc. + + Copyright (C) 2010 Embecosm Limited + + Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> + Contributor Joern Rennecke <joern.rennecke@embecosm.com> + With other contributions from the OpenCores community. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Stick in a dummy reference to main(), so that if an application + * is linking when the main() function is in a static library (.a) + * we can be sure that main() actually gets linked in */ +.type main,%function + +/* This is the canonical entry point, usually the first thing in the text + segment. + + sp The stack contains the arguments and environment: + 0(sp) argc + 4(sp) argv[0] + ... + (4*argc)(sp) NULL + (4*(argc+1))(sp) envp[0] + ... + NULL +*/ + +#include <features.h> + +.text + .globl _start + .type _start,%function + +.global _start +_start: + +#ifdef __PIC__ + /* Obtain a pointer to .got in r16 */ + l.jal .LPC0 +#ifndef __OR1K_NODELAY__ + l.nop +#endif +.LPC0: + l.movhi r16, gotpchi(_GLOBAL_OFFSET_TABLE_+(.-.LPC0)) + l.ori r16, r16, gotpclo(_GLOBAL_OFFSET_TABLE_+(.-.LPC0)) + l.add r16, r16, r9 +#endif + + /* Push stack limit onto the stack */ + /* Provides highest stack address to user code (as stack grows + * downwards + * This is the seventh argument to __uClibc_main and thus needs to + * be passed on the stack + */ + l.sw -4(r1),r1 + + /* Take values for argc and argv off the stack. + * These will be passed as arguments two and three to __uClibc_main + * and thus go in registers r4 and r5, respectively + */ + l.lwz r4,0(r1) + l.addi r5,r1,4 + +#ifdef __PIC__ + l.lwz r3,got(main)(r16) +#else + l.movhi r3,hi(main) + l.ori r3,r3,lo(main) +#endif + + /* Put the constructor and destructor initialization as args four and + five into r6 and r7 */ +#ifdef __PIC__ + l.lwz r6, got(_init)(r16) + l.lwz r7, got(_fini)(r16) +#else + l.movhi r6,hi(_init) + l.ori r6,r6,lo(_init) + l.movhi r7,hi(_fini) + l.ori r7,r7,lo(_fini) +#endif + + /* rtld_fini = NULL */ + l.movhi r8, 0 + + /* Adjust stack to account for a total of 7 args (i.e. the last one is + on the stack. */ + l.addi r1,r1,-4 + + /* Clear the frame pointer and link register since this is the + * outermost frame. + */ + l.add r2,r0,r0 + l.add r9,r0,r0 + + /* Let the libc call main and exit with its return code. */ +#ifdef __PIC__ + l.j plt(__uClibc_main) +#else + l.j __uClibc_main +#endif + l.nop + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/or1k/crti.S b/libc/sysdeps/linux/or1k/crti.S new file mode 100644 index 000000000..a96476b5e --- /dev/null +++ b/libc/sysdeps/linux/or1k/crti.S @@ -0,0 +1,11 @@ + .section .init + .global _init +_init: + l.addi r1,r1,-4 + l.sw 0(r1),r9 + + .section .fini + .global _fini +_fini: + l.addi r1,r1,-4 + l.sw 0(r1),r9 diff --git a/libc/sysdeps/linux/or1k/crtn.S b/libc/sysdeps/linux/or1k/crtn.S new file mode 100644 index 000000000..b3e8688ef --- /dev/null +++ b/libc/sysdeps/linux/or1k/crtn.S @@ -0,0 +1,9 @@ + .section .init + l.lwz r9,0(r1) + l.jr r9 + l.addi r1,r1,4 + + .section .fini + l.lwz r9,0(r1) + l.jr r9 + l.addi r1,r1,4 diff --git a/libc/sysdeps/linux/or1k/jmpbuf-offsets.h b/libc/sysdeps/linux/or1k/jmpbuf-offsets.h new file mode 100644 index 000000000..8cd82a104 --- /dev/null +++ b/libc/sysdeps/linux/or1k/jmpbuf-offsets.h @@ -0,0 +1,8 @@ +#include <features.h> + +#define JB_SR 0 +#define JB_GPRS 1 +#define JB_SP 1 +#define JB_LR 9 +#define JB_RV 11 +#define JB_SIZE (32*4) diff --git a/libc/sysdeps/linux/or1k/jmpbuf-unwind.h b/libc/sysdeps/linux/or1k/jmpbuf-unwind.h new file mode 100644 index 000000000..436073b60 --- /dev/null +++ b/libc/sysdeps/linux/or1k/jmpbuf-unwind.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2005,2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <jmpbuf-offsets.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)[JB_SP]) diff --git a/libc/sysdeps/linux/or1k/sbrk.c b/libc/sysdeps/linux/or1k/sbrk.c new file mode 100644 index 000000000..bd0635fcd --- /dev/null +++ b/libc/sysdeps/linux/or1k/sbrk.c @@ -0,0 +1,27 @@ +/* From libc-5.3.12 */ + +#include <errno.h> +#include <unistd.h> +#include <sys/syscall.h> +libc_hidden_proto(sbrk) + +extern void * ___brk_addr; + +extern int __init_brk (void); +extern void *_brk(void *ptr); + +void * +sbrk(intptr_t increment) +{ + if (__init_brk () == 0) + { + char * tmp = (char*)___brk_addr+increment; + ___brk_addr = _brk(tmp); + if (___brk_addr == tmp) + return tmp-increment; + __set_errno(ENOMEM); + return ((void *) -1); + } + return ((void *) -1); +} +libc_hidden_def(sbrk) diff --git a/libc/sysdeps/linux/or1k/setjmp.S b/libc/sysdeps/linux/or1k/setjmp.S new file mode 100644 index 000000000..2814f2f24 --- /dev/null +++ b/libc/sysdeps/linux/or1k/setjmp.S @@ -0,0 +1,96 @@ +/* setjmp for or1k + + Based on: + setjmp for PowerPC. + Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "spr_defs.h" +#include <jmpbuf-offsets.h> + +#ifdef __UCLIBC_HAS_FLOATS__ +#define FP(x...) x +#else +#define FP(x...) +#endif + +.globl _setjmp +.type _setjmp, @function +.align 2 + +_setjmp: + l.addi r4,r0,0 /* Set second argument to 0. */ + l.j .Local_sigsetjmp + l.nop +.size _setjmp,.-_setjmp + +.globl __setjmp +.type __setjmp, @function +.align 2 + +__setjmp: + l.addi r4,r0,1 /* Set second argument to 1. */ + l.j .Local_sigsetjmp + l.nop +.size __setjmp,.-__setjmp + +.globl setjmp +.set setjmp,__setjmp + +.globl __sigsetjmp +.type __sigsetjmp, @function +.align 2 + +__sigsetjmp: +.Local_sigsetjmp: +# l.mfspr r11,r0,SPR_SR +# l.sw (JB_SR*4)(r3),r11 + l.sw ((JB_GPRS+0)*4)(r3),r1 + l.sw ((JB_GPRS+1)*4)(r3),r2 +/* l.sw ((JB_GPRS+2)*4)(r3),r3*/ + l.sw ((JB_GPRS+3)*4)(r3),r4 + l.sw ((JB_GPRS+4)*4)(r3),r5 + l.sw ((JB_GPRS+5)*4)(r3),r6 + l.sw ((JB_GPRS+6)*4)(r3),r7 + l.sw ((JB_GPRS+7)*4)(r3),r8 + l.sw ((JB_GPRS+8)*4)(r3),r9 + l.sw ((JB_GPRS+9)*4)(r3),r10 + l.sw ((JB_GPRS+10)*4)(r3),r11 + l.sw ((JB_GPRS+11)*4)(r3),r12 + l.sw ((JB_GPRS+12)*4)(r3),r13 + l.sw ((JB_GPRS+13)*4)(r3),r14 + l.sw ((JB_GPRS+14)*4)(r3),r15 + l.sw ((JB_GPRS+15)*4)(r3),r16 + l.sw ((JB_GPRS+16)*4)(r3),r17 + l.sw ((JB_GPRS+17)*4)(r3),r18 + l.sw ((JB_GPRS+18)*4)(r3),r19 + l.sw ((JB_GPRS+19)*4)(r3),r20 + l.sw ((JB_GPRS+20)*4)(r3),r21 + l.sw ((JB_GPRS+21)*4)(r3),r22 + l.sw ((JB_GPRS+22)*4)(r3),r23 + l.sw ((JB_GPRS+23)*4)(r3),r24 + l.sw ((JB_GPRS+24)*4)(r3),r25 + l.sw ((JB_GPRS+25)*4)(r3),r26 + l.sw ((JB_GPRS+26)*4)(r3),r27 + l.sw ((JB_GPRS+27)*4)(r3),r28 + l.sw ((JB_GPRS+28)*4)(r3),r29 + l.sw ((JB_GPRS+29)*4)(r3),r30 + l.sw ((JB_GPRS+30)*4)(r3),r31 + l.j __sigjmp_save + l.nop +.size __sigsetjmp,.-__sigsetjmp diff --git a/libc/sysdeps/linux/or1k/spr_defs.h b/libc/sysdeps/linux/or1k/spr_defs.h new file mode 100644 index 000000000..263d3e43a --- /dev/null +++ b/libc/sysdeps/linux/or1k/spr_defs.h @@ -0,0 +1,429 @@ +/* spr_defs.h -- Defines OR1K architecture specific special-purpose registers + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file is also used by microkernel test bench. Among +others it is also used in assembly file(s). */ + +/* Definition of special-purpose registers (SPRs) */ + +#define MAX_GRPS (32) +#define MAX_SPRS_PER_GRP_BITS (11) +#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) +#define MAX_SPRS (0x10000) + +/* Base addresses for the groups */ +#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) + +/* System control and status group */ +#define SPR_VR (SPRGROUP_SYS + 0) +#define SPR_UPR (SPRGROUP_SYS + 1) +#define SPR_CPUCFGR (SPRGROUP_SYS + 2) +#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) +#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) +#define SPR_DCCFGR (SPRGROUP_SYS + 5) +#define SPR_ICCFGR (SPRGROUP_SYS + 6) +#define SPR_DCFGR (SPRGROUP_SYS + 7) +#define SPR_PCCFGR (SPRGROUP_SYS + 8) +#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ +#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ +#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ +#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ +#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ +#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) +#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) +#define SPR_ESR_BASE (SPRGROUP_SYS + 64) +#define SPR_ESR_LAST (SPRGROUP_SYS + 79) + +/* Data MMU group */ +#define SPR_DMMUCR (SPRGROUP_DMMU + 0) +#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100) +#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100) +#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100) +#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100) + +/* Instruction MMU group */ +#define SPR_IMMUCR (SPRGROUP_IMMU + 0) +#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100) +#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100) +#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100) +#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100) + +/* Data cache group */ +#define SPR_DCCR (SPRGROUP_DC + 0) +#define SPR_DCBPR (SPRGROUP_DC + 1) +#define SPR_DCBFR (SPRGROUP_DC + 2) +#define SPR_DCBIR (SPRGROUP_DC + 3) +#define SPR_DCBWR (SPRGROUP_DC + 4) +#define SPR_DCBLR (SPRGROUP_DC + 5) +#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) +#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) + +/* Instruction cache group */ +#define SPR_ICCR (SPRGROUP_IC + 0) +#define SPR_ICBPR (SPRGROUP_IC + 1) +#define SPR_ICBIR (SPRGROUP_IC + 2) +#define SPR_ICBLR (SPRGROUP_IC + 3) +#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) +#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) + +/* MAC group */ +#define SPR_MACLO (SPRGROUP_MAC + 1) +#define SPR_MACHI (SPRGROUP_MAC + 2) + +/* Debug group */ +#define SPR_DVR(N) (SPRGROUP_D + (N)) +#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) +#define SPR_DMR1 (SPRGROUP_D + 16) +#define SPR_DMR2 (SPRGROUP_D + 17) +#define SPR_DWCR0 (SPRGROUP_D + 18) +#define SPR_DWCR1 (SPRGROUP_D + 19) +#define SPR_DSR (SPRGROUP_D + 20) +#define SPR_DRR (SPRGROUP_D + 21) + +/* Performance counters group */ +#define SPR_PCCR(N) (SPRGROUP_PC + (N)) +#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) + +/* Power management group */ +#define SPR_PMR (SPRGROUP_PM + 0) + +/* PIC group */ +#define SPR_PICMR (SPRGROUP_PIC + 0) +#define SPR_PICPR (SPRGROUP_PIC + 1) +#define SPR_PICSR (SPRGROUP_PIC + 2) + +/* Tick Timer group */ +#define SPR_TTMR (SPRGROUP_TT + 0) +#define SPR_TTCR (SPRGROUP_TT + 1) + +/* + * Bit definitions for the Version Register + * + */ +#define SPR_VR_VER 0xffff0000 /* Processor version */ +#define SPR_VR_REV 0x0000003f /* Processor revision */ + +/* + * Bit definitions for the Unit Present Register + * + */ +#define SPR_UPR_UP 0x00000001 /* UPR present */ +#define SPR_UPR_DCP 0x00000002 /* Data cache present */ +#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ +#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ +#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ +#define SPR_UPR_OB32P 0x00000020 /* ORBIS32 present */ +#define SPR_UPR_OB64P 0x00000040 /* ORBIS64 present */ +#define SPR_UPR_OF32P 0x00000080 /* ORFPX32 present */ +#define SPR_UPR_OF64P 0x00000100 /* ORFPX64 present */ +#define SPR_UPR_OV32P 0x00000200 /* ORVDX32 present */ +#define SPR_UPR_OV64P 0x00000400 /* ORVDX64 present */ +#define SPR_UPR_DUP 0x00000800 /* Debug unit present */ +#define SPR_UPR_PCUP 0x00001000 /* Performance counters unit present */ +#define SPR_UPR_PMP 0x00002000 /* Power management present */ +#define SPR_UPR_PICP 0x00004000 /* PIC present */ +#define SPR_UPR_TTP 0x00008000 /* Tick timer present */ +#define SPR_UPR_SRP 0x00010000 /* Shadow registers present */ +#define SPR_UPR_RES 0x00fe0000 /* ORVDX32 present */ +#define SPR_UPR_CUST 0xff000000 /* Custom units */ + +/* + * Bit definitions for the Supervision Register + * + */ +#define SPR_SR_CID 0xf0000000 /* Context ID */ +#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */ +#define SPR_SR_FO 0x00008000 /* Fixed one */ +#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */ +#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ +#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ +#define SPR_SR_OV 0x00000800 /* Overflow flag */ +#define SPR_SR_CY 0x00000400 /* Carry flag */ +#define SPR_SR_F 0x00000200 /* Condition Flag */ +#define SPR_SR_CE 0x00000100 /* CID Enable */ +#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ +#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ +#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ +#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ +#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ +#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ +#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ +#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ + +/* + * Bit definitions for the Data MMU Control Register + * + */ +#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Instruction MMU Control Register + * + */ +#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Data TLB Match Register + * + */ +#define SPR_DTLBMR_V 0x00000001 /* Valid */ +#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ +#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */ + +/* + * Bit definitions for the Data TLB Translate Register + * + */ +#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_DTLBTR_A 0x00000010 /* Accessed */ +#define SPR_DTLBTR_D 0x00000020 /* Dirty */ +#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ +#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ +#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ +#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ +#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */ + +/* + * Bit definitions for the Instruction TLB Match Register + * + */ +#define SPR_ITLBMR_V 0x00000001 /* Valid */ +#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ +#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */ + +/* + * Bit definitions for the Instruction TLB Translate Register + * + */ +#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_ITLBTR_A 0x00000010 /* Accessed */ +#define SPR_ITLBTR_D 0x00000020 /* Dirty */ +#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ +#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ +#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */ + +/* + * Bit definitions for Data Cache Control register + * + */ +#define SPR_DCCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Insn Cache Control register + * + */ +#define SPR_ICCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Debug Control registers + * + */ +#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ +#define SPR_DCR_CC 0x0000000e /* Compare condition */ +#define SPR_DCR_SC 0x00000010 /* Signed compare */ +#define SPR_DCR_CT 0x000000e0 /* Compare to */ + +/* Bit results with SPR_DCR_CC mask */ +#define SPR_DCR_CC_MASKED 0x00000000 +#define SPR_DCR_CC_EQUAL 0x00000001 +#define SPR_DCR_CC_LESS 0x00000002 +#define SPR_DCR_CC_LESSE 0x00000003 +#define SPR_DCR_CC_GREAT 0x00000004 +#define SPR_DCR_CC_GREATE 0x00000005 +#define SPR_DCR_CC_NEQUAL 0x00000006 + +/* Bit results with SPR_DCR_CT mask */ +#define SPR_DCR_CT_DISABLED 0x00000000 +#define SPR_DCR_CT_IFEA 0x00000020 +#define SPR_DCR_CT_LEA 0x00000040 +#define SPR_DCR_CT_SEA 0x00000060 +#define SPR_DCR_CT_LD 0x00000080 +#define SPR_DCR_CT_SD 0x000000a0 +#define SPR_DCR_CT_LSEA 0x000000c0 + +/* + * Bit definitions for Debug Mode 1 register + * + */ +#define SPR_DMR1_CW0 0x00000003 /* Chain watchpoint 0 */ +#define SPR_DMR1_CW1 0x0000000c /* Chain watchpoint 1 */ +#define SPR_DMR1_CW2 0x00000030 /* Chain watchpoint 2 */ +#define SPR_DMR1_CW3 0x000000c0 /* Chain watchpoint 3 */ +#define SPR_DMR1_CW4 0x00000300 /* Chain watchpoint 4 */ +#define SPR_DMR1_CW5 0x00000c00 /* Chain watchpoint 5 */ +#define SPR_DMR1_CW6 0x00003000 /* Chain watchpoint 6 */ +#define SPR_DMR1_CW7 0x0000c000 /* Chain watchpoint 7 */ +#define SPR_DMR1_CW8 0x00030000 /* Chain watchpoint 8 */ +#define SPR_DMR1_CW9 0x000c0000 /* Chain watchpoint 9 */ +#define SPR_DMR1_CW10 0x00300000 /* Chain watchpoint 10 */ +#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ +#define SPR_DMR1_BT 0x00800000 /* Branch trace */ +#define SPR_DMR1_DXFW 0x01000000 /* Disable external force watchpoint */ + +/* + * Bit definitions for Debug Mode 2 register + * + */ +#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_AWTC 0x00001ffc /* Assign watchpoints to counters */ +#define SPR_DMR2_WGB 0x00ffe000 /* Watchpoints generating breakpoint */ + +/* + * Bit definitions for Debug watchpoint counter registers + * + */ +#define SPR_DWCR_COUNT 0x0000ffff /* Count */ +#define SPR_DWCR_MATCH 0xffff0000 /* Match */ + +/* + * Bit definitions for Debug stop register + * + */ +#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DSR_TTE 0x00000010 /* iTick Timer exception */ +#define SPR_DSR_AE 0x00000020 /* Alignment exception */ +#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DSR_RE 0x00000400 /* Range exception */ +#define SPR_DSR_SCE 0x00000800 /* System call exception */ +#define SPR_DSR_SSE 0x00001000 /* Single Step Exception */ +#define SPR_DSR_TE 0x00002000 /* Trap exception */ + +/* + * Bit definitions for Debug reason register + * + */ +#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ +#define SPR_DRR_AE 0x00000020 /* Alignment exception */ +#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DRR_RE 0x00000400 /* Range exception */ +#define SPR_DRR_SCE 0x00000800 /* System call exception */ +#define SPR_DRR_TE 0x00001000 /* Trap exception */ + +/* + * Bit definitions for Performance counters mode registers + * + */ +#define SPR_PCMR_CP 0x00000001 /* Counter present */ +#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ +#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ +#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ +#define SPR_PCMR_LA 0x00000010 /* Load access event */ +#define SPR_PCMR_SA 0x00000020 /* Store access event */ +#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ +#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ +#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ +#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ +#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ +#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ +#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ +#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ +#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ +#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ + +/* + * Bit definitions for the Power management register + * + */ +#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ +#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ +#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ +#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ +#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ + +/* + * Bit definitions for PICMR + * + */ +#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ + +/* + * Bit definitions for PICPR + * + */ +#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ + +/* + * Bit definitions for PICSR + * + */ +#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ + +/* + * Bit definitions for Tick Timer Control Register + * + */ +#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ +#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD +#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ +#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ +#define SPR_TTMR_RT 0x40000000 /* Restart tick */ +#define SPR_TTMR_SR 0x80000000 /* Single run */ +#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ +#define SPR_TTMR_M 0xc0000000 /* Tick mode */ + +/* + * l.nop constants + * + */ +#define NOP_NOP 0x0000 /* Normal nop instruction */ +#define NOP_EXIT 0x0001 /* End of simulation */ +#define NOP_REPORT 0x0002 /* Simple report */ +#define NOP_PRINTF 0x0003 /* Simprintf instruction */ +#define NOP_REPORT_FIRST 0x0400 /* Report with number */ +#define NOP_REPORT_LAST 0x03ff /* Report with number */ diff --git a/libc/sysdeps/linux/or1k/sys/procfs.h b/libc/sysdeps/linux/or1k/sys/procfs.h new file mode 100644 index 000000000..9d4c68fec --- /dev/null +++ b/libc/sysdeps/linux/or1k/sys/procfs.h @@ -0,0 +1,116 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somehow modelled after the file of the same name on SysVr4 + systems. It provides a definition of the core file format for ELF + used on Linux. */ + +#include <features.h> +#include <signal.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/ucontext.h> + +#include <asm/elf.h> + +__BEGIN_DECLS + +struct elf_siginfo + { + int si_signo; /* Signal number. */ + int si_code; /* Extra code. */ + int si_errno; /* Errno. */ + }; + + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + gdb doesn't really use excluded. Fields present but not used are + marked with "XXX". */ +struct elf_prstatus + { +#if 0 + long int pr_flags; /* XXX Process flags. */ + short int pr_why; /* XXX Reason for process halt. */ + short int pr_what; /* XXX More detailed reason. */ +#endif + struct elf_siginfo pr_info; /* Info associated with signal. */ + short int pr_cursig; /* Current signal. */ + unsigned long int pr_sigpend; /* Set of pending signals. */ + unsigned long int pr_sighold; /* Set of held signals. */ +#if 0 + struct sigaltstack pr_altstack; /* Alternate stack info. */ + struct sigaction pr_action; /* Signal action for current sig. */ +#endif + __pid_t pr_pid; + __pid_t pr_ppid; + __pid_t pr_pgrp; + __pid_t pr_sid; + struct timeval pr_utime; /* User time. */ + struct timeval pr_stime; /* System time. */ + struct timeval pr_cutime; /* Cumulative user time. */ + struct timeval pr_cstime; /* Cumulative system time. */ +#if 0 + long int pr_instr; /* Current instruction. */ +#endif + elf_gregset_t pr_reg; /* GP registers. */ + int pr_fpvalid; /* True if math copro being used. */ + }; + + +#define ELF_PRARGSZ (80) /* Number of chars for args */ + +struct elf_prpsinfo + { + char pr_state; /* Numeric process state. */ + char pr_sname; /* Char for pr_state. */ + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned long int pr_flag; /* Flags. */ + __uid_t pr_uid; + __gid_t pr_gid; + __pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + +/* Addresses. */ +typedef void *psaddr_t; + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; + +/* We don't have any differences between processes and threads, + therefore habe only ine PID type. */ +typedef __pid_t lwpid_t; + + +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +__END_DECLS + +#endif /* sys/procfs.h */ diff --git a/libc/sysdeps/linux/or1k/sys/ucontext.h b/libc/sysdeps/linux/or1k/sys/ucontext.h new file mode 100644 index 000000000..0d82cdb1c --- /dev/null +++ b/libc/sysdeps/linux/or1k/sys/ucontext.h @@ -0,0 +1,26 @@ +/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> +#include <signal.h> +#include <asm/ucontext.h> + +#endif /* sys/ucontext.h */ diff --git a/libpthread/linuxthreads/sysdeps/or1k/pt-machine.h b/libpthread/linuxthreads/sysdeps/or1k/pt-machine.h new file mode 100644 index 000000000..c6c8ee470 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/or1k/pt-machine.h @@ -0,0 +1,55 @@ +/* Machine-dependent pthreads configuration and inline functions. + OpenRISC version. + Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 + +#include <features.h> +#include <sys/syscall.h> + +#ifndef PT_EI +# define PT_EI __extern_always_inline +#endif + +PT_EI long int testandset(int*); + +#define OR1K_ATOMIC_XCHG 1 + +PT_EI long int +testandset (int *spinlock) +{ + int err; + int oldvalue = 1; + + err = INLINE_SYSCALL(or1k_atomic, 3, OR1K_ATOMIC_XCHG, spinlock, &oldvalue); + + return (oldvalue); +} + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME stack_pointer() +static inline char *stack_pointer(void) +{ + unsigned long ret; + __asm__ __volatile__ ("l.ori %0, r1, 0" : "=r" (ret)); + return (char *)ret; +} +#endif /* pt-machine.h */ |