SPARC: Added generic support for SPARC architecture.

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
This commit is contained in:
Daniel Hellstrom 2008-03-28 09:47:00 +01:00
parent aeff6d503b
commit c2f02da21a
36 changed files with 3510 additions and 1 deletions

View file

@ -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| \

View file

@ -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
#========================================================================
#########################################################################
#########################################################################
#########################################################################

1
README
View file

@ -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

View file

@ -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

61
examples/sparc.lds Normal file
View file

@ -0,0 +1,61 @@
/*
* (C) Copyright 2003, Psyent Corporation <www.psyent.com>
* Scott McNutt <smcnutt@psyent.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
*/
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 = .;
}

View file

@ -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

32
include/asm-sparc/asi.h Normal file
View file

@ -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 <asm/arch/asi.h>
#endif /* _SPARC_ASI_H */

View file

@ -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 <config.h>
/* 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

View file

@ -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_ */

View file

@ -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 */

View file

@ -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 <asm/types.h>
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define __BYTEORDER_HAS_U64__
#endif
#include <linux/byteorder/big_endian.h>
#endif /* _SPARC_BYTEORDER_H */

31
include/asm-sparc/cache.h Normal file
View file

@ -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 <linux/config.h>
#include <asm/processor.h>
#endif

162
include/asm-sparc/errno.h Normal file
View file

@ -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

View file

@ -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 */

94
include/asm-sparc/io.h Normal file
View file

@ -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

49
include/asm-sparc/irq.h Normal file
View file

@ -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 <asm/psr.h>
/* 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

View file

@ -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) */

43
include/asm-sparc/page.h Normal file
View file

@ -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 <linux/config.h>
#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 */

View file

@ -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 */

View file

@ -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 <asm/arch/asi.h>
/* 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 */

297
include/asm-sparc/prom.h Normal file
View file

@ -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

97
include/asm-sparc/psr.h Normal file
View file

@ -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__) */

181
include/asm-sparc/ptrace.h Normal file
View file

@ -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 <asm/psr.h>
/* 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 <asm/asm_offsets.h> */
/* 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) */

301
include/asm-sparc/srmmu.h Normal file
View file

@ -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 <asm/asi.h>
#include <asm/page.h>
/* 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__) */

162
include/asm-sparc/stack.h Normal file
View file

@ -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 <asm/ptrace.h>
#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

View file

@ -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

71
include/asm-sparc/types.h Normal file
View file

@ -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

View file

@ -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__ */

View file

@ -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 <asm/asmmacro.h>
#include <asm/stack.h>
/* 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

45
lib_sparc/Makefile Normal file
View file

@ -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
#########################################################################

521
lib_sparc/board.c Normal file
View file

@ -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 <common.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
#include <config.h>
#if defined(CONFIG_CMD_IDE)
#include <ide.h>
#endif
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
#include <net.h>
#include <serial.h>
#include <version.h>
#if defined(CONFIG_POST)
#include <post.h>
#endif
#ifdef CONFIG_PS2KBD
#include <keyboard.h>
#endif
#ifdef CONFIG_CMD_AMBAPP
#include <ambapp.h>
#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 <environment.h>
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 (;;) ;
}
/************************************************************************/

226
lib_sparc/bootm.c Normal file
View file

@ -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 <common.h>
#include <command.h>
#include <asm/byteorder.h>
#include <asm/prom.h>
#include <asm/cache.h>
#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;
}

33
lib_sparc/cache.c Normal file
View file

@ -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 <common.h>
#include <asm/processor.h>
void flush_cache(ulong start_addr, ulong size)
{
/* Flush All Cache */
sparc_dcache_flush_all();
sparc_icache_flush_all();
}

122
lib_sparc/interrupts.c Normal file
View file

@ -0,0 +1,122 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2003
* Gleb Natapov <gnatapov@mrv.com>
*
* (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 <common.h>
#include <asm/processor.h>
#include <asm/irq.h>
/* 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);
}

78
lib_sparc/time.c Normal file
View file

@ -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 <common.h>
/* 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);
}
/* ------------------------------------------------------------------------- */

24
sparc_config.mk Normal file
View file

@ -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__