Initial revision

This commit is contained in:
Michael Brown
2005-03-08 18:53:11 +00:00
commit 3d6123e69a
373 changed files with 114041 additions and 0 deletions

7
src/arch/e1/Config Normal file
View File

@@ -0,0 +1,7 @@
# Config for e1 Etherboot
#
CFLAGS+= -mgnu-param -DCONSOLE_SERIAL -DCOMCONSOLE=0x01C00000 -DCONSPEED=28800
CFLAGS+= -DSIZEINDICATOR -DNO_DHCP_SUPPORT -DBAR_PROGRESS
#CFLAGS+= -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"

70
src/arch/e1/Makefile Normal file
View File

@@ -0,0 +1,70 @@
ARCH_FORMAT= coff-e1
BUILD_ROMS= $(ROMS)
BUILD_COFFS= $(patsubst %img, %coff, $(IMGS))
SUFFIXES+= rom zrom coff
CC= e1-coff-gcc
AS= e1-coff-as
LD= e1-coff-ld
SIZE= e1-coff-size
AR= e1-coff-ar
RANLIB= e1-coff-ranlib
OBJCOPY=e1-coff-objcopy
# DMAC_HW_ADDR_DRV holds the ethernet's MAC address. It is passed as
# flag to the low level driver instead of reading it from an
# external EEPROM, which we do not have!
EXTRA_CFLAGS = -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
START= $(BIN)/start.o
START16= $(BIN)/start.o
SRCS+= arch/e1/core/e132_xs.c
SRCS+= arch/e1/core/e1_timer.c
SRCS+= arch/e1/core/longjmp.c
SRCS+= arch/e1/core/memcmp.S
SRCS+= arch/e1/core/memcpy.S
SRCS+= arch/e1/core/memset.S
SRCS+= arch/e1/core/setjmp.c
SRCS+= arch/e1/core/strcmp.S
SRCS+= arch/e1/core/start.S
ROMLIMIT:=3276800
include $(BIN)/Roms
ROMS= $(BIN)/cs89x0.rom
IMGS= $(BIN)/cs89x0.img
#allfiles: $(BUILD_ROMS)
all: $(BUILD_COFFS)
BOBJS+= $(BIN)/e1_timer.o
BOBJS+= $(BIN)/memcmp.o $(BIN)/memcpy.o $(BIN)/memset.o
BOBJS+= $(BIN)/setjmp.o $(BIN)/longjmp.o
BOBJS+= $(BIN)/e132_xs.o
# Utilities
$(BIN)/nrv2b: util/nrv2b.c
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
# Pattern Rules
# General for compiling/assembly source files
$(BIN)/cs89x0.o: drivers/net/cs89x0.c $(MAKEDEPS)
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $<
# With the current tools we have problem with the compilation
# of the vsprintf file when the -O2 is selected. So we compile
# the aforemntioned file with -O1 !!!
$(BIN)/vsprintf.o: core/vsprintf.c $(MAKEDEPS)
$(CC) $(CFLAGS) -O1 -o $@ -c $<
$(BIN)/%.o: arch/e1/core/%.c $(MAKEDEPS)
$(CC) $(CFLAGS) -o $@ -c $<
$(BIN)/%.o: arch/e1/core/%.S $(MAKEDEPS)
$(CPP) $(CFLAGS) -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
$(BIN)/%.coff: $(BIN)/%.tmp $(MAKEDEPS)
mv $< $(BIN)/etherboot.coff

View File

@@ -0,0 +1,67 @@
ARCH_FORMAT= coff-e1
CC= e1-coff-gcc
AS= e1-coff-as
LD= e1-coff-ld
SIZE= e1-coff-size
AR= e1-coff-ar
RANLIB= e1-coff-ranlib
OBJCOPY=e1-coff-objcopy
EXTRA_CFLAGS = -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
BUILD_ROMS= $(ROMS)
BUILD_COFFS= $(BIN)/cs89x0.coff
#BUILD_COFFS= $(patsubst %img, %coff, $(IMGS))
START= $(BIN)/start.o
START16= $(BIN)/start.o
#SRCS+= arch/e1/core/coff_loader.c
SRCS+= arch/e1/core/e132_xs.c
SRCS+= arch/e1/core/e1_timer.c
SRCS+= arch/e1/core/longjmp.c
SRCS+= arch/e1/core/memcmp.S
SRCS+= arch/e1/core/memcpy.S
SRCS+= arch/e1/core/memset.S
SRCS+= arch/e1/core/setjmp.c
SRCS+= arch/e1/core/strcmp.S
SRCS+= arch/e1/core/start.S
ROMLIMIT:=3276800
include $(BIN)/Roms
hyperstone: $(BUILD_COFFS)
coff: $(BUILD_COFFS)
BOBJS+= $(BIN)/e1_timer.o
BOBJS+= $(BIN)/memcmp.o $(BIN)/memcpy.o $(BIN)/memset.o
BOBJS+= $(BIN)/setjmp.o $(BIN)/longjmp.o
BOBJS+= $(BIN)/e132_xs.o
# Utilities
$(BIN)/nrv2b: util/nrv2b.c
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
# Pattern Rules
# General for compiling/assembly source files
$(BIN)/cs89x0.o: drivers/net/cs89x0.c $(MAKEDEPS)
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $<
# With the current tools we have problem with the compilation
# of the vsprintf file when the -O2 is selected. So we compile
# the aforemntioned file with -O1 !!!
$(BIN)/vsprintf.o: core/vsprintf.c $(MAKEDEPS)
$(CC) $(CFLAGS) -O1 -o $@ -c $<
$(BIN)/%.o: arch/e1/core/%.c $(MAKEDEPS)
$(CC) $(CFLAGS) -o $@ -c $<
$(BIN)/%.o: arch/e1/core/%.S $(MAKEDEPS)
$(CPP) $(CFLAGS) -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
$(BIN)/%.coff: $(BIN)/%.tmp $(MAKEDEPS)
mv $< $(BIN)/etherboot.coff

80
src/arch/e1/README Normal file
View File

@@ -0,0 +1,80 @@
Introduction
---------------------
This README file provides guideliness to compile successfully the
Etherboot for Hyperstone.
This directory (src/arch/e1) contains the files that depend on
Hyperstone's architecture. The header files that include the
configuration of the system are based on Hyperstone's E132-XS
development board. The can be very easily modified to support
anyother configuration environment.
Software Perquisites:
---------------------
The build environment requires a C compiler for the E1-32XS
processor. Normally you can simply install a cross-compiling tool
chain based on the GNU tools (that is binutils and gcc). If you
are running a Linux system on a x86 CPU then you can just download
the toolchain as a binary from Hyperstone's official web-site. The
binary distribution will untar the tools in the /usr/local/e1-coff
directory. On any other system you will need to build the tool
chain from the sources.
To compile successfully the following tools should be available:
- GNU toolchain:
- GCC ver 2.95.2 20030110 (release) e1-coff-gcc -v
- LD ver 2.12.90 20020726 e1-coff-ld -V
Hardware Perquisites:
---------------------
The etherboot has been successfully tested in the E1-32XS
development board. A second serial device is initialized
to act as a console. The standard messages
are redirected to the console. Nevertheless, if one wants not
to use the serial console he may omit the corresponding switches
from the Config file located under "src/arch/e1/" directory.
On the E1-32XS board that was used, a daughter-board was employed
to connect a second HyIce to the development board. Since the HyIce
embeds a standard 16550 device, the Etherboot's standard device
driver is used.
The position of the jumpers of the development board in order to
initialize both the second HyIce and the Ethernet device is
depicted in the following table:
Jumper: Position
------:--------------
J3 1-2 (default)
J4 1-2 (default)
J13 5-6
J5 1-2 (default)
J6 1-2 & 3-4
J7 3-4
J9 1-2 (default)
J10 1-2
J11 3-4
Compilation
---------------------
In order to compile Etherboot for Hyperstone, the following steps should be followed:
1) Edit the main Makefile (located under "src" directory") and comment-out
the ARCH variable (by putting a "#" in front of it). Append the following line:
ARCH:=e1
2) Edit the Config file (the one located under "src" directory) and make sure that
the CFLAGS variable will contain *only* the following swithces:
CFLAGS+= -DCONFIG_ISA
CFLAGS+= -DBOOT_FIRST=BOOT_NIC
CFLAGS+= -DALLOW_ONLY_ENCAPSULATED
CFLAGS+= -DBACKOFF_LIMIT=7 -DCONGESTED
CFLAGS+= -DCOFF_IMAGE
CFLAGS+= -DDOWNLOAD_PROTO_TFTP
Please note that extra or any other switches may cause failure of compilation!
3) type "make hyperstone" or "make coff"
4) the generated file will be located under the "src/bin" directory and will be called :
"etherboot.coff". Now you may download it with usual way using e1-coff-gdb ..
Have Fun
Yannis Mitsos, George Thanos
{gmitsos,gthanos}@telecom.ntua.gr

View File

@@ -0,0 +1,176 @@
/*
* Copyright 2003 Yannis Mitsos and George Thanos
* {gmitsos@gthanos}@telecom.ntua.gr
* Released under GPL2, see the file COPYING in the top directory
* COFF loader is based on the source code of the ELF loader.
*
*/
#include "coff.h"
#define COFF_DEBUG 0
typedef struct {
COFF_filehdr coff32;
COFF_opthdr opthdr32;
union {
COFF_scnhdr scnhdr32[1];
unsigned char dummy[1024];
} p;
unsigned long curaddr;
signed int segment; /* current segment number, -1 for none */
unsigned int loc; /* start offset of current block */
unsigned int skip; /* padding to be skipped to current segment */
unsigned long toread; /* remaining data to be read in the segment */
}coff_state;
coff_state cstate;
static sector_t coff32_download(unsigned char *data, unsigned int len, int eof);
static inline os_download_t coff_probe(unsigned char *data, unsigned int len)
{
unsigned long phdr_size;
if (len < (sizeof(cstate.coff32)+ sizeof(cstate.opthdr32))) {
return 0;
}
memcpy(&cstate.coff32, data, (sizeof(cstate.coff32)+sizeof(cstate.opthdr32)));
if ((cstate.coff32.f_magic != EM_E1) ||
(cstate.opthdr32.magic != O_MAGIC)){
return 0;
}
printf("(COFF");
printf(")... \n");
if (cstate.coff32.f_opthdr == 0){
printf("No optional header in COFF file, cannot find the entry point\n");
return dead_download;
}
phdr_size = cstate.coff32.f_nscns * sizeof(cstate.p.scnhdr32);
if (sizeof(cstate.coff32) + cstate.coff32.f_opthdr + phdr_size > len) {
printf("COFF header outside first block\n");
return dead_download;
}
memcpy(&cstate.p.scnhdr32, data + (sizeof(cstate.coff32) + cstate.coff32.f_opthdr), phdr_size);
/* Check for Etherboot related limitations. Memory
* between _text and _end is not allowed.
* Reasons: the Etherboot code/data area.
*/
for (cstate.segment = 0; cstate.segment < cstate.coff32.f_nscns; cstate.segment++) {
unsigned long start, mid, end, istart, iend;
if ((cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_TEXT) &&
(cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_DATA) &&
(cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_BSS)){ /* Do we realy need to check the BSS section ? */
#ifdef COFF_DEBUG
printf("Section <%s> in not a loadable section \n",cstate.p.scnhdr32[cstate.segment].s_name);
#endif
continue;
}
start = cstate.p.scnhdr32[cstate.segment].s_paddr;
mid = start + cstate.p.scnhdr32[cstate.segment].s_size;
end = start + cstate.p.scnhdr32[cstate.segment].s_size;
/* Do we need the following variables ? */
istart = 0x8000;
iend = 0x8000;
if (!prep_segment(start, mid, end, istart, iend)) {
return dead_download;
}
}
cstate.segment = -1;
cstate.loc = 0;
cstate.skip = 0;
cstate.toread = 0;
return coff32_download;
}
extern int mach_boot(unsigned long entry_point);
static sector_t coff32_download(unsigned char *data, unsigned int len, int eof)
{
unsigned long skip_sectors = 0;
unsigned int offset; /* working offset in the current data block */
int i;
offset = 0;
do {
if (cstate.segment != -1) {
if (cstate.skip) {
if (cstate.skip >= len - offset) {
cstate.skip -= len - offset;
break;
}
offset += cstate.skip;
cstate.skip = 0;
}
if (cstate.toread) {
unsigned int cplen;
cplen = len - offset;
if (cplen >= cstate.toread) {
cplen = cstate.toread;
}
memcpy(phys_to_virt(cstate.curaddr), data+offset, cplen);
cstate.curaddr += cplen;
cstate.toread -= cplen;
offset += cplen;
if (cstate.toread)
break;
}
}
/* Data left, but current segment finished - look for the next
* segment (in file offset order) that needs to be loaded.
* We can only seek forward, so select the program headers,
* in the correct order.
*/
cstate.segment = -1;
for (i = 0; i < cstate.coff32.f_nscns; i++) {
if ((cstate.p.scnhdr32[i].s_flags != S_TYPE_TEXT) &&
(cstate.p.scnhdr32[i].s_flags != S_TYPE_DATA))
continue;
if (cstate.p.scnhdr32[i].s_size == 0)
continue;
if (cstate.p.scnhdr32[i].s_scnptr < cstate.loc + offset)
continue; /* can't go backwards */
if ((cstate.segment != -1) &&
(cstate.p.scnhdr32[i].s_scnptr >= cstate.p.scnhdr32[cstate.segment].s_scnptr))
continue; /* search minimum file offset */
cstate.segment = i;
}
if (cstate.segment == -1) {
/* No more segments to be loaded, so just start the
* kernel. This saves a lot of network bandwidth if
* debug info is in the kernel but not loaded. */
goto coff_startkernel;
break;
}
cstate.curaddr = cstate.p.scnhdr32[cstate.segment].s_paddr;
cstate.skip = cstate.p.scnhdr32[cstate.segment].s_scnptr - (cstate.loc + offset);
cstate.toread = cstate.p.scnhdr32[cstate.segment].s_size;
#if COFF_DEBUG
printf("PHDR %d, size %#lX, curaddr %#lX\n",
cstate.segment, cstate.toread, cstate.curaddr);
#endif
} while (offset < len);
cstate.loc += len + (cstate.skip & ~0x1ff);
skip_sectors = cstate.skip >> 9;
cstate.skip &= 0x1ff;
if (eof) {
unsigned long entry;
coff_startkernel:
entry = cstate.opthdr32.entry;
done();
mach_boot(entry);
}
return skip_sectors;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2003 Yannis Mitsos and George Thanos
* {gmitsos@gthanos}@telecom.ntua.gr
* Released under GPL2, see the file COPYING in the top directory
*
*/
#include "hooks.h"
#include "io.h"
#include "etherboot.h"
#include "e132_xs_board.h"
unsigned int io_periph[NR_CS] = {[0 ... NR_CS-1] = 0 };
/*
void arch_main(struct Elf_Bhdr *ptr __unused)
{
}
*/
void init_peripherals(void)
{
int i;
for(i=0; i< NR_CS; i++){
io_periph[i]= (SLOW_IO_ACCESS | i << 22);
}
io_periph[ETHERNET_CS] = (io_periph[ETHERNET_CS] | 1 << IOWait);
asm volatile("
ori SR, 0x20
movi FCR, 0x66ffFFFF"
:
:);
}
struct meminfo meminfo;
void get_memsizes(void)
{
/* We initialize the meminfo structure
* according to our development board's specs
* We do not have a way to automatically probe the
* memspace instead we initialize it manually
*/
meminfo.basememsize = BASEMEM;
meminfo.memsize = SDRAM_SIZE;
meminfo.map_count = NR_MEMORY_REGNS;
meminfo.map[0].addr = SDRAM_BASEMEM;
meminfo.map[0].size = SDRAM_SIZE;
meminfo.map[0].type = E820_RAM;
meminfo.map[1].addr = SRAM_BASEMEM;
meminfo.map[1].size = SRAM_SIZE;
meminfo.map[1].type = E820_RAM;
meminfo.map[2].addr = IRAM_BASEMEM;
meminfo.map[2].size = IRAM_SIZE;
meminfo.map[2].type = E820_RAM;
}
int mach_boot(register unsigned long entry_point)
{
asm volatile(
"mov PC, %0"
: /* no outputs */
: "l" (entry_point) );
return 0; /* We should never reach this point ! */
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2003 Yannis Mitsos and George Thanos
* {gmitsos@gthanos}@telecom.ntua.gr
* Released under GPL2, see the file COPYING in the top directory
*
*/
#include "etherboot.h"
#include "timer.h"
#include "e132_xs_board.h"
/* get timer returns the contents of the timer */
static inline unsigned long get_timer(void)
{
unsigned long result;
__asm__ __volatile__("
ORI SR, 0x20
mov %0, TR"
: "=l"(result));
return result;
}
/* ------ Calibrate the TSC -------
* Time how long it takes to excute a loop that runs in known time.
* And find the convertion needed to get to CLOCK_TICK_RATE
*/
static unsigned long configure_timer(void)
{
unsigned long TPR_value; /* Timer Prescalar Value */
TPR_value = 0x000C00000;
asm volatile ("
FETCH 4
ORI SR, 0x20
MOV TPR, %0
ORI SR, 0x20
MOVI TR, 0x0"
: /* no outputs */
: "l" (TPR_value)
);
printf("The time prescaler register is set to: <%#x>\n",TPR_value);
return (1);
}
static unsigned long clocks_per_tick;
void setup_timers(void)
{
if (!clocks_per_tick) {
clocks_per_tick = configure_timer();
}
}
unsigned long currticks(void)
{
return get_timer()/clocks_per_tick;
}
static unsigned long timer_timeout;
static int __timer_running(void)
{
return get_timer() < timer_timeout;
}
void udelay(unsigned int usecs)
{
unsigned long now;
now = get_timer();
timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
while(__timer_running());
}
void ndelay(unsigned int nsecs)
{
unsigned long now;
now = get_timer();
timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
while(__timer_running());
}
void load_timer2(unsigned int timer2_ticks)
{
unsigned long now;
unsigned long clocks;
now = get_timer();
clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
timer_timeout = now + clocks;
}
int timer2_running(void)
{
return __timer_running();
}

View File

@@ -0,0 +1,126 @@
/* Default linker script, for normal executables */
OUTPUT_FORMAT("coff-e1-big")
MEMORY
{
romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
flash : ORIGIN = 0xE0000000, LENGTH = 0x20000
eflash : ORIGIN = 0x2200000, LENGTH = 0x20000
ram : ORIGIN = 0x00000000, LENGTH = 0x1000000
eram16MB : ORIGIN = 0x01000000, LENGTH = 0
sram : ORIGIN = 0x40000000, LENGTH = 0x40000
iram : ORIGIN = 0xC0000000, LENGTH = 0x4000
}
SEARCH_DIR("/usr/local/e1-coff/lib");
ENTRY(Main)
MEM0start = 0x00000000;
MEM0size = 0x40000000;
MEM1start = 0x40000000;
MEM1size = 0x40000000;
MEM2start = 0x80000000;
MEM2size = 0x40000000;
IRAMstart = 0xC0000000;
IRAMsize = 0x20000000;
MEM3start = 0xE0000000;
MEM3size = 0x20000000;
Stack1Reserve = 560;
_Stack1Size = DEFINED(_Stack1Size)? _Stack1Size : 1*1024;
_Stack2Size = DEFINED(_Stack2Size)? _Stack2Size : 16*1024;
_Stack1Base = DEFINED(_Stack1Base)? _Stack1Base : __bss_end__;
_Stack2Base = DEFINED(_Stack2Base)? _Stack2Base : __bss_end__ + _Stack1Size + Stack1Reserve;
_Mem0HeapBase = DEFINED(_Mem0HeapBase)? _Mem0HeapBase : _Stack2Base + _Stack2Size;
_Mem1HeapBase = DEFINED(_Mem1HeapBase)? _Mem1HeapBase : 0;
Priority = DEFINED(Priority) ? Priority : 31;
TextBase = DEFINED(TextBase) ? TextBase : 0xa00000;
SECTIONS
{
.G6 (DEFINED(G6Base) ? G6Base : 0x9000) : {
*(.G6)
}
.G7 (DEFINED(G7Base) ? G7Base : 0x40001000) : {
*(.G7)
}
.G8 (DEFINED(G8Base) ? G8Base : 0xC0000000) : {
*(.G8)
}
.G9 (DEFINED(G9Base) ? G9Base : 0) : {
*(.G9)
}
.G10 (DEFINED(G10Base) ? G10Base : 0) : {
*(.G10)
}
.G11 (DEFINED(G11Base) ? G11Base : 0) : {
*(.G11)
}
.G12 (DEFINED(G12Base) ? G12Base : 0) : {
*(.G12)
}
.G13 (DEFINED(G13Base) ? G13Base : 0) : {
*(.G13)
}
.text TextBase : {
__virt_start = .;
__text = . ;
*(.text)
*(.fini)
. = ALIGN(16);
_isa_drivers = . ;
*(.drivisa);
_isa_drivers_end = . ;
. = ALIGN(16);
*(.init)
_etext = . ;
/* _init = DEFINED(_init) ? _init : 0; */
/* _fini = DEFINED(_fini) ? _fini : 0; */
/* _argc = DEFINED(_argc) ? _argc : 0; */
/* _argv = DEFINED(_argv) ? _argv : 0; */
/* _envp = DEFINED(_envp) ? _envp : 0; */
/* _hwinit = DEFINED(_hwinit) ? _hwinit : 0; */
/* _atexit = DEFINED(_atexit) ? _atexit : 0; */
G6Size = SIZEOF(.G6);
G7Size = SIZEOF(.G7);
G8Size = SIZEOF(.G8);
G9Size = SIZEOF(.G9);
G10Size = SIZEOF(.G10);
G11Size = SIZEOF(.G11);
G12Size = SIZEOF(.G12);
G13Size = SIZEOF(.G13);
}
.data SIZEOF(.text) + ADDR(.text) : {
*(.data)
_edata = . ;
}
.bss SIZEOF(.data) + ADDR(.data) :
{
__bss_start__ = ALIGN( 0x10 ) ;
__bss = . ;
*(.bss)
*(COMMON)
__end = . ;
__bss_end__ = ALIGN( 0x10 ) ;
__ebss = . ;
}
.eram16MB :
{
___ramend = . - 0x7000;
} > eram16MB
.stab 0 (NOLOAD) :
{
[ .stab ]
}
.stabstr 0 (NOLOAD) :
{
[ .stabstr ]
}
_GOT_ 0 (NOLOAD) :
{
[ _GOT_ ]
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2003 Yannis Mitsos and George Thanos
* {gmitsos@gthanos}@telecom.ntua.gr
* Released under GPL2, see the file COPYING in the top directory
*
*/
#include "setjmp.h"
unsigned long jmpbuf_ptr;
void longjmp(jmp_buf state, int value )
{
if(!value)
state->__jmpbuf->ReturnValue = 1;
else
state->__jmpbuf->ReturnValue = value;
jmpbuf_ptr = (unsigned long)state;
#define _state_ ((struct __jmp_buf_tag*)jmpbuf_ptr)
asm volatile("mov L0, %0\n\t"
"mov L1, %1\n\t"
"mov L2, %2\n\t"
"mov G3, %3\n\t"
"mov G4, %4\n\t"
"ret PC, L1\n\t"
:/*no output*/
:"l"(_state_->__jmpbuf->ReturnValue),
"l"(_state_->__jmpbuf->SavedPC),
"l"(_state_->__jmpbuf->SavedSR),
"l"(_state_->__jmpbuf->G3),
"l"(_state_->__jmpbuf->G4)
:"%G3", "%G4", "%L0", "%L1" );
#undef _state_
}

54
src/arch/e1/core/memcmp.S Normal file
View File

@@ -0,0 +1,54 @@
/*
* Derived from the Hyperstone's library source code.
* Modefied src in order to apply the -mgnu-param compiler option.
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
* George Thanos <gthanos@telecom.ntua.gr>
*/
.text
.align 2
.global _memcmp
;ENTRY (_memcmp)
_memcmp:
FRAME L9, L3 # get incoming parameters
CMPBI L2,3 # check word alignment
BNZ byte_compare
CMPBI L1,3 # check word alignment
BNZ byte_compare
double_compare:
ADDI L0, -8
BLT is_equal
LDD.P L1, L5
LDD.P L2, L7
SUB L5, L7
DBNZ corr_8
SUB L6, L8
BZ double_compare
ADDI L0, 4
ADDI L2, -4
ADDI L1, -4
BR byte_compare
corr_8: ADDI L0, 8
ADDI L2, -8
ADDI L1, -8
byte_compare:
ADDI L0, -1
BLT equal
LDBU.N L2, L5, 1 # Load and compare bytes
LDBU.N L1, L6, 1
SUB L5, L6
BZ byte_compare
MOV L2, L5
RET PC, L3
is_equal: CMPI L0, -8
DBNE byte_compare
ADDI L0, 8
equal:
MOVI L2, 0
RET PC, L3
.END

79
src/arch/e1/core/memcpy.S Normal file
View File

@@ -0,0 +1,79 @@
/*
* Derived from the Hyperstone's library source code.
* Modefied src in order to apply the -mgnu-param compiler option.
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
* George Thanos <gthanos@telecom.ntua.gr>
*/
.text
.align 2
.global _memcpy
;ENTRY(_memcpy)
_memcpy:
FRAME L8, L3
MOV L7, L2 # Save for return
#*****************************
# Perform byte copy if both
# not on a word alignment
#*****************************
CMPBI L2, 3 # check word alignment
BNZ mem_except
CMPBI L1, 3 # check word alignment
BNZ mem_except
#*****************************
# Copy Double,Word,Halfword,
# then byte
#*****************************
DBL_LOOP:
CMPI L0, 8 # Copy Doubles
BLT DO_WORD
LDD.P L1, L5
ADDI L0, -8
DBR DBL_LOOP
STD.P L2, L5
DO_WORD:
CMPI L0, 4 # Copy leftover word
BLT DO_HALF
LDW.P L1, L5
ADDI L0, -4
DBZ DONE # Done if L0 is 0
STW.P L2, L5
DO_HALF:
CMPI L0, 2 # Copy leftover byte
BLT DO_BYTE
LDHU.N L1, L5, 2
ADDI L0, -2
DBZ DONE # Done if L0 is 0
STHU.N L2, L5, 2
DO_BYTE:
CMPI L0, 1 # Copy leftover byte
BLT DONE
LDBU.D L1, L5, 0
STBU.D L2, L5, 0
DONE: # Copy done
MOV L2, L7 # Return pointer
RET PC, L3
#****************************
# Byte memcpy
#****************************
mem_except:
DBR L_5
MOVI L6,0
L_3:
LDBS.D L1, L5, 0 # Transfer the byte
ADDI L6, 1
STBS.D L2, L5, 0
ADDI L2, 1
ADDI L1, 1
L_5: # Loop test
CMP L6, L0
BST L_3
MOV L2, L7 # Return pointer
RET PC, L3
.END

47
src/arch/e1/core/memset.S Normal file
View File

@@ -0,0 +1,47 @@
/*
* Derived from the Hyperstone's library source code.
* Modefied src in order to apply the -mgnu-param compiler option.
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
* George Thanos <gthanos@telecom.ntua.gr>
*/
.text
.align 2
.global _memset
;ENTRY(_memset)
_memset: FRAME L9, L3
MASK L5, L1, 0xFF
MOV L8, L2
CMPI L0, 0 # if n = 0 then return
BE retour
loop0: CMPBI L8, 0x3
BZ word_bound
ADDI L0, -1
DBNZ loop0
STBU.N L8, L5, 1
retour: RET PC, L3
word_bound:
CMPI L0, 8
DBLT loop2
MOV L7, L5
SHLI L7, 8
OR L5, L7
MOV L7, L5
SHLI L7, 16
OR L5, L7
MOV L6, L5
loop1: ADDI L0, -8
CMPI L0, 8
DBGE loop1
STD.P L8, L5
CMPI L0, 0
DBNZ loop2
ANDNI L5, ~ 0xFF
RET PC, L3
loop2: ADDI L0, -1
DBNZ loop2
STBU.N L8, L5, 1
RET PC, L3

26
src/arch/e1/core/setjmp.c Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright 2003 Yannis Mitsos and George Thanos
* {gmitsos@gthanos}@telecom.ntua.gr
* Released under GPL2, see the file COPYING in the top directory
*
*/
#include "setjmp.h"
int setjmp( jmp_buf state)
{
asm volatile( "mov %0, G3\n\t"
"mov %1, G4\n\t"
:"=l"(state->__jmpbuf->G3),
"=l"(state->__jmpbuf->G4)
:/*no input*/
:"%G3", "%G4" );
asm volatile( "setadr %0\n\t"
"mov %1, L1\n\t"
"mov %2, L2\n\t"
:"=l"(state->__jmpbuf->SavedSP),
"=l"(state->__jmpbuf->SavedPC),
"=l"(state->__jmpbuf->SavedSR)
:/*no input*/);
return 0;
}

111
src/arch/e1/core/start.S Normal file
View File

@@ -0,0 +1,111 @@
/*
* Derived from the Hyperstone's library source code.
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
* George Thanos <gthanos@telecom.ntua.gr>
*/
.global Priority ; Task-Priority
.global _Stack1Size ; Size of hardware stack
.global _Stack2Size ; Size of aggregate stack
.global _Stack1Base ; Base of hardware stack
.global _Stack2Base ; Base of aggregate stack
.global _Mem0HeapBase ; Base of Heap in Mem0
.global _Mem1HeapBase ; Base of Heap in Mem1
.global _init_peripherals
.global _main
.global Main
.global __exit
.global __fmode
.global __MaxArgCount
.text
BasePtrs:
.weak G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
.long G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
BasePtrsEnd:
HeapPtrs:
.long _Mem0HeapBase
.long _Mem1HeapBase
HeapPtrsEnd:
__MaxArgCount:
.long 32
__StandAloneMode:
.long 0 ; 0 indicate stand alone mode
;============================================================================;
; Startup-Code ;
;============================================================================;
.data
; do not change the order of: __argc,..
__argc:
.long 0
__argv:
.long 0
__IsShell:
.long 1
ErrorLevel:
.long 0
__lab:
.long 0
__fmode:
.long 0x4000 ; O_TEXT attribute
_isa_drivers:
.long 0
_isa_drivers_end:
.long 0
.text
Main:
StartUp:
FRAME L5, L0
MOVI L2, __bss_start__ ; clear the .bss segment
0: CMPI L2, __bss_end__
BHE 0f
DBR 0b
STW.P L2, 0
0: SUM L2, PC, BasePtrs-$ ; Load BasePtrs G6-G13
LDD.P L2, G6
LDD.P L2, G8
; LDD.P L2, G10
LDD.P L2, G12
MOVI L2, 1
SUM L3, PC, __StandAloneMode-$
STW.R L3, L2
;----------------------------------------------------------------;
; Call main C function ;
;----------------------------------------------------------------;
2: LDW.D PC, L2, __argc - $ ; pass count of arguments to main
LDW.D PC, L3, __argv - $ ; pass pointer array to main
CALL L4, PC, _init_peripherals - $
CALL L4, PC, _main - $ ; --> Call Main-Program
CHK PC, PC ; trap if execution arrives here
__exit:
FRAME L5, L1
STW.D PC, L0, ErrorLevel - $ ; Store ERRORLEVEL
CHK PC, PC
RET PC, L1
.global ___main
___main:
FRAME L4, L1
MOVI L3, 2
STW.D PC, L3, __StandAloneMode-$
RET PC, L1 ; does not return
.section _GOT_
.long Main+4 ; OnCreate
.long Main+8 ; OnError
.long BasePtrs ; G6
.long BasePtrs+4 ; G7
.long BasePtrs+8 ; G8
.END

76
src/arch/e1/core/strcmp.S Normal file
View File

@@ -0,0 +1,76 @@
/*
* Derived from the Hyperstone's library source code.
* Modefied src in order to apply the -mgnu-param compiler option.
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
* George Thanos <gthanos@telecom.ntua.gr>
*/
.text
.align 2
.global _strcmp
;ENTRY(_strcmp)
_strcmp:
FRAME L8,L2
CMPBI L1, 3 # check for word alignment
BNZ str_except
CMPBI L0, 3 # check for word alignment
BNZ str_except
start:
LDD.P L1, L4 # post inc mode
LDD.P L0, L6 # post inc mode
CMPBI L4, ANYBZ
BE correct1
CMP L4, L6
BNE correct1
CMP L5, L7
BNE correct
CMPBI L5, ANYBZ
BE correct
CMPBI L6, ANYBZ
BE correct1
CMPBI L7, ANYBZ
BNE start
correct: MASK L4, L5, 0xff000000
MASK L6, L7, 0xff000000
CMP L4, L6
BNE Exit
SHLI L5, 8
CMPI L4, 0
DBNE correct
SHLI L7, 8
MOV L1, L4
RET PC, L2
Exit: SUB L4, L6 # Subtract chars
SARI L4, 24
MOV L1, L4
RET PC, L2
correct1: MASK L5, L4, 0xff000000
MASK L7, L6, 0xff000000
CMP L5, L7
BNE Exit1
SHLI L4, 8
CMPI L5, 0
DBNE correct1
SHLI L6, 8
MOV L1, L5
RET PC, L2
Exit1: SUB L5, L7 # Subtract chars
SARI L5, 24
MOV L1, L5
RET PC, L2
testzero: CMPI L4, 0
BE L_5
str_except:
LDBU.N L1, L4, 1 # Load *s1, compare bytes
LDBU.N L0, L5, 1 # Load *s2, compare bytes
CMP L4, L5
BE testzero
SUB L4, L5 # Subtract chars
L_5: MOV L1, L4
RET PC, L2
.END

View File

@@ -0,0 +1,39 @@
#ifndef ETHERBOOT_BITS_BYTESWAP_H
#define ETHERBOOT_BITS_BYTESWAP_H
/* We do not have byte swap functions ... We are
* RISC processor ...
*/
static inline unsigned short __swap16(volatile unsigned short v)
{
return ((v << 8) | (v >> 8));
}
static inline unsigned int __swap32(volatile unsigned long v)
{
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
}
#define __bswap_constant_16(x) \
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
(((uint16_t)(x) & 0xff00) >> 8)))
#define __bswap_constant_32(x) \
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
(((uint32_t)(x) & 0x0000ff00U) << 8) | \
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \
(((uint32_t)(x) & 0xff000000U) >> 24)))
#define __bswap_16(x) \
(__builtin_constant_p(x) ? \
__bswap_constant_16(x) : \
__swap16(x))
#define __bswap_32(x) \
(__builtin_constant_p(x) ? \
__bswap_constant_32(x) : \
__swap32(x))
#endif /* ETHERBOOT_BITS_BYTESWAP_H */

View File

@@ -0,0 +1,6 @@
#ifndef E1_BITS_CPU_H
#define E1_BITS_CPU_H
#define cpu_setup() do {} while(0)
#endif /* E1_BITS_CPU_H */

View File

@@ -0,0 +1,6 @@
#ifndef E1_BITS_ELF_H
#define E1_BITS_ELF_H
/* dummy file, needed for the compilation of core/nic.c */
#endif /* E1_BITS_ELF_H */

View File

@@ -0,0 +1,6 @@
#ifndef ETHERBOOT_BITS_ENDIAN_H
#define ETHERBOOT_BITS_ENDIAN_H
#define __BYTE_ORDER __BIG_ENDIAN
#endif /* ETHERBOOT_BITS_ENDIAN_H */

View File

@@ -0,0 +1,35 @@
#ifndef ETHERBOOT_BITS_STRING_H
#define ETHERBOOT_BITS_STRING_H
/* define inline optimized string functions here */
#define __HAVE_ARCH_MEMCPY
//extern void * memcpy(const void *d, const void *s, size_t count);
#define __HAVE_ARCH_MEMCMP
//extern int memcmp(const void * s ,const void * d ,size_t );
#define __HAVE_ARCH_MEMSET
//extern void * memset(const void * s, int c, size_t count);
#define __HAVE_ARCH_MEMMOVE
static inline void *memmove(void *s1, const void *s2, size_t n) {
unsigned int i;
char *tmp = s1;
char *cs2 = (char *) s2;
if (tmp < cs2) {
for(i=0; i<n; ++i, ++tmp, ++cs2)
*tmp = *cs2;
}
else {
tmp += n - 1;
cs2 += n - 1;
for(i=0; i<n; ++i, --tmp, --cs2)
*tmp = *cs2;
}
return(s1);
}
#endif /* ETHERBOOT_BITS_STRING_H */

View File

@@ -0,0 +1,22 @@
#ifndef __E132_XS_BOARD_H
#define __E132_XS_BOARD_H
#define CONFIG_HYPERSTONE_OSC_FREQ_MHZ 15
#define NR_MEMORY_REGNS 3
#define BASEMEM 0x0
/* SDRAM mapping */
#define SDRAM_SIZE 0x01000000
#define SDRAM_BASEMEM BASEMEM
/* SRAM mapping */
#define SRAM_BASEMEM 0x40000000
#define SRAM_SIZE 0x0003FFFF
/* IRAM mapping */
#define IRAM_BASEMEM 0xC0000000
#define IRAM_SIZE 0x00003FFF
#endif /* __E132_XS_BOARD_H */

View File

@@ -0,0 +1,9 @@
#ifndef ETHERBOOT_E1_HOOKS_H
#define ETHERBOOT_E1_HOOKS_H
#define arch_main(data,params) do {} while(0)
#define arch_on_exit(status) do {} while(0)
#define arch_relocate_to(addr) do {} while(0)
#define arch_relocated_from(old_addr) do {} while(0)
#endif /* ETHERBOOT_E1_HOOKS_H */

210
src/arch/e1/include/io.h Normal file
View File

@@ -0,0 +1,210 @@
#ifndef ETHERBOOT_IO_H
#define ETHERBOOT_IO_H
/* Don't require identity mapped physical memory,
* osloader.c is the only valid user at the moment.
*/
#if 0
static inline unsigned long virt_to_phys(volatile const void *virt_addr)
{
return ((unsigned long)virt_addr);
}
#else
#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
#endif
#if 0
static inline void *phys_to_virt(unsigned long phys_addr)
{
return (void *)(phys_addr);
}
#else
#define phys_to_virt(vaddr) ((void *) (vaddr))
#endif
/* virt_to_bus converts an addresss inside of etherboot [_start, _end]
* into a memory address cards can use.
*/
#define virt_to_bus virt_to_phys
/* bus_to_virt reverses virt_to_bus, the address must be output
* from virt_to_bus to be valid. This function does not work on
* all bus addresses.
*/
#define bus_to_virt phys_to_virt
#define iounmap(addr) ((void)0)
#define ioremap(physaddr, size) (physaddr)
#define IORegAddress 13
#define IOWait 11
#define IOSetupTime 8
#define IOAccessTime 5
#define IOHoldTime 3
#define SLOW_IO_ACCESS ( 0x3 << IOSetupTime | 0x0 << IOWait | 7 << IOAccessTime | 3 << IOHoldTime )
/* The development board can generate up to 15 Chip selects */
#define NR_CS 16
extern unsigned int io_periph[NR_CS];
#define ETHERNET_CS 4
static inline unsigned short _swapw(volatile unsigned short v)
{
return ((v << 8) | (v >> 8));
}
static inline unsigned int _swapl(volatile unsigned long v)
{
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
}
#define hy_inpw(addr) \
({ register unsigned long dummy, dummy1; \
dummy = addr; \
asm volatile ("LDW.IOD %1, %0, 0" \
: "=l" (dummy1) \
: "l" (dummy)); dummy1; })
#define hy_outpw(x, addr) \
({ register unsigned long dummy0,dummy1; \
dummy0 = addr; \
dummy1 = x; \
asm volatile ("STW.IOD %1, %0, 0" \
: "=l" (dummy1) \
: "l"(dummy0), "l" (dummy1)); dummy1; })
#define readb(addr) ({ unsigned char __v = inregb(addr); __v; })
#define readw(addr) ({ unsigned short __v = inregw(addr); __v; })
#define readl(addr) ({ unsigned long __v = inregl(addr); __v; })
#define writeb(b,addr) (void)(outreg(b, addr))
#define writew(b,addr) (void)(outreg(b, addr))
#define writel(b,addr) (void)(outreg(b, addr))
static inline unsigned long common_io_access(unsigned long addr)
{
return io_periph[(addr & 0x03C00000) >> 22];
}
static inline volatile unsigned char inregb(volatile unsigned long reg)
{
unsigned char val;
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
return val;
}
static inline volatile unsigned short inregw(volatile unsigned long reg)
{
unsigned short val;
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
return val;
}
static inline volatile unsigned long inregl(volatile unsigned long reg)
{
unsigned long val;
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
return val;
}
static inline void outreg(volatile unsigned long val, volatile unsigned long reg)
{
hy_outpw(val, (common_io_access(reg) | ((0xf & reg) << IORegAddress)));
}
static inline void io_outsb(unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned char *bp = (unsigned char *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--){
hy_outpw(_swapw(*bp++), tmp);
}
}
static inline void io_outsw(volatile unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned short *bp = (unsigned short *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--){
hy_outpw(_swapw(*bp++), tmp);
}
}
static inline void io_outsl(volatile unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned int *bp = (unsigned int *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--){
hy_outpw(_swapl(*bp++), tmp);
}
}
static inline void io_insb(volatile unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned char *bp = (unsigned char *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--)
*bp++ = hy_inpw((unsigned char) tmp);
}
static inline void io_insw(unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned short *bp = (unsigned short *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--)
*bp++ = _swapw((unsigned short)hy_inpw(tmp));
}
static inline void io_insl(unsigned int addr, void *buf, int len)
{
unsigned long tmp;
unsigned int *bp = (unsigned int *) buf;
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
while (len--)
*bp++ = _swapl((unsigned int)hy_inpw(tmp));
}
#define inb(addr) readb(addr)
#define inw(addr) readw(addr)
#define inl(addr) readl(addr)
#define outb(x,addr) ((void) writeb(x,addr))
#define outw(x,addr) ((void) writew(x,addr))
#define outl(x,addr) ((void) writel(x,addr))
#define insb(a,b,l) io_insb(a,b,l)
#define insw(a,b,l) io_insw(a,b,l)
#define insl(a,b,l) io_insl(a,b,l)
#define outsb(a,b,l) io_outsb(a,b,l)
#define outsw(a,b,l) io_outsw(a,b,l)
#define outsl(a,b,l) io_outsl(a,b,l)
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
#endif /* ETHERBOOT_IO_H */

View File

@@ -0,0 +1,12 @@
#ifndef LATCH_H
#define LATCH_H
//#define TICKS_PER_SEC (1000000UL)
#define TICKS_PER_SEC (625000UL)
/* Fixed timer interval used for calibrating a more precise timer */
//#define LATCHES_PER_SEC 10
void sleep_latch(void);
#endif /* LATCH_H */

View File

@@ -0,0 +1,34 @@
/*--------------------------------------------------------------------------*/
/* Project: ANSI C Standard Header Files */
/* File: LIMITS.H */
/* Edited by: hyperstone electronics GmbH */
/* Am Seerhein 8 */
/* D-78467 Konstanz, Germany */
/* Date: January 30, 1996 */
/*--------------------------------------------------------------------------*/
/* Purpose: */
/* The header file <limits.h> defines limits of ordinal types */
/* (char, short, int, long) */
/*--------------------------------------------------------------------------*/
#ifndef __LIMITS_H
#define __LIMITS_H 1
#define MB_LEN_MAX 1
#define CHAR_BIT 8
#define SCHAR_MIN -128L
#define SCHAR_MAX 127L
#define UCHAR_MAX 255
#define CHAR_MIN 0
#define CHAR_MAX UCHAR_MAX
#define SHRT_MIN -32768
#define SHRT_MAX 32767
#define USHRT_MAX 65535
#define INT_MIN 0x80000000
#define INT_MAX 0x7FFFFFFF
#define UINT_MAX 0xFFFFFFFFL
#define LONG_MIN INT_MIN
#define LONG_MAX INT_MAX
#define ULONG_MAX UINT_MAX
#endif

View File

@@ -0,0 +1,23 @@
#ifndef _SETJMP_H
#define _SETJMP_H
typedef struct {
unsigned long G3;
unsigned long G4;
unsigned long SavedSP;
unsigned long SavedPC;
unsigned long SavedSR;
unsigned long ReturnValue;
} __jmp_buf[1];
typedef struct __jmp_buf_tag /* C++ doesn't like tagless structs. */
{
__jmp_buf __jmpbuf; /* Calling environment. */
int __mask_was_saved; /* Saved the signal mask? */
} jmp_buf[1];
void longjmp(jmp_buf state, int value );
int setjmp( jmp_buf state);
#endif

View File

@@ -0,0 +1,16 @@
#ifndef STDINT_H
#define STDINT_H
typedef unsigned long size_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
#endif /* STDINT_H */