20000317 sourceware import

This commit is contained in:
Ranjith Kumaran
2000-03-17 22:48:54 +00:00
parent fae4c299f1
commit 03261851a1
420 changed files with 66815 additions and 0 deletions

233
libgloss/mips/Makefile.in Normal file
View File

@ -0,0 +1,233 @@
# Copyright (c) 1995, 1996, 1997, 1998, 1999 Cygnus Support
#
# The authors hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose, provided
# that existing copyright notices are retained in all copies and that this
# notice is included verbatim in any distributions. No written agreement,
# license, or royalty fee is required for any of the authorized uses.
# Modifications to this software may be copyrighted by their authors
# and need not follow the licensing terms described here, provided that
# the new terms are clearly indicated on the first page of each file where
# they apply.
VPATH = @srcdir@
srcdir = @srcdir@
objdir = .
srcroot = $(srcdir)/../..
objroot = $(objdir)/../..
prefix = @prefix@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
bindir = @bindir@
libdir = @libdir@
tooldir = $(exec_prefix)/$(target_alias)
# Multilib support variables.
# TOP is used instead of MULTI{BUILD,SRC}TOP.
MULTIDIRS =
MULTISUBDIR =
MULTIDO = true
MULTICLEAN = true
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
SHELL = /bin/sh
CC = @CC@
#AS = @AS@
AS = `if [ -f ${objroot}/../gas/as.new ] ; \
then echo ${objroot}/../gas/as.new ; \
else echo as ; fi`
AR = @AR@
#LD = @LD@
LD = `if [ -f ${objroot}/../ld/ld.new ] ; \
then echo ${objroot}/../ld/ld.new ; \
else echo ld ; fi`
RANLIB = @RANLIB@
OBJDUMP = `if [ -f ${objroot}/../binutils/objdump ] ; \
then echo ${objroot}/../binutils/objdump ; \
else t='$(program_transform_name)'; echo objdump | sed -e $$t ; fi`
OBJCOPY = `if [ -f ${objroot}/../binutils/objcopy ] ; \
then echo ${objroot}/../binutils/objcopy ; \
else t='$(program_transform_name)'; echo objcopy | sed -e $$t ; fi`
CRT0 = @crt0@
PCRT0 = @pcrt0@
GENOBJS = syscalls.o fstat.o getpid.o isatty.o kill.o \
lseek.o print.o putnum.o stat.o unlink.o
IDTOBJS = idtmon.o @part_specific_obj@ ${GENOBJS}
PMONOBJS = pmon.o @part_specific_obj@ ${GENOBJS}
LSIOBJS = lsipmon.o @part_specific_obj@ ${GENOBJS}
DVEOBJS = open.o close.o dvemon.o read.o write.o @part_specific_obj@ ${GENOBJS}
JMR3904OBJS = open.o close.o jmr3904-io.o read.o write.o \
@part_specific_obj@ ${GENOBJS}
# Nullmon cannot support read and write, but the test cases pull them in via libs
NULLMONOBJS = nullmon.o @part_specific_obj@ ${GENOBJS}
CFLAGS = -g
GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \
then echo -L${objroot}/../gcc ; fi`
SCRIPTS = @script_list@
BSP = @bsp_list@
PART_SPECIFIC_DEFINES = @part_specific_defines@
# Host specific makefile fragment comes in here.
@host_makefile_frag@
#
# build a test program for each target board. Just trying to get
# it to link is a good test, so we ignore all the errors for now.
#
all: ${CRT0} ${PCRT0} test.o ${BSP}
#
# here's where we build the board support packages for each target
#
mipsidt.o: $(IDTOBJS)
${LD} -r $(IDTOBJS) -o $@
mipspmon.o: $(PMONOBJS)
${LD} -r $(PMONOBJS) -o $@
mipslsi.o: $(PMONOBJS)
${LD} -r $(LSIOBJS) -o $@
libidt.a: $(IDTOBJS)
${AR} ${ARFLAGS} $@ $(IDTOBJS)
${RANLIB} $@
libpmon.a: $(PMONOBJS)
${AR} ${ARFLAGS} $@ $(PMONOBJS)
${RANLIB} $@
liblsi.a: $(LSIOBJS)
${AR} ${ARFLAGS} $@ $(LSIOBJS)
${RANLIB} $@
libdve.a: $(DVEOBJS)
${AR} ${ARFLAGS} $@ $(DVEOBJS)
${RANLIB} $@
libjmr3904.a: $(JMR3904OBJS)
${AR} ${ARFLAGS} $@ $(JMR3904OBJS)
${RANLIB} $@
# nullmon.a , This is what you want if you want crt0 but NO mon services
# Supports GDB sim testing, board bringups, ICE operation.
libnullmon.a: $(NULLMONOBJS)
${AR} ${ARFLAGS} $@ $(NULLMONOBJS)
${RANLIB} $@
# compile a fully linked binary. The -Wl,-T*.ld is for the linker
# script. By using -Wl, the linker script is put on the proper place
# in the comand line for ld, and all the symbols will get fully
# resolved.
test: $(OBJS) ${BSP} pmon-test idt-test
@echo Done...
dtor.o: $(srcdir)/dtor.C
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -o $@ -c $<
dtor.x: dtor.o ${CRT0} ${srcdir}/pmon.ld Makefile libpmon.a
${CC} $(CFLAGS_FOR_TARGET) -L${srcdir} -L${objdir} \
dtor.o -o $@ $(NEWLIB_LDFLAGS) -N -Wl,-Tpmon.ld
pmon-test.x: test.o ${CRT0} Makefile libpmon.a
${CC} $(CFLAGS_FOR_TARGET) -L${srcdir} -L${objdir} \
test.o -o $@ $(NEWLIB_LDFLAGS) -Wl,-Tpmon.ld
pmon-test.srec: pmon-test.x
$(OBJCOPY) -O srec pmon-test.x $@
pmon-test.dis: pmon-test.x
@rm -fr pmon-test.dis
$(OBJDUMP) -d pmon-test.x > $@
pmon-test: pmon-test.srec pmon-test.dis
idt-test.x: test.o ${CRT0} Makefile libidt.a
${CC} $(CFLAGS_FOR_TARGET) -L${srcdir} -L${objdir} \
test.o -o $@ $(NEWLIB_LDFLAGS) -Wl,-Tidt.ld
idt-test.srec: idt-test.x
$(OBJCOPY) -O srec idt-test.x $@
idt-test.dis: idt-test.x
@rm -fr idt-test.dis
$(OBJDUMP) -d idt-test.x > $@
idt-test: idt-test.srec idt-test.dis
doc:
clean mostlyclean:
rm -f a.out core *.i *~ *.o *-test *.srec *.dis *.map *.x
distclean maintainer-clean realclean: clean
rm -f Makefile config.status a.out
.PHONY: install info install-info clean-info
install:
if test "x$(CRT0)" != x ; then \
$(INSTALL_PROGRAM) $(CRT0) $(tooldir)/lib${MULTISUBDIR}/$(CRT0) ; \
fi
if test "x$(PCRT0)" != x ; then \
$(INSTALL_PROGRAM) $(PCRT0) $(tooldir)/lib${MULTISUBDIR}/$(PCRT0) ; \
fi
@for bsp in ${BSP}; do\
$(INSTALL_PROGRAM) $${bsp} $(tooldir)/lib${MULTISUBDIR}; \
done
@for script in ${SCRIPTS}; do\
$(INSTALL_DATA) ${srcdir}/$${script}.ld $(tooldir)/lib${MULTISUBDIR}/$${script}.ld; \
done
info:
install-info:
clean-info:
test.o: ${srcdir}/test.c
# these are for the BSPs
crt0.o: ${srcdir}/crt0.S
pcrt0.o: ${srcdir}/crt0.S
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) -DGCRT0 ${srcdir}/crt0.S -o ${PCRT0}
idtmon.o: ${srcdir}/idtmon.S
pmon.o: ${srcdir}/pmon.S
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $(PART_SPECIFIC_DEFINES) ${srcdir}/pmon.S -o pmon.o
vr4300.o: ${srcdir}/vr4300.S
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/vr4300.S
vr5xxx.o: ${srcdir}/vr5xxx.S
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/vr5xxx.S
lsipmon.o: $(srcdir)/lsipmon.S $(srcdir)/pmon.S
jmr3904-io.o: ${srcdir}/jmr3904-io.c
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) -mips3 ${srcdir}/jmr3904-io.c -o $@
# cma101 can not be compiled mips16, if a mips16 version is needed then
# it will have to be built, then this rule can be scrapped, allowing
# the implicit rule to run.
cma101.o: ${srcdir}/cma101.c
$(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) -mno-mips16 ${srcdir}/cma101.c
syscalls.o: ${srcdir}/syscalls.c
# target specific makefile fragment comes in here.
@target_makefile_frag@
Makefile: Makefile.in config.status @host_makefile_frag_path@ @target_makefile_frag_path@
$(SHELL) config.status
config.status: configure
$(SHELL) config.status --recheck

68
libgloss/mips/array-io.c Normal file
View File

@ -0,0 +1,68 @@
/* array-io.c -- I/O code for the Array Tech RAID disk controller.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#include "mips.h"
/*
* outbyte -- shove a byte out the serial port. We wait till the byte
*/
int
outbyte(byte)
unsigned char byte;
{
return (PUTCHAR(byte));
}
/*
* inbyte -- get a byte from the serial port
*/
unsigned char
inbyte()
{
return ((unsigned char)GETCHAR);
}
/*
* led_putnum -- print a hex number on the LED. the value of num must be a byte.
* The max number 15, since the front panel only has 4 LEDs.
*/
void
led_putnum ( num )
char num;
{
print ("Sorry, unimplemented, using putnum instead\r\n");
putnum (num);
}
/*
* zylons -- draw a rotating pattern. NOTE: this function never returns.
*/
void
zylons()
{
print ("Sorry, unimplemented\r\n");
}
/*
* delay -- a really gross, ugly hack for simple time delays
*/
void
delay (x)
int x;
{
int y = 17;
while (x-- !=0)
y = y^2;
}

171
libgloss/mips/array.ld Normal file
View File

@ -0,0 +1,171 @@
/*
* memory map assumed by prom and standalone system
*
* physical kseg1 use
*
* 0x1fc20000 0xbfc20000
* to prom text and read-only data
* 0x1fc00000 0xbfc00000 (in cpu board "prom space")
*
* (Top of RAM - 8K) downward sash and standalone program stack
* | ( - 8K to preserve kernel message bufs)
* V (standalone programs grow their stack
* immediately below sash's stack)
*
* ^
* |
* 0x00100000 0xa0100000 upward sash program text, data, and bss
*
* ^
* |
* 0x00020000 0xa0020000 upward standalone program text, data, and bss
* (kernel is loaded here, also)
*
* 0x0001ffff 0xa001ffff downward dbgmon stack
* |
* V
*
* ^
* |
* 0x00010000 0xa0010000 upward dbgmon text, data, and bss
*
* 0x0000ffff 0xa000ffff downward prom monitor stack
* |
* V
*
* ^
* |
* 0x00000500 0xa0000500 upward prom monitor bss
*
* 0x000004ff 0xa00004ff
* to restart block
* 0x00000400 0xa0000400
*
* 0x000003ff 0xa00003ff
* to general exception code
* 0x00000080 0xa0000080 (note cpu addresses as 0x80000080!)
*
* 0x0000007f 0xa000007f
* to utlbmiss exception code
* 0x00000000 0xa0000000 (note cpu addresses as 0x80000000!)
*/
/* Uncomment this if you want srecords.
OUTPUT_FORMAT(srec)
*/
ENTRY(start)
STARTUP(crt0.o)
INPUT(array.o)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*
PROVIDE (__stack = 1M - 8);
*/
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0x80020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rdata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
_gp = ALIGN(16) + 0x8000;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
}

300
libgloss/mips/cma101.c Normal file
View File

@ -0,0 +1,300 @@
/*
* cma101.c -- lo-level support for Cogent CMA101 development board.
*
* Copyright (c) 1996 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#ifdef __mips16
/* The assembler portions of this file need to be re-written to
support mips16, if and when that seems useful.
*/
#error cma101.c can not be compiled -mips16
#endif
#include <time.h> /* standard ANSI time routines */
/* Normally these would appear in a header file for external
use. However, we are only building a simple example world at the
moment: */
#include "regs.S"
#if defined(MIPSEB)
#define BYTEREG(b,o) ((volatile unsigned char *)(PHYS_TO_K1((b) + (o) + 7)))
#endif /* MIPSEB */
#if defined(MIPSEL)
#define BYTEREG(b,o) ((volatile unsigned char *)(PHYS_TO_K1((b) + (o))))
#endif /* MIPSEL */
/* I/O addresses: */
#define RTCLOCK_BASE (0x0E800000) /* Mk48T02 NVRAM/RTC */
#define UART_BASE (0x0E900000) /* NS16C552 DUART */
#define LCD_BASE (0x0EB00000) /* Alphanumeric display */
/* LCD panel manifests: */
#define LCD_DATA BYTEREG(LCD_BASE,0)
#define LCD_CMD BYTEREG(LCD_BASE,8)
#define LCD_STAT_BUSY (0x80)
#define LCD_SET_DDADDR (0x80)
/* RTC manifests */
/* The lo-offsets are the NVRAM locations (0x7F8 bytes) */
#define RTC_CONTROL BYTEREG(RTCLOCK_BASE,0x3FC0)
#define RTC_SECS BYTEREG(RTCLOCK_BASE,0x3FC8)
#define RTC_MINS BYTEREG(RTCLOCK_BASE,0x3FD0)
#define RTC_HOURS BYTEREG(RTCLOCK_BASE,0x3FD8)
#define RTC_DAY BYTEREG(RTCLOCK_BASE,0x3FE0)
#define RTC_DATE BYTEREG(RTCLOCK_BASE,0x3FE8)
#define RTC_MONTH BYTEREG(RTCLOCK_BASE,0x3FF0)
#define RTC_YEAR BYTEREG(RTCLOCK_BASE,0x3FF8)
#define RTC_CTL_LOCK_READ (0x40) /* lock RTC whilst reading */
#define RTC_CTL_LOCK_WRITE (0x80) /* lock RTC whilst writing */
/* Macro to force out-standing memory transfers to complete before
next sequence. For the moment we assume that the processor in the
CMA101 board supports at least ISA II. */
#define DOSYNC() asm(" .set mips2 ; sync ; .set mips0")
/* We disable interrupts by writing zero to all of the masks, and the
global interrupt enable bit: */
#define INTDISABLE(sr,tmp) asm("\
.set mips2 ; \
mfc0 %0,$12 ; \
lui %1,0xffff ; \
ori %1,%1,0xfffe ; \
and %1, %0, %1 ; \
mtc0 %1,$12 ; \
.set mips0" : "=d" (sr), "=d" (tmp))
#define INTRESTORE(sr) asm("\
.set mips2 ; \
mtc0 %0,$12 ; \
.set mips0" : : "d" (sr))
/* TODO:FIXME: The CPU card support should be in separate source file
from the standard CMA101 support provided in this file. */
/* The CMA101 board being used contains a CMA257 Vr4300 CPU:
MasterClock is at 33MHz. PClock is derived from MasterClock by
multiplying by the ratio defined by the DivMode pins:
DivMode(1:0) MasterClock PClock Ratio
00 100MHz 100MHz 1:1
01 100MHz 150MHz 1.5:1
10 100MHz 200MHz 2:1
11 100Mhz 300MHz 3:1
Are these pins reflected in the EC bits in the CONFIG register? or
is that talking about a different clock multiplier?
110 = 1
111 = 1.5
000 = 2
001 = 3
(all other values are undefined)
*/
#define MASTERCLOCK (33) /* ticks per uS */
unsigned int pclock; /* number of PClock ticks per uS */
void
set_pclock (void)
{
unsigned int config;
asm volatile ("mfc0 %0,$16 ; nop ; nop" : "=r" (config)); /* nasty CP0 register constant */
switch ((config >> 28) & 0x7) {
case 0x7 : /* 1.5:1 */
pclock = (MASTERCLOCK + (MASTERCLOCK / 2));
break;
case 0x0 : /* 2:1 */
pclock = (2 * MASTERCLOCK);
break;
case 0x1 : /* 3:1 */
pclock = (3 * MASTERCLOCK);
break;
case 0x6 : /* 1:1 */
default : /* invalid configuration, so assume the lowest */
pclock = MASTERCLOCK;
break;
}
return;
}
#define PCLOCK_WAIT(x) __cpu_timer_poll((x) * pclock)
/* NOTE: On the Cogent CMA101 board the LCD controller will sometimes
return not-busy, even though it is. The work-around is to perform a
~50uS delay before checking the busy signal. */
static int
lcd_busy (void)
{
PCLOCK_WAIT(50); /* 50uS delay */
return(*LCD_CMD & LCD_STAT_BUSY);
}
/* Note: This code *ASSUMES* that the LCD has already been initialised
by the monitor. It only provides code to write to the LCD, and is
not a complete device driver. */
void
lcd_display (int line, const char *msg)
{
int n;
if (lcd_busy ())
return;
*LCD_CMD = (LCD_SET_DDADDR | (line == 1 ? 0x40 : 0x00));
for (n = 0; n < 16; n++) {
if (lcd_busy ())
return;
if (*msg)
*LCD_DATA = *msg++;
else
*LCD_DATA = ' ';
}
return;
}
#define SM_PATTERN (0x55AA55AA)
#define SM_INCR ((256 << 10) / sizeof(unsigned int)) /* 64K words */
extern unsigned int __buserr_count(void);
extern void __default_buserr_handler(void);
extern void __restore_buserr_handler(void);
unsigned int
__sizemem ()
{
volatile unsigned int *base;
volatile unsigned int *probe;
unsigned int baseorig;
unsigned int sr;
extern void *end;
int extra;
INTDISABLE(sr,baseorig); /* disable all interrupt masks */
__default_buserr_handler();
__cpu_flush();
DOSYNC();
/* _end is the end of the user program. _end may not be properly aligned
for an int pointer, so we adjust the address to make sure it is safe.
We use void * arithmetic to avoid accidentally truncating the pointer. */
extra = ((int) &end & (sizeof (int) - 1));
base = ((void *) &end + sizeof (int) - extra);
baseorig = *base;
*base = SM_PATTERN;
/* This assumes that the instructions fetched between the store, and
the following read will have changed the data bus contents: */
if (*base == SM_PATTERN) {
probe = base;
for (;;) {
unsigned int probeorig;
probe += SM_INCR;
probeorig = *probe;
/* Check if a bus error occurred: */
if (!__buserr_count()) {
*probe = SM_PATTERN;
DOSYNC();
if (*probe == SM_PATTERN) {
*probe = ~SM_PATTERN;
DOSYNC();
if (*probe == ~SM_PATTERN) {
if (*base == SM_PATTERN) {
*probe = probeorig;
continue;
}
}
}
*probe = probeorig;
}
break;
}
}
*base = baseorig;
__restore_buserr_handler();
__cpu_flush();
DOSYNC();
INTRESTORE(sr); /* restore interrupt mask to entry state */
return((probe - base) * sizeof(unsigned int));
}
/* Provided as a function, so as to avoid reading the I/O location
multiple times: */
static int
convertbcd(byte)
unsigned char byte;
{
return ((((byte >> 4) & 0xF) * 10) + (byte & 0xF));
}
time_t
time (_timer)
time_t *_timer;
{
time_t result = 0;
struct tm tm;
*RTC_CONTROL |= RTC_CTL_LOCK_READ;
DOSYNC();
tm.tm_sec = convertbcd(*RTC_SECS);
tm.tm_min = convertbcd(*RTC_MINS);
tm.tm_hour = convertbcd(*RTC_HOURS);
tm.tm_mday = convertbcd(*RTC_DATE);
tm.tm_mon = convertbcd(*RTC_MONTH);
tm.tm_year = convertbcd(*RTC_YEAR);
DOSYNC();
*RTC_CONTROL &= ~(RTC_CTL_LOCK_READ | RTC_CTL_LOCK_WRITE);
tm.tm_isdst = 0;
/* Check for invalid time information */
if ((tm.tm_sec < 60) && (tm.tm_min < 60) && (tm.tm_hour < 24)
&& (tm.tm_mday < 32) && (tm.tm_mon < 13)) {
/* Get the correct year number, but keep it in YEAR-1900 form: */
if (tm.tm_year < 70)
tm.tm_year += 100;
#if 0 /* NOTE: mon_printf() can only accept 4 arguments (format string + 3 fields) */
mon_printf("[DBG: s=%d m=%d h=%d]", tm.tm_sec, tm.tm_min, tm.tm_hour);
mon_printf("[DBG: d=%d m=%d y=%d]", tm.tm_mday, tm.tm_mon, tm.tm_year);
#endif
/* Convert the time-structure into a second count */
result = mktime (&tm);
}
if (_timer != NULL)
*_timer = result;
return (result);
}
/*> EOF cma101.c <*/

1254
libgloss/mips/configure vendored Executable file

File diff suppressed because it is too large Load Diff

144
libgloss/mips/configure.in Normal file
View File

@ -0,0 +1,144 @@
# Copyright (c) 1995, 1996, 1997, 1998, 1999 Cygnus Support
#
# The authors hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose, provided
# that existing copyright notices are retained in all copies and that this
# notice is included verbatim in any distributions. No written agreement,
# license, or royalty fee is required for any of the authorized uses.
# Modifications to this software may be copyrighted by their authors
# and need not follow the licensing terms described here, provided that
# the new terms are clearly indicated on the first page of each file where
# they apply.
#
# Process this file with autoconf to produce a configure script.
#
AC_PREREQ(2.5)dnl
AC_INIT(crt0.S)
if test "${enable_shared}" = "yes" ; then
echo "Shared libraries not supported for cross compiling, ignored"
fi
if test "$srcdir" = "." ; then
if test "${with_target_subdir}" != "." ; then
libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
else
libgloss_topdir="${srcdir}/${with_multisrctop}../.."
fi
else
libgloss_topdir="${srcdir}/../.."
fi
AC_CONFIG_AUX_DIR($libgloss_topdir)
AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM
AC_PROG_INSTALL
# FIXME: We temporarily define our own version of AC_PROG_CC. This is
# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
# are building a library that must be included in all links, so we
# can't link an executable until this lib is built.
# autoconf should provide a way to do this.
AC_DEFUN(LIB_AC_PROG_CC,
[AC_BEFORE([$0], [AC_PROG_CPP])dnl
AC_CHECK_PROG(CC, gcc, gcc)
if test -z "$CC"; then
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
fi
AC_PROG_CC_GNU
if test $ac_cv_prog_gcc = yes; then
GCC=yes
dnl Check whether -g works, even if CFLAGS is set, in case the package
dnl plays around with CFLAGS (such as to build both debugging and
dnl normal versions of a library), tasteless as that idea is.
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
AC_PROG_CC_G
if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-O2"
fi
else
GCC=
test "${CFLAGS+set}" = set || CFLAGS="-g"
fi
])
LIB_AC_PROG_CC
AS=${AS-as}
AC_SUBST(AS)
AR=${AR-ar}
AC_SUBST(AR)
LD=${LD-ld}
AC_SUBST(LD)
AC_PROG_RANLIB
crt0=crt0.o
pcrt0=pcrt0.o
case "${target}" in
mips*-tx39*-*|mipstx39*-*-*)
part_specific_obj=
part_specific_defines=
script_list="dve idt jmr3904app jmr3904dram jmr3904dram-java jmr3904app-java"
bsp_list="libdve.a libidt.a libjmr3904.a"
;;
mips*-lsi*-*)
part_specific_obj=entry.o
part_specific_defines=
script_list="lsi"
bsp_list=liblsi.a
;;
mips64vr5*-*-*)
part_specific_obj="vr5xxx.o cma101.o"
part_specific_defines=-DR5000
script_list="idt pmon ddb lsi idtecoff nullmon"
bsp_list="libidt.a libpmon.a liblsi.a libnullmon.a"
;;
*)
part_specific_obj="vr4300.o cma101.o"
part_specific_defines=
script_list="idt pmon ddb lsi idtecoff nullmon"
bsp_list="libidt.a libpmon.a liblsi.a libnullmon.a"
;;
esac
host_makefile_frag=${srcdir}/../config/default.mh
target_makefile_frag=${srcdir}/../config/mips.mt
dnl We have to assign the same value to other variables because autoconf
dnl doesn't provide a mechanism to substitute a replacement keyword with
dnl arbitrary data or pathnames.
dnl
host_makefile_frag_path=$host_makefile_frag
AC_SUBST(host_makefile_frag_path)
AC_SUBST_FILE(host_makefile_frag)
target_makefile_frag_path=$target_makefile_frag
AC_SUBST(target_makefile_frag_path)
AC_SUBST_FILE(target_makefile_frag)
AC_SUBST(part_specific_obj)
AC_SUBST(part_specific_defines)
AC_SUBST(script_list)
AC_SUBST(bsp_list)
AC_SUBST(crt0)
AC_SUBST(pcrt0)
AC_OUTPUT(Makefile,
. ${libgloss_topdir}/config-ml.in,
srcdir=${srcdir}
target=${target}
ac_configure_args="${ac_configure_args} --enable-multilib"
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
libgloss_topdir=${libgloss_topdir}
)

230
libgloss/mips/crt0.S Normal file
View File

@ -0,0 +1,230 @@
/*
* crt0.S -- startup file for MIPS.
*
* Copyright (c) 1995, 1996, 1997 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#include "regs.S"
/*
* Set up some room for a stack. We just grab a chunk of memory.
*/
#define STACK_SIZE 0x4000
#define GLOBAL_SIZE 0x2000
#define STARTUP_STACK_SIZE 0x0100
/* This is for referencing addresses that are not in the .sdata or
.sbss section under embedded-pic, or before we've set up gp. */
#ifdef __mips_embedded_pic
# ifdef __mips64
# define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
# else
# define LA(t,x) la t,x-PICBASE ; addu t,s0,t
# endif
#else /* __mips_embedded_pic */
# define LA(t,x) la t,x
#endif /* __mips_embedded_pic */
.comm __memsize, 12
.comm __lstack, STARTUP_STACK_SIZE
.comm __stackbase,4
.text
.align 2
/* Without the following nop, GDB thinks _start is a data variable.
* This is probably a bug in GDB in handling a symbol that is at the
* start of the .text section.
*/
nop
.globl _start
.ent _start
_start:
.set noreorder
#ifdef __mips_embedded_pic
PICBASE = .+8
bal PICBASE
nop
move s0,$31
#endif
#if __mips < 3
#define STATUS_MASK (SR_CU1|SR_PE)
#else
# For mips3 or mips4, turn on 64-bit addressing and additional float regs
#define STATUS_MASK (SR_CU1|SR_PE|SR_FR|SR_KX|SR_SX|SR_UX)
#endif
li v0, STATUS_MASK
mtc0 v0, C0_SR
mtc0 zero, C0_CAUSE
nop
/* Check for FPU presence. Don't check if we know that soft_float is
being used. (This also avoids illegal instruction exceptions.) */
#ifndef __mips_soft_float
li t2,0xAAAA5555
mtc1 t2,fp0 /* write to FPR 0 */
mtc1 zero,fp1 /* write to FPR 1 */
mfc1 t0,fp0
mfc1 t1,fp1
nop
bne t0,t2,1f /* check for match */
nop
bne t1,zero,1f /* double check */
nop
j 2f /* FPU is present. */
nop
#endif
1:
/* FPU is not present. Set status register to say that. */
li v0, (STATUS_MASK-(STATUS_MASK & SR_CU1))
mtc0 v0, C0_SR
nop
2:
/* Fix high bits, if any, of the PC so that exception handling
doesn't get confused. */
LA (v0, 3f)
jr v0
nop
3:
LA (gp, _gp) # set the global data pointer
.end _start
/*
* zero out the bss section.
*/
.globl __memsize
.globl get_mem_info .text
.globl __stack
.globl __global
.globl zerobss
.ent zerobss
zerobss:
LA (v0, _fbss)
LA (v1, _end)
3:
sw zero,0(v0)
bltu v0,v1,3b
addiu v0,v0,4 # executed in delay slot
la t0, __lstack # make a small stack so we
addiu sp, t0, STARTUP_STACK_SIZE # can run some C code
la a0, __memsize # get the usable memory size
jal get_mem_info
nop
/* setup the stack pointer */
LA (t0, __stack) # is __stack set ?
bne t0,zero,4f
nop
/* NOTE: a0[0] contains the amount of memory available, and
not the last memory address. */
lw t0,0(a0) # last address of memory available
la t1,K0BASE # cached kernel memory
addu t0,t0,t1 # get the end of memory address
/* We must subtract 24 bytes for the 3 8 byte arguments to main, in
case main wants to write them back to the stack. The caller is
supposed to allocate stack space for parameters in registers in
the old MIPS ABIs. We must do this even though we aren't passing
arguments, because main might be declared to have them.
Some ports need a larger alignment for the stack, so we subtract
32, which satisifes the stack for the arguments and keeps the
stack pointer better aligned. */
subu t0,t0,32 # and generate a starting stack-pointer
4:
move sp,t0 # set stack pointer
sw sp,__stackbase # keep this for future ref
.end zerobss
/*
* initialize target specific stuff. Only execute these
* functions it they exist.
*/
.globl hardware_init_hook .text
.globl software_init_hook .text
.globl __do_global_dtors .text
.globl atexit .text
.globl exit .text
.globl init
.ent init
init:
LA (t9, hardware_init_hook) # init the hardware if needed
beq t9,zero,6f
nop
jal t9
nop
6:
LA (t9, software_init_hook) # init the hardware if needed
beq t9,zero,7f
nop
jal t9
nop
7:
LA (a0, __do_global_dtors)
jal atexit
nop
#ifdef GCRT0
.globl _ftext
.globl _extext
LA (a0, _ftext)
LA (a1, _etext)
jal monstartup
nop
#endif
move a0,zero # set argc to 0
jal main # call the program start function
nop
# fall through to the "exit" routine
jal exit # call libc exit to run the G++
# destructors
move a0,v0 # pass through the exit code
.end init
/*
* _exit -- Exit from the application. Normally we cause a user trap
* to return to the ROM monitor for another run. NOTE: This is
* the only other routine we provide in the crt0.o object, since
* it may be tied to the "_start" routine. It also allows
* executables that contain a complete world to be linked with
* just the crt0.o object.
*/
.globl _exit
.ent _exit
_exit:
7:
#ifdef GCRT0
jal _mcleanup
nop
#endif
# break instruction can cope with 0xfffff, but GAS limits the range:
break 1023
nop
b 7b # but loop back just in-case
nop
.end _exit
/* EOF crt0.S */

154
libgloss/mips/ddb.ld Normal file
View File

@ -0,0 +1,154 @@
/* The following TEXT start address leaves space for the monitor
workspace. */
ENTRY(_start)
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -lpmon -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0100000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rdata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

25
libgloss/mips/dtor.C Normal file
View File

@ -0,0 +1,25 @@
#include <stdio.h>
extern "C" void print (char *, ...);
class foo
{
public:
foo () { print ("ctor\n"); }
~foo () { print ("dtor\n"); }
};
foo x;
main ()
{
outbyte ('&');
outbyte ('@');
outbyte ('$');
outbyte ('%');
print ("FooBar\r\n");
/* whew, we made it */
print ("\r\nDone...\r\n");
fflush(stdout);
}

155
libgloss/mips/dve.ld Normal file
View File

@ -0,0 +1,155 @@
/* Linker script for Densan DVE-R3900/20A board */
ENTRY(_start)
OUTPUT_ARCH("mips:3000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -ldve -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0040000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

83
libgloss/mips/dvemon.c Normal file
View File

@ -0,0 +1,83 @@
/* dve.c -- I/O code for the Densan DVE-R3900 board.
*
* Copyright (c) 1998, 1999 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
/* Flag indicating that we are being debugged by GDB. If set,
preceded each character output to the console with a ^O,
so that GDB will print it instead of discarding it. */
int output_debug = 1;
/* Monitor "ci" function (console input) */
typedef int (*cifunc)(int waitflag);
#ifdef __mips64
static cifunc ci = (cifunc) 0xffffffffbfc00010L;
#else
static cifunc ci = (cifunc) 0xbfc00010;
#endif
#define WAIT 1
#define NOWAIT 0
#define NOCHAR (-1)
/* Monitor "co" function (console output) */
typedef void (*cofunc)(int c);
#ifdef __mips64
static cofunc co = (cofunc) 0xffffffffbfc00018L;
#else
static cofunc co = (cofunc) 0xbfc00018;
#endif
/* outbyte -- shove a byte out the serial port; used by write.c. */
int
outbyte(byte)
unsigned char byte;
{
/* Output a ^O prefix so that GDB won't discard the output. */
if (output_debug)
co (0x0f);
co (byte);
return byte;
}
/* inbyte -- get a byte from the serial port; used by read.c. */
unsigned char
inbyte()
{
return (unsigned char) ci (WAIT);
}
/* Structure filled in by get_mem_info. Only the size field is
actually used (by sbrk), so the others aren't even filled in. */
struct s_mem
{
unsigned int size;
unsigned int icsize;
unsigned int dcsize;
};
void
get_mem_info (mem)
struct s_mem *mem;
{
mem->size = 0x1000000; /* DVE-R3900 board has 16 MB of RAM */
}

281
libgloss/mips/entry.S Normal file
View File

@ -0,0 +1,281 @@
/* entry.S - exception handler for emulating MIPS16 'entry' and 'exit'
pseudo-instructions. These instructions are generated by the compiler
when the -mentry switch is used. The instructions are not implemented
in the MIPS16 CPU; hence the exception handler that emulates them.
This module contains the following public functions:
* void __install_entry_handler(void);
This function installs the entry/exit exception handler. It should
be called before executing any MIPS16 functions that were compiled with
-mentry, typically before main() is called.
* void __remove_entry_handler(void);
This function removes the entry/exit exception handler. It should
be called when the program is exiting, or when it is known that no
more MIPS16 functions compiled with -mentry will be called.
*/
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#include "regs.S"
#define CAUSE_EXCMASK 0x3c /* mask for ExcCode in Cause Register */
#define EXC_RI 0x28 /* 101000 == 10 << 2 */
/* Set DEBUG to 1 to enable recording of the last 16 interrupt causes. */
#define DEBUG 0
#if DEBUG
.sdata
int_count:
.space 4 /* interrupt count modulo 16 */
int_cause:
.space 4*16 /* last 16 interrupt causes */
#endif
.text
.set noreorder /* Do NOT reorder instructions */
/* __entry_exit_handler - the reserved instruction exception handler
that emulates the entry and exit instruction. */
__entry_exit_handler:
.set noat /* Do NOT use at register */
#if DEBUG
/* Must avoid using 'la' pseudo-op because it uses gp register, which
may not have a good value in an exception handler. */
# la k0, int_count /* intcount = (intcount + 1) & 0xf */
lui k0 ,%hi(int_count)
addiu k0, k0 ,%lo(int_count)
lw k1, (k0)
addiu k1, k1, 1
andi k1, k1, 0x0f
sw k1, (k0)
# la k0, int_cause /* k1 = &int_cause[intcount] */
lui k0, %hi(int_cause)
addiu k0, k0, %lo(int_cause)
sll k1, k1, 2
add k1, k1, k0
#endif
mfc0 k0, C0_CAUSE /* Fetch cause */
#if DEBUG
sw k0, -4(k1) /* Save exception cause in buffer */
#endif
mfc0 k1, C0_EPC /* Check for Reserved Inst. without */
and k0, CAUSE_EXCMASK /* destroying any register */
subu k0, EXC_RI
bne k0, zero, check_others /* Sorry, go do something else */
and k0, k1, 1 /* Check for TR mode (pc.0 = 1) */
beq k0, zero, ri_in_32 /* Sorry, RI in 32-bit mode */
xor k1, 1
/* Since we now are going to emulate or die, we can use all the T-registers */
/* that MIPS16 does not use (at, t0-t8), and we don't have to save them. */
.set at /* Now it's ok to use at again */
#if 0
j leave
rfe
#endif
lhu t0, 0(k1) /* Fetch the offending instruction */
xor t8, k1, 1 /* Prepare t8 for exit */
and t1, t0, 0xf81f /* Check for entry/exit opcode */
bne t1, 0xe809, other_ri
deareg: and t1, t0, 0x0700 /* Isolate the three a-bits */
srl t1, 6 /* Adjust them so x4 is applied */
slt t2, t1, 17 /* See if this is the exit instruction */
beqz t2, doexit
la t2, savea
subu t2, t1
jr t2 /* Jump into the instruction table */
rfe /* We run the rest in user-mode */
/* This is the entry instruction! */
sw a3, 12(sp) /* 4: a0-a3 saved */
sw a2, 8(sp) /* 3: a0-a2 saved */
sw a1, 4(sp) /* 2: a0-a1 saved */
sw a0, 0(sp) /* 1: a0 saved */
savea: /* 0: No arg regs saved */
dera: and t1, t0, 0x0020 /* Isolate the save-ra bit */
move t7, sp /* Temporary SP */
beq t1, zero, desreg
subu sp, 32 /* Default SP adjustment */
sw ra, -4(t7)
subu t7, 4
desreg: and t1, t0, 0x00c0 /* Isolate the two s-bits */
beq t1, zero, leave
subu t1, 0x0040
beq t1, zero, leave /* Only one to save... */
sw s0, -4(t7) /* Do the first one */
sw s1, -8(t7) /* Do the last one */
leave: jr t8 /* Exit to unmodified EPC */
nop /* Urgh - the only nop!! */
doexf0: mtc1 v0,$f0 /* Copy float value */
b doex2
doexf1: mtc1 v1,$f0 /* Copy double value */
mtc1 v0,$f1
b doex2
doexit: slt t2, t1, 21
beq t2, zero, doexf0
slt t2, t1, 25
beq t2, zero, doexf1
doex2: and t1, t0, 0x0020 /* Isolate ra bit */
beq t1, zero, dxsreg /* t1 holds ra-bit */
addu t7, sp, 32 /* Temporary SP */
lw ra, -4(t7)
subu t7, 4
dxsreg: and t1, t0, 0x00c0 /* Isolate the two s-bits */
beq t1, zero, leavex
subu t1, 0x0040
beq t1, zero, leavex /* Only one to save... */
lw s0, -4(t7) /* Do the first one */
lw s1, -8(t7) /* Do the last one */
leavex: jr ra /* Exit to ra */
addu sp, 32 /* Clean up stack pointer */
/* Come here for exceptions we can't handle. */
ri_in_32:
other_ri:
check_others: /* call the previous handler */
la k0,__previous
jr k0
nop
__exception_code:
.set noreorder
la k0, __entry_exit_handler
# lui k0, %hi(exception)
# addiu k0, k0, %lo(exception)
jr k0
nop
.set reorder
__exception_code_end:
.data
__previous:
.space (__exception_code_end - __exception_code)
.text
/* void __install_entry_handler(void)
Install our entry/exit reserved instruction exception handler.
*/
.ent __install_entry_handler
.globl __install_entry_handler
__install_entry_handler:
.set noreorder
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,baseaddr
lui a0,0x8000 /* delay slot */
lui a0,0xbfc0
addiu a0,a0,0x0100
baseaddr:
addiu a0,a0,0x080 /* a0 = base vector table address */
li a1,(__exception_code_end - __exception_code)
la a2,__exception_code
la a3,__previous
/* there must be a better way of doing this???? */
copyloop:
lw v0,0(a0)
sw v0,0(a3)
lw v0,0(a2)
sw v0,0(a0)
addiu a0,a0,4
addiu a2,a2,4
addiu a3,a3,4
subu a1,a1,4
bne a1,$0,copyloop
nop
j ra
nop
.set reorder
.end __install_entry_handler
/* void __remove_entry_handler(void);
Remove our entry/exit reserved instruction exception handler.
*/
.ent __remove_entry_handler
.globl __remove_entry_handler
__remove_entry_handler:
.set noreorder
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,res_baseaddr
lui a0,0x8000 /* delay slot */
lui a0,0xbfc0
addiu a0,a0,0x0200
res_baseaddr:
addiu a0,a0,0x0180 /* a0 = base vector table address */
li a1,(__exception_code_end - __exception_code)
la a3,__previous
/* there must be a better way of doing this???? */
res_copyloop:
lw v0,0(a3)
sw v0,0(a0)
addiu a0,a0,4
addiu a3,a3,4
subu a1,a1,4
bne a1,$0,res_copyloop
nop
j ra
nop
.set reorder
.end __remove_entry_handler
/* software_init_hook - install entry/exit handler and arrange to have it
removed at exit. This function is called by crt0.S. */
.text
.globl software_init_hook
.ent software_init_hook
software_init_hook:
.set noreorder
subu sp, sp, 8 /* allocate stack space */
sw ra, 4(sp) /* save return address */
jal __install_entry_handler /* install entry/exit handler */
nop
lui a0, %hi(__remove_entry_handler) /* arrange for exit to */
jal atexit /* de-install handler */
addiu a0, a0, %lo(__remove_entry_handler) /* delay slot */
lw ra, 4(sp) /* get return address */
j ra /* return */
addu sp, sp, 8 /* deallocate stack */
.set reorder
.end software_init_hook

155
libgloss/mips/idt.ld Normal file
View File

@ -0,0 +1,155 @@
/* The following TEXT start address leaves space for the monitor
workspace. i.e. the NEC VR4300 (IDT) first free address is actually
0xa001af20. */
ENTRY(_start)
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -lidt -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

93
libgloss/mips/idtecoff.ld Normal file
View File

@ -0,0 +1,93 @@
/* The following TEXT start address leaves space for the monitor
workspace. i.e. the NEC VR4300 (IDT) first free address is actually
0xa001af20. */
ENTRY(_start)
STARTUP(crt0.o)
OUTPUT_ARCH("mips:4000")
OUTPUT_FORMAT("ecoff-bigmips", "ecoff-bigmips", "ecoff-littlemips")
GROUP(-lc -lidt -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
. = .;
.rdata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
}

46
libgloss/mips/idtmon.S Normal file
View File

@ -0,0 +1,46 @@
/*
* idtmon.S -- lo-level entry points into IDT monitor.
*
* Copyright (c) 1996 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#include "regs.S"
.text
.align 2
/* Provide named functions for entry into the IDT monitor: */
#define INDIRECT(name,index) \
.globl name; \
.ent name; \
name: la $2,+(0xbfc00000+((index)*8)); \
j $2; \
.end name
/* The following magic numbers are for the slots into the IDT monitor: */
INDIRECT(open,6)
INDIRECT(read,7)
INDIRECT(write,8)
INDIRECT(close,10)
INDIRECT(inbyte,11)
INDIRECT(outbyte,12)
INDIRECT(mon_printf,16)
INDIRECT(_flush_cache,28)
INDIRECT(get_mem_info,55) /* expects pointer to three word vector */
/* EOF idtmon.S */

104
libgloss/mips/jmr3904-io.c Normal file
View File

@ -0,0 +1,104 @@
#define READ_UINT8( _register_, _value_ ) \
((_value_) = *((volatile unsigned char *)(_register_)))
#define WRITE_UINT8( _register_, _value_ ) \
(*((volatile unsigned char *)(_register_)) = (_value_))
/* - Board specific addresses for serial chip */
#define DIAG_BASE 0xfffff300
#define DIAG_SLCR (DIAG_BASE+0x00)
#define DIAG_SLSR (DIAG_BASE+0x04)
#define DIAG_SLDICR (DIAG_BASE+0x08)
#define DIAG_SLDISR (DIAG_BASE+0x0C)
#define DIAG_SFCR (DIAG_BASE+0x10)
#define DIAG_SBRG (DIAG_BASE+0x14)
#define DIAG_TFIFO (DIAG_BASE+0x20)
#define DIAG_RFIFO (DIAG_BASE+0x30)
#define BRG_T0 0x0000
#define BRG_T2 0x0100
#define BRG_T4 0x0200
#define BRG_T5 0x0300
#define READ_UINT16( _register_, _value_ ) \
((_value_) = *((volatile unsigned short *)(_register_)))
#define WRITE_UINT16( _register_, _value_ ) \
(*((volatile unsigned short *)(_register_)) = (_value_))
unsigned char
inbyte (void)
{
unsigned char c;
unsigned short disr;
for (;;)
{
READ_UINT16 (DIAG_SLDISR, disr);
if (disr & 0x0001)
break;
}
disr = disr & ~0x0001;
READ_UINT8 (DIAG_RFIFO, c);
WRITE_UINT16 (DIAG_SLDISR, disr);
return c;
}
void
outbyte (unsigned char c)
{
unsigned short disr;
for (;;)
{
READ_UINT16 (DIAG_SLDISR, disr);
if (disr & 0x0002)
break;
}
disr = disr & ~0x0002;
WRITE_UINT8 (DIAG_TFIFO, c);
WRITE_UINT16 (DIAG_SLDISR, disr);
}
/* Stuff required to setup IO on this board */
void board_serial_init (void)
{
WRITE_UINT16 (DIAG_SLCR, 0x0020);
WRITE_UINT16 (DIAG_SLDICR, 0x0000);
WRITE_UINT16 (DIAG_SFCR, 0x0000);
WRITE_UINT16 (DIAG_SBRG, BRG_T2 | 5);
}
/* If you want this to be initialized as part of the stuff which gets called
by crt0, it should be named 'hardware_init_hook'.
Local implementations may want to move or add to this function OR
do the initializations after main() is entered.
*/
void hardware_init_hook(void)
{
board_serial_init() ;
}
/* Structure filled in by get_mem_info. Only the size field is
actually used (by sbrk), so the others aren't even filled in. */
struct s_mem
{
unsigned int size;
unsigned int icsize;
unsigned int dcsize;
};
/* mem_size is provided in the linker script so that we don't have to
define it here. */
extern char _mem_size[];
void
get_mem_info (mem)
struct s_mem *mem;
{
mem->size = (unsigned int)_mem_size;
}

View File

@ -0,0 +1,127 @@
/* Linker script forJMR 3904 board using Java + qthreads */
ENTRY(_start)
OUTPUT_ARCH("mips:3000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -ljmr3904 -lgcc -lgcjcoop)
SEARCH_DIR(.)
__DYNAMIC = 0;
PROVIDE (_mem_size = 0x100000); /* JMR3904 comes as standard with 512k of RAM */
/* Set the size of the stack for Java with qthreads. */
PROVIDE (_Jv_QthreadsStackSize = 0x10000);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0x80008000;
/* This is NOT the address which fits with the monitor from jmr. */
/* It fits the Cygmon ROMS */
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
. += 0x2000 ; /* 8k bytes of stack. */
__stack = ALIGN(64) ;
. = __stack ;
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

156
libgloss/mips/jmr3904app.ld Normal file
View File

@ -0,0 +1,156 @@
/* Linker script forJMR 3904 board */
ENTRY(_start)
OUTPUT_ARCH("mips:3000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -ljmr3904 -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
PROVIDE (_mem_size = 0x100000); /* JMR3904 comes as standard with 512k of RAM */
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0x80008000;
/* This is NOT the address which fits with the monitor from jmr. */
/* It fits the Cygmon ROMS */
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
. += 0x2000 ; /* 8k bytes of stack. */
__stack = ALIGN(64) ;
. = __stack ;
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1,130 @@
/* Linker script forJMR 3904 board using Java + qthreads */
ENTRY(_start)
OUTPUT_ARCH("mips:3000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -ljmr3904 -lgcc -lgcjcoop)
SEARCH_DIR(.)
__DYNAMIC = 0;
PROVIDE (_mem_size = 0x100000); /* JMR3904 comes as standard with 512k of RAM */
/* but this is 1 Mb */
/* Set the size of the stack for Java with qthreads. */
PROVIDE (_Jv_QthreadsStackSize = 0x10000);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
/* Load everything into DRAM, except for the stack. Put stack in SRAM */
. = 0x88000000;
/* This is NOT the address which fits with the monitor from jmr. */
/* It fits the Cygmon ROMS */
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
. = .;
.rdata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* Put stack in SRAM (8 Kb); this size is the same as the stack from
the original script (when everything was in SRAM). */
__stack = 0x8000A000;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1,127 @@
/* Linker script forJMR 3904 board */
ENTRY(_start)
OUTPUT_ARCH("mips:3000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -ljmr3904 -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
PROVIDE (_mem_size = 0x100000); /* JMR3904 comes as standard with 512k of RAM */
/* but this is 1 Mb */
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
/* Load everything into DRAM, except for the stack. Put stack in SRAM */
. = 0x88000000;
/* This is NOT the address which fits with the monitor from jmr. */
/* It fits the Cygmon ROMS */
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
. = .;
.rdata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* Put stack in SRAM (8 Kb); this size is the same as the stack from
the original script (when everything was in SRAM). */
__stack = 0x8000A000;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

121
libgloss/mips/lsi.ld Normal file
View File

@ -0,0 +1,121 @@
/* The following TEXT start address leaves space for the monitor
workspace. */
ENTRY(_start)
OUTPUT_ARCH("mips:4000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -llsi -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
}

595
libgloss/mips/lsi33k-stub.c Normal file
View File

@ -0,0 +1,595 @@
/****************************************************************************
*
* Module name: remcom.c $
* Revision: 1.34 $
* Date: 91/03/09 12:29:49 $
* Contributor: Lake Stevens Instrument Division$
*
* Description: low level support for gdb debugger. $
*
* Considerations: only works on target hardware $
*
* Written by: Glenn Engel $
* ModuleState: Experimental $
*
* NOTES: See Below $
*
* Modified for SPARC by Stu Grossman, Cygnus Support.
*
* This code has been extensively tested on the Fujitsu SPARClite demo board.
*
* To enable debugger support, two things need to happen. One, a
* call to set_debug_traps() is necessary in order to allow any breakpoints
* or error conditions to be properly intercepted and reported to gdb.
* Two, a breakpoint needs to be generated to begin communication. This
* is most easily accomplished by a call to breakpoint(). Breakpoint()
* simulates a breakpoint by executing a trap #1.
*
*************
*
* The following gdb commands are supported:
*
* command function Return value
*
* g return the value of the CPU registers hex data or ENN
* G set the value of the CPU registers OK or ENN
*
* mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
* MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
*
* c Resume at current address SNN ( signal NN)
* cAA..AA Continue at address AA..AA SNN
*
* s Step one instruction SNN
* sAA..AA Step one instruction from AA..AA SNN
*
* k kill
*
* ? What was the last sigval ? SNN (signal NN)
*
* bBB..BB Set baud rate to BB..BB OK or BNN, then sets
* baud rate
*
* All commands and responses are sent with a packet which includes a
* checksum. A packet consists of
*
* $<packet info>#<checksum>.
*
* where
* <packet info> :: <characters representing the command or response>
* <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
*
* When a packet is received, it is first acknowledged with either '+' or '-'.
* '+' indicates a successful transfer. '-' indicates a failed transfer.
*
* Example:
*
* Host: Reply:
* $m0,10#2a +$00010203040506070809101112131415#42
*
****************************************************************************/
#include <string.h>
#include <signal.h>
#include "dbgmon.h"
#include "parser.h"
#include "ctype.h"
/************************************************************************
*
* external low-level support routines
*/
extern putchar(); /* write a single character */
extern getchar(); /* read and return a single char */
/************************************************************************/
/* Stuff for stdio-like gets_debugger_check() */
#define CTRL(x) ('x'&0x1f)
#define DEL 0x7f
#define INTR CTRL(C)
#define BELL 0x7
#define PROMPT "? "
#define BUFSIZE 512 /* Big enough for register packets */
static int initialized = 0; /* !0 means we've been initialized */
static char hexchars[]="0123456789abcdef";
extern unsigned int _regs[]; /* Saved registers from client */
/* Convert ch from a hex digit to an int */
static int
hex(ch)
unsigned char ch;
{
if (ch >= 'a' && ch <= 'f')
return ch-'a'+10;
if (ch >= '0' && ch <= '9')
return ch-'0';
if (ch >= 'A' && ch <= 'F')
return ch-'A'+10;
return -1;
}
/* scan for the sequence $<data>#<checksum> */
static void
getpacket(buffer)
char *buffer;
{
unsigned char checksum;
unsigned char xmitcsum;
int i;
int count;
unsigned char ch;
/* At this point, the start character ($) has been received through
* the debug monitor parser. Get the remaining characters and
* process them.
*/
checksum = 0;
xmitcsum = -1;
count = 0;
/* read until a # or end of buffer is found */
while (count < BUFSIZE)
{
ch = getchar();
if (ch == '#')
break;
checksum = checksum + ch;
buffer[count] = ch;
count = count + 1;
}
if (count >= BUFSIZE)
buffer[count] = 0;
if (ch == '#')
{
xmitcsum = hex(getchar()) << 4;
xmitcsum |= hex(getchar());
#if 0
/* Humans shouldn't have to figure out checksums to type to it. */
putchar ('+');
return;
#endif
if (checksum != xmitcsum)
{
putchar('-'); /* failed checksum */
return; /* Back to monitor loop */
}
else
{
putchar('+'); /* successful transfer */
/* if a sequence char is present, reply the sequence ID */
if (buffer[2] == ':')
{
putchar(buffer[0]);
putchar(buffer[1]);
/* remove sequence chars from buffer */
count = strlen(buffer);
for (i=3; i <= count; i++)
buffer[i-3] = buffer[i];
}
/* Buffer command received- go and process it. */
}
}
}
/* send the packet in buffer. */
static void
putpacket(buffer)
unsigned char *buffer;
{
unsigned char checksum;
int count;
unsigned char ch;
/* $<packet info>#<checksum>. */
do
{
putchar('$');
checksum = 0;
count = 0;
while (ch = buffer[count])
{
if (! putchar(ch))
return;
checksum += ch;
count += 1;
}
putchar('#');
putchar(hexchars[checksum >> 4]);
putchar(hexchars[checksum & 0xf]);
}
while (getchar() != '+');
}
static char remcomInBuffer[BUFSIZE];
static char remcomOutBuffer[BUFSIZE];
/* Indicate to caller of mem2hex or hex2mem that there has been an error. */
static volatile int mem_err = 0;
/* Convert the memory pointed to by mem into hex, placing result in buf.
* Return a pointer to the last char put in buf (null), in case of mem fault,
* return 0.
* If MAY_FAULT is non-zero, then we will handle memory faults by returning
* a 0, else treat a fault like any other fault in the stub.
*/
static unsigned char *
mem2hex(mem, buf, count, may_fault)
unsigned char *mem;
unsigned char *buf;
int count;
int may_fault;
{
unsigned char ch;
while (count-- > 0)
{
ch = *mem++;
if (mem_err)
return 0;
*buf++ = hexchars[ch >> 4];
*buf++ = hexchars[ch & 0xf];
}
*buf = 0;
return buf;
}
/* convert the hex array pointed to by buf into binary to be placed in mem
* return a pointer to the character AFTER the last byte written */
static char *
hex2mem(buf, mem, count, may_fault)
unsigned char *buf;
unsigned char *mem;
int count;
int may_fault;
{
int i;
unsigned char ch;
for (i=0; i<count; i++)
{
ch = hex(*buf++) << 4;
ch |= hex(*buf++);
*mem++ = ch;
if (mem_err)
return 0;
}
return mem;
}
/* This table contains the mapping between SPARC hardware trap types, and
signals, which are primarily what GDB understands. It also indicates
which hardware traps we need to commandeer when initializing the stub. */
static struct hard_trap_info
{
unsigned char tt; /* Trap type code for SPARClite */
unsigned char signo; /* Signal that we map this trap into */
} hard_trap_info[] = {
{0x06, SIGSEGV}, /* instruction access error */
{0x0a, SIGILL}, /* privileged instruction */
{0x0a, SIGILL}, /* illegal instruction */
{0x0b, SIGEMT}, /* cp disabled */
{0x07, SIGSEGV}, /* data access exception */
{0x09, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
{0, 0} /* Must be last */
};
/* Convert the SPARC hardware trap type code to a unix signal number. */
static int
computeSignal(tt)
int tt;
{
struct hard_trap_info *ht;
for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
if (ht->tt == tt)
return ht->signo;
return SIGHUP; /* default for things we don't know about */
}
/*
* While we find nice hex chars, build an int.
* Return number of chars processed.
*/
static int
hexToInt(char **ptr, int *intValue)
{
int numChars = 0;
int hexValue;
*intValue = 0;
while (**ptr)
{
hexValue = hex(**ptr);
if (hexValue < 0)
break;
*intValue = (*intValue << 4) | hexValue;
numChars ++;
(*ptr)++;
}
return (numChars);
}
/* This function lets GDB know that an exception has occured. */
static void
debug_handle_exception ()
{
int tt; /* Trap type */
int sigval;
char *ptr;
tt = (_regs[R_CAUSE] >> 2) & 0x0f;
/* reply to host that an exception has occurred */
sigval = computeSignal(tt);
ptr = remcomOutBuffer;
*ptr++ = 'T';
*ptr++ = hexchars[sigval >> 4];
*ptr++ = hexchars[sigval & 0xf];
*ptr++ = hexchars[R_EPC >> 4];
*ptr++ = hexchars[R_EPC & 0xf];
*ptr++ = ':';
ptr = mem2hex((char *)&_regs[R_EPC], ptr, 4, 0);
*ptr++ = ';';
*ptr++ = hexchars[R_FP >> 4];
*ptr++ = hexchars[R_FP & 0xf];
*ptr++ = ':';
ptr = mem2hex((char *)&_regs[R_FP], ptr, 4, 0);
*ptr++ = ';';
*ptr++ = hexchars[R_SP >> 4];
*ptr++ = hexchars[R_SP & 0xf];
*ptr++ = ':';
ptr = mem2hex((char *)&_regs[R_SP], ptr, 4, 0);
*ptr++ = ';';
*ptr++ = 0;
putpacket(remcomOutBuffer);
return;
}
void process_packet()
{
char *ptr;
int length;
int addr;
int sigval;
int tt; /* Trap type */
remcomOutBuffer[0] = 0;
getpacket(remcomInBuffer);
switch (remcomInBuffer[0])
{
/* Return Last SIGVAL */
case '?':
tt = (_regs[R_CAUSE] >> 2) & 0x0f;
sigval = computeSignal(tt);
remcomOutBuffer[0] = 'S';
remcomOutBuffer[1] = hexchars[sigval >> 4];
remcomOutBuffer[2] = hexchars[sigval & 0xf];
remcomOutBuffer[3] = 0;
break;
/* toggle debug flag */
case 'd':
break;
/* Return the values of the CPU registers */
case 'g':
ptr = remcomOutBuffer;
ptr = mem2hex((char *)_regs, ptr, 32 * 4, 0); /* General Purpose Registers */
ptr = mem2hex((char *)&_regs[R_EPC], ptr, 9 * 4, 0); /* CP0 Registers */
break;
/* set the value of the CPU registers - return OK */
case 'G':
ptr = &remcomInBuffer[1];
hex2mem(ptr, (char *)_regs, 32 * 4, 0); /* General Purpose Registers */
hex2mem(ptr + 32 * 4 * 2, (char *)&_regs[R_EPC], 9 * 4, 0); /* CP0 Registers */
strcpy(remcomOutBuffer,"OK");
break;
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
case 'm':
ptr = &remcomInBuffer[1];
if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length))
{
if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
break;
strcpy (remcomOutBuffer, "E03");
}
else
strcpy(remcomOutBuffer,"E01");
break;
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
case 'M':
ptr = &remcomInBuffer[1];
if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length) && *ptr++ == ':')
{
if (hex2mem(ptr, (char *)addr, length, 1))
strcpy(remcomOutBuffer, "OK");
else
strcpy(remcomOutBuffer, "E03");
}
else
strcpy(remcomOutBuffer, "E02");
break;
/* cAA..AA Continue at address AA..AA(optional) */
case 'c':
/* try to read optional parameter, pc unchanged if no parm */
ptr = &remcomInBuffer[1];
if (hexToInt(&ptr, &addr))
{
gdb_go ( addr );
}
else
{
dbg_cont();
}
return;
/* kill the program */
case 'k':
break;
/* Reset */
case 'r':
break;
/* switch */
}
/* Reply to the request */
putpacket(remcomOutBuffer);
}
/*
* gets_debugger_check - This is the same as the stdio gets, but we also
* check for a leading $ in the buffer. This so we
* gracefully handle the GDB protocol packets.
*/
char *
gets_debugger_check(buf)
char *buf;
{
register char c;
char *bufp;
bufp = buf;
for (;;)
{
c = getchar();
switch (c)
{
/* quote next char */
case '$':
if ( buf == bufp )
process_packet();
break;
case CTRL(V):
c = getchar();
if (bufp < &buf[LINESIZE-3])
{
rmw_byte (bufp++,c);
showchar(c);
}
else
{
putchar(BELL);
}
break;
case '\n':
case '\r':
putchar('\n');
rmw_byte (bufp,0);
return(buf);
case CTRL(H):
case DEL:
if (bufp > buf)
{
bufp--;
putchar(CTRL(H));
putchar(' ');
putchar(CTRL(H));
}
break;
case CTRL(U):
if (bufp > buf)
{
printf("^U\n%s", PROMPT);
bufp = buf;
}
break;
case '\t':
c = ' ';
default:
/*
* Make sure there's room for this character
* plus a trailing \n and 0 byte
*/
if (isprint(c) && bufp < &buf[LINESIZE-3])
{
rmw_byte ( bufp++, c );
putchar(c);
}
else
{
putchar(BELL);
}
break;
}
}
}

179
libgloss/mips/lsi33k-stub.h Normal file
View File

@ -0,0 +1,179 @@
/*STARTINC
*
* COPYRIGHT (C) 1991, 1992 ARRAY TECHNOLOGY CORPORATION
* All Rights Reserved
*
* This software is confidential information which is proprietary to and
* a trade secret of ARRAY Technology Corporation. Use, duplication, or
* disclosure is subject to the terms of a separate license agreement.
*
*
* NAME:
*
*
* DESCRIPTION:
*
*
*ENDINC
*/
/* %Q% %I% %M% */
/*
* Copyright 1985 by MIPS Computer Systems, Inc.
*/
/*
* dbgmon.h -- debugging monitor definitions
*/
/*
* catch bogus compiles
*/
#if defined(MIPSEB) && defined(MIPSEL)
# include "error -- both MIPSEB and MIPSEL defined"
#endif
#if !defined(MIPSEB) && !defined(MIPSEL)
# include "error -- neither MIPSEB or MIPSEL defined"
#endif
/*
* PROM_STACK is the address of the first word above the prom stack
* the prom stack grows downward from the first word less than PROM_STACK
*/
#define PROM_STACK 0xa0010000
/*
* register names
*/
#define R_R0 0
#define R_R1 1
#define R_R2 2
#define R_R3 3
#define R_R4 4
#define R_R5 5
#define R_R6 6
#define R_R7 7
#define R_R8 8
#define R_R9 9
#define R_R10 10
#define R_R11 11
#define R_R12 12
#define R_R13 13
#define R_R14 14
#define R_R15 15
#define R_R16 16
#define R_R17 17
#define R_R18 18
#define R_R19 19
#define R_R20 20
#define R_R21 21
#define R_R22 22
#define R_R23 23
#define R_R24 24
#define R_R25 25
#define R_R26 26
#define R_R27 27
#define R_R28 28
#define R_R29 29
#define R_R30 30
#define R_R31 31
#define R_F0 32
#define R_F1 33
#define R_F2 34
#define R_F3 35
#define R_F4 36
#define R_F5 37
#define R_F6 38
#define R_F7 39
#define R_F8 40
#define R_F9 41
#define R_F10 42
#define R_F11 43
#define R_F12 44
#define R_F13 45
#define R_F14 46
#define R_F15 47
#define R_F16 48
#define R_F17 49
#define R_F18 50
#define R_F19 51
#define R_F20 52
#define R_F21 53
#define R_F22 54
#define R_F23 55
#define R_F24 56
#define R_F25 57
#define R_F26 58
#define R_F27 59
#define R_F28 60
#define R_F29 61
#define R_F30 62
#define R_F31 63
#define R_EPC 64
#define R_MDHI 65
#define R_MDLO 66
#define R_SR 67
#define R_CAUSE 68
#define R_BADVADDR 69
#define R_DCIC 70
#define R_BPC 71
#define R_BDA 72
#define R_EXCTYPE 73
#define NREGS 74
/*
* compiler defined bindings
*/
#define R_ZERO R_R0
#define R_AT R_R1
#define R_V0 R_R2
#define R_V1 R_R3
#define R_A0 R_R4
#define R_A1 R_R5
#define R_A2 R_R6
#define R_A3 R_R7
#define R_T0 R_R8
#define R_T1 R_R9
#define R_T2 R_R10
#define R_T3 R_R11
#define R_T4 R_R12
#define R_T5 R_R13
#define R_T6 R_R14
#define R_T7 R_R15
#define R_S0 R_R16
#define R_S1 R_R17
#define R_S2 R_R18
#define R_S3 R_R19
#define R_S4 R_R20
#define R_S5 R_R21
#define R_S6 R_R22
#define R_S7 R_R23
#define R_T8 R_R24
#define R_T9 R_R25
#define R_K0 R_R26
#define R_K1 R_R27
#define R_GP R_R28
#define R_SP R_R29
#define R_FP R_R30
#define R_RA R_R31
/*
* memory reference widths
*/
#define SW_BYTE 1
#define SW_HALFWORD 2
#define SW_WORD 4
/*
* Monitor modes
*/
#define MODE_DBGMON 0 /* debug monitor is executing */
#define MODE_CLIENT 1 /* client is executing */
/*
* String constants
*/
#define DEFAULT_STRLEN 70 /* default max strlen for string cmd */

2
libgloss/mips/lsipmon.S Normal file
View File

@ -0,0 +1,2 @@
#define LSI 1
#include "pmon.S"

69
libgloss/mips/nullmon.c Normal file
View File

@ -0,0 +1,69 @@
/* nullmon.c - Stub or monitor services.
*
* Copyright (c) 1998 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
/* This is a ROMSTUB
Various libraries in libgloss may reference board specific services.
These are often performed by system calls and by rom specific
interfaces such as dvemon.c This file defines the null interface in
which the rom monitor either does not exist or is not used.
Linking with this file supports applications which only exercise
the processor, specifically, the GDB test suite.
By linking this object in rather than a monitor specific support
we can insure that the testsuite will run without references or
linkages to nonexistent monitor services.
Similarly, every service provided by this file muse be provided by all
monitor speciifc interfaces.
PLEASE DO NOT MAKE THIS FILE SPECIFIC TO ANY MONITOR
*/
/* This form is giving linker relocation errors */
#if ! defined(BOARD_MEM_SIZE)
#define BOARD_MEM_SIZE 0x100000 /* About a megabyte */
#endif
extern unsigned char _ftext ; /* Defined in nullmon.ld */
extern unsigned char _end ; /* Defined in nullmon.ld */
#if defined(FIXME_WARNINGS)
#warning("FIXME: struct s_mem belongs in a header file")
#endif
struct s_mem
{ unsigned int size;
unsigned int icsize;
unsigned int dcsize;
};
void
get_mem_info (mem)
struct s_mem *mem;
{ char * t1, * t2 ;
unsigned long long tmp ;
t1 = & _ftext ;
t2 = & _end ;
tmp = (unsigned long long) (t2 - t1) ;
tmp = (unsigned long long) BOARD_MEM_SIZE - tmp ;
mem->size = tmp ;
}
/* SYSTEM INTERFACE
Since we are defining a NULL operating environment here, I am
entering the stub definitions for the GNUpro libraries, System Calls.
I would rather not to even pretend to support these functions but, they
get pulled in by other libraries.
*/
int read(int file, char * ptr , int len) { return 0 ; }
int close (int file) { return -1 ; }
int write(int file , char * ptr, int len) { return 0 ; }
/*eof*/

156
libgloss/mips/nullmon.ld Normal file
View File

@ -0,0 +1,156 @@
/* The following TEXT start address leaves space for the monitor
workspace. */
ENTRY(_start)
OUTPUT_ARCH("mips:4000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -lnullmon -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
. = ALIGN(64) ;
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

177
libgloss/mips/pmon.S Normal file
View File

@ -0,0 +1,177 @@
/*
* pmon.S -- low-level entry points into PMON monitor.
*
* Copyright (c) 1996, 1997 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#if __mips < 3
/* This machine does not support 64-bit operations. */
#define ADDU addu
#define SUBU subu
#else
/* This machine supports 64-bit operations. */
#define ADDU daddu
#define SUBU dsubu
#endif
#include "regs.S"
.text
.align 2
#ifdef LSI
#define PMON_VECTOR 0xffffffffbfc00200
#else
#define PMON_VECTOR 0xffffffffbfc00500
#endif
#ifndef __mips_eabi
/* Provide named functions for entry into the monitor: */
#define INDIRECT(name,index) \
.globl name; \
.ent name; \
.set noreorder; \
name: la $2,+(PMON_VECTOR+((index)*4)); \
lw $2,0($2); \
j $2; \
nop; \
.set reorder; \
.end name
#else
#define INDIRECT(name,index) \
.globl name; \
.ent name; \
.set noreorder; \
name: la $2,+(PMON_VECTOR+((index)*4)); \
lw $2,0($2); \
SUBU sp,sp,0x40; \
sd ra,0x38(sp); \
sd fp,0x30(sp); \
jal $2; \
move fp,sp; \
ld ra,0x38(sp); \
ld fp,0x30(sp); \
j ra; \
ADDU sp,sp,0x40; \
.set reorder; \
.end name
#endif
/* The following magic numbers are for the slots into the PMON monitor */
/* The first are used as the lo-level library run-time: */
INDIRECT(read,0)
INDIRECT(write,1)
INDIRECT(open,2)
INDIRECT(close,3)
/* The following are useful monitor routines: */
INDIRECT(mon_ioctl,4)
INDIRECT(mon_printf,5)
INDIRECT(mon_vsprintf,6)
INDIRECT(mon_ttctl,7)
INDIRECT(mon_cliexit,8)
INDIRECT(mon_getenv,9)
INDIRECT(mon_onintr,10)
INDIRECT(mon_flush_cache,11)
INDIRECT(_flush_cache,11)
INDIRECT(mon_exception,12)
/* The following routine is required by the "print()" function: */
.globl outbyte
.ent outbyte
.set noreorder
outbyte:
subu sp,sp,0x20 /* allocate stack space for string */
sd ra,0x18(sp) /* stack return address */
sd fp,0x10(sp) /* stack frame-pointer */
move fp,sp /* take a copy of the stack pointer */
/* We leave so much space on the stack for the string (16
characters), since the call to mon_printf seems to corrupt
the 8bytes at offset 8 into the string/stack. */
sb a0,0x00(sp) /* character to print */
sb z0,0x01(sp) /* NUL terminator */
jal mon_printf /* and output the string */
move a0,sp /* take a copy of the string pointer {DELAY SLOT} */
move sp,fp /* recover stack pointer */
ld ra,0x18(sp) /* recover return address */
ld fp,0x10(sp) /* recover frame-pointer */
j ra /* return to the caller */
addu sp,sp,0x20 /* dump the stack space {DELAY SLOT} */
.set reorder
.end outbyte
/* The following routine is required by the "sbrk()" function: */
.globl get_mem_info
.ent get_mem_info
.set noreorder
get_mem_info:
# in: a0 = pointer to 3 word structure
# out: void
subu sp,sp,0x18 /* create some stack space */
sd ra,0x00(sp) /* stack return address */
sd fp,0x08(sp) /* stack frame-pointer */
sd a0,0x10(sp) /* stack structure pointer */
move fp,sp /* take a copy of the stack pointer */
# The monitor has already sized memory, but unfortunately we
# do not have access to the data location containing the
# memory size.
jal __sizemem
nop
ld a0,0x10(sp) # recover structure pointer
sw v0,0(a0) # amount of memory available
# Deal with getting the cache size information:
mfc0 a1, C0_CONFIG
nop
nop
andi a2,a1,0x7 << 9 # bits 11..9 for instruction cache size
sll a2,a2,12 - 8
sw a2,4(a0)
andi a2,a1,0x7 << 6 # bits 8..6 for data cache size
sll a2,a2,12 - 5
sw a2,8(a0) # data cache size
#
move sp,fp /* recover stack pointer */
ld ra,0x00(sp) /* recover return address */
ld fp,0x08(sp) /* recover frame-pointer */
j ra /* return to the caller */
addu sp,sp,0x18 /* restore stack pointer {DELAY SLOT} */
.set reorder
.end get_mem_info
#ifdef LSI
# For the LSI MiniRISC board, we can safely assume that we have
# at least one megabyte of RAM.
.globl __sizemem
.ent __sizemem
__sizemem:
li v0,0x100000
j ra
.end __sizemem
#else
#endif
/* EOF pmon.S */

155
libgloss/mips/pmon.ld Normal file
View File

@ -0,0 +1,155 @@
/* The following TEXT start address leaves space for the monitor
workspace. */
ENTRY(_start)
OUTPUT_ARCH("mips:4000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -lpmon -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the stack
* grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them in the
* crt0 without core dumping. These functions are all optional, but
* we do this so we can have our crt0 always use them if they exist.
* This is so BSPs work better when using the crt0 installed with gcc.
* We have to initalize them twice, so we multiple object file
* formats, as some prepend an underscore.
*/
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
. = .;
.rodata : {
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}
_fdata = ALIGN(16);
.data : {
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s*)
}
. = ALIGN(4);
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

151
libgloss/mips/regs.S Normal file
View File

@ -0,0 +1,151 @@
/*
* regs.S -- standard MIPS register names.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
/* Standard MIPS register names: */
#define zero $0
#define z0 $0
#define v0 $2
#define v1 $3
#define a0 $4
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24
#define t9 $25
#define k0 $26 /* kernel private register 0 */
#define k1 $27 /* kernel private register 1 */
#define gp $28 /* global data pointer */
#define sp $29 /* stack-pointer */
#define fp $30 /* frame-pointer */
#define ra $31 /* return address */
#define pc $pc /* pc, used on mips16 */
#define fp0 $f0
#define fp1 $f1
/* Useful memory constants: */
#define K0BASE 0x80000000
#ifndef __mips64
#define K1BASE 0xA0000000
#else
#define K1BASE 0xFFFFFFFFA0000000LL
#endif
#define PHYS_TO_K1(a) ((unsigned)(a) | K1BASE)
/* Standard Co-Processor 0 register numbers:
#define C0_COUNT $9 /* Count Register */
#define C0_SR $12 /* Status Register */
#define C0_CAUSE $13 /* last exception description */
#define C0_EPC $14 /* Exception error address */
#define C0_PRID $15 /* Processor Revision ID */
#define C0_CONFIG $16 /* CPU configuration */
/* Standard Processor Revision ID Register field offsets */
#define PR_IMP 8
/* Standard Config Register field offsets */
#define CR_DB 4
#define CR_IB 5
#define CR_DC 6 /* NOTE v4121 semantics != 43,5xxx semantics */
#define CR_IC 9 /* NOTE v4121 semantics != 43,5xxx semantics */
#define CR_SC 17
#define CR_SS 20
#define CR_SB 22
/* Standard Status Register bitmasks: */
#define SR_CU1 0x20000000 /* Mark CP1 as usable */
#define SR_FR 0x04000000 /* Enable MIPS III FP registers */
#define SR_BEV 0x00400000 /* Controls location of exception vectors */
#define SR_PE 0x00100000 /* Mark soft reset (clear parity error) */
#define SR_KX 0x00000080 /* Kernel extended addressing enabled */
#define SR_SX 0x00000040 /* Supervisor extended addressing enabled */
#define SR_UX 0x00000020 /* User extended addressing enabled */
/* Standard (R4000) cache operations. Taken from "MIPS R4000
Microprocessor User's Manual" 2nd edition: */
#define CACHE_I (0) /* primary instruction */
#define CACHE_D (1) /* primary data */
#define CACHE_SI (2) /* secondary instruction */
#define CACHE_SD (3) /* secondary data (or combined instruction/data) */
#define INDEX_INVALIDATE (0) /* also encodes WRITEBACK if CACHE_D or CACHE_SD */
#define INDEX_LOAD_TAG (1)
#define INDEX_STORE_TAG (2)
#define CREATE_DIRTY_EXCLUSIVE (3) /* CACHE_D and CACHE_SD only */
#define HIT_INVALIDATE (4)
#define CACHE_FILL (5) /* CACHE_I only */
#define HIT_WRITEBACK_INVALIDATE (5) /* CACHE_D and CACHE_SD only */
#define HIT_WRITEBACK (6) /* CACHE_I, CACHE_D and CACHE_SD only */
#define HIT_SET_VIRTUAL (7) /* CACHE_SI and CACHE_SD only */
#define BUILD_CACHE_OP(o,c) (((o) << 2) | (c))
/* Individual cache operations: */
#define INDEX_INVALIDATE_I BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_I)
#define INDEX_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_D)
#define INDEX_INVALIDATE_SI BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SI)
#define INDEX_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SD)
#define INDEX_LOAD_TAG_I BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_I)
#define INDEX_LOAD_TAG_D BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_D)
#define INDEX_LOAD_TAG_SI BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SI)
#define INDEX_LOAD_TAG_SD BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SD)
#define INDEX_STORE_TAG_I BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_I)
#define INDEX_STORE_TAG_D BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_D)
#define INDEX_STORE_TAG_SI BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SI)
#define INDEX_STORE_TAG_SD BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SD)
#define CREATE_DIRTY_EXCLUSIVE_D BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_D)
#define CREATE_DIRTY_EXCLUSIVE_SD BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_SD)
#define HIT_INVALIDATE_I BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_I)
#define HIT_INVALIDATE_D BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_D)
#define HIT_INVALIDATE_SI BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SI)
#define HIT_INVALIDATE_SD BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SD)
#define CACHE_FILL_I BUILD_CACHE_OP(CACHE_FILL,CACHE_I)
#define HIT_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_D)
#define HIT_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_SD)
#define HIT_WRITEBACK_I BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_I)
#define HIT_WRITEBACK_D BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_D)
#define HIT_WRITEBACK_SD BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_SD)
#define HIT_SET_VIRTUAL_SI BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SI)
#define HIT_SET_VIRTUAL_SD BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SD)
/*> EOF regs.S <*/

45
libgloss/mips/syscalls.c Normal file
View File

@ -0,0 +1,45 @@
#include <_ansi.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "regs.S"
extern char _end[];
/* FIXME: This is not ideal, since we do a get_mem_info() call for
every sbrk() call. */
char *
sbrk (nbytes)
int nbytes;
{
static char *heap_ptr = _end;
static char *heap_start = _end;
char *base;
struct s_mem {
unsigned int size;
unsigned int icsize;
unsigned int dcsize;
} mem;
unsigned int avail = 0;
/* The sizeof (s_mem.size) must be 4 bytes. The compiler should be
able to eliminate this check */
if (sizeof (unsigned int) != 4)
return (char *)-1;
get_mem_info(&mem);
/* NOTE: The value returned from the get_mem_info call is the amount
of memory, and not the address of the (last byte + 1) */
if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start + mem.size))) {
avail = (heap_start + mem.size) - (size_t)heap_ptr;
base = heap_ptr;
} /* else will fail since "nbytes" will be greater than zeroed "avail" value */
if ((nbytes > avail) || (heap_ptr + nbytes < _end))
base = (char *)-1;
else
heap_ptr += nbytes;
return base;
}

13
libgloss/mips/test.c Normal file
View File

@ -0,0 +1,13 @@
main()
{
outbyte ('&');
outbyte ('@');
outbyte ('$');
outbyte ('%');
/* whew, we made it */
print ("\r\nDone...");
return;
}

341
libgloss/mips/vr4300.S Normal file
View File

@ -0,0 +1,341 @@
/*
* vr4300.S -- CPU specific support routines
*
* Copyright (c) 1995,1996 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#ifndef __mips64
.set mips3
#endif
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#include "regs.S"
.text
.align 2
# Taken from "R4300 Preliminary RISC Processor Specification
# Revision 2.0 January 1995" page 39: "The Count
# register... increments at a constant rate... at one-half the
# PClock speed."
# We can use this fact to provide small polled delays.
.globl __cpu_timer_poll
.ent __cpu_timer_poll
__cpu_timer_poll:
.set noreorder
# in: a0 = (unsigned int) number of PClock ticks to wait for
# out: void
# The Vr4300 counter updates at half PClock, so divide by 2 to
# get counter delta:
bnezl a0, 1f # continue if delta non-zero
srl a0, a0, 1 # divide ticks by 2 {DELAY SLOT}
# perform a quick return to the caller:
j ra
nop # {DELAY SLOT}
1:
mfc0 v0, $9 # C0_COUNT: get current counter value
nop
nop
# We cannot just do the simple test, of adding our delta onto
# the current value (ignoring overflow) and then checking for
# equality. The counter is incrementing every two PClocks,
# which means the counter value can change between
# instructions, making it hard to sample at the exact value
# desired.
# However, we do know that our entry delta value is less than
# half the number space (since we divide by 2 on entry). This
# means we can use a difference in signs to indicate timer
# overflow.
addu a0, v0, a0 # unsigned add (ignore overflow)
# We know have our end value (which will have been
# sign-extended to fill the 64bit register value).
2:
# get current counter value:
mfc0 v0, $9 # C0_COUNT
nop
nop
# This is an unsigned 32bit subtraction:
subu v0, a0, v0 # delta = (end - now) {DELAY SLOT}
bgtzl v0, 2b # looping back is most likely
nop
# We have now been delayed (in the foreground) for AT LEAST
# the required number of counter ticks.
j ra # return to caller
nop # {DELAY SLOT}
.set reorder
.end __cpu_timer_poll
# Flush the processor caches to memory:
.globl __cpu_flush
.ent __cpu_flush
__cpu_flush:
.set noreorder
# NOTE: The Vr4300 *CANNOT* have any secondary cache (bit 17
# of the CONFIG registered is hard-wired to 1). We just
# provide code to flush the Data and Instruction caches.
# Even though the Vr4300 has hard-wired cache and cache line
# sizes, we still interpret the relevant Config register
# bits. This allows this code to be used for other conforming
# MIPS architectures if desired.
# Get the config register
mfc0 a0, C0_CONFIG
nop
nop
li a1, 1 # a useful constant
#
srl a2, a0, 9 # bits 11..9 for instruction cache size
andi a2, a2, 0x7 # 3bits of information
add a2, a2, 12 # get full power-of-2 value
sllv a2, a1, a2 # instruction cache size
#
srl a3, a0, 6 # bits 8..6 for data cache size
andi a3, a3, 0x7 # 3bits of information
add a3, a3, 12 # get full power-of-2 value
sllv a3, a1, a3 # data cache size
#
li a1, (1 << 5) # check IB (instruction cache line size)
and a1, a0, a1 # mask against the CONFIG register value
beqz a1, 1f # branch on result of delay slot operation
nop
li a1, 32 # non-zero, then 32bytes
j 2f # continue
nop
1:
li a1, 16 # 16bytes
2:
#
li t0, (1 << 4) # check DB (data cache line size)
and a0, a0, t0 # mask against the CONFIG register value
beqz a0, 3f # branch on result of delay slot operation
nop
li a0, 32 # non-zero, then 32bytes
j 4f # continue
nop
3:
li a0, 16 # 16bytes
4:
#
# a0 = data cache line size
# a1 = instruction cache line size
# a2 = instruction cache size
# a3 = data cache size
#
lui t0, ((K0BASE >> 16) & 0xFFFF)
ori t0, t0, (K0BASE & 0xFFFF)
addu t1, t0, a2 # end cache address
subu t2, a1, 1 # line size mask
not t2 # invert the mask
and t3, t0, t2 # get start address
addu t1, -1
and t1, t2 # get end address
5:
cache INDEX_INVALIDATE_I,0(t3)
bne t3, t1, 5b
addu t3, a1
#
addu t1, t0, a3 # end cache address
subu t2, a0, 1 # line size mask
not t2 # invert the mask
and t3, t0, t2 # get start address
addu t1, -1
and t1, t2 # get end address
6:
cache INDEX_WRITEBACK_INVALIDATE_D,0(t3)
bne t3, t1, 6b
addu t3, a0
#
j ra # return to the caller
nop
.set reorder
.end __cpu_flush
# NOTE: This variable should *NOT* be addressed relative to
# the $gp register since this code is executed before $gp is
# initialised... hence we leave it in the text area. This will
# cause problems if this routine is ever ROMmed:
.globl __buserr_cnt
__buserr_cnt:
.word 0
.align 3
__k1_save:
.word 0
.word 0
.align 2
.ent __buserr
.globl __buserr
__buserr:
.set noat
.set noreorder
# k0 and k1 available for use:
mfc0 k0,C0_CAUSE
nop
nop
andi k0,k0,0x7c
sub k0,k0,7 << 2
beq k0,$0,__buserr_do
nop
# call the previous handler
la k0,__previous
jr k0
nop
#
__buserr_do:
# TODO: check that the cause is indeed a bus error
# - if not then just jump to the previous handler
la k0,__k1_save
sd k1,0(k0)
#
la k1,__buserr_cnt
lw k0,0(k1) # increment counter
addu k0,1
sw k0,0(k1)
#
la k0,__k1_save
ld k1,0(k0)
#
mfc0 k0,C0_EPC
nop
nop
addu k0,k0,4 # skip offending instruction
mtc0 k0,C0_EPC # update EPC
nop
nop
eret
# j k0
# rfe
.set reorder
.set at
.end __buserr
__exception_code:
.set noreorder
lui k0,%hi(__buserr)
daddiu k0,k0,%lo(__buserr)
jr k0
nop
.set reorder
__exception_code_end:
.data
__previous:
.space (__exception_code_end - __exception_code)
# This subtracting two addresses is working
# but is not garenteed to continue working.
# The assemble reserves the right to put these
# two labels into different frags, and then
# cant take their difference.
.text
.ent __default_buserr_handler
.globl __default_buserr_handler
__default_buserr_handler:
.set noreorder
# attach our simple bus error handler:
# in: void
# out: void
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,baseaddr
lui a0,0x8000 # delay slot
lui a0,0xbfc0
daddiu a0,a0,0x0200
baseaddr:
daddiu a0,a0,0x0180
# a0 = base vector table address
la a1,__exception_code_end
la a2,__exception_code
subu a1,a1,a2
la a3,__previous
# there must be a better way of doing this????
copyloop:
lw v0,0(a0)
sw v0,0(a3)
lw v0,0(a2)
sw v0,0(a0)
daddiu a0,a0,4
daddiu a2,a2,4
daddiu a3,a3,4
subu a1,a1,4
bne a1,$0,copyloop
nop
la a0,__buserr_cnt
sw $0,0(a0)
j ra
nop
.set reorder
.end __default_buserr_handler
.ent __restore_buserr_handler
.globl __restore_buserr_handler
__restore_buserr_handler:
.set noreorder
# restore original (monitor) bus error handler
# in: void
# out: void
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,res_baseaddr
lui a0,0x8000 # delay slot
lui a0,0xbfc0
daddiu a0,a0,0x0200
res_baseaddr:
daddiu a0,a0,0x0180
# a0 = base vector table address
la a1,__exception_code_end
la a3,__exception_code
subu a1,a1,a3
la a3,__previous
# there must be a better way of doing this????
res_copyloop:
lw v0,0(a3)
sw v0,0(a0)
daddiu a0,a0,4
daddiu a3,a3,4
subu a1,a1,4
bne a1,$0,res_copyloop
nop
j ra
nop
.set reorder
.end __restore_buserr_handler
.ent __buserr_count
.globl __buserr_count
__buserr_count:
.set noreorder
# restore original (monitor) bus error handler
# in: void
# out: unsigned int __buserr_cnt
la v0,__buserr_cnt
lw v0,0(v0)
j ra
nop
.set reorder
.end __buserr_count
/* EOF vr4300.S */

457
libgloss/mips/vr5xxx.S Normal file
View File

@ -0,0 +1,457 @@
/*
* vr5xxx.S -- CPU specific support routines
*
* Copyright (c) 1999 Cygnus Solutions
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
/* This file cloned from vr4300.S by dlindsay@cygnus.com
* and recoded to suit Vr5432 and Vr5000.
* Should be no worse for Vr43{00,05,10}.
* Specifically, __cpu_flush() has been changed (a) to allow for the hardware
* difference (in set associativity) between the Vr5432 and Vr5000,
* and (b) to flush the optional secondary cache of the Vr5000.
*/
/* Processor Revision Identifier (PRID) Register: Implementation Numbers */
#define IMPL_VR5432 0x54
/* Cache Constants not determinable dynamically */
#define VR5000_2NDLINE 32 /* secondary cache line size */
#define VR5432_LINE 32 /* I,Dcache line sizes */
#define VR5432_SIZE (16*1024) /* I,Dcache half-size */
#ifndef __mips64
.set mips3
#endif
#ifdef __mips16
/* This file contains 32 bit assembly code. */
.set nomips16
#endif
#include "regs.S"
.text
.align 2
# Taken from "R4300 Preliminary RISC Processor Specification
# Revision 2.0 January 1995" page 39: "The Count
# register... increments at a constant rate... at one-half the
# PClock speed."
# We can use this fact to provide small polled delays.
.globl __cpu_timer_poll
.ent __cpu_timer_poll
__cpu_timer_poll:
.set noreorder
# in: a0 = (unsigned int) number of PClock ticks to wait for
# out: void
# The Vr4300 counter updates at half PClock, so divide by 2 to
# get counter delta:
bnezl a0, 1f # continue if delta non-zero
srl a0, a0, 1 # divide ticks by 2 {DELAY SLOT}
# perform a quick return to the caller:
j ra
nop # {DELAY SLOT}
1:
mfc0 v0, $9 # C0_COUNT: get current counter value
nop
nop
# We cannot just do the simple test, of adding our delta onto
# the current value (ignoring overflow) and then checking for
# equality. The counter is incrementing every two PClocks,
# which means the counter value can change between
# instructions, making it hard to sample at the exact value
# desired.
# However, we do know that our entry delta value is less than
# half the number space (since we divide by 2 on entry). This
# means we can use a difference in signs to indicate timer
# overflow.
addu a0, v0, a0 # unsigned add (ignore overflow)
# We know have our end value (which will have been
# sign-extended to fill the 64bit register value).
2:
# get current counter value:
mfc0 v0, $9 # C0_COUNT
nop
nop
# This is an unsigned 32bit subtraction:
subu v0, a0, v0 # delta = (end - now) {DELAY SLOT}
bgtzl v0, 2b # looping back is most likely
nop
# We have now been delayed (in the foreground) for AT LEAST
# the required number of counter ticks.
j ra # return to caller
nop # {DELAY SLOT}
.set reorder
.end __cpu_timer_poll
# Flush the processor caches to memory:
.globl __cpu_flush
.ent __cpu_flush
__cpu_flush:
.set noreorder
# NOTE: The Vr4300 and Vr5432 *CANNOT* have any secondary cache.
# On those, SC (bit 17 of CONFIG register) is hard-wired to 1,
# except that email from Dennis_Han@el.nec.com says that old
# versions of the Vr5432 incorrectly hard-wired this bit to 0.
# The Vr5000 has an optional direct-mapped secondary cache,
# and the SC bit correctly indicates this.
# So, for the 4300 and 5432 we want to just
# flush the primary Data and Instruction caches.
# For the 5000 it is desired to flush the secondary cache too.
# There is an operation difference worth noting.
# The 4300 and 5000 primary caches use VA bit 14 to choose cache set,
# whereas 5432 primary caches use VA bit 0.
# This code interprets the relevant Config register bits as
# much as possible, except for the 5432.
# The code therefore has some portability.
# However, the associativity issues mean you should not just assume
# that this code works anywhere. Also, the secondary cache set
# size is hardwired, since the 5000 series does not define codes
# for variant sizes.
# Note: this version of the code flushes D$ before I$.
# It is difficult to construct a case where that matters,
# but it cant hurt.
mfc0 a0, C0_PRID # a0 = Processor Revision register
nop # dlindsay: unclear why the nops, but
nop # vr4300.S had such so I do too.
srl a2, a0, PR_IMP # want bits 8..15
andi a2, a2, 0x255 # mask: now a2 = Implementation # field
li a1, IMPL_VR5432
beq a1, a2, 8f # use Vr5432-specific flush algorithm
nop
# Non-Vr5432 version of the code.
# (The distinctions being: CONFIG is truthful about secondary cache,
# and we act as if the primary Icache and Dcache are direct mapped.)
mfc0 t0, C0_CONFIG # t0 = CONFIG register
nop
nop
li a1, 1 # a1=1, a useful constant
srl a2, t0, CR_IC # want IC field of CONFIG
andi a2, a2, 0x7 # mask: now a2= code for Icache size
add a2, a2, 12 # +12
sllv a2, a1, a2 # a2=primary instruction cache size in bytes
srl a3, t0, CR_DC # DC field of CONFIG
andi a3, a3, 0x7 # mask: now a3= code for Dcache size
add a3, a3, 12 # +12
sllv a3, a1, a3 # a3=primary data cache size in bytes
li t2, (1 << CR_IB) # t2=mask over IB boolean
and t2, t2, t0 # test IB field of CONFIG register value
beqz t2, 1f #
li a1, 16 # 16 bytes (branch shadow: always loaded.)
li a1, 32 # non-zero, then 32bytes
1:
li t2, (1 << CR_DB) # t2=mask over DB boolean
and t2, t2, t0 # test BD field of CONFIG register value
beqz t2, 2f #
li a0, 16 # 16bytes (branch shadow: always loaded.)
li a0, 32 # non-zero, then 32bytes
2:
lui t1, ((K0BASE >> 16) & 0xFFFF)
ori t1, t1, (K0BASE & 0xFFFF)
# At this point,
# a0 = primary Dcache line size in bytes
# a1 = primary Icache line size in bytes
# a2 = primary Icache size in bytes
# a3 = primary Dcache size in bytes
# t0 = CONFIG value
# t1 = a round unmapped cached base address (we are in kernel mode)
# t2,t3 scratch
addi t3, t1, 0 # t3=t1=start address for any cache
add t2, t3, a3 # t2=end adress+1 of Dcache
sub t2, t2, a0 # t2=address of last line in Dcache
3:
cache INDEX_WRITEBACK_INVALIDATE_D,0(t3)
bne t3, t2, 3b #
addu t3, a0 # (delay slot) increment by Dcache line size
# Now check CONFIG to see if there is a secondary cache
lui t2, (1 << (CR_SC-16)) # t2=mask over SC boolean
and t2, t2, t0 # test SC in CONFIG
bnez t2, 6f
# There is a secondary cache. Find out its sizes.
srl t3, t0, CR_SS # want SS field of CONFIG
andi t3, t3, 0x3 # mask: now t3= code for cache size.
beqz t3, 4f
lui a3, ((512*1024)>>16) # a3= 512K, code was 0
addu t3, -1 # decrement code
beqz t3, 4f
lui a3, ((1024*1024)>>16) # a3= 1 M, code 1
addu t3, -1 # decrement code
beqz t3, 4f
lui a3, ((2*1024*1024)>>16) # a3= 2 M, code 2
j 6f # no secondary cache, code 3
4: # a3 = secondary cache size in bytes
li a0, VR5000_2NDLINE # no codes assigned for other than 32
# At this point,
# a0 = secondary cache line size in bytes
# a1 = primary Icache line size in bytes
# a2 = primary Icache size in bytes
# a3 = secondary cache size in bytes
# t1 = a round unmapped cached base address (we are in kernel mode)
# t2,t3 scratch
addi t3, t1, 0 # t3=t1=start address for any cache
add t2, t3, a3 # t2=end address+1 of secondary cache
sub t2, t2, a0 # t2=address of last line in secondary cache
5:
cache INDEX_WRITEBACK_INVALIDATE_SD,0(t3)
bne t3, t2, 5b
addu t3, a0 # (delay slot) increment by line size
6: # Any optional secondary cache done. Now do I-cache and return.
# At this point,
# a1 = primary Icache line size in bytes
# a2 = primary Icache size in bytes
# t1 = a round unmapped cached base address (we are in kernel mode)
# t2,t3 scratch
add t2, t1, a2 # t2=end adress+1 of Icache
sub t2, t2, a1 # t2=address of last line in Icache
7:
cache INDEX_INVALIDATE_I,0(t1)
bne t1, t2, 7b
addu t1, a1 # (delay slot) increment by Icache line size
j ra # return to the caller
nop
8:
# Vr5432 version of the cpu_flush code.
# (The distinctions being: CONFIG can not be trusted about secondary
# cache (which does not exist). The primary caches use Virtual Address Bit 0
# to control set selection.
# Code does not consult CONFIG about cache sizes: knows the hardwired sizes.
# Since both I and D have the same size and line size, uses a merged loop.
li a0, VR5432_LINE
li a1, VR5432_SIZE
lui t1, ((K0BASE >> 16) & 0xFFFF)
ori t1, t1, (K0BASE & 0xFFFF)
# a0 = cache line size in bytes
# a1 = 1/2 cache size in bytes
# t1 = a round unmapped cached base address (we are in kernel mode)
add t2, t1, a1 # t2=end address+1
sub t2, t2, a0 # t2=address of last line in Icache
9:
cache INDEX_WRITEBACK_INVALIDATE_D,0(t1) # set 0
cache INDEX_WRITEBACK_INVALIDATE_D,1(t1) # set 1
cache INDEX_INVALIDATE_I,0(t1) # set 0
cache INDEX_INVALIDATE_I,1(t1) # set 1
bne t1, t2, 9b
addu t1, a0
j ra # return to the caller
nop
.set reorder
.end __cpu_flush
# NOTE: This variable should *NOT* be addressed relative to
# the $gp register since this code is executed before $gp is
# initialised... hence we leave it in the text area. This will
# cause problems if this routine is ever ROMmed:
.globl __buserr_cnt
__buserr_cnt:
.word 0
.align 3
__k1_save:
.word 0
.word 0
.align 2
.ent __buserr
.globl __buserr
__buserr:
.set noat
.set noreorder
# k0 and k1 available for use:
mfc0 k0,C0_CAUSE
nop
nop
andi k0,k0,0x7c
sub k0,k0,7 << 2
beq k0,$0,__buserr_do
nop
# call the previous handler
la k0,__previous
jr k0
nop
#
__buserr_do:
# TODO: check that the cause is indeed a bus error
# - if not then just jump to the previous handler
la k0,__k1_save
sd k1,0(k0)
#
la k1,__buserr_cnt
lw k0,0(k1) # increment counter
addu k0,1
sw k0,0(k1)
#
la k0,__k1_save
ld k1,0(k0)
#
mfc0 k0,C0_EPC
nop
nop
addu k0,k0,4 # skip offending instruction
mtc0 k0,C0_EPC # update EPC
nop
nop
eret
# j k0
# rfe
.set reorder
.set at
.end __buserr
__exception_code:
.set noreorder
lui k0,%hi(__buserr)
daddiu k0,k0,%lo(__buserr)
jr k0
nop
.set reorder
__exception_code_end:
.data
__previous:
.space (__exception_code_end - __exception_code)
# This subtracting two addresses is working
# but is not garenteed to continue working.
# The assemble reserves the right to put these
# two labels into different frags, and then
# cant take their difference.
.text
.ent __default_buserr_handler
.globl __default_buserr_handler
__default_buserr_handler:
.set noreorder
# attach our simple bus error handler:
# in: void
# out: void
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,baseaddr
lui a0,0x8000 # delay slot
lui a0,0xbfc0
daddiu a0,a0,0x0200
baseaddr:
daddiu a0,a0,0x0180
# a0 = base vector table address
la a1,__exception_code_end
la a2,__exception_code
subu a1,a1,a2
la a3,__previous
# there must be a better way of doing this????
copyloop:
lw v0,0(a0)
sw v0,0(a3)
lw v0,0(a2)
sw v0,0(a0)
daddiu a0,a0,4
daddiu a2,a2,4
daddiu a3,a3,4
subu a1,a1,4
bne a1,$0,copyloop
nop
la a0,__buserr_cnt
sw $0,0(a0)
j ra
nop
.set reorder
.end __default_buserr_handler
.ent __restore_buserr_handler
.globl __restore_buserr_handler
__restore_buserr_handler:
.set noreorder
# restore original (monitor) bus error handler
# in: void
# out: void
mfc0 a0,C0_SR
nop
li a1,SR_BEV
and a1,a1,a0
beq a1,$0,res_baseaddr
lui a0,0x8000 # delay slot
lui a0,0xbfc0
daddiu a0,a0,0x0200
res_baseaddr:
daddiu a0,a0,0x0180
# a0 = base vector table address
la a1,__exception_code_end
la a3,__exception_code
subu a1,a1,a3
la a3,__previous
# there must be a better way of doing this????
res_copyloop:
lw v0,0(a3)
sw v0,0(a0)
daddiu a0,a0,4
daddiu a3,a3,4
subu a1,a1,4
bne a1,$0,res_copyloop
nop
j ra
nop
.set reorder
.end __restore_buserr_handler
.ent __buserr_count
.globl __buserr_count
__buserr_count:
.set noreorder
# restore original (monitor) bus error handler
# in: void
# out: unsigned int __buserr_cnt
la v0,__buserr_cnt
lw v0,0(v0)
j ra
nop
.set reorder
.end __buserr_count
/* EOF vr5xxx.S */