2002-02-08 Joel Sherrill <joel@OARcorp.com>

* Makefile, stubinit.S, r46kstub.ld, ioaddr.h: Removed as unused
	with RTEMS.
	* r46kstub.c: Renamed to mips-stub.c.
	* mips-stub.c: New file -- was r46kstub.c.
	* memlimits.h: New file was limits.h.
	* limits.h: Removed.
	* r4600.h: Eliminated need for this file.
	* README: Updated.
 	* gdb_if.h: Added CVS Id.
	* mips-stub.c: Attempt to deal with MIPS1 versus MIPS3.
This commit is contained in:
Joel Sherrill
2002-02-08 21:26:00 +00:00
parent fb63984771
commit fc82e71072
10 changed files with 112 additions and 1206 deletions

View File

@@ -1,3 +1,16 @@
2002-02-08 Joel Sherrill <joel@OARcorp.com>
* Makefile, stubinit.S, r46kstub.ld, ioaddr.h: Removed as unused
with RTEMS.
* r46kstub.c: Renamed to mips-stub.c.
* mips-stub.c: New file -- was r46kstub.c.
* memlimits.h: New file was limits.h.
* limits.h: Removed.
* r4600.h: Eliminated need for this file.
* README: Updated.
* gdb_if.h: Added CVS Id.
* mips-stub.c: Attempt to deal with MIPS1 versus MIPS3.
2002-02-08 Joel Sherrill <joel@OARcorp.com>
* Merged r46kstub.c into RTEMS distribution without modification.

View File

@@ -1,38 +0,0 @@
CC = mips64orion-idt-elf-gcc
CFLAGS = -g -Wa,-ahld -Wall -membedded-data -O3
AS = mips64orion-idt-elf-as
ASFLAGS = -ahld
LD = mips64orion-idt-elf-ld
LDFLAGS = -t -s
# Inference rules
.SUFFIXES: $(SUFFIXES) .out .ld
.ld.out:
$(LD) $(LDFLAGS) -T $< -Map $*.map -o $*.out
.c.o:
$(CC) $(CFLAGS) -c $< >$*.L
.S.o:
$(CC) $(CFLAGS) -c $< >$*.L
.s.o:
$(AS) $(ASFLAGS) -o $*.o $< >$*.L
# Targets
r46kstub.hex: r46kstub.out
mips64orion-idt-elf-objcopy -S -R .bss -R .data -R .reginfo \
-O srec r46kstub.out r46kstub.hex
clean:
rm -f *.L *.map *.o *.out *.hex
# Dependencies
r46kstub.out: r46kstub.ld r46kstub.o stubinit.o
r46kstub.o: mips_opcode.h r4600.h limits.h gdb_if.h r46kstub.c
stubinit.o: r4600.h ioaddr.h gdb_if.h stubinit.S

View File

@@ -1,7 +1,29 @@
/* r46kstub 9/29/96 c. m. heard */
/* 7/26/96 -- original posting */
/* 8/06/96 -- cache initialization/flushing logic fixed */
/* 9/29/96 -- coprocessor load delay slots respected, documentation improved */
#
# $Id$
#
The contents of this directory are based upon the "r46kstub.tar.gz" package
released to the net by
C. M. Heard
VVNET, Inc. phone: +1 408 247 9376
4040 Moorpark Ave. Suite 206 fax: +1 408 244 3651
San Jose, CA 95117 USA e-mail: heard@vvnet.com
This package was released in the September 1996 time frame for use
with gdb 4.16 and an IDT R4600 Orion. The stub was modified to support
R3000 class CPUs and to work within the mips-rtems exeception processing
framework.
THe file memlimits.h could end up being target board dependent. If
this is the case, copy it to your BSP directory and modify as necessary.
--joel
8 February 2002
Original README
===============
The r46kstub directory and its compressed archive (r46kstub.tar.gz) contain
the 9/29/96 source code snapshot for a ROM-resident gdb-4.16 debug agent
@@ -108,8 +130,3 @@ the "set" command to load an unmapped sixty-four bit virtual address into
the PC, as you can for all other registers.
Please send bug reports, comments, or suggestions for improvement to:
C. M. Heard
VVNET, Inc. phone: +1 408 247 9376
4040 Moorpark Ave. Suite 206 fax: +1 408 244 3651
San Jose, CA 95117 USA e-mail: heard@vvnet.com

View File

@@ -10,13 +10,15 @@
* THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
#ifndef _GDB_IF_H
#define _GDB_IF_H
/*
* R4600 registers, numbered in the order in which gdb expects to see them.
* MIPS registers, numbered in the order in which gdb expects to see them.
*/
#define ZERO 0
#define AT 1

View File

@@ -1,113 +0,0 @@
/*
* ioaddr.h - 16C450 serial port memory-mapped I/O address definitions
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _IOADDR_H
#define _IOADDR_H
/*
* The following addresses are implementation-specific.
* Note that big-endian memory addressing is assumed.
*/
#define ISA_IO_BASE 0xb8000000
#define BYTE_IO(ioaddr) ((ioaddr<<3)+7)
#define WORD_IO(ioaddr) ((ioaddr<<3)+6)
#define ISA_IRQ9_RESET 0xb8043000
#define ISA_IRQ5_RESET 0xb8042000
#define ISA_IRQ4_RESET 0xb8041000
#define ISA_IRQ3_RESET 0xb8040000
#define ISA_IRQ_STATUS 0xb8040000
/* ISA IRQ Status Register fields */
#define ISA_IRQ9_STATUS 0x08
#define ISA_IRQ5_STATUS 0x04
#define ISA_IRQ4_STATUS 0x02
#define ISA_IRQ3_STATUS 0x01
/*
* Serial Port 1 (COM1) I/O Addresses. These definitions
* follows the standard IBM AT I/O address assignments.
* Note that IRQ4 is normally assigned to serial port 1.
*/
#define DIV_LO_COM1 BYTE_IO(0x3f8) /* Div latch lo (line ctl bit 7 = 1) */
#define DIV_HI_COM1 BYTE_IO(0x3f9) /* Div latch hi (line ctl bit 7 = 1) */
#define DATA_REG_COM1 BYTE_IO(0x3f8) /* TX Buf (write)/RX Buf (read) */
#define INT_ENA_COM1 BYTE_IO(0x3f9) /* Interrupt Enable Register */
#define INT_ID_COM1 BYTE_IO(0x3fa) /* Interrupt ID Register */
#define LINE_CTL_COM1 BYTE_IO(0x3fb) /* Line Control Register */
#define MODEM_CTL_COM1 BYTE_IO(0x3fc) /* Modem Control Register */
#define LINE_STS_COM1 BYTE_IO(0x3fd) /* Line Status Register */
#define MODEM_STS_COM1 BYTE_IO(0x3fe) /* Modem Status Register */
/*
* Serial Port 2 (COM1) I/O Addresses. These definitions
* follows the standard IBM AT I/O address assignments.
* Note that IRQ3 is normally assigned to serial port 2.
*/
#define DIV_LO_COM2 BYTE_IO(0x2f8) /* Div latch lo (line ctl bit 7 = 1) */
#define DIV_HI_COM2 BYTE_IO(0x2f9) /* Div latch hi (line ctl bit 7 = 1) */
#define DATA_REG_COM2 BYTE_IO(0x2f8) /* TX Buf (write)/RX Buf (read) */
#define INT_ENA_COM2 BYTE_IO(0x2f9) /* Interrupt Enable Register */
#define INT_ID_COM2 BYTE_IO(0x2fa) /* Interrupt ID Register */
#define LINE_CTL_COM2 BYTE_IO(0x2fb) /* Line Control Register */
#define MODEM_CTL_COM2 BYTE_IO(0x2fc) /* Modem Control Register */
#define LINE_STS_COM2 BYTE_IO(0x2fd) /* Line Status Register */
#define MODEM_STS_COM2 BYTE_IO(0x2fe) /* Modem Status Register */
/* Interrupt Enable Register fields */
#define IENA_MODEM 0x08
#define IENA_LINE 0x04
#define IENA_TX 0x02
#define IENA_RX 0x01
/* Interrupt Identification Register fields */
#define INT_ID_MASK 0x06
#define INT_PENDING 0x01
/* Line Control Register fields */
#define DIV_LATCH_EN 0x80
#define SET_BREAK 0x40
#define STICK_PARITY 0x20
#define EVEN_PARITY 0x10
#define PARITY_ENA 0x08
#define STOP_BITS 0x04
#define WORD_LEN_MASK 0x03
/* Line Status Register fields */
#define TX_SHR_EMPTY 0x40
#define TX_BUF_EMPTY 0x20
#define BRK_RCVD 0x10
#define FRAMING_ERR 0x08
#define PARITY_ERR 0x04
#define OVRUN_ERR 0x02
#define RX_CHAR_AVA 0x01
/* Modem Control Register fields */
#define LOOPBACK 0x10
#define OUT2 0x08
#define OUT1 0x04
#define RTS 0x02
#define DTR 0x01
/* Modem Status Register fields */
#define RLSD 0x80
#define RI 0x40
#define DSR 0x20
#define CTS 0x10
#define DELTA_RLSD 0x08
#define TRAIL_EDGE_RI 0x04
#define DELTA_DSR 0x02
#define DELTA_CTS 0x01
#endif /* _IOADDR_H */

View File

@@ -10,6 +10,8 @@
REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
$Id$
********************************************************************************
*
* r46kstub.c -- target debugging stub for the IDT R4600 Orion processor
@@ -120,16 +122,74 @@
#include <string.h>
#include <signal.h>
#include "mips_opcode.h"
#include "r4600.h"
#include "limits.h"
#include "memlimits.h"
#include <rtems.h>
#include "gdb_if.h"
/***************/
/* Exception Codes */
#define EXC_INT 0 /* External interrupt */
#define EXC_MOD 1 /* TLB modification exception */
#define EXC_TLBL 2 /* TLB miss (Load or Ifetch) */
#define EXC_TLBS 3 /* TLB miss (Store) */
#define EXC_ADEL 4 /* Address error (Load or Ifetch) */
#define EXC_ADES 5 /* Address error (Store) */
#define EXC_IBE 6 /* Bus error (Ifetch) */
#define EXC_DBE 7 /* Bus error (data load or store) */
#define EXC_SYS 8 /* System call */
#define EXC_BP 9 /* Break point */
#define EXC_RI 10 /* Reserved instruction */
#define EXC_CPU 11 /* Coprocessor unusable */
#define EXC_OVF 12 /* Arithmetic overflow */
#define EXC_TRAP 13 /* Trap exception */
#define EXC_FPE 15 /* Floating Point Exception */
/* FPU Control/Status register fields */
#define CSR_FS 0x01000000 /* Set to flush denormals to zero */
#define CSR_C 0x00800000 /* Condition bit (set by FP compare) */
#define CSR_CMASK (0x3f<<12)
#define CSR_CE 0x00020000
#define CSR_CV 0x00010000
#define CSR_CZ 0x00008000
#define CSR_CO 0x00004000
#define CSR_CU 0x00002000
#define CSR_CI 0x00001000
#define CSR_EMASK (0x1f<<7)
#define CSR_EV 0x00000800
#define CSR_EZ 0x00000400
#define CSR_EO 0x00000200
#define CSR_EU 0x00000100
#define CSR_EI 0x00000080
#define CSR_FMASK (0x1f<<2)
#define CSR_FV 0x00000040
#define CSR_FZ 0x00000020
#define CSR_FO 0x00000010
#define CSR_FU 0x00000008
#define CSR_FI 0x00000004
#define CSR_RMODE_MASK (0x3<<0)
#define CSR_RM 0x00000003
#define CSR_RP 0x00000002
#define CSR_RZ 0x00000001
#define CSR_RN 0x00000000
/***************/
/*
* Saved register information. Must be prepared by the exception
* preprocessor before handle_exception is invoked.
*/
extern long long registers[NUM_REGS];
#if (__mips == 3)
typedef long long mips_register_t;
#elif (__mips == 1)
typedef unsigned int mips_register_t;
#else
#error "unknown MIPS ISA"
#endif
static mips_register_t *registers;
/*
@@ -720,7 +780,7 @@ computeSignal (void)
* reacts to gdb's requests.
*/
void
handle_exception (void)
handle_exception (CPU_Interrupt_frame *frame)
{
int host_has_detached = 0;
int sigval;
@@ -728,6 +788,8 @@ handle_exception (void)
long long regval;
char *ptr;
registers = (mips_register_t *)frame;
/* reply to host that an exception has occurred */
sigval = computeSignal ();
outBuffer[0] = 'S';
@@ -757,6 +819,10 @@ handle_exception (void)
outBuffer[3] = '\0';
break;
case 'd':
/* toggle debug flag */
break;
case 'g':
/* return the values of the CPU registers */
mem2hex ((int) registers, sizeof registers, outBuffer);

View File

@@ -1,372 +0,0 @@
/*
* r4600.h - register and address space definitions for the R4600 processor
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _R4600_H
#define _R4600_H
/*
* R4600 general registers
*/
#define zero $0
#define at $1 /* assembler temporary */
#define v0 $2 /* value holders */
#define v1 $3
#define a0 $4 /* arguments */
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 /* temporaries */
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 /* saved registers */
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 /* temporaries */
#define t9 $25
#define k0 $26 /* kernel registers */
#define k1 $27
#define gp $28 /* global pointer */
#define sp $29 /* stack pointer */
#define s8 $30 /* saved register */
#define fp $30 /* frame pointer (obsolete usage) */
#define ra $31 /* return address */
/*
* Kernel address space definitions (32 bit/64 bit compatibility spaces)
*/
#define K0BASE 0x80000000
#define K0SIZE 0x20000000
#define K1BASE 0xa0000000
#define K1SIZE 0x20000000
#define PHYS_TO_K0(pa) ((pa)|K0BASE)
#define PHYS_TO_K1(pa) ((pa)|K1BASE)
#define K0_TO_PHYS(va) ((va)&(K0SIZE-1))
#define K1_TO_PHYS(va) ((va)&(K1SIZE-1))
#define K0_TO_K1(va) ((va)|K1SIZE)
#define K1_TO_K0(va) ((va)&~K1SIZE)
/*
* System Control Coprocessor (CP0) memory-management registers
*/
#define C0_INDEX $0 /* TLB Index */
#define C0_RANDOM $1 /* TLB Random */
#define C0_ENTRYLO0 $2 /* TLB EntryLo0 */
#define C0_ENTRYLO1 $3 /* TLB EntryLo1 */
#define C0_PAGEMASK $5 /* TLB PageMask */
#define C0_WIRED $6 /* TLB Wired */
#define C0_ENTRYHI $10 /* TLB EntryHi */
#define C0_PRID $15 /* Processor Revision Indentifier */
#define C0_CONFIG $16 /* Config */
#define C0_LLADDR $17 /* LLAddr */
#define C0_TAGLO $28 /* TagLo */
#define C0_TAGHI $29 /* TagHi (always zero on the R4600) */
/* EntryHi register fields */
#define EH_REGION_MASK 0xc000000000000000 /* 11=krnl, 01=supv, 00=user */
#define EH_REGION_SHIFT 62
#define EH_FILL_MASK 0x3fffff0000000000 /* (holds replica of bit 63) */
#define EH_FILL_SHIFT 40
#define EH_VPN2_MASK 0x000000ffffffe000 /* Virtual pageno div 2 */
#define EH_VPN2_SHIFT 13
#define EH_ASID_MASK 0x00000000000000ff /* Address space ID */
#define EH_ASID_SHIFT 0
/* EntryLo register fields */
#define EL_PFN_MASK 0x000000003fffffc0 /* Page Frame Number */
#define EL_PFN_SHIFT 6
#define EL_C_MASK 0x0000000000000038 /* Cacheability attributes */
#define EL_C_SHIFT 3
#define EL_D_MASK 0x0000000000000004 /* Dirty bit */
#define EL_D_SHIFT 2
#define EL_V_MASK 0x0000000000000002 /* Valid bit */
#define EL_V_SHIFT 1
#define EL_G_MASK 0x0000000000000001 /* Global bit */
#define EL_G_SHIFT 0
/* PageMask register fields */
#define PM_MASK 0x01ffe000 /* Page size mask: */
#define PM_M_4K 0x00000000 /* 4K bytes */
#define PM_M_16K 0x00006000 /* 16K bytes */
#define PM_M_64K 0x0001e000 /* 64K bytes */
#define PM_M_256K 0x0007e000 /* 256K bytes */
#define PM_M_1M 0x001fe000 /* 1M bytes */
#define PM_M_4M 0x007fe000 /* 4M bytes */
#define PM_M_16M 0x01ffe000 /* 16M bytes */
/* Index register fields */
#define IR_P_MASK 0x80000000 /* TLB Probe (TLBP) failure */
#define IR_INDEX_MASK 0x0000003f /* Index of TLB entry for TLBR/TLBWI */
/* Random register */
#define RR_INDEX_MASK 0x0000003f /* Index of TLB entry for TLBWR */
#define NTLBENTRIES 48 /* Max TLB index is one less */
/* Wired register */
#define WR_INDEX_MASK 0x0000003f /* Number of wired TLB entries */
/* PrID register fields */
#define PRID_IMP_MASK (0xff<<8) /* Implementation number */
#define PRID_REV_MASK (0xff<<0) /* Revision number */
/* Config register fields (read only except for K0 cacheability attributes) */
#define CFG_ECMASK 0x70000000 /* System Clock Ratio: */
#define CFG_ECBY2 0x00000000 /* processor clock divided by 2 */
#define CFG_ECBY3 0x10000000 /* processor clock divided by 3 */
#define CFG_ECBY4 0x20000000 /* processor clock divided by 4 */
#define CFG_ECBY5 0x30000000 /* processor clock divided by 5 */
#define CFG_ECBY6 0x40000000 /* processor clock divided by 6 */
#define CFG_ECBY7 0x50000000 /* processor clock divided by 7 */
#define CFG_ECBY8 0x60000000 /* processor clock divided by 8 */
#define CFG_EC_RESERVED 0x70000000 /* (reserved) */
#define CFG_EPMASK 0x0f000000 /* Writeback pattern: */
#define CFG_EPD 0x00000000 /* DDDD (one dword every cycle) */
#define CFG_EPDDx 0x01000000 /* DDxDDx (2 dword/3 cyc) */
#define CFG_EPDDxx 0x02000000 /* DDxDDx (2 dword/4 cyc) */
#define CFG_EPDxDx 0x03000000 /* DxDxDxDx (2 dword/4 cyc) */
#define CFG_EPDDxxx 0x04000000 /* DDxxxDDxxx (2 dword/5 cyc) */
#define CFG_EPDDxxxx 0x05000000 /* DDxxxxDDxxxx (2 dword/6 cyc) */
#define CFG_EPDxxDxx 0x06000000 /* DxxDxxDxxDxx (2 dword/6 cyc) */
#define CFG_EPDDxxxxx 0x07000000 /* DDxxxxxDDxxxxx (2 dword/7 cyc) */
#define CFG_EPDDxxxxxx 0x08000000 /* DDxxxxxxDDxxxxxx (2 dword/8 cyc) */
#define CFG_BEMASK 0x00008000 /* Big Endian */
#define CFG_EMMASK 0x00004000 /* set to 1 => Parity mode enabled */
#define CFG_EBMASK 0x00002000 /* set to 1 => Sub-block ordering */
#define CFG_ICMASK 0x00000e00 /* I-cache size = 2**(12+IC) bytes */
#define CFG_ICSHIFT 9
#define CFG_DCMASK 0x000001c0 /* D-cache size = 2**(12+DC) bytes */
#define CFG_DCSHIFT 6
#define CFG_IBMASK 0x00000020 /* set to 1 => 32 byte I-cache line */
#define CFG_DBMASK 0x00000010 /* set to 1 => 32 byte D-cache line */
#define CFG_K0C_MASK 0x00000007 /* KSEG0 cacheability attributes: */
#define CFG_C_WTNOALLOC 0 /* write thru, no write allocate */
#define CFG_C_WTALLOC 1 /* write thru, write allocate */
#define CFG_C_UNCACHED 2 /* uncached */
#define CFG_C_WRITEBACK 3 /* writeback, non-coherent */
/* Primary Cache TagLo */
#define TAG_PTAG_MASK 0xffffff00 /* P-Cache Tag (Addr 35:12) */
#define TAG_PTAG_SHIFT 8
#define TAG_PSTATE_MASK 0x000000c0 /* P-Cache State */
#define TAG_PSTATE_SHIFT 6
#define TAG_FIFO_BIT_MASK 0x00000002 /* P-Cache FIFO bit */
#define TAG_FIFO_BIT_SHIFT 1
#define TAG_PARITY_MASK 0x00000001 /* P-Cache Tag Parity */
#define TAG_PARITY_SHIFT 0
#define PSTATE_INVAL 0 /* Invalid */
#define PSTATE_SHARED 1 /* Should not occur */
#define PSTATE_CLEAN_EXCL 2 /* Should not occur */
#define PSTATE_DIRTY_EXCL 3 /* Dirty exclusive */
/*
* System Control Coprocessor (CP0) exception processing registers
*/
#define C0_CONTEXT $4 /* Context */
#define C0_BADVADDR $8 /* Bad Virtual Address */
#define C0_COUNT $9 /* Count */
#define C0_COMPARE $11 /* Compare */
#define C0_STATUS $12 /* Processor Status */
#define C0_CAUSE $13 /* Exception Cause */
#define C0_EPC $14 /* Exception PC */
#define C0_XCONTEXT $20 /* XContext */
#define C0_ECC $26 /* ECC */
#define C0_CACHEERR $27 /* CacheErr */
#define C0_ERROREPC $30 /* ErrorEPC */
/* Status register fields */
#define SR_CUMASK 0xf0000000 /* Coprocessor usable bits */
#define SR_CU3 0x80000000 /* Coprocessor 3 usable */
#define SR_CU2 0x40000000 /* coprocessor 2 usable */
#define SR_CU1 0x20000000 /* Coprocessor 1 usable */
#define SR_CU0 0x10000000 /* Coprocessor 0 usable */
#define SR_FR 0x04000000 /* Enable 32 floating-point registers */
#define SR_RE 0x02000000 /* Reverse Endian in user mode */
#define SR_BEV 0x00400000 /* Bootstrap Exception Vector */
#define SR_TS 0x00200000 /* TLB shutdown (reserved on R4600) */
#define SR_SR 0x00100000 /* Soft Reset */
#define SR_CH 0x00040000 /* Cache Hit */
#define SR_CE 0x00020000 /* ECC register modifies check bits */
#define SR_DE 0x00010000 /* Disable cache errors */
#define SR_IMASK 0x0000ff00 /* Interrupt Mask */
#define SR_IMASK8 0x00000000 /* Interrupt Mask level=8 */
#define SR_IMASK7 0x00008000 /* Interrupt Mask level=7 */
#define SR_IMASK6 0x0000c000 /* Interrupt Mask level=6 */
#define SR_IMASK5 0x0000e000 /* Interrupt Mask level=5 */
#define SR_IMASK4 0x0000f000 /* Interrupt Mask level=4 */
#define SR_IMASK3 0x0000f800 /* Interrupt Mask level=3 */
#define SR_IMASK2 0x0000fc00 /* Interrupt Mask level=2 */
#define SR_IMASK1 0x0000fe00 /* Interrupt Mask level=1 */
#define SR_IMASK0 0x0000ff00 /* Interrupt Mask level=0 */
#define SR_IBIT8 0x00008000 /* (Intr5) */
#define SR_IBIT7 0x00004000 /* (Intr4) */
#define SR_IBIT6 0x00002000 /* (Intr3) */
#define SR_IBIT5 0x00001000 /* (Intr2) */
#define SR_IBIT4 0x00000800 /* (Intr1) */
#define SR_IBIT3 0x00000400 /* (Intr0) */
#define SR_IBIT2 0x00000200 /* (Software Interrupt 1) */
#define SR_IBIT1 0x00000100 /* (Software Interrupt 0) */
#define SR_KX 0x00000080 /* xtlb in kernel mode */
#define SR_SX 0x00000040 /* mips3 & xtlb in supervisor mode */
#define SR_UX 0x00000020 /* mips3 & xtlb in user mode */
#define SR_KSU_MASK 0x00000018 /* ksu mode mask */
#define SR_KSU_USER 0x00000010 /* user mode */
#define SR_KSU_SUPV 0x00000008 /* supervisor mode */
#define SR_KSU_KERN 0x00000000 /* kernel mode */
#define SR_ERL 0x00000004 /* error level */
#define SR_EXL 0x00000002 /* exception level */
#define SR_IE 0x00000001 /* interrupt enable */
/* Cause register fields */
#define CAUSE_BD 0x80000000 /* Branch Delay */
#define CAUSE_CEMASK 0x30000000 /* Coprocessor Error */
#define CAUSE_CESHIFT 28 /* Right justify CE */
#define CAUSE_IPMASK 0x0000ff00 /* Interrupt Pending */
#define CAUSE_IPSHIFT 8 /* Right justify IP */
#define CAUSE_IP8 0x00008000 /* (Intr5) */
#define CAUSE_IP7 0x00004000 /* (Intr4) */
#define CAUSE_IP6 0x00002000 /* (Intr3) */
#define CAUSE_IP5 0x00001000 /* (Intr2) */
#define CAUSE_IP4 0x00000800 /* (Intr1) */
#define CAUSE_IP3 0x00000400 /* (Intr0) */
#define CAUSE_SW2 0x00000200 /* (Software Interrupt 1) */
#define CAUSE_SW1 0x00000100 /* (Software Interrupt 0) */
#define CAUSE_EXCMASK 0x0000007c /* Exception Code */
#define CAUSE_EXCSHIFT 2 /* Right justify EXC */
/* Exception Codes */
#define EXC_INT 0 /* External interrupt */
#define EXC_MOD 1 /* TLB modification exception */
#define EXC_TLBL 2 /* TLB miss (Load or Ifetch) */
#define EXC_TLBS 3 /* TLB miss (Store) */
#define EXC_ADEL 4 /* Address error (Load or Ifetch) */
#define EXC_ADES 5 /* Address error (Store) */
#define EXC_IBE 6 /* Bus error (Ifetch) */
#define EXC_DBE 7 /* Bus error (data load or store) */
#define EXC_SYS 8 /* System call */
#define EXC_BP 9 /* Break point */
#define EXC_RI 10 /* Reserved instruction */
#define EXC_CPU 11 /* Coprocessor unusable */
#define EXC_OVF 12 /* Arithmetic overflow */
#define EXC_TRAP 13 /* Trap exception */
#define EXC_FPE 15 /* Floating Point Exception */
/* CacheErr register */
#define CACHEERR_TYPE 0x80000000 /* reference type:
0=Instr, 1=Data */
#define CACHEERR_LEVEL 0x40000000 /* cache level:
0=Primary, 1=Secondary */
#define CACHEERR_DATA 0x20000000 /* data field:
0=No error, 1=Error */
#define CACHEERR_TAG 0x10000000 /* tag field:
0=No error, 1=Error */
#define CACHEERR_REQ 0x08000000 /* request type:
0=Internal, 1=External */
#define CACHEERR_BUS 0x04000000 /* error on bus:
0=No, 1=Yes */
#define CACHEERR_BOTH 0x02000000 /* Data & Instruction error:
0=No, 1=Yes */
#define CACHEERR_REFILL 0x01000000 /* Error on Refill:
0=No, 1=Yes */
#define CACHEERR_SIDX_MASK 0x003ffff8 /* PADDR(21..3) */
#define CACHEERR_SIDX_SHIFT 0
#define CACHEERR_PIDX_MASK 0x00000007 /* VADDR(14..12) */
#define CACHEERR_PIDX_SHIFT 12
/*
* R4600 Cache operations
*/
#define Index_Invalidate_I 0x0 /* 0 0 */
#define Index_Writeback_Inv_D 0x1 /* 0 1 */
#define Index_Load_Tag_I 0x4 /* 1 0 */
#define Index_Load_Tag_D 0x5 /* 1 1 */
#define Index_Store_Tag_I 0x8 /* 2 0 */
#define Index_Store_Tag_D 0x9 /* 2 1 */
#define Create_Dirty_Exc_D 0xD /* 3 1 */
#define Hit_Invalidate_I 0x10 /* 4 0 */
#define Hit_Invalidate_D 0x11 /* 4 1 */
#define Fill_I 0x14 /* 5 0 */
#define Hit_Writeback_Inv_D 0x15 /* 5 1 */
#define Hit_Writeback_I 0x18 /* 6 0 */
#define Hit_Writeback_D 0x19 /* 6 1 */
/*
* Floating Point Coprocessor (CP1) registers
*/
#define C1_IRR $0 /* Implementation/Revision register */
#define C1_CSR $31 /* FPU Control/Status register */
/* Implementation/Revision reg fields */
#define IRR_IMP_MASK (0xff<<8) /* Implementation number */
#define IRR_REV_MASK (0xff<<0) /* Revision number */
/* FPU Control/Status register fields */
#define CSR_FS 0x01000000 /* Set to flush denormals to zero */
#define CSR_C 0x00800000 /* Condition bit (set by FP compare) */
#define CSR_CMASK (0x3f<<12)
#define CSR_CE 0x00020000
#define CSR_CV 0x00010000
#define CSR_CZ 0x00008000
#define CSR_CO 0x00004000
#define CSR_CU 0x00002000
#define CSR_CI 0x00001000
#define CSR_EMASK (0x1f<<7)
#define CSR_EV 0x00000800
#define CSR_EZ 0x00000400
#define CSR_EO 0x00000200
#define CSR_EU 0x00000100
#define CSR_EI 0x00000080
#define CSR_FMASK (0x1f<<2)
#define CSR_FV 0x00000040
#define CSR_FZ 0x00000020
#define CSR_FO 0x00000010
#define CSR_FU 0x00000008
#define CSR_FI 0x00000004
#define CSR_RMODE_MASK (0x3<<0)
#define CSR_RM 0x00000003
#define CSR_RP 0x00000002
#define CSR_RZ 0x00000001
#define CSR_RN 0x00000000
#endif /* _R4600_H */

View File

@@ -1,53 +0,0 @@
MEMORY
{
NUL : ORIGIN = 0xa00f0000, LENGTH = 0
RAM : ORIGIN = 0xa00fe000, LENGTH = 8K
ROM : ORIGIN = 0xbfc00000, LENGTH = 8K
}
SECTIONS
{
/* Initialized data is _not_ supported. */
/* Assign it to an empty region in order */
/* to force a link error if any exists. */
.data 0xa00f0000 (NOLOAD): {
_fdata = .;
*(.data)
. = ALIGN(8);
_gp = . + 0x8000;
*(.sdata)
. = ALIGN(8);
_edata = .;
} >NUL
/* Assign uninitialized read/write data to RAM. */
.bss 0xa00fe000 (NOLOAD): {
_fbss = .;
stubinit.o(.bss)
*(.sbss)
*(.bss)
*(.scommon)
*(COMMON)
. = ALIGN(8);
_end = .;
} >RAM
/* Assign code and read-only data to ROM. This */
/* section MUST start at the reset address, */
/* and the reset code MUST be linked first. */
.text 0xbfc00000: {
_ftext = .;
stubinit.o(.text)
. = ALIGN(8);
r46kstub.o(.text)
. = ALIGN(8);
*(.rdata)
. = ALIGN(8);
*(.rodata)
. = ALIGN(8);
_etext = .;
} >ROM = 0
}
ENTRY(_reset_exception)

View File

@@ -1,616 +0,0 @@
/*
* stubinit.S - low level startup code for the ROM-based R4600 gdb stub
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
.nolist
#include "r4600.h"
#include "ioaddr.h"
#include "gdb_if.h"
.list
#define SERIAL_SPEED 19200 /* use 19200 bps serial link */
#define FORCE_PC_TO_32_BITS /* to work around a bug in gdb-4.16 */
#define STACKSIZE 4096 /* allocate 4K bootstack */
.sdata
.globl _gp /* value to put in gp register */
.bss
.globl _fbss /* start of .bss area */
.space STACKSIZE /* allocate the exception stack */
_stack: /* stack top here (stack grows DOWN) */
.globl registers /* register save area */
registers:
.space NUM_REGS*8
.globl _end /* end of .bss area */
.eject
.text
.globl handle_exception /* C exception handler */
.set noreorder
.set noat
.globl _reset_exception /* entry point into the EPROM */
/* it MUST reside at bfc00000 */
/*
* Set the STATUS register initial state: mark CP1 usable, MIPS-3
* floating point registers enabled, boot exception vectors selected,
* cache parity exceptions disabled, kernel TLB miss to XTLB refill
* vector, machine in kernel mode, exception level cleared, error
* level set, interrupt enable cleared, all interrupts masked. Note
* that the value written here is what will saved in the register
* image; this will put the machine in a reasonable default state
* even if the debug exception handler does nothing to the status
* register image.
*/
_reset_exception:
li k0,SR_CU1 + SR_FR + SR_BEV + SR_DE + SR_KX \
+ SR_KSU_KERN + SR_ERL
mtc0 k0,C0_STATUS
/*
* Mark each TLB entry as "invalid" and fill the tag field with a VPN that
* cannot occur and an ASID that will not match the value left in EntryHi.
*/
li k0,K1BASE+EH_ASID_MASK /* EntryHi = unmapped VPN2, ASID 255 */
dmtc0 zero,C0_ENTRYLO0 /* EntryLo0 = invalid */
dmtc0 zero,C0_ENTRYLO1 /* EntryLo1 = invalid */
mtc0 zero,C0_PAGEMASK /* PageSize = 4K */
li k1,(NTLBENTRIES-1) /* TLB index */
1:
dmtc0 k0,C0_ENTRYHI
mtc0 k1,C0_INDEX
addu k0,(1<<EH_VPN2_SHIFT) /* incr VPN2 */
tlbwi
bnel k1,zero,1b
addiu k1,k1,-1 /* decr INDEX */
dmtc0 zero,C0_ENTRYHI /* Clear EntryHi to select ASID = 0 */
nop /* wait for update to take effect */
.eject
/*
* Invalidate each line in both of the caches, then
* set kseg0 config to cached/writeback/non-coherent.
*/
mtc0 zero,C0_TAGLO /* clear TAGLO and TAGHI - used below */
mtc0 zero,C0_TAGHI /* to set cache line state to invalid */
nop
mfc0 k0,C0_CONFIG /* read config info */
li k1,(1<<12) /* base size is 4K */
and k0,CFG_ICMASK /* isolate I-cache shift count param */
srl k0,CFG_ICSHIFT /* which determines the actual size */
sll k1,k0 /* shift left to get actual size */
mfc0 k0,C0_CONFIG /* read config info */
nop /* wait for CP0 read to take effect */
and k0,CFG_IBMASK /* isolate line size config bit */
bne k0,zero,2f /* jump if line size is 32 bytes */
lui k0,((K0BASE>>16)&0xffff)/* set lower limit to unmapped addr */
addu k1,k0 /* this prevents a TLB exception */
addiu k1,-16 /* set upper limit for 16 byte line */
1:
cache Index_Store_Tag_I,(k0) /* write TAGLO/TAGHI to the cache */
bnel k0,k1,1b /* do that by index so that a */
addiu k0,k0,16 /* cache hit is not required */
b 4f
nop
2:
addu k1,k0 /* come here for 32 byte line size */
addiu k1,-32
3:
cache Index_Store_Tag_I,(k0)
bnel k0,k1,3b
addiu k0,k0,32
4:
.eject
mfc0 k0,C0_CONFIG /* repeat for D-cache */
li k1,(1<<12)
and k0,CFG_DCMASK
srl k0,CFG_DCSHIFT
sll k1,k0
mfc0 k0,C0_CONFIG
nop
and k0,CFG_DBMASK
bne k0,zero,6f
lui k0,((K0BASE>>16)&0xffff)
addu k1,k0
addiu k1,-16
5:
cache Index_Store_Tag_D,(k0)
bnel k0,k1,5b
addiu k0,k0,16
b 8f
nop
6:
addu k1,k0
addiu k1,-32
7:
cache Index_Store_Tag_D,(k0)
bnel k0,k1,7b
addiu k0,k0,32
8:
mfc0 k0,C0_CONFIG /* read config info one last time */
li k1,~CFG_K0C_MASK /* clear K0 config field */
and k0,k1 /* in CONFIG image register image */
or k0,CFG_C_WRITEBACK /* set config to cached/writeback */
mtc0 k0,C0_CONFIG /* write back to CP0 */
nop /* wait for update to take effect */
.eject
/*
* Initialize the serial port
*/
li k0,DIV_LATCH_EN + WORD_LEN_MASK
la k1,ISA_IO_BASE /* set 8/bits char, no parity, and */
sb k0,LINE_CTL_COM1(k1) /* enable access to divisor latch */
li k0,(1843200/(16*SERIAL_SPEED))
sb k0,DIV_LO_COM1(k1) /* set clock divisor low byte */
sra k0,8
sb k0,DIV_HI_COM1(k1) /* set clock divisor high byte */
li k0,WORD_LEN_MASK /* set 8/bits char, no parity, and */
sb k0,LINE_CTL_COM1(k1) /* disable access to divisor latch */
lbu k0,DATA_REG_COM1(k1) /* read & discard any existing char */
sb zero,INT_ENA_COM1(k1) /* disable all interrupt sources */
li k0,RTS + DTR /* turn RTS and DTR on */
sb k0,MODEM_CTL_COM1(k1)
/*
* Reset all pending ISA interrupts
*/
la k1,ISA_IRQ3_RESET
sd zero,(k1)
la k1,ISA_IRQ4_RESET
sd zero,(k1)
la k1,ISA_IRQ5_RESET
sd zero,(k1)
la k1,ISA_IRQ9_RESET
sd zero,(k1)
.eject
/*
* Clear the CAUSE register to indicate the
* absence of software-initiated exceptions.
*/
mtc0 zero,C0_CAUSE
/*
* Clear floating point errors and configure
* the FPU to flush denormals to zero.
*/
li k0,CSR_FS
ctc1 k0,C1_CSR
/*
* Clear the .bss area
*/
la k0,_fbss
la k1,_end
1:
addiu k1,k1,-8
bne k1,k0,1b
sd zero,(k1)
/*
* Save the ErrorEPC register, in case of a pushbutton
* reset, and join the general exception-handling path.
*/
la k0,registers
dmfc0 k1,C0_ERROREPC
j _common_path_join
sd k1,8*PC(k0)
.align 9
.eject
_tlbmiss_exception: /* bfc00200: tlbmiss exception */
j _general_exception
nop
.align 7
_xtlbmiss_exception: /* bfc00280: xtlbmiss exception */
j _general_exception
nop
.align 7
_cache_parity_error: /* bfc00300: cache parity error */
j _reset_exception
nop
.align 7
/* bfc00380: general exception */
/*
* Clear the register save area
*/
_general_exception:
la k0,registers
addiu k1,k0,8*(NUM_REGS-1)
1:
sd zero,(k1)
bnel k1,k0,1b
addiu k1,k1,-8
/*
* Save the PC
*/
dmfc0 k1,C0_EPC
nop
sd k1,8*PC(k0)
.eject
/*
* Save the SR, CAUSE, and BAD_VA registers.
*/
_common_path_join:
mfc0 k1,C0_STATUS
nop
sd k1,8*SR(k0)
mfc0 k1,C0_CAUSE
nop
sd k1,8*CAUSE(k0)
mfc0 k1,C0_BADVADDR
nop
sd k1,8*BAD_VA(k0)
/*
* Save LO, HI, and the general registers.
* Note that zero, k0 & k1 are not saved.
*/
mflo k1
sd k1,8*LO(k0)
mfhi k1
sd k1,8*HI(k0)
/* zero is hard-wired */
sd at,8*AT(k0)
sd v0,8*V0(k0)
sd v1,8*V1(k0)
sd a0,8*A0(k0)
sd a1,8*A1(k0)
sd a2,8*A2(k0)
sd a3,8*A3(k0)
sd t0,8*T0(k0)
sd t1,8*T1(k0)
sd t2,8*T2(k0)
sd t3,8*T3(k0)
sd t4,8*T4(k0)
sd t5,8*T5(k0)
sd t6,8*T6(k0)
sd t7,8*T7(k0)
.eject
sd s0,8*S0(k0)
sd s1,8*S1(k0)
sd s2,8*S2(k0)
sd s3,8*S3(k0)
sd s4,8*S4(k0)
sd s5,8*S5(k0)
sd s6,8*S6(k0)
sd s7,8*S7(k0)
sd t8,8*T8(k0)
sd t9,8*T9(k0)
/* k0 is not saved */
/* k1 is not saved */
sd gp,8*GP(k0)
sd sp,8*SP(k0)
sd s8,8*S8(k0)
sd ra,8*RA(k0)
/*
* Save the floating point control registers.
*/
cfc1 k1,C1_CSR
nop
sd k1,8*FCSR(k0)
cfc1 k1,C1_IRR
nop
sd k1,8*FIRR(k0)
/*
* Save the even-numbered floating point registers.
*/
sdc1 $0,8*F0(k0)
sdc1 $2,8*F2(k0)
sdc1 $4,8*F4(k0)
sdc1 $6,8*F6(k0)
sdc1 $8,8*F8(k0)
sdc1 $10,8*F10(k0)
sdc1 $12,8*F12(k0)
sdc1 $14,8*F14(k0)
sdc1 $16,8*F16(k0)
sdc1 $18,8*F18(k0)
sdc1 $20,8*F20(k0)
sdc1 $22,8*F22(k0)
sdc1 $24,8*F24(k0)
sdc1 $26,8*F26(k0)
sdc1 $28,8*F28(k0)
sdc1 $30,8*F30(k0)
.eject
/*
* If they are enabled, save the odd-numbered
* floating point registers as well.
*/
mfc0 k1,C0_STATUS
li at,SR_FR
and k1,at
beq k1,zero,1f
nop
sdc1 $1,8*F1(k0)
sdc1 $3,8*F3(k0)
sdc1 $5,8*F5(k0)
sdc1 $7,8*F7(k0)
sdc1 $9,8*F9(k0)
sdc1 $11,8*F11(k0)
sdc1 $13,8*F13(k0)
sdc1 $15,8*F15(k0)
sdc1 $17,8*F17(k0)
sdc1 $19,8*F19(k0)
sdc1 $21,8*F21(k0)
sdc1 $23,8*F23(k0)
sdc1 $25,8*F25(k0)
sdc1 $27,8*F27(k0)
sdc1 $29,8*F29(k0)
sdc1 $31,8*F31(k0)
1:
/*
* Set up the global pointer and the stack
* and invoke the exception handler.
*/
la gp,_gp
la sp,_stack
jal handle_exception
addiu fp,sp,0
.eject
/*
* On exit from the exception handler invalidate each line in the I-cache
* and write back each dirty line in the D-cache. This needs to be done
* before the target program is resumed in order to ensure that software
* breakpoints and downloaded code will actually take effect.
*/
mfc0 t0,C0_CONFIG /* read config info into t0 */
nop /* wait for CP0 read to take effect */
and t1,t0,CFG_ICMASK /* isolate I-cache shift */
srl t1,t1,CFG_ICSHIFT /* count param into t1 */
li t2,(1<<12) /* put base size in t2 */
sllv t2,t2,t1 /* shift left to get actual size */
and t1,t0,CFG_IBMASK /* isolate linesize config bit */
bne t1,zero,1f /* guess line size is 32 bytes */
addiu t3,zero,32 /* skip next load if guessed right */
addiu t3,zero,16 /* else set size to 16 bytes */
1:
la t1,K0BASE /* set lower & upper address limits */
addu t2,t2,t1 /* use kseg0 to avoid TLB exception */
subu t2,t2,t3
2:
cache Index_Invalidate_I,(t1) /* invalidate each I-cache line */
bnel t1,t2,2b /* do this by index so that */
addu t1,t1,t3 /* a hit is not required */
and t1,t0,CFG_DCMASK /* repeat for D-cache with writeback */
srl t1,t1,CFG_DCSHIFT
li t2,(1<<12)
sllv t2,t2,t1
and t1,t0,CFG_DBMASK
bne t1,zero,3f
addiu t3,zero,32
addiu t3,zero,16
3:
la t1,K0BASE
addu t2,t2,t1
subu t2,t2,t3
4:
cache Index_Writeback_Inv_D,(t1)
bnel t1,t2,4b
addu t1,t1,t3
.eject
/*
* Now restore the registers. Note that they may
* have been modified while within the debugger.
* Start with even-numbered floating point registers.
*/
la k0,registers
ldc1 $0,8*F0(k0)
ldc1 $2,8*F2(k0)
ldc1 $4,8*F4(k0)
ldc1 $6,8*F6(k0)
ldc1 $8,8*F8(k0)
ldc1 $10,8*F10(k0)
ldc1 $12,8*F12(k0)
ldc1 $14,8*F14(k0)
ldc1 $16,8*F16(k0)
ldc1 $18,8*F18(k0)
ldc1 $20,8*F20(k0)
ldc1 $22,8*F22(k0)
ldc1 $24,8*F24(k0)
ldc1 $26,8*F26(k0)
ldc1 $28,8*F28(k0)
ldc1 $30,8*F30(k0)
/*
* If they are enabled, restore the odd-numbered
* floating point registers as well.
*/
mfc0 k1,C0_STATUS
li at,SR_FR
and k1,at
beq k1,zero,1f
nop
ldc1 $1,8*F1(k0)
ldc1 $3,8*F3(k0)
ldc1 $5,8*F5(k0)
ldc1 $7,8*F7(k0)
ldc1 $9,8*F9(k0)
ldc1 $11,8*F11(k0)
ldc1 $13,8*F13(k0)
ldc1 $15,8*F15(k0)
ldc1 $17,8*F17(k0)
ldc1 $19,8*F19(k0)
ldc1 $21,8*F21(k0)
ldc1 $23,8*F23(k0)
ldc1 $25,8*F25(k0)
ldc1 $27,8*F27(k0)
ldc1 $29,8*F29(k0)
ldc1 $31,8*F31(k0)
1:
.eject
/*
* Restore the floating point control & status register.
* FIRR is not restored because it is read-only.
*/
ld k1,8*FCSR(k0)
ctc1 k1,C1_CSR
/*
* Restore LO, HI, and the general registers.
*/
ld k1,8*LO(k0)
mtlo k1
ld k1,8*HI(k0)
mthi k1
/* zero is hard-wired */
ld at,8*AT(k0)
ld v0,8*V0(k0)
ld v1,8*V1(k0)
ld a0,8*A0(k0)
ld a1,8*A1(k0)
ld a2,8*A2(k0)
ld a3,8*A3(k0)
ld t0,8*T0(k0)
ld t1,8*T1(k0)
ld t2,8*T2(k0)
ld t3,8*T3(k0)
ld t4,8*T4(k0)
ld t5,8*T5(k0)
ld t6,8*T6(k0)
ld t7,8*T7(k0)
ld s0,8*S0(k0)
ld s1,8*S1(k0)
ld s2,8*S2(k0)
ld s3,8*S3(k0)
ld s4,8*S4(k0)
ld s5,8*S5(k0)
ld s6,8*S6(k0)
ld s7,8*S7(k0)
ld t8,8*T8(k0)
ld t9,8*T9(k0)
/* k0 is not restored */
/* k1 is not restored */
ld gp,8*GP(k0)
ld sp,8*SP(k0)
ld s8,8*S8(k0)
ld ra,8*RA(k0)
.eject
/*
* Restore the cause register, the status register, and the PC. Note
* that the saved PC is loaded into the ErrorEPC if ERL is set in the
* status register image and is loaded into the EPC otherwise.
*/
ld k1,8*CAUSE(k0)
mtc0 k1,C0_CAUSE
ld k1,8*SR(k0)
mtc0 k1,C0_STATUS
andi k1,k1,SR_ERL
beq k1,zero,1f
ld k1,8*PC(k0)
#if !defined(FORCE_PC_TO_32_BITS)
b 2f
dmtc0 k1,C0_ERROREPC
1:
dmtc0 k1,C0_EPC
2:
#else
addu k1,k1,zero
b 2f
dmtc0 k1,C0_ERROREPC
1:
addu k1,k1,zero
dmtc0 k1,C0_EPC
2:
#endif
/*
* Flush the write buffer to memory.
*/
sync
/*
* Hide the contents of k0 & k1
* and return to the user program.
*/
move k0,zero
move k1,zero
eret
.eject
/*
* char getDebugChar (void);
*/
.set reorder
.globl getDebugChar
.ent getDebugChar
getDebugChar:
la t0,ISA_IO_BASE /* point to ISA slot I/O */
1:
lbu t1,LINE_STS_COM1(t0) /* read line status register */
and t1,RX_CHAR_AVA /* isolate RX status bit */
beqz t1,1b /* loop until char is available */
lbu v0,DATA_REG_COM1(t0) /* read the character */
j ra /* and return */
.end getDebugChar
/*
* void putDebugChar (char);
*/
.set reorder
.globl putDebugChar
.ent putDebugChar
putDebugChar:
la t0,ISA_IO_BASE /* point to ISA slot I/O */
1:
lbu t1,LINE_STS_COM1(t0) /* read line status register */
and t1,TX_BUF_EMPTY /* isolate TX status bit */
beqz t1,1b /* loop while buffer is full */
sb a0,DATA_REG_COM1(t0) /* write the outgoing character */
sync /* flush the write buffer to memory */
j ra /* and return */
.end putDebugChar