diff options
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | common/prom.h | 7 | ||||
-rw-r--r-- | common/subarch.h | 1 | ||||
-rw-r--r-- | ext2load/Makefile | 16 | ||||
-rw-r--r-- | snilib/Makefile | 20 | ||||
-rw-r--r-- | snilib/sniprom.c | 181 | ||||
-rw-r--r-- | snilib/sniprom.h | 59 | ||||
-rw-r--r-- | tip22/Makefile | 19 | ||||
-rw-r--r-- | tip22/tftpload.c | 4 |
9 files changed, 302 insertions, 16 deletions
@@ -12,12 +12,21 @@ KERNELADDR=0x88002000 MAXLOADSIZE=0x1700000 LOADADDR=0x88802000 OUTPUTFORMAT=ecoff-bigmips +ARCHLIB=arclib endif ifeq ($(SUBARCH),IP32) KERNELADDR=0x80004000 MAXLOADSIZE=0x1400000 LOADADDR=0x81404000 OUTPUTFORMAT=elf32-tradbigmips +ARCHLIB=arclib +endif +ifeq ($(SUBARCH),SNIRM) +KERNELADDR=0x80030000 +MAXLOADSIZE=0x400000 +LOADADDR=0x80e00000 +OUTPUTFORMAT=elf32-tradbigmips +ARCHLIB=snilib endif # these contain subarch independent files @@ -26,7 +35,7 @@ SUBARCH_INDEP_DIRS= \ # these contain subarch dependent files SUBARCH_DIRS= \ common \ - arclib \ + $(ARCHLIB) \ ext2load \ tip22 diff --git a/common/prom.h b/common/prom.h index 1a3acf5..9f81e76 100644 --- a/common/prom.h +++ b/common/prom.h @@ -1,4 +1,11 @@ + +/* + * Gets called before anything else - even the first printf + * + */ +void prom_init(void ); + void prom_restart(void ); void prom_return_interactive(void ); void prom_flush_cache_all(void ); diff --git a/common/subarch.h b/common/subarch.h index 28e2d1d..284d6ed 100644 --- a/common/subarch.h +++ b/common/subarch.h @@ -10,5 +10,6 @@ #define PAGE_SIZE 4096 #define STACK_PAGES 16 #define KSEG0ADDR(addr) (((addr) & 0x1fffffff) | 0x80000000) +#define KSEG1ADDR(addr) (((addr) & 0x1fffffff) | 0xa0000000) #endif diff --git a/ext2load/Makefile b/ext2load/Makefile index f10d678..3d441a8 100644 --- a/ext2load/Makefile +++ b/ext2load/Makefile @@ -11,17 +11,23 @@ E2FSINCLUDEDIR ?= /usr/include/ext2fs E2FSLIBDIR ?= /usr/lib EXT2LIB ?= $(E2FSLIBDIR)/libext2fs-nopic.a -ARCINCLUDEDIR = ../arclib -ARCLIBDIR = ../arclib -ARCLIB = $(ARCLIBDIR)/libarc.a +ifeq ($(SUBARCH),SNIRM) +PROMINCLUDEDIR = ../snilib +PROMLIBDIR = ../snilib +PROMLIB = $(PROMLIBDIR)/libsni.a +else +PROMINCLUDEDIR = ../arclib +PROMLIBDIR = ../arclib +PROMLIB = $(PROMLIBDIR)/libarc.a +endif LIBC = ../common/libc.a OBJECTS = loader.o ext2io.o conffile.o -LIBS = $(EXT2LIB) $(LIBC) $(ARCLIB) +LIBS = $(EXT2LIB) $(LIBC) $(PROMLIB) TARGETS = ext2load -CFLAGS = -O2 -I$(COMMONDIR) -I$(ARCINCLUDEDIR) -I$(E2FSINCLUDEDIR) \ +CFLAGS = -O2 -I$(COMMONDIR) -I$(PROMINCLUDEDIR) -I$(E2FSINCLUDEDIR) \ -W -Wall -mno-abicalls -G 0 -fno-pic \ -DSUBARCH=${SUBARCH} -fno-strict-aliasing diff --git a/snilib/Makefile b/snilib/Makefile new file mode 100644 index 0000000..4e6ec18 --- /dev/null +++ b/snilib/Makefile @@ -0,0 +1,20 @@ +# +# Copyright 1999 Silicon Graphics, Inc. +# +CFLAGS += -O2 -I../common -mno-abicalls -G 0 -fno-pic -ffreestanding -DDEBUG + +TARGETS = libsni.a +OBJECTS = sniprom.o + +all: $(TARGETS) + +$(TARGETS): $(OBJECTS) + rm -f $@ + $(AR) -crs $@ $(OBJECTS) + +install: $(TARGETS) + install -d ${PREFIX}/${LIBDIR} + install -m 644 $< ${PREFIX}/${LIBDIR} + +clean: + rm -f libsni.a $(OBJECTS) *~ tags diff --git a/snilib/sniprom.c b/snilib/sniprom.c new file mode 100644 index 0000000..fa5acc1 --- /dev/null +++ b/snilib/sniprom.c @@ -0,0 +1,181 @@ + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> + +#include <subarch.h> +#include "sniprom.h" + +#define MAX_ARG 64 + +static char *iargv[MAX_ARG]; +static int iargc=0; +static char *label=NULL; + +extern unsigned long _end; + +void prom_wait(const char *prompt) { + printf("%s: called\n\r", __FUNCTION__); +} + +void prom_fatal(const char *message, ...) { + va_list ap; + + if (message != NULL) { + printf("FATAL ERROR: "); + va_start(ap, message); + vprintf(message, ap); + va_end(ap); + } + + prom_wait("\n\r--- Press <spacebar> to enter ARC interactive mode ---"); + __prom_reset(); +} + +int (*__prom_lseek)(FILE, int, int) = NULL; + + +/* + * The SNI Prom does not contain an official entry point for "prom_seek" which is + * a pain and basically is a showstopper for bootloaders. There is a seek function + * though which seems to be inbetween prom_open and prom_read. We try to find + * it by looking for the function prolog e.g. the $sp setup. We then know the + * address of the seek. flo@rfc822.org 2007-08-13 + */ + +void prom_init(void ) { + unsigned int jump; + unsigned int *readaddr, + *openaddr, + *saddr; + + jump = *((unsigned int *)PROM_ENTRY(PROM_READ)); + readaddr=(unsigned int *) (((jump & 0x03ffffff)<<2)|0xb0000000); + jump = *((unsigned int *)PROM_ENTRY(PROM_OPEN)); + openaddr= (unsigned int *) (((jump & 0x03ffffff)<<2)|0xb0000000); + + for(saddr=readaddr-1;saddr>openaddr;saddr--) { + /* Search for addiu $sp, negative */ + if ((*saddr & 0xffff8000) == 0x27bd8000) { + __prom_lseek=(void *) saddr; + break; + } + } + + if (__prom_lseek == NULL) + prom_fatal("Didnt find prom_seek prolog between open and read\n\r"); +} + + +/* Give 1MByte of memory behind the arcboot to the allocator */ +void prom_init_malloc(unsigned long loadaddr, unsigned long size) { + malloc_area_add((unsigned long) &_end, 0x100000); +} + +int prom_seek(FILE stream, long long position, int whence) { + int pos32=position, res; + + res=__prom_lseek(stream, pos32, whence); + + if (res != position) + prom_fatal("Seek failed\n\r"); + + return 0; +} + +void prom_restart(void ) { + printf("%s: called\n\r", __FUNCTION__); +} + +void prom_flush_cache_all(void ) { + __prom_flushcache(); +} + +void prom_return_interactive(void ) { + printf("%s: called\n\r", __FUNCTION__); +} + +int prom_write(FILE stream, char *buf, unsigned long len, unsigned long *rlen) { + int res; + /* SNI returns no status but standard conform length */ + res=__prom_write(stream, buf, len); + *rlen=res; + return res<0; +} + +/* + * We have seen larger reads to fail on RM200C Prom Version 5 + * and RM400 Prom Version 4. It seems this is secondary cache related. As we + * would like to use the read-ahead and cache we simply split the reads into + * smaller chunks here. + * + */ +int prom_read(FILE stream, char *buf, unsigned long len, unsigned long *rlen) { + int res=0,i; + int read=0, thisread; + + while(read < len) { + int left=len-read; + if (left > 4096) + thisread=4096; + else + thisread=left; + + res=__prom_read(stream, buf+read, thisread); + + read+=thisread; + + if (res < thisread) + break; + } + *rlen=read; + + return (len > read); +} + +int prom_open(char *name, int mode, FILE *stream) { + int res; + res=__prom_open(name, mode); + *stream=res; + return 0; +} + +int prom_close(FILE stream) { + return 0; +} + +void prom_add_arg(char *arg) { + iargv[iargc++]=strdup(arg); +} + +/* + * dkncr(0,0,10) label cmd line arg + * Kernel drops argv[0] so we need to add dkncr... and drop the label + * + */ +int prom_parse_args(int argc, char **argv) { + int i; + prom_add_arg(argv[0]); + if (argc > 1) + label=strdup(argv[1]); + for(i=2;i<argc;i++ ) + prom_add_arg(argv[i]); + return iargc; +} + +char *prom_get_label(void ) { + return (label) ? label : "linux"; +} + +char *prom_get_partition(void ) { + return "dkncr(0,0,1)"; +} + +char *prom_get_options(void ) { + return NULL; +} + +void prom_get_karg(int *argc, char ***argv) { + *argc=iargc; + *argv=iargv; +} diff --git a/snilib/sniprom.h b/snilib/sniprom.h new file mode 100644 index 0000000..db079ad --- /dev/null +++ b/snilib/sniprom.h @@ -0,0 +1,59 @@ + +#include <subarch.h> + +#define PROM_VEC KSEG1ADDR(0x1fc00000) +#define PROM_ENTRY(x) (PROM_VEC + (x*8)) + +#define PROM_RESET 0 +#define PROM_OPEN 6 +#define PROM_READ 7 +#define PROM_WRITE 8 +//#define PROM_SEEK 8 +#define PROM_PUTCHAR 12 +#define PROM_FLUSHCACHE 28 +#define PROM_CLEARCACHE 29 +#define PROM_GETENV 33 +#define PROM_GET_MEMCONF 58 + + +typedef struct { + unsigned int size; + unsigned int base; + unsigned int size2; + unsigned int pad1; + unsigned int pad2; +} MEMBANK; + +typedef struct { + MEMBANK bank[8]; +} MEMCONF; + +static inline int __prom_get_memconf(MEMCONF *mc) { + return ((int (*)(MEMCONF *))PROM_ENTRY(PROM_GET_MEMCONF))(mc); +} + +static inline int __prom_putchar(char a) { + return ((int (*)(int))PROM_ENTRY(PROM_PUTCHAR))(a); +} + +static inline int __prom_open(char *filename, int mode) { + return ((int (*)(char *, int))PROM_ENTRY(PROM_OPEN))(filename, mode); +} + +static inline int __prom_write(FILE stream, char *buf, unsigned long len) { + return ((int (*)(FILE, char *, unsigned long))PROM_ENTRY(PROM_WRITE)) + (stream, buf, len); +} + +static inline int __prom_read(FILE stream, char *buf, unsigned long len) { + return ((int (*)(FILE, char *, unsigned long))PROM_ENTRY(PROM_READ)) + (stream, buf, len); +} + +static inline void __prom_reset(void ) { + ((void (*)(void ))PROM_ENTRY(PROM_RESET))(); +} + +static inline void __prom_flushcache(void) { + ((void (*)(void ))PROM_ENTRY(PROM_FLUSHCACHE))(); +} diff --git a/tip22/Makefile b/tip22/Makefile index 48829b4..27ba0ce 100644 --- a/tip22/Makefile +++ b/tip22/Makefile @@ -2,12 +2,19 @@ # Copyright 2002-2004 Guido Guenther <agx@sigxcpu.org> # -ARCLIBDIR = ../arclib -ARCLIB = $(ARCLIBDIR)/libarc.a +ifeq ($(SUBARCH),SNIRM) +PROMINCLUDEDIR = ../snilib +PROMLIBDIR = ../snilib +PROMLIB = $(PROMLIBDIR)/libsni.a +else +PROMINCLUDEDIR = ../arclib +PROMLIBDIR = ../arclib +PROMLIB = $(PROMLIBDIR)/libarc.a +endif COMMONDIR = ../common -CFLAGS += -O2 -I$(COMMONDIR) -I$(ARCLIBDIR) -Wall -mno-abicalls -G 0 \ +CFLAGS += -O2 -I$(COMMONDIR) -I$(PROMLIBDIR) -Wall -mno-abicalls -G 0 \ -fno-pic -DSUBARCH=${SUBARCH} ASFLAGS = -O2 -mno-abicalls -G 0 -fno-pic @@ -15,7 +22,7 @@ ASFLAGS = -O2 -mno-abicalls -G 0 -fno-pic LIBDIR ?= /usr/lib/tip22 BINDIR ?= /usr/sbin -LIBS=${ARCLIB} +LIBS=${PROMLIB} BINS=tip22 tip32 LD_SCRIPTS = ld.kernel.script ld.ramdisk.script ld.script OBJECTS = tftpload.o @@ -29,7 +36,7 @@ all: ${LIBS} $(TARGETS) $(ARCLIB): - @$(MAKE) -C $(ARCLIBDIR) + @$(MAKE) -C $(PROMLIBDIR) $(PRINT_LOADADDR): @$(MAKE) -C $(COMMONDIR) SUBARCH=$(SUBARCH) @@ -45,7 +52,7 @@ $(PRINT_LOADADDR): -e "s/@@OUTPUTFORMAT@@/$$OUTPUTFORMAT/" <$< >$@ clean: - @$(MAKE) -C $(ARCLIBDIR) clean + @$(MAKE) -C $(PROMLIBDIR) clean @$(MAKE) -C $(COMMONDIR) clean rm -f $(TARGETS) diff --git a/tip22/tftpload.c b/tip22/tftpload.c index ed31e15..e048399 100644 --- a/tip22/tftpload.c +++ b/tip22/tftpload.c @@ -9,9 +9,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <types.h> -#include <arc.h> #include <prom.h> #include <elf.h> @@ -20,8 +18,6 @@ #include <version.h> #include <subarch.h> -#define KSEG0ADDR(addr) (((addr) & 0x1fffffff) | 0x80000000) - #define ANSI_CLEAR "\033[2J" extern void* __kernel_start; |