From c2f02da21a3f37f0878554eebc785e04fdc4e128 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 28 Mar 2008 09:47:00 +0100 Subject: [PATCH] SPARC: Added generic support for SPARC architecture. Signed-off-by: Daniel Hellstrom --- MAKEALL | 7 + Makefile | 9 +- README | 1 + examples/Makefile | 3 + examples/sparc.lds | 61 ++++ examples/stubs.c | 16 + include/asm-sparc/asi.h | 32 ++ include/asm-sparc/asmmacro.h | 45 +++ include/asm-sparc/atomic.h | 29 ++ include/asm-sparc/bitops.h | 29 ++ include/asm-sparc/byteorder.h | 37 +++ include/asm-sparc/cache.h | 31 ++ include/asm-sparc/errno.h | 162 ++++++++++ include/asm-sparc/global_data.h | 85 ++++++ include/asm-sparc/io.h | 94 ++++++ include/asm-sparc/irq.h | 49 +++ include/asm-sparc/machines.h | 92 ++++++ include/asm-sparc/page.h | 43 +++ include/asm-sparc/posix_types.h | 139 +++++++++ include/asm-sparc/processor.h | 109 +++++++ include/asm-sparc/prom.h | 297 ++++++++++++++++++ include/asm-sparc/psr.h | 97 ++++++ include/asm-sparc/ptrace.h | 181 +++++++++++ include/asm-sparc/srmmu.h | 301 ++++++++++++++++++ include/asm-sparc/stack.h | 162 ++++++++++ include/asm-sparc/string.h | 55 ++++ include/asm-sparc/types.h | 71 +++++ include/asm-sparc/u-boot.h | 74 +++++ include/asm-sparc/winmacro.h | 151 +++++++++ lib_sparc/Makefile | 45 +++ lib_sparc/board.c | 521 ++++++++++++++++++++++++++++++++ lib_sparc/bootm.c | 226 ++++++++++++++ lib_sparc/cache.c | 33 ++ lib_sparc/interrupts.c | 122 ++++++++ lib_sparc/time.c | 78 +++++ sparc_config.mk | 24 ++ 36 files changed, 3510 insertions(+), 1 deletion(-) create mode 100644 examples/sparc.lds create mode 100644 include/asm-sparc/asi.h create mode 100644 include/asm-sparc/asmmacro.h create mode 100644 include/asm-sparc/atomic.h create mode 100644 include/asm-sparc/bitops.h create mode 100644 include/asm-sparc/byteorder.h create mode 100644 include/asm-sparc/cache.h create mode 100644 include/asm-sparc/errno.h create mode 100644 include/asm-sparc/global_data.h create mode 100644 include/asm-sparc/io.h create mode 100644 include/asm-sparc/irq.h create mode 100644 include/asm-sparc/machines.h create mode 100644 include/asm-sparc/page.h create mode 100644 include/asm-sparc/posix_types.h create mode 100644 include/asm-sparc/processor.h create mode 100644 include/asm-sparc/prom.h create mode 100644 include/asm-sparc/psr.h create mode 100644 include/asm-sparc/ptrace.h create mode 100644 include/asm-sparc/srmmu.h create mode 100644 include/asm-sparc/stack.h create mode 100644 include/asm-sparc/string.h create mode 100644 include/asm-sparc/types.h create mode 100644 include/asm-sparc/u-boot.h create mode 100644 include/asm-sparc/winmacro.h create mode 100644 lib_sparc/Makefile create mode 100644 lib_sparc/board.c create mode 100644 lib_sparc/bootm.c create mode 100644 lib_sparc/cache.c create mode 100644 lib_sparc/interrupts.c create mode 100644 lib_sparc/time.c create mode 100644 sparc_config.mk diff --git a/MAKEALL b/MAKEALL index 2a872acd6a..9a2afe66fc 100755 --- a/MAKEALL +++ b/MAKEALL @@ -723,6 +723,12 @@ LIST_sh=" \ ${LIST_sh4} \ " +######################################################################### +## SPARC Systems +######################################################################### + +LIST_sparc="" + #----------------------------------------------------------------------- #----- for now, just run PPC by default ----- @@ -751,6 +757,7 @@ do case "$arg" in arm|SA|ARM7|ARM9|ARM10|ARM11|ixp|pxa| \ avr32| \ + sparc| \ blackfin| \ coldfire| \ microblaze| \ diff --git a/Makefile b/Makefile index a7f886b489..7219e7a318 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,10 @@ CROSS_COMPILE = avr32-linux- endif ifeq ($(ARCH),sh) CROSS_COMPILE = sh4-linux- -endif # sh +endif +ifeq ($(ARCH),sparc) +CROSS_COMPILE = sparc-elf- +endif # sparc endif # HOSTARCH,ARCH endif # CROSS_COMPILE @@ -2892,6 +2895,10 @@ r2dplus_config : unconfig @echo "#define CONFIG_R2DPLUS 1" >> include/config.h @./mkconfig -a $(@:_config=) sh sh4 r2dplus +#======================================================================== +# SPARC +#======================================================================== + ######################################################################### ######################################################################### ######################################################################### diff --git a/README b/README index 5d059e73c6..9160306c47 100644 --- a/README +++ b/README @@ -186,6 +186,7 @@ Directory Hierarchy: - lib_mips Files generic to MIPS architecture - lib_nios Files generic to NIOS architecture - lib_ppc Files generic to PowerPC architecture +- lib_sparc Files generic to SPARC architecture - libfdt Library files to support flattened device trees - net Networking code - post Power On Self Test diff --git a/examples/Makefile b/examples/Makefile index c5d629b68a..66b354daaf 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -69,6 +69,9 @@ ifeq ($(ARCH),sh) LOAD_ADDR = 0x8C000000 endif +ifeq ($(ARCH),sparc) +LOAD_ADDR = 0x00000000 -L $(gcclibdir) -T sparc.lds +endif include $(TOPDIR)/config.mk diff --git a/examples/sparc.lds b/examples/sparc.lds new file mode 100644 index 0000000000..75925449ed --- /dev/null +++ b/examples/sparc.lds @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2003, Psyent Corporation + * Scott McNutt + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc") +OUTPUT_ARCH(sparc) +ENTRY(_start) + +SECTIONS +{ + .text : + { + *(.text) + } + __text_end = .; + + . = ALIGN(4); + .rodata : + { + *(.rodata) + } + __rodata_end = .; + + . = ALIGN(4); + .data : + { + *(.data) + } + . = ALIGN(4); + __data_end = .; + + __bss_start = .; + . = ALIGN(4); + .bss : + { + *(.bss) + } + . = ALIGN(4); + __bss_end = .; + _end = .; +} diff --git a/examples/stubs.c b/examples/stubs.c index b9dbcf9065..ec5353216b 100644 --- a/examples/stubs.c +++ b/examples/stubs.c @@ -167,6 +167,22 @@ gd_t *global_data; " nop\n" \ " nop\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1"); +#elif defined(CONFIG_SPARC) +/* + * g7 holds the pointer to the global_data. g1 is call clobbered. + */ +#define EXPORT_FUNC(x) \ + asm volatile( \ +" .globl\t" #x "\n" \ +#x ":\n" \ +" set %0, %%g1\n" \ +" or %%g1, %%g7, %%g1\n" \ +" ld [%%g1], %%g1\n" \ +" ld [%%g1 + %1], %%g1\n" \ +" call %%g1\n" \ +" nop\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x) : "g1" ); + #else #error stubs definition missing for this architecture #endif diff --git a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h new file mode 100644 index 0000000000..bf6d70fece --- /dev/null +++ b/include/asm-sparc/asi.h @@ -0,0 +1,32 @@ +/* Address Space Identifier (ASI) values for sparc processors. + * + * (C) Copyright 2008 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_ASI_H +#define _SPARC_ASI_H + +/* ASI numbers are processor implementation specific */ +#include + +#endif /* _SPARC_ASI_H */ diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h new file mode 100644 index 0000000000..0c4cefdf40 --- /dev/null +++ b/include/asm-sparc/asmmacro.h @@ -0,0 +1,45 @@ +/* Assembler macros for SPARC + * + * (C) Copyright 2007, taken from linux asm-sparc/asmmacro.h + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_ASMMACRO_H__ +#define __SPARC_ASMMACRO_H__ + +#include + +/* All trap entry points _must_ begin with this macro or else you + * lose. It makes sure the kernel has a proper window so that + * c-code can be called. + */ +#define SAVE_ALL_HEAD \ + sethi %hi(trap_setup+(CFG_RELOC_MONITOR_BASE-TEXT_BASE)), %l4; \ + jmpl %l4 + %lo(trap_setup+(CFG_RELOC_MONITOR_BASE-TEXT_BASE)), %l6; +#define SAVE_ALL \ + SAVE_ALL_HEAD \ + nop; + +/* All traps low-level code here must end with this macro. */ +#define RESTORE_ALL b ret_trap_entry; clr %l6; + +#endif diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h new file mode 100644 index 0000000000..636498d557 --- /dev/null +++ b/include/asm-sparc/atomic.h @@ -0,0 +1,29 @@ +/* SPARC atomic operations + * + * (C) Copyright 2008 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _ASM_SPARC_ATOMIC_H_ +#define _ASM_SPARC_ATOMIC_H_ + +#endif /* _ASM_SPARC_ATOMIC_H_ */ diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h new file mode 100644 index 0000000000..ceb39f2fe5 --- /dev/null +++ b/include/asm-sparc/bitops.h @@ -0,0 +1,29 @@ +/* Bit string operations on the SPARC + * + * (C) Copyright 2007, taken from asm-ppc/bitops.h + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_BITOPS_H +#define _SPARC_BITOPS_H + +#endif /* _SPARC_BITOPS_H */ diff --git a/include/asm-sparc/byteorder.h b/include/asm-sparc/byteorder.h new file mode 100644 index 0000000000..b9fc65663f --- /dev/null +++ b/include/asm-sparc/byteorder.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2008 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_BYTEORDER_H +#define _SPARC_BYTEORDER_H + +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define __BYTEORDER_HAS_U64__ +#endif +#include +#endif /* _SPARC_BYTEORDER_H */ diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h new file mode 100644 index 0000000000..03e8d94bb2 --- /dev/null +++ b/include/asm-sparc/cache.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2008, + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_CACHE_H__ +#define __SPARC_CACHE_H__ + +#include +#include + +#endif diff --git a/include/asm-sparc/errno.h b/include/asm-sparc/errno.h new file mode 100644 index 0000000000..3a74f6fa47 --- /dev/null +++ b/include/asm-sparc/errno.h @@ -0,0 +1,162 @@ +/* SPARC errno definitions, taken from asm-ppc/errno.h + * + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __SPARC_ERRNO_H__ +#define __SPARC_ERRNO_H__ + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ +#define EDEADLOCK 58 /* File locking deadlock error */ +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +/* Should never be seen by user programs */ +#define ERESTARTSYS 512 +#define ERESTARTNOINTR 513 +#define ERESTARTNOHAND 514 /* restart if no handler.. */ +#define ENOIOCTLCMD 515 /* No ioctl command */ + +#define _LAST_ERRNO 515 + +#endif diff --git a/include/asm-sparc/global_data.h b/include/asm-sparc/global_data.h new file mode 100644 index 0000000000..7c29fc6840 --- /dev/null +++ b/include/asm-sparc/global_data.h @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +#include "asm/types.h" + +/* + * The following data structure is placed in some memory wich is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) + */ + +typedef struct global_data { + bd_t *bd; + unsigned long flags; + unsigned long baudrate; + unsigned long cpu_clk; /* CPU clock in Hz! */ + unsigned long bus_clk; + + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long reset_status; /* reset status register at boot */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + unsigned long have_console; /* serial_init() was called */ + +#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) + unsigned long fb_base; /* Base address of framebuffer memory */ +#endif +#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) + unsigned long post_log_word; /* Record POST activities */ + unsigned long post_init_f_time; /* When post_init_f started */ +#endif +#ifdef CONFIG_BOARD_TYPES + unsigned long board_type; +#endif +#ifdef CONFIG_MODEM_SUPPORT + unsigned long do_mdm_init; + unsigned long be_quiet; +#endif +#ifdef CONFIG_LWMON + unsigned long kbd_status; +#endif + void **jt; /* jump table */ +} gd_t; + +/* + * Global Data Flags + */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ +#define GD_FLG_SILENT 0x00004 /* Silent mode */ + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("%g7") + +#endif /* __ASM_GBL_DATA_H */ diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h new file mode 100644 index 0000000000..2a27d06798 --- /dev/null +++ b/include/asm-sparc/io.h @@ -0,0 +1,94 @@ +/* SPARC I/O definitions + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_IO_H +#define _SPARC_IO_H + +/* Nothing to sync, total store ordering (TSO)... */ +#define sync() + +/* Forces a cache miss on read/load. + * On some architectures we need to bypass the cache when reading + * I/O registers so that we are not reading the same status word + * over and over again resulting in a hang (until an IRQ if lucky) + * + */ +#ifndef CFG_HAS_NO_CACHE +#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)(var)) +#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var)) +#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)(var)) +#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var)) +#else +#define READ_BYTE(var) (var) +#define READ_HWORD(var) (var) +#define READ_WORD(var) (var) +#define READ_DWORD(var) (var) +#endif + +/* + * Generic virtual read/write. + */ +#define __arch_getb(a) (READ_BYTE(a)) +#define __arch_getw(a) (READ_HWORD(a)) +#define __arch_getl(a) (READ_WORD(a)) +#define __arch_getq(a) (READ_DWORD(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) +#define __raw_readq(a) __arch_getq(a) + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +typedef unsigned long phys_addr_t; + +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void *map_physmem(phys_addr_t paddr, unsigned long len, + unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ + +} + +#endif diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h new file mode 100644 index 0000000000..c5538c092d --- /dev/null +++ b/include/asm-sparc/irq.h @@ -0,0 +1,49 @@ +/* IRQ functions + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_IRQ_H__ +#define __SPARC_IRQ_H__ + +#include + +/* Set SPARC Processor Interrupt Level */ +extern inline void set_pil(unsigned int level) +{ + unsigned int psr = get_psr(); + + put_psr((psr & ~PSR_PIL) | ((level & 0xf) << PSR_PIL_OFS)); +} + +/* Get SPARC Processor Interrupt Level */ +extern inline unsigned int get_pil(void) +{ + unsigned int psr = get_psr(); + return (psr & PSR_PIL) >> PSR_PIL_OFS; +} + +/* Disables interrupts and return current PIL value */ +extern int intLock(void); + +/* Sets the PIL to oldLevel */ +extern void intUnlock(int oldLevel); + +#endif diff --git a/include/asm-sparc/machines.h b/include/asm-sparc/machines.h new file mode 100644 index 0000000000..1e26195991 --- /dev/null +++ b/include/asm-sparc/machines.h @@ -0,0 +1,92 @@ +/* machines.h: Defines for taking apart the machine type value in the + * idprom and determining the kind of machine we are on. + * + * Taken from the SPARC port of Linux. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_MACHINES_H__ +#define __SPARC_MACHINES_H__ + +struct Sun_Machine_Models { + char *name; + unsigned char id_machtype; +}; + +/* Current number of machines we know about that has an IDPROM + * machtype entry including one entry for the 0x80 OBP machines. + */ +#define NUM_SUN_MACHINES 16 + +extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES]; + +/* The machine type in the idprom area looks like this: + * + * --------------- + * | ARCH | MACH | + * --------------- + * 7 4 3 0 + * + * The ARCH field determines the architecture line (sun4, sun4c, etc). + * The MACH field determines the machine make within that architecture. + */ + +#define SM_ARCH_MASK 0xf0 +#define SM_SUN4 0x20 +#define M_LEON2 0x30 +#define SM_SUN4C 0x50 +#define SM_SUN4M 0x70 +#define SM_SUN4M_OBP 0x80 + +#define SM_TYP_MASK 0x0f +/* Sun4 machines */ +#define SM_4_260 0x01 /* Sun 4/200 series */ +#define SM_4_110 0x02 /* Sun 4/100 series */ +#define SM_4_330 0x03 /* Sun 4/300 series */ +#define SM_4_470 0x04 /* Sun 4/400 series */ + +/* Leon machines */ +#define M_LEON2_SOC 0x01 /* Leon2 SoC */ + +/* Sun4c machines Full Name - PROM NAME */ +#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ +#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ +#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ +#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ +#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ +#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ +#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ + +/* Sun4m machines, these predate the OpenBoot. These values only mean + * something if the value in the ARCH field is SM_SUN4M, if it is + * SM_SUN4M_OBP then you have the following situation: + * 1) You either have a sun4d, a sun4e, or a recently made sun4m. + * 2) You have to consult OpenBoot to determine which machine this is. + */ +#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */ +#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */ +#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */ + +/* Sun4d machines -- N/A */ +/* Sun4e machines -- N/A */ +/* Sun4u machines -- N/A */ + +#endif /* !(_SPARC_MACHINES_H) */ diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h new file mode 100644 index 0000000000..484953a86d --- /dev/null +++ b/include/asm-sparc/page.h @@ -0,0 +1,43 @@ +/* page.h: Various defines and such for MMU operations on the Sparc for + * the Linux kernel. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_PAGE_H +#define _SPARC_PAGE_H + +#include +#ifdef CONFIG_SUN4 +#define PAGE_SHIFT 13 +#else +#define PAGE_SHIFT 12 +#endif + +#ifndef __ASSEMBLY__ +/* I have my suspicions... -DaveM */ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#else +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif + +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#endif /* _SPARC_PAGE_H */ diff --git a/include/asm-sparc/posix_types.h b/include/asm-sparc/posix_types.h new file mode 100644 index 0000000000..8d98b2a6a1 --- /dev/null +++ b/include/asm-sparc/posix_types.h @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007, taken from asm-ppc/posix_types.h + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_POSIX_TYPES_H__ +#define __SPARC_POSIX_TYPES_H__ + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int __kernel_dev_t; +typedef unsigned int __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned int __kernel_old_uid_t; +typedef unsigned int __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#ifndef __GNUC__ + +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) + +#else /* __GNUC__ */ + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set * fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL << _rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set * fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL << _rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set * p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL << _rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set * p) +{ + unsigned int *tmp = (unsigned int *)p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 8: + tmp[0] = 0; + tmp[1] = 0; + tmp[2] = 0; + tmp[3] = 0; + tmp[4] = 0; + tmp[5] = 0; + tmp[6] = 0; + tmp[7] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ +#endif /* __GNUC__ */ +#endif /* _SPARC_POSIX_TYPES_H */ diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h new file mode 100644 index 0000000000..31b44c5463 --- /dev/null +++ b/include/asm-sparc/processor.h @@ -0,0 +1,109 @@ +/* SPARC Processor specifics + * taken from the SPARC port of Linux (ptrace.h). + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_SPARC_PROCESSOR_H +#define __ASM_SPARC_PROCESSOR_H + +#include + +/* Includeprocessor specific header file here */ +#error Unknown SPARC Processor + +#ifndef __ASSEMBLY__ + +/* flush data cache */ +static __inline__ void sparc_dcache_flush_all(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory"); +} + +/* flush instruction cache */ +static __inline__ void sparc_icache_flush_all(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_IFLUSH):"memory"); +} + +/* do a cache miss load */ +static __inline__ unsigned long long sparc_load_reg_cachemiss_qword(unsigned + long paddr) +{ + unsigned long long retval; + __asm__ __volatile__("ldda [%1] %2, %0\n\t": + "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS)); + return retval; +} + +static __inline__ unsigned long sparc_load_reg_cachemiss(unsigned long paddr) +{ + unsigned long retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS)); + return retval; +} + +static __inline__ unsigned short sparc_load_reg_cachemiss_word(unsigned long + paddr) +{ + unsigned short retval; + __asm__ __volatile__("lduha [%1] %2, %0\n\t": + "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS)); + return retval; +} + +static __inline__ unsigned char sparc_load_reg_cachemiss_byte(unsigned long + paddr) +{ + unsigned char retval; + __asm__ __volatile__("lduba [%1] %2, %0\n\t": + "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS)); + return retval; +} + +/* do a physical address bypass write, i.e. for 0x80000000 */ +static __inline__ void sparc_store_reg_bypass(unsigned long paddr, + unsigned long value) +{ + __asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(value), "r"(paddr), + "i"(ASI_BYPASS):"memory"); +} + +static __inline__ unsigned long sparc_load_reg_bypass(unsigned long paddr) +{ + unsigned long retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval):"r"(paddr), "i"(ASI_BYPASS)); + return retval; +} + +/* Macros for bypassing cache when reading */ +#define SPARC_NOCACHE_READ_DWORD(address) sparc_load_reg_cachemiss_qword((unsigned int)(address)) +#define SPARC_NOCACHE_READ(address) sparc_load_reg_cachemiss((unsigned int)(address)) +#define SPARC_NOCACHE_READ_HWORD(address) sparc_load_reg_cachemiss_word((unsigned int)(address)) +#define SPARC_NOCACHE_READ_BYTE(address) sparc_load_reg_cachemiss_byte((unsigned int)(address)) + +#define SPARC_BYPASS_READ(address) sparc_load_reg_bypass((unsigned int)(address)) +#define SPARC_BYPASS_WRITE(address,value) sparc_store_reg_bypass((unsigned int)(address),(unsigned int)(value)) + +#endif + +#endif /* __ASM_SPARC_PROCESSOR_H */ diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h new file mode 100644 index 0000000000..d55cc863da --- /dev/null +++ b/include/asm-sparc/prom.h @@ -0,0 +1,297 @@ +/* OpenProm defines mainly taken from linux kernel header files + * + * openprom.h: Prom structures and defines for access to the OPENBOOT + * prom routines and data areas. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_OPENPROM_H__ +#define __SPARC_OPENPROM_H__ + +/* Empirical constants... */ +#define LINUX_OPPROM_MAGIC 0x10010407 + +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ +struct linux_dev_v0_funcs { + int (*v0_devopen) (char *device_str); + int (*v0_devclose) (int dev_desc); + int (*v0_rdblkdev) (int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev) (int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev) (int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev) (int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev) (int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev) (int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev) (int dev_desc, long logical_offst, int from); +}; + +/* V2 and later prom device operations. */ +struct linux_dev_v2_funcs { + int (*v2_inst2pkg) (int d); /* Convert ihandle to phandle */ + char *(*v2_dumb_mem_alloc) (char *va, unsigned sz); + void (*v2_dumb_mem_free) (char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char *(*v2_dumb_mmap) (char *virta, int which_io, unsigned paddr, + unsigned sz); + void (*v2_dumb_munmap) (char *virta, unsigned size); + + int (*v2_dev_open) (char *devpath); + void (*v2_dev_close) (int d); + int (*v2_dev_read) (int d, char *buf, int nbytes); + int (*v2_dev_write) (int d, char *buf, int nbytes); + int (*v2_dev_seek) (int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2) (void); + void (*v2_wheee3) (void); +}; + +struct linux_mlist_v0 { + struct linux_mlist_v0 *theres_more; + char *start_adr; + unsigned num_bytes; +}; + +struct linux_mem_v0 { + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ +}; + +/* Arguments sent to the kernel from the boot prompt. */ +struct linux_arguments_v0 { + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ +}; + +/* V2 and up boot things. */ +struct linux_bootargs_v2 { + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; +}; + +/* The top level PROM vector. */ +struct linux_romvec { + /* Version numbers. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; + + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; + + /* Node operations. */ + struct linux_nodeops *pv_nodeops; + + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; + + char *pv_stdin; + char *pv_stdout; +#define PROMDEV_KBD 0 /* input from keyboard */ +#define PROMDEV_SCREEN 0 /* output to screen */ +#define PROMDEV_TTYA 1 /* in/out to ttya */ +#define PROMDEV_TTYB 2 /* in/out to ttyb */ + + /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ + int (*pv_getchar) (void); + void (*pv_putchar) (int ch); + + /* Non-blocking variants. */ + int (*pv_nbgetchar) (void); + int (*pv_nbputchar) (int ch); + + void (*pv_putstr) (char *str, int len); + + /* Miscellany. */ + void (*pv_reboot) (char *bootstr); + void (*pv_printf) (__const__ char *fmt, ...); + void (*pv_abort) (void); + __volatile__ int *pv_ticks; + void (*pv_halt) (void); + void (**pv_synchook) (void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ + union { + void (*v0_eval) (int len, char *str); + void (*v2_eval) (char *str); + } pv_fortheval; + + struct linux_arguments_v0 **pv_v0bootargs; + + /* Get ether address. */ + unsigned int (*pv_enaddr) (int d, char *enaddr); + + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; + + int filler[15]; + + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt) (int ctxt, char *va, int pmeg); + + /* Prom version 3 Multiprocessor routines. This stuff is crazy. + * No joke. Calling these when there is only one cpu probably + * crashes the machine, have to test this. :-) + */ + + /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context + * 'thiscontext' executing at address 'prog_counter' + */ + int (*v3_cpustart) (unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); + + /* v3_cpustop() will cause cpu 'whichcpu' to stop executing + * until a resume cpu call is made. + */ + int (*v3_cpustop) (unsigned int whichcpu); + + /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or + * resume cpu call is made. + */ + int (*v3_cpuidle) (unsigned int whichcpu); + + /* v3_cpuresume() will resume processor 'whichcpu' executing + * starting with whatever 'pc' and 'npc' were left at the + * last 'idle' or 'stop' call. + */ + int (*v3_cpuresume) (unsigned int whichcpu); +}; + +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode) (int node); + int (*no_child) (int node); + int (*no_proplen) (int node, char *name); + int (*no_getprop) (int node, char *name, char *val); + int (*no_setprop) (int node, char *name, char *val, int len); + char *(*no_nextprop) (int node, char *name); +}; + +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + unsigned int which_io; /* is this in OBIO space? */ + unsigned int phys_addr; /* The physical address of this register */ + unsigned int reg_size; /* How many bytes does this register take up? */ +}; + +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; + +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; +}; + +/* Ranges and reg properties are a bit different for PCI. */ +struct linux_prom_pci_registers { + /* + * We don't know what information this field contain. + * We guess, PCI device function is in bits 15:8 + * So, ... + */ + unsigned int which_io; /* Let it be which_io */ + + unsigned int phys_hi; + unsigned int phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_ranges { + unsigned int child_phys_hi; /* Only certain bits are encoded here. */ + unsigned int child_phys_mid; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_pci_assigned_addresses { + unsigned int which_io; + + unsigned int phys_hi; + unsigned int phys_lo; + + unsigned int size_hi; + unsigned int size_lo; +}; + +struct linux_prom_ebus_ranges { + unsigned int child_phys_hi; + unsigned int child_phys_lo; + + unsigned int parent_phys_hi; + unsigned int parent_phys_mid; + unsigned int parent_phys_lo; + + unsigned int size; +}; + +/* Offset into the EEPROM where the id PROM is located on the 4c */ +#define IDPROM_OFFSET 0x7d8 + +/* On sun4m; physical. */ +/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ +#define IDPROM_OFFSET_M 0xfd8 + +struct idprom { + unsigned char id_format; /* Format identifier (always 0x01) */ + unsigned char id_machtype; /* Machine type */ + unsigned char id_ethaddr[6]; /* Hardware ethernet address */ + long id_date; /* Date of manufacture */ + unsigned int id_sernum:24; /* Unique serial number */ + unsigned char id_cksum; /* Checksum - xor of the data bytes */ + unsigned char reserved[16]; +}; + +extern struct idprom *idprom; +extern void idprom_init(void); + +#define IDPROM_SIZE (sizeof(struct idprom)) + +#endif /* !(__ASSEMBLY__) */ + +#endif diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h new file mode 100644 index 0000000000..fc779477e5 --- /dev/null +++ b/include/asm-sparc/psr.h @@ -0,0 +1,97 @@ +/* psr.h: This file holds the macros for masking off various parts of + * the processor status register on the Sparc. This is valid + * for Version 8. On the V9 this is renamed to the PSTATE + * register and its members are accessed as fields like + * PSTATE.PRIV for the current CPU privilege level. + * + * taken from the SPARC port of Linux, + * + * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_PSR_H__ +#define __SPARC_PSR_H__ + +/* The Sparc PSR fields are laid out as the following: + * + * ------------------------------------------------------------------------ + * | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP | + * | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 | + * ------------------------------------------------------------------------ + */ +#define PSR_CWP 0x0000001f /* current window pointer */ +#define PSR_ET 0x00000020 /* enable traps field */ +#define PSR_PS 0x00000040 /* previous privilege level */ +#define PSR_S 0x00000080 /* current privilege level */ +#define PSR_PIL 0x00000f00 /* processor interrupt level */ +#define PSR_EF 0x00001000 /* enable floating point */ +#define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_LE 0x00008000 /* SuperSparcII little-endian */ +#define PSR_ICC 0x00f00000 /* integer condition codes */ +#define PSR_C 0x00100000 /* carry bit */ +#define PSR_V 0x00200000 /* overflow bit */ +#define PSR_Z 0x00400000 /* zero bit */ +#define PSR_N 0x00800000 /* negative bit */ +#define PSR_VERS 0x0f000000 /* cpu-version field */ +#define PSR_IMPL 0xf0000000 /* cpu-implementation field */ + +#define PSR_PIL_OFS 8 + +#ifndef __ASSEMBLY__ +/* Get the %psr register. */ +extern __inline__ unsigned int get_psr(void) +{ + unsigned int psr; + __asm__ __volatile__("rd %%psr, %0\n\t" + "nop\n\t" "nop\n\t" "nop\n\t":"=r"(psr) + : /* no inputs */ + :"memory"); + + return psr; +} + +extern __inline__ void put_psr(unsigned int new_psr) +{ + __asm__ __volatile__("wr %0, 0x0, %%psr\n\t" "nop\n\t" "nop\n\t" "nop\n\t": /* no outputs */ + :"r"(new_psr) + :"memory", "cc"); +} + +/* Get the %fsr register. Be careful, make sure the floating point + * enable bit is set in the %psr when you execute this or you will + * incur a trap. + */ + +extern unsigned int fsr_storage; + +extern __inline__ unsigned int get_fsr(void) +{ + unsigned int fsr = 0; + + __asm__ __volatile__("st %%fsr, %1\n\t" + "ld %1, %0\n\t":"=r"(fsr) + :"m"(fsr_storage)); + + return fsr; +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC_PSR_H__) */ diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h new file mode 100644 index 0000000000..12a9c569a2 --- /dev/null +++ b/include/asm-sparc/ptrace.h @@ -0,0 +1,181 @@ +/* Contain the Stack frame layout on interrupt. pt_regs. + * taken from the SPARC port of Linux (ptrace.h). + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_PTRACE_H__ +#define __SPARC_PTRACE_H__ + +#include + +/* This struct defines the way the registers are stored on the + * stack during a system call and basically all traps. + */ + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long psr; + unsigned long pc; + unsigned long npc; + unsigned long y; + unsigned long u_regs[16]; /* globals and ins */ +}; + +#define UREG_G0 0 +#define UREG_G1 1 +#define UREG_G2 2 +#define UREG_G3 3 +#define UREG_G4 4 +#define UREG_G5 5 +#define UREG_G6 6 +#define UREG_G7 7 +#define UREG_I0 8 +#define UREG_I1 9 +#define UREG_I2 10 +#define UREG_I3 11 +#define UREG_I4 12 +#define UREG_I5 13 +#define UREG_I6 14 +#define UREG_I7 15 +#define UREG_WIM UREG_G0 +#define UREG_FADDR UREG_G0 +#define UREG_FP UREG_I6 +#define UREG_RETPC UREG_I7 + +/* A register window */ +struct reg_window { + unsigned long locals[8]; + unsigned long ins[8]; +}; + +/* A Sparc stack frame */ +struct sparc_stackf { + unsigned long locals[8]; + unsigned long ins[6]; + struct sparc_stackf *fp; + unsigned long callers_pc; + char *structptr; + unsigned long xargs[6]; + unsigned long xxargs[1]; +}; + +#define TRACEREG_SZ sizeof(struct pt_regs) +#define STACKFRAME_SZ sizeof(struct sparc_stackf) + +#else /* __ASSEMBLY__ */ +/* For assembly code. */ +#define TRACEREG_SZ 0x50 +#define STACKFRAME_SZ 0x60 +#endif + +/* + * The asm_offsets.h is a generated file, so we cannot include it. + * It may be OK for glibc headers, but it's utterly pointless for C code. + * The assembly code using those offsets has to include it explicitly. + */ +/* #include */ + +/* These are for pt_regs. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + +/* Reg_window offsets */ +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* Stack_frame offsets */ +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + +/* Stuff for the ptrace system call */ +#define PTRACE_SUNATTACH 10 +#define PTRACE_SUNDETACH 11 +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_READDATA 16 +#define PTRACE_WRITEDATA 17 +#define PTRACE_READTEXT 18 +#define PTRACE_WRITETEXT 19 +#define PTRACE_GETFPAREGS 20 +#define PTRACE_SETFPAREGS 21 + +#define PTRACE_GETUCODE 29 /* stupid bsd-ism */ + +#endif /* !(_SPARC_PTRACE_H) */ diff --git a/include/asm-sparc/srmmu.h b/include/asm-sparc/srmmu.h new file mode 100644 index 0000000000..5214d96a7e --- /dev/null +++ b/include/asm-sparc/srmmu.h @@ -0,0 +1,301 @@ +/* SRMMU page table defines and code, + * taken from the SPARC port of Linux + * + * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_SRMMU_H__ +#define __SPARC_SRMMU_H__ + +#include +#include + +/* Number of contexts is implementation-dependent; 64k is the most we support */ +#define SRMMU_MAX_CONTEXTS 65536 + +/* PMD_SHIFT determines the size of the area a second-level page table entry can map */ +#define SRMMU_REAL_PMD_SHIFT 18 +#define SRMMU_REAL_PMD_SIZE (1UL << SRMMU_REAL_PMD_SHIFT) +#define SRMMU_REAL_PMD_MASK (~(SRMMU_REAL_PMD_SIZE-1)) +#define SRMMU_REAL_PMD_ALIGN(__addr) (((__addr)+SRMMU_REAL_PMD_SIZE-1)&SRMMU_REAL_PMD_MASK) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define SRMMU_PGDIR_SHIFT 24 +#define SRMMU_PGDIR_SIZE (1UL << SRMMU_PGDIR_SHIFT) +#define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1)) +#define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK) + +#define SRMMU_REAL_PTRS_PER_PTE 64 +#define SRMMU_REAL_PTRS_PER_PMD 64 +#define SRMMU_PTRS_PER_PGD 256 + +#define SRMMU_REAL_PTE_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PTE*4) +#define SRMMU_PMD_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PMD*4) +#define SRMMU_PGD_TABLE_SIZE (SRMMU_PTRS_PER_PGD*4) + +/* + * To support pagetables in highmem, Linux introduces APIs which + * return struct page* and generally manipulate page tables when + * they are not mapped into kernel space. Our hardware page tables + * are smaller than pages. We lump hardware tabes into big, page sized + * software tables. + * + * PMD_SHIFT determines the size of the area a second-level page table entry + * can map, and our pmd_t is 16 times larger than normal. The values which + * were once defined here are now generic for 4c and srmmu, so they're + * found in pgtable.h. + */ +#define SRMMU_PTRS_PER_PMD 4 + +/* Definition of the values in the ET field of PTD's and PTE's */ +#define SRMMU_ET_MASK 0x3 +#define SRMMU_ET_INVALID 0x0 +#define SRMMU_ET_PTD 0x1 +#define SRMMU_ET_PTE 0x2 +#define SRMMU_ET_REPTE 0x3 /* AIEEE, SuperSparc II reverse endian page! */ + +/* Physical page extraction from PTP's and PTE's. */ +#define SRMMU_CTX_PMASK 0xfffffff0 +#define SRMMU_PTD_PMASK 0xfffffff0 +#define SRMMU_PTE_PMASK 0xffffff00 + +/* The pte non-page bits. Some notes: + * 1) cache, dirty, valid, and ref are frobbable + * for both supervisor and user pages. + * 2) exec and write will only give the desired effect + * on user pages + * 3) use priv and priv_readonly for changing the + * characteristics of supervisor ptes + */ +#define SRMMU_CACHE 0x80 +#define SRMMU_DIRTY 0x40 +#define SRMMU_REF 0x20 +#define SRMMU_NOREAD 0x10 +#define SRMMU_EXEC 0x08 +#define SRMMU_WRITE 0x04 +#define SRMMU_VALID 0x02 /* SRMMU_ET_PTE */ +#define SRMMU_PRIV 0x1c +#define SRMMU_PRIV_RDONLY 0x18 + +#define SRMMU_FILE 0x40 /* Implemented in software */ + +#define SRMMU_PTE_FILE_SHIFT 8 /* == 32-PTE_FILE_MAX_BITS */ + +#define SRMMU_CHG_MASK (0xffffff00 | SRMMU_REF | SRMMU_DIRTY) + +/* SRMMU swap entry encoding + * + * We use 5 bits for the type and 19 for the offset. This gives us + * 32 swapfiles of 4GB each. Encoding looks like: + * + * oooooooooooooooooootttttRRRRRRRR + * fedcba9876543210fedcba9876543210 + * + * The bottom 8 bits are reserved for protection and status bits, especially + * FILE and PRESENT. + */ +#define SRMMU_SWP_TYPE_MASK 0x1f +#define SRMMU_SWP_TYPE_SHIFT SRMMU_PTE_FILE_SHIFT +#define SRMMU_SWP_OFF_MASK 0x7ffff +#define SRMMU_SWP_OFF_SHIFT (SRMMU_PTE_FILE_SHIFT + 5) + +/* Some day I will implement true fine grained access bits for + * user pages because the SRMMU gives us the capabilities to + * enforce all the protection levels that vma's can have. + * XXX But for now... + */ +#define SRMMU_PAGE_NONE __pgprot(SRMMU_CACHE | \ + SRMMU_PRIV | SRMMU_REF) +#define SRMMU_PAGE_SHARED __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF) +#define SRMMU_PAGE_COPY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_REF) +#define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_REF) +#define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ + SRMMU_DIRTY | SRMMU_REF) + +/* SRMMU Register addresses in ASI 0x4. These are valid for all + * current SRMMU implementations that exist. + */ +#define SRMMU_CTRL_REG 0x00000000 +#define SRMMU_CTXTBL_PTR 0x00000100 +#define SRMMU_CTX_REG 0x00000200 +#define SRMMU_FAULT_STATUS 0x00000300 +#define SRMMU_FAULT_ADDR 0x00000400 + +#define WINDOW_FLUSH(tmp1, tmp2) \ + mov 0, tmp1; \ +98: ld [%g6 + TI_UWINMASK], tmp2; \ + orcc %g0, tmp2, %g0; \ + add tmp1, 1, tmp1; \ + bne 98b; \ + save %sp, -64, %sp; \ +99: subcc tmp1, 1, tmp1; \ + bne 99b; \ + restore %g0, %g0, %g0; + +#ifndef __ASSEMBLY__ + +/* This makes sense. Honest it does - Anton */ +/* XXX Yes but it's ugly as sin. FIXME. -KMW */ +extern void *srmmu_nocache_pool; +#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool)) +#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR) +#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR)) + +/* Accessing the MMU control register. */ +extern __inline__ unsigned int srmmu_get_mmureg(void) +{ + unsigned int retval; + __asm__ __volatile__("lda [%%g0] %1, %0\n\t": + "=r"(retval):"i"(ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ void srmmu_set_mmureg(unsigned long regval) +{ + __asm__ __volatile__("sta %0, [%%g0] %1\n\t"::"r"(regval), + "i"(ASI_M_MMUREGS):"memory"); + +} + +extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr) +{ + paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); + __asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(paddr), + "r"(SRMMU_CTXTBL_PTR), + "i"(ASI_M_MMUREGS):"memory"); +} + +extern __inline__ unsigned long srmmu_get_ctable_ptr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval): + "r"(SRMMU_CTXTBL_PTR), "i"(ASI_M_MMUREGS)); + return (retval & SRMMU_CTX_PMASK) << 4; +} + +extern __inline__ void srmmu_set_context(int context) +{ + __asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(context), + "r"(SRMMU_CTX_REG), "i"(ASI_M_MMUREGS):"memory"); +} + +extern __inline__ int srmmu_get_context(void) +{ + register int retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval): + "r"(SRMMU_CTX_REG), "i"(ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ unsigned int srmmu_get_fstatus(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval): + "r"(SRMMU_FAULT_STATUS), "i"(ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ unsigned int srmmu_get_faddr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval): + "r"(SRMMU_FAULT_ADDR), "i"(ASI_M_MMUREGS)); + return retval; +} + +/* This is guaranteed on all SRMMU's. */ +extern __inline__ void srmmu_flush_whole_tlb(void) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400), /* Flush entire TLB!! */ + "i"(ASI_M_FLUSH_PROBE):"memory"); + +} + +/* These flush types are not available on all chips... */ +extern __inline__ void srmmu_flush_tlb_ctx(void) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x300), /* Flush TLB ctx.. */ + "i"(ASI_M_FLUSH_PROBE):"memory"); + +} + +extern __inline__ void srmmu_flush_tlb_region(unsigned long addr) +{ + addr &= SRMMU_PGDIR_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(addr | 0x200), /* Flush TLB region.. */ + "i"(ASI_M_FLUSH_PROBE):"memory"); + +} + +extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr) +{ + addr &= SRMMU_REAL_PMD_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(addr | 0x100), /* Flush TLB segment.. */ + "i"(ASI_M_FLUSH_PROBE):"memory"); + +} + +extern __inline__ void srmmu_flush_tlb_page(unsigned long page) +{ + page &= PAGE_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(page), /* Flush TLB page.. */ + "i"(ASI_M_FLUSH_PROBE):"memory"); + +} + +extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr) +{ + unsigned long retval; + + vaddr &= PAGE_MASK; + __asm__ __volatile__("lda [%1] %2, %0\n\t": + "=r"(retval): + "r"(vaddr | 0x400), "i"(ASI_M_FLUSH_PROBE)); + + return retval; +} + +extern __inline__ int srmmu_get_pte(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("\n\tlda [%1] %2,%0\n\t": + "=r"(entry): + "r"((addr & 0xfffff000) | 0x400), + "i"(ASI_M_FLUSH_PROBE)); + return entry; +} + +extern unsigned long (*srmmu_read_physical) (unsigned long paddr); +extern void (*srmmu_write_physical) (unsigned long paddr, unsigned long word); + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC_SRMMU_H__) */ diff --git a/include/asm-sparc/stack.h b/include/asm-sparc/stack.h new file mode 100644 index 0000000000..b40a9f355f --- /dev/null +++ b/include/asm-sparc/stack.h @@ -0,0 +1,162 @@ +/* SPARC stack layout Macros and structures, + * mainly taken from BCC (the Bare C compiler for + * SPARC LEON2/3) sources. + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __SPARC_STACK_H__ +#define __SPARC_STACK_H__ + +#include + +#ifndef __ASSEMBLER__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define PT_REGS_SZ sizeof(struct pt_regs) + +/* A Sparc stack frame */ + struct sparc_stackframe_regs { + unsigned long sf_locals[8]; + unsigned long sf_ins[6]; + struct sparc_stackframe_regs *sf_fp; + unsigned long sf_callers_pc; + char *sf_structptr; + unsigned long sf_xargs[6]; + unsigned long sf_xxargs[1]; + }; +#define SF_REGS_SZ sizeof(struct sparc_stackframe_regs) + +/* A register window */ + struct sparc_regwindow_regs { + unsigned long locals[8]; + unsigned long ins[8]; + }; +#define RW_REGS_SZ sizeof(struct sparc_regwindow_regs) + +/* A fpu window */ + struct sparc_fpuwindow_regs { + unsigned long locals[32]; + unsigned long fsr; + unsigned long lastctx; + }; +#define FW_REGS_SZ sizeof(struct sparc_fpuwindow_regs) + +#ifdef __cplusplus +} +#endif +#else +#define PT_REGS_SZ 0x50 /* 20*4 */ +#define SF_REGS_SZ 0x60 /* 24*4 */ +#define RW_REGS_SZ 0x20 /* 16*4 */ +#define FW_REGS_SZ 0x88 /* 34*4 */ +#endif /* !ASM */ + +/* These are for pt_regs. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + +/* Stack_frame offsets */ +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + +/* Reg_window offsets */ +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* Fpu_window offsets */ +#define FW_F0 0x00 +#define FW_F2 0x08 +#define FW_F4 0x10 +#define FW_F6 0x18 +#define FW_F8 0x20 +#define FW_F10 0x28 +#define FW_F12 0x30 +#define FW_F14 0x38 +#define FW_F16 0x40 +#define FW_F18 0x48 +#define FW_F20 0x50 +#define FW_F22 0x58 +#define FW_F24 0x60 +#define FW_F26 0x68 +#define FW_F28 0x70 +#define FW_F30 0x78 +#define FW_FSR 0x80 + +#endif diff --git a/include/asm-sparc/string.h b/include/asm-sparc/string.h new file mode 100644 index 0000000000..c6bbc203d5 --- /dev/null +++ b/include/asm-sparc/string.h @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_STRING_H_ +#define _SPARC_STRING_H_ + +/* +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRLEN +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_BCOPY +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_MEMCHR +*/ + +extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); +extern char *strcpy(char *, const char *); +extern char *strncpy(char *, const char *, __kernel_size_t); +extern __kernel_size_t strlen(const char *); +extern int strcmp(const char *, const char *); +extern char *strcat(char *, const char *); +extern void *memset(void *, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t); +extern int memcmp(const void *, const void *, __kernel_size_t); +extern void *memchr(const void *, int, __kernel_size_t); + +#endif diff --git a/include/asm-sparc/types.h b/include/asm-sparc/types.h new file mode 100644 index 0000000000..69f93d60b8 --- /dev/null +++ b/include/asm-sparc/types.h @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _SPARC_TYPES_H +#define _SPARC_TYPES_H + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +typedef struct { + __u32 u[4]; +} __attribute((aligned(16))) vector128; + +#ifdef __KERNEL__ +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* DMA addresses are 32-bits wide */ +typedef u32 dma_addr_t; + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-sparc/u-boot.h b/include/asm-sparc/u-boot.h new file mode 100644 index 0000000000..9c594e1f8c --- /dev/null +++ b/include/asm-sparc/u-boot.h @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007, From asm-ppc/u-boot.h + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef __U_BOOT_H__ +#define __U_BOOT_H__ + +/* + * Currently, this Board information is not passed to + * Linux kernel from U-Boot, but may be passed to other + * Operating systems. This is because U-boot emulates + * a SUN PROM loader (from Linux point of view). + * + * include/asm-sparc/u-boot.h + */ + +#ifndef __ASSEMBLY__ + +typedef struct bd_info { + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ + unsigned long bi_sramstart; /* start of SRAM memory */ + unsigned long bi_sramsize; /* size of SRAM memory */ + unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ + unsigned long bi_intfreq; /* Internal Freq, in MHz */ + unsigned long bi_busfreq; /* Bus Freq, in MHz */ + unsigned long bi_baudrate; /* Console Baudrate */ +#ifdef CONFIG_HAS_ETH1 + /* second onboard ethernet port */ + unsigned char bi_enet1addr[6]; +#endif +#ifdef CONFIG_HAS_ETH2 + /* third onboard ethernet port */ + unsigned char bi_enet2addr[6]; +#endif +#ifdef CONFIG_HAS_ETH3 + unsigned char bi_enet3addr[6]; +#endif +} bd_t; + +#endif /* __ASSEMBLY__ */ +#endif /* __U_BOOT_H__ */ diff --git a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h new file mode 100644 index 0000000000..66fc639a7e --- /dev/null +++ b/include/asm-sparc/winmacro.h @@ -0,0 +1,151 @@ +/* + * Added to U-boot, + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * Copyright (C) 2007 + * + * LEON2/3 LIBIO low-level routines + * Written by Jiri Gaisler. + * Copyright (C) 2004 Gaisler Research AB + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef __SPARC_WINMACRO_H__ +#define __SPARC_WINMACRO_H__ + +#include +#include + +/* Store the register window onto the 8-byte aligned area starting + * at %reg. It might be %sp, it might not, we don't care. + */ +#define RW_STORE(reg) \ + std %l0, [%reg + RW_L0]; \ + std %l2, [%reg + RW_L2]; \ + std %l4, [%reg + RW_L4]; \ + std %l6, [%reg + RW_L6]; \ + std %i0, [%reg + RW_I0]; \ + std %i2, [%reg + RW_I2]; \ + std %i4, [%reg + RW_I4]; \ + std %i6, [%reg + RW_I6]; + +/* Load a register window from the area beginning at %reg. */ +#define RW_LOAD(reg) \ + ldd [%reg + RW_L0], %l0; \ + ldd [%reg + RW_L2], %l2; \ + ldd [%reg + RW_L4], %l4; \ + ldd [%reg + RW_L6], %l6; \ + ldd [%reg + RW_I0], %i0; \ + ldd [%reg + RW_I2], %i2; \ + ldd [%reg + RW_I4], %i4; \ + ldd [%reg + RW_I6], %i6; + +/* Loading and storing struct pt_reg trap frames. */ +#define PT_LOAD_INS(base_reg) \ + ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \ + ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \ + ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \ + ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6; + +#define PT_LOAD_GLOBALS(base_reg) \ + ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \ + ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \ + ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \ + ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6; + +#define PT_LOAD_YREG(base_reg, scratch) \ + ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \ + wr %scratch, 0x0, %y; + +#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \ + ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \ + ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc; + +#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ + PT_LOAD_YREG(base_reg, scratch) \ + PT_LOAD_INS(base_reg) \ + PT_LOAD_GLOBALS(base_reg) \ + PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) + +#define PT_STORE_INS(base_reg) \ + std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \ + std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \ + std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \ + std %i6, [%base_reg + SF_REGS_SZ + PT_I6]; + +#define PT_STORE_GLOBALS(base_reg) \ + st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \ + std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \ + std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \ + std %g6, [%base_reg + SF_REGS_SZ + PT_G6]; + +#define PT_STORE_YREG(base_reg, scratch) \ + rd %y, %scratch; \ + st %scratch, [%base_reg + SF_REGS_SZ + PT_Y]; + +#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \ + st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \ + st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC]; + +#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ + PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ + PT_STORE_GLOBALS(base_reg) \ + PT_STORE_YREG(base_reg, g_scratch) \ + PT_STORE_INS(base_reg) + +/* Store the fpu register window*/ +#define FW_STORE(reg) \ + std %f0, [reg + FW_F0]; \ + std %f2, [reg + FW_F2]; \ + std %f4, [reg + FW_F4]; \ + std %f6, [reg + FW_F6]; \ + std %f8, [reg + FW_F8]; \ + std %f10, [reg + FW_F10]; \ + std %f12, [reg + FW_F12]; \ + std %f14, [reg + FW_F14]; \ + std %f16, [reg + FW_F16]; \ + std %f18, [reg + FW_F18]; \ + std %f20, [reg + FW_F20]; \ + std %f22, [reg + FW_F22]; \ + std %f24, [reg + FW_F24]; \ + std %f26, [reg + FW_F26]; \ + std %f28, [reg + FW_F28]; \ + std %f30, [reg + FW_F30]; \ + st %fsr, [reg + FW_FSR]; + +/* Load a fpu register window from the area beginning at reg. */ +#define FW_LOAD(reg) \ + ldd [reg + FW_F0], %f0; \ + ldd [reg + FW_F2], %f2; \ + ldd [reg + FW_F4], %f4; \ + ldd [reg + FW_F6], %f6; \ + ldd [reg + FW_F8], %f8; \ + ldd [reg + FW_F10], %f10; \ + ldd [reg + FW_F12], %f12; \ + ldd [reg + FW_F14], %f14; \ + ldd [reg + FW_F16], %f16; \ + ldd [reg + FW_F18], %f18; \ + ldd [reg + FW_F20], %f20; \ + ldd [reg + FW_F22], %f22; \ + ldd [reg + FW_F24], %f24; \ + ldd [reg + FW_F26], %f26; \ + ldd [reg + FW_F28], %f28; \ + ldd [reg + FW_F30], %f30; \ + ld [reg + FW_FSR], %fsr; + +#endif diff --git a/lib_sparc/Makefile b/lib_sparc/Makefile new file mode 100644 index 0000000000..1a354b6eab --- /dev/null +++ b/lib_sparc/Makefile @@ -0,0 +1,45 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(ARCH).a + +SOBJS = + +COBJS = board.o cache.o interrupts.o time.o bootm.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/lib_sparc/board.c b/lib_sparc/board.c new file mode 100644 index 0000000000..af301c046e --- /dev/null +++ b/lib_sparc/board.c @@ -0,0 +1,521 @@ +/* SPARC Board initialization + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#if defined(CONFIG_CMD_IDE) +#include +#endif +#ifdef CONFIG_STATUS_LED +#include +#endif +#include +#include +#include +#if defined(CONFIG_POST) +#include +#endif +#ifdef CONFIG_PS2KBD +#include +#endif +#ifdef CONFIG_CMD_AMBAPP +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* Debug options +#define DEBUG_INIT_SEQUENCE +#define DEBUG_MEM_LAYOUT +#define DEBUG_COMMANDS +*/ + +extern void timer_interrupt_init(void); +extern void malloc_bin_reloc(void); +extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +extern int prom_init(void); + +#if defined(CONFIG__CMD_DOC) +void doc_init(void); +#endif + +#if !defined(CFG_NO_FLASH) +static char *failed = "*** failed ***\n"; +#endif + +#include + +ulong monitor_flash_len; + +/* + * Begin and End of memory area for malloc(), and current "brk" + */ +static ulong mem_malloc_start = 0; +static ulong mem_malloc_end = 0; +static ulong mem_malloc_brk = 0; + +/************************************************************************ + * Utilities * + ************************************************************************ + */ + +/* + * The Malloc area is immediately below the monitor copy in RAM + */ +static void mem_malloc_init(void) +{ + mem_malloc_start = CFG_MALLOC_BASE; + mem_malloc_end = CFG_MALLOC_END; + mem_malloc_brk = mem_malloc_start; + memset((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); +} + +void *sbrk(ptrdiff_t increment) +{ + ulong old = mem_malloc_brk; + ulong new = old + increment; + + if ((new < mem_malloc_start) || (new > mem_malloc_end)) { + return (NULL); + } + mem_malloc_brk = new; + return ((void *)old); +} + +/***********************************************************************/ + +/************************************************************************ + * Init Utilities * + ************************************************************************ + * Some of this code should be moved into the core functions, + * but let's get it working (again) first... + */ + +static int init_baudrate(void) +{ + char tmp[64]; /* long enough for environment variables */ + int i = getenv_r("baudrate", tmp, sizeof(tmp)); + + gd->baudrate = (i > 0) + ? (int)simple_strtoul(tmp, NULL, 10) + : CONFIG_BAUDRATE; + return (0); +} + +/***********************************************************************/ + +/* + * All attempts to come up with a "common" initialization sequence + * that works for all boards and architectures failed: some of the + * requirements are just _too_ different. To get rid of the resulting + * mess of board dependend #ifdef'ed code we now make the whole + * initialization sequence configurable to the user. + * + * The requirements for any new initalization function is simple: it + * receives a pointer to the "global data" structure as it's only + * argument, and returns an integer return code, where 0 means + * "continue" and != 0 means "fatal error, hang the system". + */ +typedef int (init_fnc_t) (void); + +#define WATCHDOG_RESET(x) + +/************************************************************************ + * Initialization sequence * + ************************************************************************ + */ + +init_fnc_t *init_sequence[] = { + +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, +#endif + serial_init, + + init_timebase, + +#if defined(CONFIG_CMD_AMBAPP) + ambapp_init_reloc, +#endif + + env_init, + + init_baudrate, + + console_init_f, + display_options, + + checkcpu, + checkboard, +#if defined(CONFIG_MISC_INIT_F) + misc_init_f, +#endif + +#ifdef CONFIG_POST + post_init_f, +#endif + + NULL, /* Terminate this list, + * beware: this list will be relocated + * which means that NULL will become + * NULL+RELOC_OFFSET. We simply make + * NULL be -RELOC_OFFSET instead. + */ +}; + +/************************************************************************ + * + * This is the SPARC board initialization routine, running from RAM. + * + ************************************************************************ + */ +#ifdef DEBUG_INIT_SEQUENCE +char *str_init_seq = "INIT_SEQ 00\n"; +char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n"; +#endif + +void board_init_f(ulong bootflag) +{ + cmd_tbl_t *cmdtp; + bd_t *bd; + unsigned char *s; + init_fnc_t **init_fnc_ptr; + int j; + int i; + char *e; + +#ifndef CFG_NO_FLASH + ulong flash_size; +#endif + + gd = (gd_t *) (CFG_GBL_DATA_OFFSET); + + /* Clear initial global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + gd->bd = (bd_t *) (gd + 1); /* At end of global data */ + gd->baudrate = CONFIG_BAUDRATE; + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + + bd = gd->bd; + bd->bi_memstart = CFG_RAM_BASE; + bd->bi_memsize = CFG_RAM_SIZE; + bd->bi_flashstart = CFG_FLASH_BASE; +#if defined(CFG_SRAM_BASE) && defined(CFG_SRAM_SIZE) + bd->bi_sramstart = CFG_SRAM_BASE; + bd->bi_sramsize = CFG_SRAM_SIZE; +#endif + bd->bi_baudrate = CONFIG_BAUDRATE; + bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */ + + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + gd->reloc_off = CFG_RELOC_MONITOR_BASE - CFG_MONITOR_BASE; + + for (init_fnc_ptr = init_sequence, j = 0; *init_fnc_ptr; + ++init_fnc_ptr, j++) { +#ifdef DEBUG_INIT_SEQUENCE + if (j > 9) + str_init_seq[9] = '0' + (j / 10); + str_init_seq[10] = '0' + (j - (j / 10) * 10); + serial_puts(str_init_seq); +#endif + if ((*init_fnc_ptr + gd->reloc_off) () != 0) { + hang(); + } + } +#ifdef DEBUG_INIT_SEQUENCE + serial_puts(str_init_seq_done); +#endif + + /* + * Now that we have DRAM mapped and working, we can + * relocate the code and continue running from DRAM. + * + * Reserve memory at end of RAM for (top down in that order): + * - kernel log buffer + * - protected RAM + * - LCD framebuffer + * - monitor code + * - board info struct + */ +#ifdef DEBUG_MEM_LAYOUT + printf("CFG_MONITOR_BASE: 0x%lx\n", CFG_MONITOR_BASE); + printf("CFG_ENV_ADDR: 0x%lx\n", CFG_ENV_ADDR); + printf("CFG_RELOC_MONITOR_BASE: 0x%lx (%d)\n", CFG_RELOC_MONITOR_BASE, + CFG_MONITOR_LEN); + printf("CFG_MALLOC_BASE: 0x%lx (%d)\n", CFG_MALLOC_BASE, + CFG_MALLOC_LEN); + printf("CFG_INIT_SP_OFFSET: 0x%lx (%d)\n", CFG_INIT_SP_OFFSET, + CFG_STACK_SIZE); + printf("CFG_PROM_OFFSET: 0x%lx (%d)\n", CFG_PROM_OFFSET, + CFG_PROM_SIZE); + printf("CFG_GBL_DATA_OFFSET: 0x%lx (%d)\n", CFG_GBL_DATA_OFFSET, + CFG_GBL_DATA_SIZE); +#endif + +#ifdef CONFIG_POST + post_bootmode_init(); + post_run(NULL, POST_ROM | post_bootmode_get(0)); +#endif + + /* + * We have to relocate the command table manually + */ + for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) { + ulong addr; + addr = (ulong) (cmdtp->cmd) + gd->reloc_off; +#if DEBUG_COMMANDS + printf("Command \"%s\": 0x%08lx => 0x%08lx\n", + cmdtp->name, (ulong) (cmdtp->cmd), addr); +#endif + cmdtp->cmd = + (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr; + + addr = (ulong) (cmdtp->name) + gd->reloc_off; + cmdtp->name = (char *)addr; + + if (cmdtp->usage) { + addr = (ulong) (cmdtp->usage) + gd->reloc_off; + cmdtp->usage = (char *)addr; + } +#ifdef CFG_LONGHELP + if (cmdtp->help) { + addr = (ulong) (cmdtp->help) + gd->reloc_off; + cmdtp->help = (char *)addr; + } +#endif + } + +#if defined(CONFIG_CMD_AMBAPP) && defined(CFG_AMBAPP_PRINT_ON_STARTUP) + puts("AMBA:\n"); + do_ambapp_print(NULL, 0, 0, NULL); +#endif + + /* initialize higher level parts of CPU like time base and timers */ + cpu_init_r(); + + /* start timer */ + timer_interrupt_init(); + + /* + * Enable Interrupts before any calls to udelay, + * the flash driver may use udelay resulting in + * a hang if not timer0 IRQ is enabled. + */ + interrupt_init(); + +#if !defined(CFG_NO_FLASH) + puts("FLASH: "); + + if ((flash_size = flash_init()) > 0) { +# ifdef CFG_FLASH_CHECKSUM + print_size(flash_size, ""); + /* + * Compute and print flash CRC if flashchecksum is set to 'y' + * + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + */ + s = getenv("flashchecksum"); + if (s && (*s == 'y')) { + printf(" CRC: %08lX", + crc32(0, (const unsigned char *)CFG_FLASH_BASE, + flash_size) + ); + } + putc('\n'); +# else /* !CFG_FLASH_CHECKSUM */ + print_size(flash_size, "\n"); +# endif /* CFG_FLASH_CHECKSUM */ + } else { + puts(failed); + hang(); + } + + bd->bi_flashstart = CFG_FLASH_BASE; /* update start of FLASH memory */ + bd->bi_flashsize = flash_size; /* size of FLASH memory (final value) */ +#if CFG_MONITOR_BASE == CFG_FLASH_BASE + bd->bi_flashoffset = monitor_flash_len; /* reserved area for startup monitor */ +#else + bd->bi_flashoffset = 0; +#endif +#else /* CFG_NO_FLASH */ + bd->bi_flashsize = 0; + bd->bi_flashstart = 0; + bd->bi_flashoffset = 0; +#endif /* !CFG_NO_FLASH */ + + /* initialize malloc() area */ + mem_malloc_init(); + + malloc_bin_reloc(); + +#ifdef CONFIG_SPI +# if !defined(CFG_ENV_IS_IN_EEPROM) + spi_init_f(); +# endif + spi_init_r(); +#endif + + /* relocate environment function pointers etc. */ + env_relocate(); + +#if defined(CONFIG_BOARD_LATE_INIT) + board_late_init(); +#endif + + s = getenv("ethaddr"); + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + +#ifdef CONFIG_HAS_ETH1 + /* handle the 2nd ethernet address */ + + s = getenv("eth1addr"); + + for (i = 0; i < 6; ++i) { + bd->bi_enet1addr[i] = s ? simple_strtoul(s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } +#endif + +#ifdef CFG_ID_EEPROM + mac_read_from_eeprom(); +#endif + + /* IP Address */ + bd->bi_ip_addr = getenv_IPaddr("ipaddr"); +#if defined(CONFIG_PCI) + /* + * Do pci configuration + */ + pci_init(); +#endif + + /* Initialize devices */ + devices_init(); + + /* Initialize the jump table for applications */ + jumptable_init(); + + /* Initialize the console (after the relocation and devices init) */ + console_init_r(); + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO + serial_buffered_init(); +#endif + +#ifdef CONFIG_STATUS_LED + status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); +#endif + + udelay(20); + + set_timer(0); + + /* Initialize from environment */ + if ((s = getenv("loadaddr")) != NULL) { + load_addr = simple_strtoul(s, NULL, 16); + } +#if defined(CONFIG_CMD_NET) + if ((s = getenv("bootfile")) != NULL) { + copy_filename(BootFile, s, sizeof(BootFile)); + } +#endif /* CFG_CMD_NET */ + + WATCHDOG_RESET(); + +#if defined(CONFIG_CMD_DOC) + WATCHDOG_RESET(); + puts("DOC: "); + doc_init(); +#endif + +#if defined(CONFIG_CMD_NET) +#if defined(CONFIG_NET_MULTI) + WATCHDOG_RESET(); + puts("Net: "); +#endif + eth_initialize(bd); +#endif + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) + WATCHDOG_RESET(); + debug("Reset Ethernet PHY\n"); + reset_phy(); +#endif + +#ifdef CONFIG_POST + post_run(NULL, POST_RAM | post_bootmode_get(0)); +#endif + +#if defined(CONFIG_CMD_IDE) + WATCHDOG_RESET(); + puts("IDE: "); + ide_init(); +#endif /* CFG_CMD_IDE */ + +#ifdef CONFIG_LAST_STAGE_INIT + WATCHDOG_RESET(); + /* + * Some parts can be only initialized if all others (like + * Interrupts) are up and running (i.e. the PC-style ISA + * keyboard). + */ + last_stage_init(); +#endif + +#ifdef CONFIG_PS2KBD + puts("PS/2: "); + kbd_init(); +#endif + prom_init(); + + /* main_loop */ + for (;;) { + WATCHDOG_RESET(); + main_loop(); + } + +} + +void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); +#ifdef CONFIG_SHOW_BOOT_PROGRESS + show_boot_progress(-30); +#endif + for (;;) ; +} + +/************************************************************************/ diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c new file mode 100644 index 0000000000..8900b2e581 --- /dev/null +++ b/lib_sparc/bootm.c @@ -0,0 +1,226 @@ +/* SPARC code for booting linux 2.6 + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#define PRINT_KERNEL_HEADER + +extern image_header_t header; +extern void srmmu_init_cpu(unsigned int entry); +extern void prepare_bootargs(char *bootargs); +extern int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); + +#ifdef CONFIG_USB_UHCI +extern int usb_lowlevel_stop(void); +#endif + +/* sparc kernel argument (the ROM vector) */ +struct linux_romvec *kernel_arg_promvec; + +/* page szie is 4k */ +#define PAGE_SIZE 0x1000 +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 +struct __attribute__ ((packed)) { + char traptable[PAGE_SIZE]; + char swapper_pg_dir[PAGE_SIZE]; + char pg0[PAGE_SIZE]; + char pg1[PAGE_SIZE]; + char pg2[PAGE_SIZE]; + char pg3[PAGE_SIZE]; + char empty_bad_page[PAGE_SIZE]; + char empty_bad_page_table[PAGE_SIZE]; + char empty_zero_page[PAGE_SIZE]; + unsigned char hdr[4]; /* ascii "HdrS" */ + /* 00.02.06.0b is for Linux kernel 2.6.11 */ + unsigned char linuxver_mega_major; + unsigned char linuxver_major; + unsigned char linuxver_minor; + unsigned char linuxver_revision; + /* header version 0x0203 */ + unsigned short hdr_ver; + union __attribute__ ((packed)) { + struct __attribute__ ((packed)) { + unsigned short root_flags; + unsigned short root_dev; + unsigned short ram_flags; + unsigned int sparc_ramdisk_image; + unsigned int sparc_ramdisk_size; + unsigned int reboot_command; + unsigned int resv[3]; + unsigned int end; + } ver_0203; + } hdr_input; +} *linux_hdr; + +/* temporary initrd image holder */ +image_header_t ihdr; + +/* boot the linux kernel */ +void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + bootm_headers_t * images) +{ + char *bootargs; + ulong ep, load; + ulong initrd_start, initrd_end; + ulong rd_data_start, rd_data_end, rd_len; + unsigned int data, len, checksum; + unsigned int initrd_addr, kernend; + void (*kernel) (struct linux_romvec *, void *); + struct lmb *lmb = images->lmb; + int ret; + + if (images->legacy_hdr_valid) { + ep = image_get_ep(images->legacy_hdr_os); + load = image_get_load(images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret = fit_image_get_entry(images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts("Can't get entry point property!\n"); + goto error; + } + + ret = fit_image_get_load(images->fit_hdr_os, + images->fit_noffset_os, &load); + if (ret) { + puts("Can't get load address property!\n"); + goto error; + } +#endif + } else { + puts("Could not find kernel entry point!\n"); + goto error; + } + + /* Get virtual address of kernel start */ + linux_hdr = (void *)load; + + /* */ + kernel = (void (*)(struct linux_romvec *, void *))ep; + + /* check for a SPARC kernel */ + if ((linux_hdr->hdr[0] != 'H') || + (linux_hdr->hdr[1] != 'd') || + (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) { + puts("Error reading header of SPARC Linux kernel, aborting\n"); + goto error; + } +#ifdef PRINT_KERNEL_HEADER + printf("## Found SPARC Linux kernel %d.%d.%d ...\n", + linux_hdr->linuxver_major, + linux_hdr->linuxver_minor, linux_hdr->linuxver_revision); +#endif + +#ifdef CONFIG_USB_UHCI + usb_lowlevel_stop(); +#endif + + /* set basic boot params in kernel header now that it has been + * extracted and is writeable. + */ + + /* + * Are we going to use an initrd image? + */ + ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_SPARC, + &rd_data_start, &rd_data_end); + if (ret) { + /* RAM disk found but was corrupt */ + puts("RAM Disk corrupt\n"); + goto error; + } + + /* Calc length of RAM disk, if zero no ramdisk available */ + rd_len = rd_data_end - rd_data_start; + + if (rd_len) { + + /* Reserve the space used by PROM and stack. This is done + * to avoid that the RAM image is copied over stack or + * PROM. + */ + lmb_reserve(lmb, CFG_RELOC_MONITOR_BASE, CFG_RAM_END); + + ret = boot_ramdisk_high(lmb, rd_data_start, rd_len, + &initrd_start, &initrd_end); + if (ret) { + puts("### Failed to relocate RAM disk\n"); + goto error; + } + + /* Update SPARC kernel header so that Linux knows + * what is going on and where to find RAM disk. + * + * Set INITRD Image address relative to RAM Start + */ + linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image = + initrd_start - CFG_RAM_BASE; + linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = rd_len; + /* Clear READ ONLY flag if set to non-zero */ + linux_hdr->hdr_input.ver_0203.root_flags = 1; + /* Set root device to: Root_RAM0 */ + linux_hdr->hdr_input.ver_0203.root_dev = 0x100; + linux_hdr->hdr_input.ver_0203.ram_flags = 0; + } else { + /* NOT using RAMDISK image, overwriting kernel defaults */ + linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image = 0; + linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = 0; + /* Leave to kernel defaults + linux_hdr->hdr_input.ver_0203.root_flags = 1; + linux_hdr->hdr_input.ver_0203.root_dev = 0; + linux_hdr->hdr_input.ver_0203.ram_flags = 0; + */ + } + + /* Copy bootargs from bootargs variable to kernel readable area */ + bootargs = getenv("bootargs"); + prepare_bootargs(bootargs); + + if (!images->autostart) + return; + + /* turn on mmu & setup context table & page table for process 0 (kernel) */ + srmmu_init_cpu((unsigned int)kernel); + + /* Enter SPARC Linux kernel + * From now on the only code in u-boot that will be + * executed is the PROM code. + */ + kernel(kernel_arg_promvec, (void *)ep); + + /* It will never come to this... */ + while (1) ; + + error: + if (images->autostart) + do_reset(cmdtp, flag, argc, argv); + return; +} diff --git a/lib_sparc/cache.c b/lib_sparc/cache.c new file mode 100644 index 0000000000..59d9bbe672 --- /dev/null +++ b/lib_sparc/cache.c @@ -0,0 +1,33 @@ +/* Sparc cache library + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +void flush_cache(ulong start_addr, ulong size) +{ + /* Flush All Cache */ + sparc_dcache_flush_all(); + sparc_icache_flush_all(); +} diff --git a/lib_sparc/interrupts.c b/lib_sparc/interrupts.c new file mode 100644 index 0000000000..4c73b82a6f --- /dev/null +++ b/lib_sparc/interrupts.c @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2003 + * Gleb Natapov + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* Implemented by SPARC CPUs */ +extern int interrupt_init_cpu(void); +extern void timer_interrupt_cpu(void *arg); +extern int timer_interrupt_init_cpu(void); + +int intLock(void) +{ + unsigned int pil; + + pil = get_pil(); + + /* set PIL to 15 ==> no pending interrupts will interrupt CPU */ + set_pil(15); + + return pil; +} + +void intUnlock(int oldLevel) +{ + set_pil(oldLevel); +} + +void enable_interrupts(void) +{ + set_pil(0); /* enable all interrupts */ +} + +int disable_interrupts(void) +{ + return intLock(); +} + +int interrupt_init(void) +{ + int ret; + + /* call cpu specific function from $(CPU)/interrupts.c */ + ret = interrupt_init_cpu(); + + /* enable global interrupts */ + enable_interrupts(); + + return ret; +} + +/* timer interrupt/overflow counter */ +static volatile ulong timestamp = 0; + +/* regs can not be used here! regs is actually the pointer given in + * irq_install_handler + */ +void timer_interrupt(struct pt_regs *regs) +{ + /* call cpu specific function from $(CPU)/interrupts.c */ + timer_interrupt_cpu((void *)regs); + + timestamp++; +} + +void reset_timer(void) +{ + timestamp = 0; +} + +ulong get_timer(ulong base) +{ + return (timestamp - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void timer_interrupt_init(void) +{ + int irq; + + reset_timer(); + + irq = timer_interrupt_init_cpu(); + + if (irq < 0) { + /* cpu specific code handled the interrupt registration it self */ + return; + } + /* register interrupt handler for timer */ + irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL); +} diff --git a/lib_sparc/time.c b/lib_sparc/time.c new file mode 100644 index 0000000000..433f3eb5a0 --- /dev/null +++ b/lib_sparc/time.c @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* Implemented by SPARC CPUs */ +extern void cpu_wait_ticks(unsigned long ticks); +extern unsigned long cpu_usec2ticks(unsigned long usec); +extern unsigned long cpu_ticks2usec(unsigned long ticks); + +/* ------------------------------------------------------------------------- */ + +void wait_ticks(unsigned long ticks) +{ + cpu_wait_ticks(ticks); +} + +/* + * This function is intended for SHORT delays only. + */ +unsigned long usec2ticks(unsigned long usec) +{ + return cpu_usec2ticks(usec); +} + +/* ------------------------------------------------------------------------- */ + +/* + * We implement the delay by converting the delay (the number of + * microseconds to wait) into a number of time base ticks; then we + * watch the time base until it has incremented by that amount. + */ +void udelay(unsigned long usec) +{ + ulong ticks = usec2ticks(usec); + + wait_ticks(ticks); +} + +/* ------------------------------------------------------------------------- */ + +unsigned long ticks2usec(unsigned long ticks) +{ + return cpu_ticks2usec(ticks); +} + +/* ------------------------------------------------------------------------- */ + +int init_timebase(void) +{ + + return (0); +} + +/* ------------------------------------------------------------------------- */ diff --git a/sparc_config.mk b/sparc_config.mk new file mode 100644 index 0000000000..87f745f614 --- /dev/null +++ b/sparc_config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2007 +# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_CPPFLAGS += -DCONFIG_SPARC -D__sparc__ -- 2.25.1