URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 13 to Rev 14
- ↔ Reverse comparison
Rev 13 → Rev 14
/eco32/trunk/hwtests/serial/fpga2pc/receive.c
0,0 → 1,126
/* |
* receive.c -- serial line test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <termios.h> |
|
|
#define SERIAL_PORT "/dev/ttyS0" |
|
#define NUM_TRIES 10 |
|
#define SYN 0x16 |
#define ACK 0x06 |
|
|
static FILE *diskFile = NULL; |
static int sfd = 0; |
static struct termios origOptions; |
static struct termios currOptions; |
|
|
void serialClose(void); |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
if (diskFile != NULL) { |
fclose(diskFile); |
diskFile = NULL; |
} |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
exit(1); |
} |
|
|
void serialOpen(void) { |
sfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); |
if (sfd == -1) { |
error("cannot open serial port '%s'", SERIAL_PORT); |
} |
tcgetattr(sfd, &origOptions); |
currOptions = origOptions; |
cfsetispeed(&currOptions, B38400); |
cfsetospeed(&currOptions, B38400); |
currOptions.c_cflag |= (CLOCAL | CREAD); |
currOptions.c_cflag &= ~PARENB; |
currOptions.c_cflag &= ~CSTOPB; |
currOptions.c_cflag &= ~CSIZE; |
currOptions.c_cflag |= CS8; |
currOptions.c_cflag &= ~CRTSCTS; |
currOptions.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN); |
currOptions.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK); |
currOptions.c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL); |
currOptions.c_iflag &= ~(IXON | IXOFF | IXANY); |
currOptions.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); |
tcsetattr(sfd, TCSANOW, &currOptions); |
} |
|
|
void serialClose(void) { |
tcsetattr(sfd, TCSANOW, &origOptions); |
close(sfd); |
} |
|
|
int serialSnd(unsigned char b) { |
int n; |
|
n = write(sfd, &b, 1); |
return n == 1; |
} |
|
|
int serialRcv(unsigned char *bp) { |
int n; |
|
n = read(sfd, bp, 1); |
return n == 1; |
} |
|
|
int main(int argc, char *argv[]) { |
unsigned char prev, curr; |
int count, errors; |
|
if (argc != 1) { |
printf("Usage: %s\n", argv[0]); |
exit(1); |
} |
serialOpen(); |
count = 0; |
errors = 0; |
while (!serialRcv(&prev)) ; |
count++; |
while (count < 100000) { |
while (!serialRcv(&curr)) ; |
count++; |
if (((prev + 1) & 0xFF) != curr) { |
errors++; |
} |
prev = curr; |
} |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
printf("count = %d (ok = %d, errors = %d)\n", |
count, count - errors, errors); |
return 0; |
} |
/eco32/trunk/hwtests/serial/fpga2pc/send0.s
0,0 → 1,27
; |
; send.s -- send stream of bytes |
; |
|
; $8 serial base address |
; $9 temporary value |
; $10 character |
; $11 counter |
; $31 return address |
|
.set tba,0xF0300000 |
|
add $8,$0,tba |
add $11,$0,0 |
loop: |
add $10,$11,0 |
and $10,$10,0xFF |
jal out |
add $11,$11,1 |
j loop |
|
out: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out |
stw $10,$8,12 |
jr $31 |
/eco32/trunk/hwtests/serial/fpga2pc/send1.s
0,0 → 1,27
; |
; send.s -- send stream of bytes |
; |
|
; $8 serial base address |
; $9 temporary value |
; $10 character |
; $11 counter |
; $31 return address |
|
.set tba,0xF0300010 |
|
add $8,$0,tba |
add $11,$0,0 |
loop: |
add $10,$11,0 |
and $10,$10,0xFF |
jal out |
add $11,$11,1 |
j loop |
|
out: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out |
stw $10,$8,12 |
jr $31 |
/eco32/trunk/hwtests/serial/fpga2pc/Makefile
0,0 → 1,38
# |
# Makefile for serial line test program (FPGA --> PC) |
# |
|
BUILD = ../../../build |
|
.PHONY: all install clean |
|
all: send0.exo send1.exo receive |
|
install: send0.exo send1.exo receive |
|
send0.o: send0.s |
$(BUILD)/bin/as -o send0.o send0.s |
|
send1.o: send1.s |
$(BUILD)/bin/as -o send1.o send1.s |
|
send0.bin: send0.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o send0.bin send0.o |
|
send1.bin: send1.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o send1.bin send1.o |
|
send0.exo: send0.bin |
$(BUILD)/bin/bin2exo 0 send0.bin send0.exo |
|
send1.exo: send1.bin |
$(BUILD)/bin/bin2exo 0 send1.bin send1.exo |
|
receive: receive.c |
gcc -m32 -g -Wall -o receive receive.c |
|
clean: |
rm -f *~ |
rm -f send0.o send0.bin send0.exo |
rm -f send1.o send1.bin send1.exo |
rm -f receive |
/eco32/trunk/hwtests/serial/pc2fpga/receive0.s
0,0 → 1,54
; |
; receive.s -- receive & check a stream of bytes |
; |
|
; $8 serial base address |
; $9 temporary value |
; $10 current character |
; $11 previous character |
; $12 counter |
; $13 error |
; $31 return address |
|
.set tba,0xF0300000 |
|
add $8,$0,tba |
add $12,$0,100000 |
add $13,$0,0 |
jal in |
add $11,$10,0 |
sub $12,$12,1 |
loop: |
add $11,$11,1 |
and $11,$11,0xFF |
jal in |
beq $10,$11,chrok |
add $13,$13,1 |
chrok: |
sub $12,$12,1 |
bne $12,$0,loop |
bne $13,$0,error |
add $13,$0,'.' |
jal out |
j halt |
error: |
add $13,$0,'?' |
jal out |
j halt |
|
halt: |
j halt |
|
in: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,in |
ldw $10,$8,4 |
jr $31 |
|
out: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out |
stw $13,$8,12 |
jr $31 |
/eco32/trunk/hwtests/serial/pc2fpga/receive1.s
0,0 → 1,54
; |
; receive.s -- receive & check a stream of bytes |
; |
|
; $8 serial base address |
; $9 temporary value |
; $10 current character |
; $11 previous character |
; $12 counter |
; $13 error |
; $31 return address |
|
.set tba,0xF0300010 |
|
add $8,$0,tba |
add $12,$0,100000 |
add $13,$0,0 |
jal in |
add $11,$10,0 |
sub $12,$12,1 |
loop: |
add $11,$11,1 |
and $11,$11,0xFF |
jal in |
beq $10,$11,chrok |
add $13,$13,1 |
chrok: |
sub $12,$12,1 |
bne $12,$0,loop |
bne $13,$0,error |
add $13,$0,'.' |
jal out |
j halt |
error: |
add $13,$0,'?' |
jal out |
j halt |
|
halt: |
j halt |
|
in: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,in |
ldw $10,$8,4 |
jr $31 |
|
out: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out |
stw $13,$8,12 |
jr $31 |
/eco32/trunk/hwtests/serial/pc2fpga/send.c
0,0 → 1,122
/* |
* send.c -- serial line test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <termios.h> |
|
|
#define SERIAL_PORT "/dev/ttyS0" |
|
#define NUM_TRIES 10 |
|
#define SYN 0x16 |
#define ACK 0x06 |
|
|
static FILE *diskFile = NULL; |
static int sfd = 0; |
static struct termios origOptions; |
static struct termios currOptions; |
|
|
void serialClose(void); |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
if (diskFile != NULL) { |
fclose(diskFile); |
diskFile = NULL; |
} |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
exit(1); |
} |
|
|
void serialOpen(void) { |
sfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); |
if (sfd == -1) { |
error("cannot open serial port '%s'", SERIAL_PORT); |
} |
tcgetattr(sfd, &origOptions); |
currOptions = origOptions; |
cfsetispeed(&currOptions, B38400); |
cfsetospeed(&currOptions, B38400); |
currOptions.c_cflag |= (CLOCAL | CREAD); |
currOptions.c_cflag &= ~PARENB; |
currOptions.c_cflag &= ~CSTOPB; |
currOptions.c_cflag &= ~CSIZE; |
currOptions.c_cflag |= CS8; |
currOptions.c_cflag &= ~CRTSCTS; |
currOptions.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN); |
currOptions.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK); |
currOptions.c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL); |
currOptions.c_iflag &= ~(IXON | IXOFF | IXANY); |
currOptions.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); |
tcsetattr(sfd, TCSANOW, &currOptions); |
} |
|
|
void serialClose(void) { |
tcsetattr(sfd, TCSANOW, &origOptions); |
close(sfd); |
} |
|
|
int serialSnd(unsigned char b) { |
int n; |
|
n = write(sfd, &b, 1); |
return n == 1; |
} |
|
|
int serialRcv(unsigned char *bp) { |
int n; |
|
n = read(sfd, bp, 1); |
return n == 1; |
} |
|
|
int main(int argc, char *argv[]) { |
unsigned char curr; |
int count; |
|
if (argc != 1) { |
printf("Usage: %s\n", argv[0]); |
exit(1); |
} |
serialOpen(); |
curr = 0; |
count = 0; |
while (count < 100000) { |
while (!serialSnd(curr)) ; |
curr = (curr + 1) & 0xFF; |
count++; |
} |
printf("count = %d\n", count); |
while (!serialRcv(&curr)) ; |
printf("answer = %c\n", curr); |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
return 0; |
} |
/eco32/trunk/hwtests/serial/pc2fpga/Makefile
0,0 → 1,38
# |
# Makefile for serial line test program (PC --> FPGA) |
# |
|
BUILD = ../../../build |
|
.PHONY: all install clean |
|
all: receive0.exo receive1.exo send |
|
install: receive0.exo receive1.exo send |
|
receive0.o: receive0.s |
$(BUILD)/bin/as -o receive0.o receive0.s |
|
receive1.o: receive1.s |
$(BUILD)/bin/as -o receive1.o receive1.s |
|
receive0.bin: receive0.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o receive0.bin receive0.o |
|
receive1.bin: receive1.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o receive1.bin receive1.o |
|
receive0.exo: receive0.bin |
$(BUILD)/bin/bin2exo 0 receive0.bin receive0.exo |
|
receive1.exo: receive1.bin |
$(BUILD)/bin/bin2exo 0 receive1.bin receive1.exo |
|
send: send.c |
gcc -m32 -g -Wall -o send send.c |
|
clean: |
rm -f *~ |
rm -f receive0.o receive0.bin receive0.exo |
rm -f receive1.o receive1.bin receive1.exo |
rm -f send |
/eco32/trunk/hwtests/serial/sertest/echo0.s
0,0 → 1,20
; |
; echo.s -- test the serial interface |
; |
|
.set sba,0xF0300000 ; serial base address |
|
add $8,$0,sba ; set serial base address |
L1: |
ldw $9,$8,0 ; load receiver status into $9 |
and $9,$9,1 ; check receiver ready |
beq $9,$0,L1 ; loop while not ready |
ldw $10,$8,4 ; load receiver data into $10 |
add $10,$10,0x5C |
and $10,$10,0xFF |
L2: |
ldw $9,$8,8 ; load transmitter status into $9 |
and $9,$9,1 ; check transmitter ready |
beq $9,$0,L2 ; loop while not ready |
stw $10,$8,12 ; load char into transmitter data |
j L1 ; all over again |
/eco32/trunk/hwtests/serial/sertest/echo1.s
0,0 → 1,20
; |
; echo.s -- test the serial interface |
; |
|
.set sba,0xF0300010 ; serial base address |
|
add $8,$0,sba ; set serial base address |
L1: |
ldw $9,$8,0 ; load receiver status into $9 |
and $9,$9,1 ; check receiver ready |
beq $9,$0,L1 ; loop while not ready |
ldw $10,$8,4 ; load receiver data into $10 |
add $10,$10,0x5C |
and $10,$10,0xFF |
L2: |
ldw $9,$8,8 ; load transmitter status into $9 |
and $9,$9,1 ; check transmitter ready |
beq $9,$0,L2 ; loop while not ready |
stw $10,$8,12 ; load char into transmitter data |
j L1 ; all over again |
/eco32/trunk/hwtests/serial/sertest/sertest.c
0,0 → 1,149
/* |
* sertest.c -- serial line test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <termios.h> |
|
|
#define SERIAL_PORT "/dev/ttyS0" |
|
#define NUM_TRIES 10 |
|
#define SYN 0x16 |
#define ACK 0x06 |
|
|
static FILE *diskFile = NULL; |
static int sfd = 0; |
static struct termios origOptions; |
static struct termios currOptions; |
static int errors; |
|
|
void serialClose(void); |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
if (diskFile != NULL) { |
fclose(diskFile); |
diskFile = NULL; |
} |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
exit(1); |
} |
|
|
void serialOpen(void) { |
sfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); |
if (sfd == -1) { |
error("cannot open serial port '%s'", SERIAL_PORT); |
} |
tcgetattr(sfd, &origOptions); |
currOptions = origOptions; |
cfsetispeed(&currOptions, B38400); |
cfsetospeed(&currOptions, B38400); |
currOptions.c_cflag |= (CLOCAL | CREAD); |
currOptions.c_cflag &= ~PARENB; |
currOptions.c_cflag &= ~CSTOPB; |
currOptions.c_cflag &= ~CSIZE; |
currOptions.c_cflag |= CS8; |
currOptions.c_cflag &= ~CRTSCTS; |
currOptions.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN); |
currOptions.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK); |
currOptions.c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL); |
currOptions.c_iflag &= ~(IXON | IXOFF | IXANY); |
currOptions.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); |
tcsetattr(sfd, TCSANOW, &currOptions); |
} |
|
|
void serialClose(void) { |
tcsetattr(sfd, TCSANOW, &origOptions); |
close(sfd); |
} |
|
|
int serialSnd(unsigned char b) { |
int n; |
|
n = write(sfd, &b, 1); |
return n == 1; |
} |
|
|
int serialRcv(unsigned char *bp) { |
int n; |
|
n = read(sfd, bp, 1); |
return n == 1; |
} |
|
|
void block(void) { |
unsigned char src[1000]; |
unsigned char dst[1000]; |
unsigned char *p, *q; |
int i; |
|
for (i = 0; i < 1000; i++) { |
src[i] = rand(); |
} |
p = src; |
q = dst; |
while (1) { |
if (p != &src[1000] && serialSnd(*p)) { |
p++; |
} |
if (q != &dst[1000] && serialRcv(q)) { |
q++; |
} |
if (q == &dst[1000]) { |
break; |
} |
} |
for (i = 0; i < 1000; i++) { |
if (((src[i] + 0x5C) & 0xFF) != dst[i]) { |
errors++; |
} |
} |
} |
|
|
int main(int argc, char *argv[]) { |
int i; |
|
if (argc != 1) { |
printf("Usage: %s\n", argv[0]); |
exit(1); |
} |
serialOpen(); |
errors = 0; |
for (i = 1; i <= 100; i++) { |
block(); |
if (i % 10 == 0) { |
printf("%d bytes, errors = %d\n", i * 1000, errors); |
} |
} |
if (sfd != 0) { |
serialClose(); |
sfd = 0; |
} |
return 0; |
} |
/eco32/trunk/hwtests/serial/sertest/Makefile
0,0 → 1,38
# |
# Makefile for serial line test program (FPGA <--> PC) |
# |
|
BUILD = ../../../build |
|
.PHONY: all install clean |
|
all: echo0.exo echo1.exo sertest |
|
install: echo0.exo echo1.exo sertest |
|
echo0.o: echo0.s |
$(BUILD)/bin/as -o echo0.o echo0.s |
|
echo1.o: echo1.s |
$(BUILD)/bin/as -o echo1.o echo1.s |
|
echo0.bin: echo0.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o echo0.bin echo0.o |
|
echo1.bin: echo1.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o echo1.bin echo1.o |
|
echo0.exo: echo0.bin |
$(BUILD)/bin/bin2exo 0 echo0.bin echo0.exo |
|
echo1.exo: echo1.bin |
$(BUILD)/bin/bin2exo 0 echo1.bin echo1.exo |
|
sertest: sertest.c |
gcc -m32 -g -Wall -o sertest sertest.c |
|
clean: |
rm -f *~ |
rm -f echo0.o echo0.bin echo0.exo |
rm -f echo1.o echo1.bin echo1.exo |
rm -f sertest |
/eco32/trunk/hwtests/serial/Makefile
0,0 → 1,25
# |
# Makefile for serial interface tests |
# |
|
BUILD = ../../build |
|
DIRS = fpga2pc pc2fpga sertest |
|
.PHONY: all install clean |
|
all: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i all ; \ |
done |
|
install: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i install ; \ |
done |
|
clean: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i clean ; \ |
done |
rm -f *~ |
/eco32/trunk/hwtests/tlbtest/serial.s
0,0 → 1,98
; |
; serial.s -- the serial line interface |
; |
|
;*************************************************************** |
|
.set ser0base,0xF0300000 ; serial line 0 base address |
.set ser1base,0xF0300010 ; serial line 1 base address |
|
.export serinit ; initialize serial interface |
|
.export ser0inchk ; line 0 input check |
.export ser0in ; line 0 input |
.export ser0outchk ; line 0 output check |
.export ser0out ; line 0 output |
|
.export ser1inchk ; line 1 input check |
.export ser1in ; line 1 input |
.export ser1outchk ; line 1 output check |
.export ser1out ; line 1 output |
|
;*************************************************************** |
|
.code |
.align 4 |
|
serinit: |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser0inchk: |
add $8,$0,ser0base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser0in: |
add $8,$0,ser0base |
ser0in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser0in1 |
ldw $2,$8,4 |
jr $31 |
|
ser0outchk: |
add $8,$0,ser0base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser0out: |
add $8,$0,ser0base |
ser0out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser0out1 |
stw $4,$8,12 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser1inchk: |
add $8,$0,ser1base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser1in: |
add $8,$0,ser1base |
ser1in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser1in1 |
ldw $2,$8,4 |
jr $31 |
|
ser1outchk: |
add $8,$0,ser1base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser1out: |
add $8,$0,ser1base |
ser1out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser1out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/tlbtest/start.h
0,0 → 1,21
/* |
* start.h -- startup and support routines |
*/ |
|
|
#ifndef _START_H_ |
#define _START_H_ |
|
|
int cin(void); |
void cout(char c); |
|
Word getTLB_HI(int index); |
Word getTLB_LO(int index); |
void setTLB(int index, Word entryHi, Word entryLo); |
void wrtRndTLB(Word entryHi, Word entryLo); |
Word probeTLB(Word entryHi); |
void wait(int n); |
|
|
#endif /* _START_H_ */ |
/eco32/trunk/hwtests/tlbtest/main.c
0,0 → 1,320
/* |
* main.c -- the main program |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "start.h" |
|
|
#define NUM_ENTRIES 32 |
#define NUM_FIXED 4 |
|
|
struct { |
Word hi; |
Word lo; |
} randomEntries[NUM_ENTRIES] = { |
{ 0x25FACEE3, 0x8ACF75B6 }, |
{ 0xCCDC1C4C, 0x524499EF }, |
{ 0x81CB5C0B, 0x7E098E5D }, |
{ 0xEB6F7F76, 0xAAA301DB }, |
{ 0x6FB1A2B8, 0x4E206502 }, |
{ 0x7FE39DFD, 0x3E74D858 }, |
{ 0x0422E083, 0x73B2D23A }, |
{ 0x71144B0A, 0xE623F4AF }, |
{ 0x5AAED767, 0xC34BEB52 }, |
{ 0x35A8D36A, 0x8E584748 }, |
{ 0x41B6B347, 0x544A9B0D }, |
{ 0x039AED34, 0x6927DF69 }, |
{ 0x3E3EEC16, 0xF7585602 }, |
{ 0x339AC351, 0xDD43F704 }, |
{ 0xA14C0101, 0x81FC5D62 }, |
{ 0x5B522D47, 0x9BC2EF2D }, |
{ 0x61235741, 0x67377AE9 }, |
{ 0x45BDFCA7, 0x4CDBDCF1 }, |
{ 0x2E044D77, 0xF70E7CE1 }, |
{ 0x33FC4126, 0x18B3D47C }, |
{ 0xF5F3CBEA, 0x9583DCC8 }, |
{ 0xA6B7454B, 0x887C5270 }, |
{ 0xED805C94, 0x9A6D6F8F }, |
{ 0xF27359EC, 0x2FC185D8 }, |
{ 0x0DDD34A3, 0x47B5D83A }, |
{ 0xEFDB299A, 0xC784294A }, |
{ 0x17A4E2F6, 0x5EAEFA99 }, |
{ 0x6EE1B054, 0xD716C16C }, |
{ 0xA34AF381, 0x8F775888 }, |
{ 0x2F48D37B, 0x46D72169 }, |
{ 0x97FC2065, 0xC3685619 }, |
{ 0x48B21FA3, 0x976B4EFB }, |
}; |
|
|
struct { |
Word hi; |
Word lo; |
} mappingEntries[NUM_ENTRIES] = { |
{ 0x00006000, 0x000F8001 }, |
{ 0x00017000, 0x00099001 }, |
{ 0x00004000, 0x0001A001 }, |
{ 0x0000D000, 0x000DB001 }, |
{ 0x00012000, 0x0009C001 }, |
{ 0x00013000, 0x0007D001 }, |
{ 0x00010000, 0x0001E001 }, |
{ 0x00009000, 0x0009F001 }, |
{ 0x0001E000, 0x00000001 }, |
{ 0x0000F000, 0x00021001 }, |
{ 0x0001C000, 0x000E2001 }, |
{ 0x00005000, 0x00023001 }, |
{ 0x0000A000, 0x000C4001 }, |
{ 0x0000B000, 0x00085001 }, |
{ 0x00008000, 0x00006001 }, |
{ 0x00001000, 0x00067001 }, |
{ 0x00016000, 0x000A8001 }, |
{ 0x00007000, 0x000A9001 }, |
{ 0x00014000, 0x0004A001 }, |
{ 0x0001D000, 0x0004B001 }, |
{ 0x00002000, 0x000EC001 }, |
{ 0x00003000, 0x0008D001 }, |
{ 0x00000000, 0x000EE001 }, |
{ 0x00019000, 0x0000F001 }, |
{ 0x0000E000, 0x00050001 }, |
{ 0x0001F000, 0x00011001 }, |
{ 0x0000C000, 0x000B2001 }, |
{ 0x00015000, 0x00093001 }, |
{ 0x0001A000, 0x00074001 }, |
{ 0x0001B000, 0x00075001 }, |
{ 0x00018000, 0x00036001 }, |
{ 0x00011000, 0x000D7001 }, |
}; |
|
|
void flushTLB(void) { |
unsigned int invalPage; |
int i; |
|
invalPage = 0xC0000000; |
for (i = 0; i < NUM_ENTRIES; i++) { |
setTLB(i, invalPage, 0); |
invalPage += (1 << 12); |
} |
} |
|
|
int countTLB(void) { |
int i; |
int n; |
Word hi; |
|
n = 0; |
for (i = 0; i < NUM_ENTRIES; i++) { |
hi = getTLB_HI(i); |
if ((hi & 0xC0000000) != 0xC0000000) { |
n++; |
} |
} |
return n; |
} |
|
|
/**************************************************************/ |
|
|
void indexedReadWriteTest(void) { |
int i; |
Word hi, lo; |
Bool fail; |
|
printf("Indexed R/W test\t\t"); |
for (i = 0; i < NUM_ENTRIES; i++) { |
setTLB(i, randomEntries[i].hi, randomEntries[i].lo); |
} |
fail = false; |
for (i = 0; i < NUM_ENTRIES; i++) { |
hi = getTLB_HI(i); |
lo = getTLB_LO(i); |
if ((hi & 0xFFFFF000) != (randomEntries[i].hi & 0xFFFFF000) || |
(lo & 0x3FFFF003) != (randomEntries[i].lo & 0x3FFFF003)) { |
fail = true; |
} |
} |
if (fail) { |
printf("failed\n"); |
} else { |
printf("ok\n"); |
} |
} |
|
|
void writeRandomTest(void) { |
int i; |
int n; |
int i04, i08, i12, i16; |
int i20, i24, i28; |
|
printf("Write random test\n"); |
flushTLB(); |
i04 = 0; |
i08 = 0; |
i12 = 0; |
i16 = 0; |
i20 = 0; |
i24 = 0; |
i28 = 0; |
for (i = 1; i <= 100 * NUM_ENTRIES; i++) { |
wrtRndTLB(i << 12, i << 12); |
n = countTLB(); |
if (n == 4 && i04 == 0) { |
i04 = i; |
} |
if (n == 8 && i08 == 0) { |
i08 = i; |
} |
if (n == 12 && i12 == 0) { |
i12 = i; |
} |
if (n == 16 && i16 == 0) { |
i16 = i; |
} |
if (n == 20 && i20 == 0) { |
i20 = i; |
} |
if (n == 24 && i24 == 0) { |
i24 = i; |
} |
if (n == 28 && i28 == 0) { |
i28 = i; |
} |
wait(randomEntries[i % NUM_ENTRIES].hi & 0xFF); |
} |
if (i04 > 0) { |
printf(" 4 entries filled after %3d random writes\n", i04); |
} else { |
printf(" 4 entries never filled\n"); |
} |
if (i08 > 0) { |
printf(" 8 entries filled after %3d random writes\n", i08); |
} else { |
printf(" 8 entries never filled\n"); |
} |
if (i12 > 0) { |
printf(" 12 entries filled after %3d random writes\n", i12); |
} else { |
printf(" 12 entries never filled\n"); |
} |
if (i16 > 0) { |
printf(" 16 entries filled after %3d random writes\n", i16); |
} else { |
printf(" 16 entries never filled\n"); |
} |
if (i20 > 0) { |
printf(" 20 entries filled after %3d random writes\n", i20); |
} else { |
printf(" 20 entries never filled\n"); |
} |
if (i24 > 0) { |
printf(" 24 entries filled after %3d random writes\n", i24); |
} else { |
printf(" 24 entries never filled\n"); |
} |
if (i28 > 0) { |
printf(" 28 entries filled after %3d random writes\n", i28); |
} else { |
printf(" 28 entries never filled\n"); |
} |
} |
|
|
void searchTest(void) { |
int i; |
Word index; |
Bool fail; |
|
printf("Search test\t\t\t"); |
for (i = 0; i < NUM_ENTRIES; i++) { |
setTLB(i, randomEntries[i].hi, randomEntries[i].lo); |
} |
fail = false; |
for (i = 0; i < NUM_ENTRIES; i++) { |
index = probeTLB(randomEntries[i].hi); |
if (index != i) { |
fail = true; |
} |
} |
index = probeTLB(0xDEADBEEF); |
if ((index & 0x80000000) == 0) { |
fail = true; |
} |
if (fail) { |
printf("failed\n"); |
} else { |
printf("ok\n"); |
} |
} |
|
|
void mapTest(void) { |
int i; |
Word page, offset; |
Word virt; |
int index; |
Word frame; |
Word phys; |
Word cont; |
Bool fail; |
|
printf("Map test\t\t\t"); |
/* preset each memory word (below 1M) with its physical address */ |
for (i = 0; i < 0x100000; i += 4) { |
*(Word *)(0xC0000000 | i) = i; |
} |
/* preset TLB */ |
for (i = 0; i < NUM_ENTRIES; i++) { |
setTLB(i, mappingEntries[i].hi, mappingEntries[i].lo); |
} |
/* now access memory and check if addresses are mapped correctly */ |
fail = false; |
page = 7; |
offset = 0x123; |
for (i = 0; i < 100000; i++) { |
/* compute pseudo-random virtual word address (page number 0..31) */ |
page = (page * 13 + 1) & 0x1F; |
offset = (offset * 109) & 0x00000FFF; |
virt = (page << 12) | (offset & ~0x3); |
/* lookup frame number in TLB and construct physical word address */ |
index = probeTLB(virt); |
if (index & 0x80000000) { |
fail = true; |
break; |
} |
frame = getTLB_LO(index) & 0xFFFFF000; |
phys = frame | (offset & ~0x3); |
/* access memory by dereferencing the virtual address */ |
cont = *(Word *)virt; |
/* word read should equal physical address */ |
if (cont != phys) { |
fail = true; |
} |
} |
if (fail) { |
printf("failed\n"); |
} else { |
printf("ok\n"); |
} |
} |
|
|
/**************************************************************/ |
|
|
int main(void) { |
printf("\nStart of TLB tests.\n\n"); |
indexedReadWriteTest(); |
writeRandomTest(); |
searchTest(); |
mapTest(); |
printf("\nEnd of TLB tests.\n"); |
while (1) ; |
return 0; |
} |
/eco32/trunk/hwtests/tlbtest/end.s
0,0 → 1,19
; |
; end.s -- end-of-segment labels |
; |
|
.export _ecode |
.export _edata |
.export _ebss |
|
.code |
.align 4 |
_ecode: |
|
.data |
.align 4 |
_edata: |
|
.bss |
.align 4 |
_ebss: |
/eco32/trunk/hwtests/tlbtest/lib.c
0,0 → 1,624
/* |
* lib.c -- the library |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "stdarg.h" |
#include "start.h" |
|
|
/**************************************************************/ |
|
|
/* |
* This is only for debugging. |
* Place a breakpoint at the very beginning of this routine |
* and call it wherever you want to break execution. |
*/ |
void debugBreak(void) { |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the length of a string (without terminating null character). |
*/ |
int strlen(const char *s) { |
const char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
return p - s; |
} |
|
|
/* |
* Compare two strings. |
* Return a number < 0, = 0, or > 0 iff the first string is less |
* than, equal to, or greater than the second one, respectively. |
*/ |
int strcmp(const char *s, const char *t) { |
while (*s == *t) { |
if (*s == '\0') { |
return 0; |
} |
s++; |
t++; |
} |
return *s - *t; |
} |
|
|
/* |
* Copy string t to string s (includes terminating null character). |
*/ |
char *strcpy(char *s, const char *t) { |
char *p; |
|
p = s; |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Append string t to string s. |
*/ |
char *strcat(char *s, const char *t) { |
char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Locate character c in string s. |
*/ |
char *strchr(const char *s, char c) { |
while (*s != c) { |
if (*s == '\0') { |
return NULL; |
} |
s++; |
} |
return (char *) s; |
} |
|
|
/* |
* Extract the next token from the string s, delimited |
* by any character from the delimiter string t. |
*/ |
char *strtok(char *s, const char *t) { |
static char *p; |
char *q; |
|
if (s != NULL) { |
p = s; |
} else { |
p++; |
} |
while (*p != '\0' && strchr(t, *p) != NULL) { |
p++; |
} |
if (*p == '\0') { |
return NULL; |
} |
q = p++; |
while (*p != '\0' && strchr(t, *p) == NULL) { |
p++; |
} |
if (*p != '\0') { |
*p = '\0'; |
} else { |
p--; |
} |
return q; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Determine if a character is 'white space'. |
*/ |
static Bool isspace(char c) { |
Bool res; |
|
switch (c) { |
case ' ': |
case '\f': |
case '\n': |
case '\r': |
case '\t': |
case '\v': |
res = true; |
break; |
default: |
res = false; |
break; |
} |
return res; |
} |
|
|
/* |
* Check for valid digit, and convert to value. |
*/ |
static Bool checkDigit(char c, int base, int *value) { |
if (c >= '0' && c <= '9') { |
*value = c - '0'; |
} else |
if (c >= 'A' && c <= 'Z') { |
*value = c - 'A' + 10; |
} else |
if (c >= 'a' && c <= 'z') { |
*value = c - 'a' + 10; |
} else { |
return false; |
} |
return *value < base; |
} |
|
|
/* |
* Convert initial part of string to unsigned long integer. |
*/ |
unsigned long strtoul(const char *s, char **endp, int base) { |
unsigned long res; |
int sign; |
int digit; |
|
res = 0; |
while (isspace(*s)) { |
s++; |
} |
if (*s == '+') { |
sign = 1; |
s++; |
} else |
if (*s == '-') { |
sign = -1; |
s++; |
} else { |
sign = 1; |
} |
if (base == 0 || base == 16) { |
if (*s == '0' && |
(*(s + 1) == 'x' || *(s + 1) == 'X')) { |
/* base is 16 */ |
s += 2; |
base = 16; |
} else { |
/* base is 0 or 16, but number does not start with "0x" */ |
if (base == 0) { |
if (*s == '0') { |
s++; |
base = 8; |
} else { |
base = 10; |
} |
} else { |
/* take base as is */ |
} |
} |
} else { |
/* take base as is */ |
} |
while (checkDigit(*s, base, &digit)) { |
res *= base; |
res += digit; |
s++; |
} |
if (endp != NULL) { |
*endp = (char *) s; |
} |
return sign * res; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Exchange two array items of a given size. |
*/ |
static void xchg(char *p, char *q, int size) { |
char t; |
|
while (size--) { |
t = *p; |
*p++ = *q; |
*q++ = t; |
} |
} |
|
|
/* |
* This is a recursive version of quicksort. |
*/ |
static void sort(char *l, char *r, int size, |
int (*cmp)(const void *, const void *)) { |
char *i; |
char *j; |
char *x; |
|
i = l; |
j = r; |
x = l + (((r - l) / size) / 2) * size; |
do { |
while (cmp(i, x) < 0) { |
i += size; |
} |
while (cmp(x, j) < 0) { |
j -= size; |
} |
if (i <= j) { |
/* exchange array elements i and j */ |
/* attention: update x if it is one of these */ |
if (x == i) { |
x = j; |
} else |
if (x == j) { |
x = i; |
} |
xchg(i, j, size); |
i += size; |
j -= size; |
} |
} while (i <= j); |
if (l < j) { |
sort(l, j, size, cmp); |
} |
if (i < r) { |
sort(i, r, size, cmp); |
} |
} |
|
|
/* |
* External interface for the quicksort algorithm. |
*/ |
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void*)) { |
sort((char *) base, (char *) base + (n - 1) * size, size, cmp); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Input a character from the console. |
*/ |
char getchar(void) { |
return cin(); |
} |
|
|
/* |
* Output a character on the console. |
* Replace LF by CR/LF. |
*/ |
void putchar(char c) { |
if (c == '\n') { |
cout('\r'); |
} |
cout(c); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in base 10. |
*/ |
static int countPrintn(long n) { |
long a; |
int res; |
|
res = 0; |
if (n < 0) { |
res++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
res += countPrintn(a); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in base 10. |
*/ |
static void *printn(void *(*emit)(void *, char), void *arg, |
int *nchar, long n) { |
long a; |
|
if (n < 0) { |
arg = emit(arg, '-'); |
(*nchar)++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
arg = printn(emit, arg, nchar, a); |
} |
arg = emit(arg, n % 10 + '0'); |
(*nchar)++; |
return arg; |
} |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in a given base. |
*/ |
static int countPrintu(unsigned long n, unsigned long b) { |
unsigned long a; |
int res; |
|
res = 0; |
a = n / b; |
if (a != 0) { |
res += countPrintu(a, b); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in a given base. |
*/ |
static void *printu(void *(*emit)(void *, char), void *arg, |
int *nchar, unsigned long n, unsigned long b, |
Bool upperCase) { |
unsigned long a; |
|
a = n / b; |
if (a != 0) { |
arg = printu(emit, arg, nchar, a, b, upperCase); |
} |
if (upperCase) { |
arg = emit(arg, "0123456789ABCDEF"[n % b]); |
(*nchar)++; |
} else { |
arg = emit(arg, "0123456789abcdef"[n % b]); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* Output a number of filler characters. |
*/ |
static void *fill(void *(*emit)(void *, char), void *arg, |
int *nchar, int numFillers, char filler) { |
while (numFillers-- > 0) { |
arg = emit(arg, filler); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* This function does the real work of formatted printing. |
*/ |
static int doPrintf(void *(*emit)(void *, char), void *arg, |
const char *fmt, va_list ap) { |
int nchar; |
char c; |
int n; |
long ln; |
unsigned int u; |
unsigned long lu; |
char *s; |
Bool negFlag; |
char filler; |
int width, count; |
|
nchar = 0; |
while (1) { |
while ((c = *fmt++) != '%') { |
if (c == '\0') { |
return nchar; |
} |
arg = emit(arg, c); |
nchar++; |
} |
c = *fmt++; |
if (c == '-') { |
negFlag = true; |
c = *fmt++; |
} else { |
negFlag = false; |
} |
if (c == '0') { |
filler = '0'; |
c = *fmt++; |
} else { |
filler = ' '; |
} |
width = 0; |
while (c >= '0' && c <= '9') { |
width *= 10; |
width += c - '0'; |
c = *fmt++; |
} |
if (c == 'd') { |
n = va_arg(ap, int); |
count = countPrintn(n); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, n); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
u = va_arg(ap, int); |
count = countPrintu(u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'l') { |
c = *fmt++; |
if (c == 'd') { |
ln = va_arg(ap, long); |
count = countPrintn(ln); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, ln); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
lu = va_arg(ap, long); |
count = countPrintu(lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else { |
arg = emit(arg, 'l'); |
nchar++; |
arg = emit(arg, c); |
nchar++; |
} |
} else |
if (c == 's') { |
s = va_arg(ap, char *); |
count = strlen(s); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
while ((c = *s++) != '\0') { |
arg = emit(arg, c); |
nchar++; |
} |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'c') { |
c = va_arg(ap, char); |
arg = emit(arg, c); |
nchar++; |
} else { |
arg = emit(arg, c); |
nchar++; |
} |
} |
/* never reached */ |
return 0; |
} |
|
|
/* |
* Emit a character to the console. |
*/ |
static void *emitToConsole(void *dummy, char c) { |
putchar(c); |
return dummy; |
} |
|
|
/* |
* Formatted output with a variable argument list. |
*/ |
static int vprintf(const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToConsole, NULL, fmt, ap); |
return n; |
} |
|
|
/* |
* Formatted output. |
*/ |
int printf(const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vprintf(fmt, ap); |
va_end(ap); |
return n; |
} |
|
|
/* |
* Emit a character to a buffer. |
*/ |
static void *emitToBuffer(void *bufptr, char c) { |
*(char *)bufptr = c; |
return (char *) bufptr + 1; |
} |
|
|
/* |
* Formatted output into a buffer with a variable argument list. |
*/ |
static int vsprintf(char *s, const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToBuffer, s, fmt, ap); |
s[n] = '\0'; |
return n; |
} |
|
|
/* |
* Formatted output into a buffer. |
*/ |
int sprintf(char *s, const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vsprintf(s, fmt, ap); |
va_end(ap); |
return n; |
} |
/eco32/trunk/hwtests/tlbtest/stdarg.h
0,0 → 1,41
/* |
* stdarg.h -- variable argument lists |
*/ |
|
|
#ifndef _STDARG_H_ |
#define _STDARG_H_ |
|
|
typedef char *va_list; |
|
|
static float __va_arg_tmp; |
|
|
#define va_start(list, start) \ |
((void)((list) = (sizeof(start)<4 ? \ |
(char *)((int *)&(start)+1) : (char *)(&(start)+1)))) |
|
#define __va_arg(list, mode, n) \ |
(__typecode(mode)==1 && sizeof(mode)==4 ? \ |
(__va_arg_tmp = *(double *)(&(list += \ |
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ |
*(mode *)&__va_arg_tmp) : \ |
*(mode *)(&(list += \ |
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) |
|
#define _bigendian_va_arg(list, mode, n) \ |
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ |
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ |
__va_arg(list, mode, n)) |
|
#define va_end(list) ((void)0) |
|
#define va_arg(list, mode) \ |
(sizeof(mode)==8 ? \ |
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ |
_bigendian_va_arg(list, mode, 3U)) |
|
|
#endif /* _STDARG_H_ */ |
/eco32/trunk/hwtests/tlbtest/lib.h
0,0 → 1,31
/* |
* lib.h -- the library |
*/ |
|
|
#ifndef _LIB_H_ |
#define _LIB_H_ |
|
|
void debugBreak(void); |
|
int strlen(const char *s); |
int strcmp(const char *s, const char *t); |
char *strcpy(char *s, const char *t); |
char *strcat(char *s, const char *t); |
char *strchr(const char *s, char c); |
char *strtok(char *s, const char *t); |
|
unsigned long strtoul(const char *s, char **endp, int base); |
|
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void *)); |
|
char getchar(void); |
void putchar(char c); |
|
int printf(const char *fmt, ...); |
int sprintf(char *s, const char *fmt, ...); |
|
|
#endif /* _LIB_H_ */ |
/eco32/trunk/hwtests/tlbtest/Makefile
0,0 → 1,27
# |
# Makefile for tlbtest ROM |
# |
|
BUILD = ../../build |
|
TLBTEST_SRC = start.s main.c lib.c serial.s end.s |
|
.PHONY: all install run clean |
|
all: tlbtest.exo |
|
install: tlbtest.exo |
|
tlbtest.exo: tlbtest.bin |
$(BUILD)/bin/bin2exo 0 tlbtest.bin tlbtest.exo |
|
tlbtest.bin: $(TLBTEST_SRC) |
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ |
-Wl-m -Wltlbtest.map -o tlbtest.bin $(TLBTEST_SRC) |
|
run: tlbtest.bin |
$(BUILD)/bin/sim -i -t 1 -r tlbtest.bin |
|
clean: |
rm -f *~ |
rm -f tlbtest.map tlbtest.bin tlbtest.exo |
/eco32/trunk/hwtests/tlbtest/common.h
0,0 → 1,27
/* |
* common.h -- common definitions |
*/ |
|
|
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
|
#define PAGE_SHIFT 12 /* log2 of page size */ |
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ |
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ |
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ |
|
|
typedef enum { false, true } Bool; /* truth values */ |
|
|
typedef unsigned int Word; /* 32 bit quantities */ |
typedef unsigned short Half; /* 16 bit quantities */ |
typedef unsigned char Byte; /* 8 bit quantities */ |
|
|
#define NULL ((void *) 0) |
|
|
#endif /* _COMMON_H_ */ |
/eco32/trunk/hwtests/tlbtest/start.s
0,0 → 1,176
; |
; start.s -- startup and support routines |
; |
|
.set dmapaddr,0xC0000000 ; base of directly mapped addresses |
.set stacktop,0xC0400000 ; monitor stack is at top of memory |
|
.set PSW,0 ; reg # of PSW |
.set TLB_INDEX,1 ; reg # of TLB Index |
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi |
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo |
.set TLB_ENTRIES,32 ; number of TLB entries |
|
;*************************************************************** |
|
.import _ecode |
.import _edata |
.import _ebss |
|
.import serinit |
.import ser0in |
.import ser0out |
|
.import main |
|
.export _bcode |
.export _bdata |
.export _bbss |
|
.export cin |
.export cout |
|
.export getTLB_HI |
.export getTLB_LO |
.export setTLB |
.export wrtRndTLB |
.export probeTLB |
.export wait |
|
;*************************************************************** |
|
.code |
_bcode: |
|
.data |
_bdata: |
|
.bss |
_bbss: |
|
;*************************************************************** |
|
.code |
.align 4 |
|
reset: |
j start |
|
interrupt: |
j interrupt |
|
userMiss: |
j userMiss |
|
;*************************************************************** |
|
.code |
.align 4 |
|
cin: |
j ser0in |
|
cout: |
j ser0out |
|
;*************************************************************** |
|
.code |
.align 4 |
|
start: |
; force CPU into a defined state |
mvts $0,PSW ; disable interrupts and user mode |
|
; initialize TLB |
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries |
add $8,$0,dmapaddr ; by impossible virtual page number |
add $9,$0,$0 |
add $10,$0,TLB_ENTRIES |
tlbloop: |
mvts $8,TLB_ENTRY_HI |
mvts $9,TLB_INDEX |
tbwi |
add $8,$8,0x1000 ; all entries must be different |
add $9,$9,1 |
bne $9,$10,tlbloop |
|
; copy data segment |
add $10,$0,_bdata ; lowest dst addr to be written to |
add $8,$0,_edata ; one above the top dst addr |
sub $9,$8,$10 ; $9 = size of data segment |
add $9,$9,_ecode ; data is waiting right after code |
j cpytest |
cpyloop: |
ldw $11,$9,0 ; src addr in $9 |
stw $11,$8,0 ; dst addr in $8 |
cpytest: |
sub $8,$8,4 ; downward |
sub $9,$9,4 |
bgeu $8,$10,cpyloop |
|
; clear bss segment |
add $8,$0,_bbss ; start with first word of bss |
add $9,$0,_ebss ; this is one above the top |
j clrtest |
clrloop: |
stw $0,$8,0 ; dst addr in $8 |
add $8,$8,4 ; upward |
clrtest: |
bltu $8,$9,clrloop |
|
; now do some useful work |
add $29,$0,stacktop ; setup monitor stack |
jal serinit ; init serial interface |
jal main ; enter command loop |
|
; main should never return |
j start ; just to be sure... |
|
;*************************************************************** |
|
; Word getTLB_HI(int index) |
getTLB_HI: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_HI |
jr $31 |
|
; Word getTLB_LO(int index) |
getTLB_LO: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_LO |
jr $31 |
|
; void setTLB(int index, Word entryHi, Word entryLo) |
setTLB: |
mvts $4,TLB_INDEX |
mvts $5,TLB_ENTRY_HI |
mvts $6,TLB_ENTRY_LO |
tbwi |
jr $31 |
|
; void wrtRndTLB(Word entryHi, Word entryLo) |
wrtRndTLB: |
mvts $4,TLB_ENTRY_HI |
mvts $5,TLB_ENTRY_LO |
tbwr |
jr $31 |
|
; Word probeTLB(Word entryHi) |
probeTLB: |
mvts $4,TLB_ENTRY_HI |
tbs |
mvfs $2,TLB_INDEX |
jr $31 |
|
; void wait(int n) |
wait: |
j wait2 |
wait1: |
add $4,$4,$0 |
sub $4,$4,1 |
wait2: |
bne $4,$0,wait1 |
jr $31 |
/eco32/trunk/hwtests/divtest/mkdivtest.c
0,0 → 1,137
/* |
* mkdivtest.c -- generate divide test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
unsigned mydiv(unsigned x, unsigned y) { |
return (unsigned) ((signed) x / (signed) y); |
} |
|
|
unsigned mydivu(unsigned x, unsigned y) { |
return x / y; |
} |
|
|
unsigned nums[] = { |
0x00000000, |
0x00000001, |
0x00000002, |
0x00000003, |
0x0000FFFC, |
0x0000FFFD, |
0x0000FFFE, |
0x0000FFFF, |
0x00010000, |
0x00010001, |
0x00010002, |
0x00010003, |
0x7FFFFFFC, |
0x7FFFFFFD, |
0x7FFFFFFE, |
0x7FFFFFFF, |
0x80000000, |
0x80000001, |
0x80000002, |
0x80000003, |
0x8000FFFC, |
0x8000FFFD, |
0x8000FFFE, |
0x8000FFFF, |
0x80010000, |
0x80010001, |
0x80010002, |
0x80010003, |
0xFFFFFFFC, |
0xFFFFFFFD, |
0xFFFFFFFE, |
0xFFFFFFFF, |
}; |
|
int snums = sizeof(nums) / sizeof(nums[0]); |
|
|
struct { |
char *name; |
unsigned (*func)(unsigned x, unsigned y); |
} ops[] = { |
{ "div", mydiv }, |
{ "divu", mydivu }, |
}; |
|
int sops = sizeof(ops) / sizeof(ops[0]); |
|
|
int chooseReg(void) { |
int r; |
|
r = (rand() >> 8) % 16; |
return r + 8; |
} |
|
|
void chooseRegs(int *r1, int *r2, int *r3, int *r4) { |
*r1 = chooseReg(); |
do { |
*r2 = chooseReg(); |
} while (*r2 == *r1); |
do { |
*r3 = chooseReg(); |
} while (*r3 == *r2 || *r3 == *r1); |
do { |
*r4 = chooseReg(); |
} while (*r4 == *r3 || *r4 == *r2 || *r4 == *r1); |
} |
|
|
int newLabel(void) { |
static int lbl = 1000; |
return lbl++; |
} |
|
|
int main(void) { |
int i, j, k; |
unsigned res; |
int r1, r2, r3, r4; |
int lbl; |
|
printf("\tadd\t$7,$0,'.'\n"); |
for (i = 0; i < snums; i++) { |
for (j = 0; j < snums; j++) { |
if (nums[j] == 0) { |
continue; |
} |
for (k = 0; k < sops; k++) { |
if (nums[i] == 0x80000000 && nums[j] == 0xFFFFFFFF && k == 0) { |
continue; |
} |
res = ops[k].func(nums[i], nums[j]); |
chooseRegs(&r1, &r2, &r3, &r4); |
lbl = newLabel(); |
printf("\tadd\t$%d,$0,0x%08X\n", r1, nums[i]); |
printf("\tadd\t$%d,$0,0x%08X\n", r2, nums[j]); |
printf("\t%s\t$%d,$%d,$%d\n", ops[k].name, r3, r1, r2); |
printf("\tadd\t$%d,$0,0x%08X\n", r4, res); |
printf("\tbeq\t$%d,$%d,L%d\n", r3, r4, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
} |
} |
} |
printf("out:\n"); |
printf("\tadd\t$6,$0,0xF0300000\n"); |
printf("out1:\n"); |
printf("\tldw\t$5,$6,8\n"); |
printf("\tand\t$5,$5,1\n"); |
printf("\tbeq\t$5,$0,out1\n"); |
printf("\tstw\t$7,$6,12\n"); |
printf("halt:\n"); |
printf("\tj\thalt\n"); |
return 0; |
} |
/eco32/trunk/hwtests/divtest/Makefile
0,0 → 1,33
# |
# Makefile for divtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: divtest.exo |
|
install: divtest.exo |
|
divtest.exo: divtest.bin |
$(BUILD)/bin/bin2exo 0 divtest.bin divtest.exo |
|
divtest.bin: divtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o divtest.bin divtest.o |
|
divtest.o: divtest.s |
$(BUILD)/bin/as -o divtest.o divtest.s |
|
divtest.s: mkdivtest |
./mkdivtest > divtest.s |
|
mkdivtest: mkdivtest.c |
gcc -m32 -g -Wall -o mkdivtest mkdivtest.c |
|
run: divtest.bin |
$(BUILD)/bin/sim -i -t 1 -r divtest.bin |
|
clean: |
rm -f *~ mkdivtest divtest.s divtest.o |
rm -f divtest.bin divtest.exo |
/eco32/trunk/hwtests/remtest/mkremtest.c
0,0 → 1,137
/* |
* mkremtest.c -- generate remainder test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
unsigned myrem(unsigned x, unsigned y) { |
return (unsigned) ((signed) x % (signed) y); |
} |
|
|
unsigned myremu(unsigned x, unsigned y) { |
return x % y; |
} |
|
|
unsigned nums[] = { |
0x00000000, |
0x00000001, |
0x00000002, |
0x00000003, |
0x0000FFFC, |
0x0000FFFD, |
0x0000FFFE, |
0x0000FFFF, |
0x00010000, |
0x00010001, |
0x00010002, |
0x00010003, |
0x7FFFFFFC, |
0x7FFFFFFD, |
0x7FFFFFFE, |
0x7FFFFFFF, |
0x80000000, |
0x80000001, |
0x80000002, |
0x80000003, |
0x8000FFFC, |
0x8000FFFD, |
0x8000FFFE, |
0x8000FFFF, |
0x80010000, |
0x80010001, |
0x80010002, |
0x80010003, |
0xFFFFFFFC, |
0xFFFFFFFD, |
0xFFFFFFFE, |
0xFFFFFFFF, |
}; |
|
int snums = sizeof(nums) / sizeof(nums[0]); |
|
|
struct { |
char *name; |
unsigned (*func)(unsigned x, unsigned y); |
} ops[] = { |
{ "rem", myrem }, |
{ "remu", myremu }, |
}; |
|
int sops = sizeof(ops) / sizeof(ops[0]); |
|
|
int chooseReg(void) { |
int r; |
|
r = (rand() >> 8) % 16; |
return r + 8; |
} |
|
|
void chooseRegs(int *r1, int *r2, int *r3, int *r4) { |
*r1 = chooseReg(); |
do { |
*r2 = chooseReg(); |
} while (*r2 == *r1); |
do { |
*r3 = chooseReg(); |
} while (*r3 == *r2 || *r3 == *r1); |
do { |
*r4 = chooseReg(); |
} while (*r4 == *r3 || *r4 == *r2 || *r4 == *r1); |
} |
|
|
int newLabel(void) { |
static int lbl = 1000; |
return lbl++; |
} |
|
|
int main(void) { |
int i, j, k; |
unsigned res; |
int r1, r2, r3, r4; |
int lbl; |
|
printf("\tadd\t$7,$0,'.'\n"); |
for (i = 0; i < snums; i++) { |
for (j = 0; j < snums; j++) { |
if (nums[j] == 0) { |
continue; |
} |
for (k = 0; k < sops; k++) { |
if (nums[i] == 0x80000000 && nums[j] == 0xFFFFFFFF && k == 0) { |
continue; |
} |
res = ops[k].func(nums[i], nums[j]); |
chooseRegs(&r1, &r2, &r3, &r4); |
lbl = newLabel(); |
printf("\tadd\t$%d,$0,0x%08X\n", r1, nums[i]); |
printf("\tadd\t$%d,$0,0x%08X\n", r2, nums[j]); |
printf("\t%s\t$%d,$%d,$%d\n", ops[k].name, r3, r1, r2); |
printf("\tadd\t$%d,$0,0x%08X\n", r4, res); |
printf("\tbeq\t$%d,$%d,L%d\n", r3, r4, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
} |
} |
} |
printf("out:\n"); |
printf("\tadd\t$6,$0,0xF0300000\n"); |
printf("out1:\n"); |
printf("\tldw\t$5,$6,8\n"); |
printf("\tand\t$5,$5,1\n"); |
printf("\tbeq\t$5,$0,out1\n"); |
printf("\tstw\t$7,$6,12\n"); |
printf("halt:\n"); |
printf("\tj\thalt\n"); |
return 0; |
} |
/eco32/trunk/hwtests/remtest/Makefile
0,0 → 1,33
# |
# Makefile for remtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: remtest.exo |
|
install: remtest.exo |
|
remtest.exo: remtest.bin |
$(BUILD)/bin/bin2exo 0 remtest.bin remtest.exo |
|
remtest.bin: remtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o remtest.bin remtest.o |
|
remtest.o: remtest.s |
$(BUILD)/bin/as -o remtest.o remtest.s |
|
remtest.s: mkremtest |
./mkremtest > remtest.s |
|
mkremtest: mkremtest.c |
gcc -m32 -g -Wall -o mkremtest mkremtest.c |
|
run: remtest.bin |
$(BUILD)/bin/sim -i -t 1 -r remtest.bin |
|
clean: |
rm -f *~ mkremtest remtest.s remtest.o |
rm -f remtest.bin remtest.exo |
/eco32/trunk/hwtests/dsptest/serial.s
0,0 → 1,98
; |
; serial.s -- the serial line interface |
; |
|
;*************************************************************** |
|
.set ser0base,0xF0300000 ; serial line 0 base address |
.set ser1base,0xF0300010 ; serial line 1 base address |
|
.export serinit ; initialize serial interface |
|
.export ser0inchk ; line 0 input check |
.export ser0in ; line 0 input |
.export ser0outchk ; line 0 output check |
.export ser0out ; line 0 output |
|
.export ser1inchk ; line 1 input check |
.export ser1in ; line 1 input |
.export ser1outchk ; line 1 output check |
.export ser1out ; line 1 output |
|
;*************************************************************** |
|
.code |
.align 4 |
|
serinit: |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser0inchk: |
add $8,$0,ser0base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser0in: |
add $8,$0,ser0base |
ser0in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser0in1 |
ldw $2,$8,4 |
jr $31 |
|
ser0outchk: |
add $8,$0,ser0base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser0out: |
add $8,$0,ser0base |
ser0out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser0out1 |
stw $4,$8,12 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser1inchk: |
add $8,$0,ser1base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser1in: |
add $8,$0,ser1base |
ser1in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser1in1 |
ldw $2,$8,4 |
jr $31 |
|
ser1outchk: |
add $8,$0,ser1base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser1out: |
add $8,$0,ser1base |
ser1out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser1out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/dsptest/start.h
0,0 → 1,21
/* |
* start.h -- startup and support routines |
*/ |
|
|
#ifndef _START_H_ |
#define _START_H_ |
|
|
int cin(void); |
void cout(char c); |
|
Word getTLB_HI(int index); |
Word getTLB_LO(int index); |
void setTLB(int index, Word entryHi, Word entryLo); |
void wrtRndTLB(Word entryHi, Word entryLo); |
Word probeTLB(Word entryHi); |
void wait(int n); |
|
|
#endif /* _START_H_ */ |
/eco32/trunk/hwtests/dsptest/main.c
0,0 → 1,27
/* |
* main.c -- the main program |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "start.h" |
|
|
int main(void) { |
int i, j; |
unsigned int attr, ch; |
unsigned int *p; |
|
for (i = 0; i < 16; i++) { |
for (j = 0; j < 16; j++) { |
attr = i * 16 + j; |
ch = (attr << 8) | 0x23; |
p = (unsigned int *) 0xF0100000; |
p += 128 * i + 2 * j; |
*p = ch; |
} |
} |
while (1) ; |
return 0; |
} |
/eco32/trunk/hwtests/dsptest/end.s
0,0 → 1,19
; |
; end.s -- end-of-segment labels |
; |
|
.export _ecode |
.export _edata |
.export _ebss |
|
.code |
.align 4 |
_ecode: |
|
.data |
.align 4 |
_edata: |
|
.bss |
.align 4 |
_ebss: |
/eco32/trunk/hwtests/dsptest/lib.c
0,0 → 1,624
/* |
* lib.c -- the library |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "stdarg.h" |
#include "start.h" |
|
|
/**************************************************************/ |
|
|
/* |
* This is only for debugging. |
* Place a breakpoint at the very beginning of this routine |
* and call it wherever you want to break execution. |
*/ |
void debugBreak(void) { |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the length of a string (without terminating null character). |
*/ |
int strlen(const char *s) { |
const char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
return p - s; |
} |
|
|
/* |
* Compare two strings. |
* Return a number < 0, = 0, or > 0 iff the first string is less |
* than, equal to, or greater than the second one, respectively. |
*/ |
int strcmp(const char *s, const char *t) { |
while (*s == *t) { |
if (*s == '\0') { |
return 0; |
} |
s++; |
t++; |
} |
return *s - *t; |
} |
|
|
/* |
* Copy string t to string s (includes terminating null character). |
*/ |
char *strcpy(char *s, const char *t) { |
char *p; |
|
p = s; |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Append string t to string s. |
*/ |
char *strcat(char *s, const char *t) { |
char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Locate character c in string s. |
*/ |
char *strchr(const char *s, char c) { |
while (*s != c) { |
if (*s == '\0') { |
return NULL; |
} |
s++; |
} |
return (char *) s; |
} |
|
|
/* |
* Extract the next token from the string s, delimited |
* by any character from the delimiter string t. |
*/ |
char *strtok(char *s, const char *t) { |
static char *p; |
char *q; |
|
if (s != NULL) { |
p = s; |
} else { |
p++; |
} |
while (*p != '\0' && strchr(t, *p) != NULL) { |
p++; |
} |
if (*p == '\0') { |
return NULL; |
} |
q = p++; |
while (*p != '\0' && strchr(t, *p) == NULL) { |
p++; |
} |
if (*p != '\0') { |
*p = '\0'; |
} else { |
p--; |
} |
return q; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Determine if a character is 'white space'. |
*/ |
static Bool isspace(char c) { |
Bool res; |
|
switch (c) { |
case ' ': |
case '\f': |
case '\n': |
case '\r': |
case '\t': |
case '\v': |
res = true; |
break; |
default: |
res = false; |
break; |
} |
return res; |
} |
|
|
/* |
* Check for valid digit, and convert to value. |
*/ |
static Bool checkDigit(char c, int base, int *value) { |
if (c >= '0' && c <= '9') { |
*value = c - '0'; |
} else |
if (c >= 'A' && c <= 'Z') { |
*value = c - 'A' + 10; |
} else |
if (c >= 'a' && c <= 'z') { |
*value = c - 'a' + 10; |
} else { |
return false; |
} |
return *value < base; |
} |
|
|
/* |
* Convert initial part of string to unsigned long integer. |
*/ |
unsigned long strtoul(const char *s, char **endp, int base) { |
unsigned long res; |
int sign; |
int digit; |
|
res = 0; |
while (isspace(*s)) { |
s++; |
} |
if (*s == '+') { |
sign = 1; |
s++; |
} else |
if (*s == '-') { |
sign = -1; |
s++; |
} else { |
sign = 1; |
} |
if (base == 0 || base == 16) { |
if (*s == '0' && |
(*(s + 1) == 'x' || *(s + 1) == 'X')) { |
/* base is 16 */ |
s += 2; |
base = 16; |
} else { |
/* base is 0 or 16, but number does not start with "0x" */ |
if (base == 0) { |
if (*s == '0') { |
s++; |
base = 8; |
} else { |
base = 10; |
} |
} else { |
/* take base as is */ |
} |
} |
} else { |
/* take base as is */ |
} |
while (checkDigit(*s, base, &digit)) { |
res *= base; |
res += digit; |
s++; |
} |
if (endp != NULL) { |
*endp = (char *) s; |
} |
return sign * res; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Exchange two array items of a given size. |
*/ |
static void xchg(char *p, char *q, int size) { |
char t; |
|
while (size--) { |
t = *p; |
*p++ = *q; |
*q++ = t; |
} |
} |
|
|
/* |
* This is a recursive version of quicksort. |
*/ |
static void sort(char *l, char *r, int size, |
int (*cmp)(const void *, const void *)) { |
char *i; |
char *j; |
char *x; |
|
i = l; |
j = r; |
x = l + (((r - l) / size) / 2) * size; |
do { |
while (cmp(i, x) < 0) { |
i += size; |
} |
while (cmp(x, j) < 0) { |
j -= size; |
} |
if (i <= j) { |
/* exchange array elements i and j */ |
/* attention: update x if it is one of these */ |
if (x == i) { |
x = j; |
} else |
if (x == j) { |
x = i; |
} |
xchg(i, j, size); |
i += size; |
j -= size; |
} |
} while (i <= j); |
if (l < j) { |
sort(l, j, size, cmp); |
} |
if (i < r) { |
sort(i, r, size, cmp); |
} |
} |
|
|
/* |
* External interface for the quicksort algorithm. |
*/ |
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void*)) { |
sort((char *) base, (char *) base + (n - 1) * size, size, cmp); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Input a character from the console. |
*/ |
char getchar(void) { |
return cin(); |
} |
|
|
/* |
* Output a character on the console. |
* Replace LF by CR/LF. |
*/ |
void putchar(char c) { |
if (c == '\n') { |
cout('\r'); |
} |
cout(c); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in base 10. |
*/ |
static int countPrintn(long n) { |
long a; |
int res; |
|
res = 0; |
if (n < 0) { |
res++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
res += countPrintn(a); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in base 10. |
*/ |
static void *printn(void *(*emit)(void *, char), void *arg, |
int *nchar, long n) { |
long a; |
|
if (n < 0) { |
arg = emit(arg, '-'); |
(*nchar)++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
arg = printn(emit, arg, nchar, a); |
} |
arg = emit(arg, n % 10 + '0'); |
(*nchar)++; |
return arg; |
} |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in a given base. |
*/ |
static int countPrintu(unsigned long n, unsigned long b) { |
unsigned long a; |
int res; |
|
res = 0; |
a = n / b; |
if (a != 0) { |
res += countPrintu(a, b); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in a given base. |
*/ |
static void *printu(void *(*emit)(void *, char), void *arg, |
int *nchar, unsigned long n, unsigned long b, |
Bool upperCase) { |
unsigned long a; |
|
a = n / b; |
if (a != 0) { |
arg = printu(emit, arg, nchar, a, b, upperCase); |
} |
if (upperCase) { |
arg = emit(arg, "0123456789ABCDEF"[n % b]); |
(*nchar)++; |
} else { |
arg = emit(arg, "0123456789abcdef"[n % b]); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* Output a number of filler characters. |
*/ |
static void *fill(void *(*emit)(void *, char), void *arg, |
int *nchar, int numFillers, char filler) { |
while (numFillers-- > 0) { |
arg = emit(arg, filler); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* This function does the real work of formatted printing. |
*/ |
static int doPrintf(void *(*emit)(void *, char), void *arg, |
const char *fmt, va_list ap) { |
int nchar; |
char c; |
int n; |
long ln; |
unsigned int u; |
unsigned long lu; |
char *s; |
Bool negFlag; |
char filler; |
int width, count; |
|
nchar = 0; |
while (1) { |
while ((c = *fmt++) != '%') { |
if (c == '\0') { |
return nchar; |
} |
arg = emit(arg, c); |
nchar++; |
} |
c = *fmt++; |
if (c == '-') { |
negFlag = true; |
c = *fmt++; |
} else { |
negFlag = false; |
} |
if (c == '0') { |
filler = '0'; |
c = *fmt++; |
} else { |
filler = ' '; |
} |
width = 0; |
while (c >= '0' && c <= '9') { |
width *= 10; |
width += c - '0'; |
c = *fmt++; |
} |
if (c == 'd') { |
n = va_arg(ap, int); |
count = countPrintn(n); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, n); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
u = va_arg(ap, int); |
count = countPrintu(u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'l') { |
c = *fmt++; |
if (c == 'd') { |
ln = va_arg(ap, long); |
count = countPrintn(ln); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, ln); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
lu = va_arg(ap, long); |
count = countPrintu(lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else { |
arg = emit(arg, 'l'); |
nchar++; |
arg = emit(arg, c); |
nchar++; |
} |
} else |
if (c == 's') { |
s = va_arg(ap, char *); |
count = strlen(s); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
while ((c = *s++) != '\0') { |
arg = emit(arg, c); |
nchar++; |
} |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'c') { |
c = va_arg(ap, char); |
arg = emit(arg, c); |
nchar++; |
} else { |
arg = emit(arg, c); |
nchar++; |
} |
} |
/* never reached */ |
return 0; |
} |
|
|
/* |
* Emit a character to the console. |
*/ |
static void *emitToConsole(void *dummy, char c) { |
putchar(c); |
return dummy; |
} |
|
|
/* |
* Formatted output with a variable argument list. |
*/ |
static int vprintf(const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToConsole, NULL, fmt, ap); |
return n; |
} |
|
|
/* |
* Formatted output. |
*/ |
int printf(const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vprintf(fmt, ap); |
va_end(ap); |
return n; |
} |
|
|
/* |
* Emit a character to a buffer. |
*/ |
static void *emitToBuffer(void *bufptr, char c) { |
*(char *)bufptr = c; |
return (char *) bufptr + 1; |
} |
|
|
/* |
* Formatted output into a buffer with a variable argument list. |
*/ |
static int vsprintf(char *s, const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToBuffer, s, fmt, ap); |
s[n] = '\0'; |
return n; |
} |
|
|
/* |
* Formatted output into a buffer. |
*/ |
int sprintf(char *s, const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vsprintf(s, fmt, ap); |
va_end(ap); |
return n; |
} |
/eco32/trunk/hwtests/dsptest/stdarg.h
0,0 → 1,41
/* |
* stdarg.h -- variable argument lists |
*/ |
|
|
#ifndef _STDARG_H_ |
#define _STDARG_H_ |
|
|
typedef char *va_list; |
|
|
static float __va_arg_tmp; |
|
|
#define va_start(list, start) \ |
((void)((list) = (sizeof(start)<4 ? \ |
(char *)((int *)&(start)+1) : (char *)(&(start)+1)))) |
|
#define __va_arg(list, mode, n) \ |
(__typecode(mode)==1 && sizeof(mode)==4 ? \ |
(__va_arg_tmp = *(double *)(&(list += \ |
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ |
*(mode *)&__va_arg_tmp) : \ |
*(mode *)(&(list += \ |
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) |
|
#define _bigendian_va_arg(list, mode, n) \ |
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ |
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ |
__va_arg(list, mode, n)) |
|
#define va_end(list) ((void)0) |
|
#define va_arg(list, mode) \ |
(sizeof(mode)==8 ? \ |
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ |
_bigendian_va_arg(list, mode, 3U)) |
|
|
#endif /* _STDARG_H_ */ |
/eco32/trunk/hwtests/dsptest/lib.h
0,0 → 1,31
/* |
* lib.h -- the library |
*/ |
|
|
#ifndef _LIB_H_ |
#define _LIB_H_ |
|
|
void debugBreak(void); |
|
int strlen(const char *s); |
int strcmp(const char *s, const char *t); |
char *strcpy(char *s, const char *t); |
char *strcat(char *s, const char *t); |
char *strchr(const char *s, char c); |
char *strtok(char *s, const char *t); |
|
unsigned long strtoul(const char *s, char **endp, int base); |
|
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void *)); |
|
char getchar(void); |
void putchar(char c); |
|
int printf(const char *fmt, ...); |
int sprintf(char *s, const char *fmt, ...); |
|
|
#endif /* _LIB_H_ */ |
/eco32/trunk/hwtests/dsptest/Makefile
0,0 → 1,27
# |
# Makefile for dsptest ROM |
# |
|
BUILD = ../../build |
|
DSPTEST_SRC = start.s main.c lib.c serial.s end.s |
|
.PHONY: all install run clean |
|
all: dsptest.exo |
|
install: dsptest.exo |
|
dsptest.exo: dsptest.bin |
$(BUILD)/bin/bin2exo 0 dsptest.bin dsptest.exo |
|
dsptest.bin: $(DSPTEST_SRC) |
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ |
-Wl-m -Wldsptest.map -o dsptest.bin $(DSPTEST_SRC) |
|
run: dsptest.bin |
$(BUILD)/bin/sim -i -c -r dsptest.bin |
|
clean: |
rm -f *~ |
rm -f dsptest.map dsptest.bin dsptest.exo |
/eco32/trunk/hwtests/dsptest/common.h
0,0 → 1,27
/* |
* common.h -- common definitions |
*/ |
|
|
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
|
#define PAGE_SHIFT 12 /* log2 of page size */ |
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ |
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ |
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ |
|
|
typedef enum { false, true } Bool; /* truth values */ |
|
|
typedef unsigned int Word; /* 32 bit quantities */ |
typedef unsigned short Half; /* 16 bit quantities */ |
typedef unsigned char Byte; /* 8 bit quantities */ |
|
|
#define NULL ((void *) 0) |
|
|
#endif /* _COMMON_H_ */ |
/eco32/trunk/hwtests/dsptest/start.s
0,0 → 1,176
; |
; start.s -- startup and support routines |
; |
|
.set dmapaddr,0xC0000000 ; base of directly mapped addresses |
.set stacktop,0xC0400000 ; monitor stack is at top of memory |
|
.set PSW,0 ; reg # of PSW |
.set TLB_INDEX,1 ; reg # of TLB Index |
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi |
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo |
.set TLB_ENTRIES,32 ; number of TLB entries |
|
;*************************************************************** |
|
.import _ecode |
.import _edata |
.import _ebss |
|
.import serinit |
.import ser0in |
.import ser0out |
|
.import main |
|
.export _bcode |
.export _bdata |
.export _bbss |
|
.export cin |
.export cout |
|
.export getTLB_HI |
.export getTLB_LO |
.export setTLB |
.export wrtRndTLB |
.export probeTLB |
.export wait |
|
;*************************************************************** |
|
.code |
_bcode: |
|
.data |
_bdata: |
|
.bss |
_bbss: |
|
;*************************************************************** |
|
.code |
.align 4 |
|
reset: |
j start |
|
interrupt: |
j interrupt |
|
userMiss: |
j userMiss |
|
;*************************************************************** |
|
.code |
.align 4 |
|
cin: |
j ser0in |
|
cout: |
j ser0out |
|
;*************************************************************** |
|
.code |
.align 4 |
|
start: |
; force CPU into a defined state |
mvts $0,PSW ; disable interrupts and user mode |
|
; initialize TLB |
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries |
add $8,$0,dmapaddr ; by impossible virtual page number |
add $9,$0,$0 |
add $10,$0,TLB_ENTRIES |
tlbloop: |
mvts $8,TLB_ENTRY_HI |
mvts $9,TLB_INDEX |
tbwi |
add $8,$8,0x1000 ; all entries must be different |
add $9,$9,1 |
bne $9,$10,tlbloop |
|
; copy data segment |
add $10,$0,_bdata ; lowest dst addr to be written to |
add $8,$0,_edata ; one above the top dst addr |
sub $9,$8,$10 ; $9 = size of data segment |
add $9,$9,_ecode ; data is waiting right after code |
j cpytest |
cpyloop: |
ldw $11,$9,0 ; src addr in $9 |
stw $11,$8,0 ; dst addr in $8 |
cpytest: |
sub $8,$8,4 ; downward |
sub $9,$9,4 |
bgeu $8,$10,cpyloop |
|
; clear bss segment |
add $8,$0,_bbss ; start with first word of bss |
add $9,$0,_ebss ; this is one above the top |
j clrtest |
clrloop: |
stw $0,$8,0 ; dst addr in $8 |
add $8,$8,4 ; upward |
clrtest: |
bltu $8,$9,clrloop |
|
; now do some useful work |
add $29,$0,stacktop ; setup monitor stack |
jal serinit ; init serial interface |
jal main ; enter command loop |
|
; main should never return |
j start ; just to be sure... |
|
;*************************************************************** |
|
; Word getTLB_HI(int index) |
getTLB_HI: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_HI |
jr $31 |
|
; Word getTLB_LO(int index) |
getTLB_LO: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_LO |
jr $31 |
|
; void setTLB(int index, Word entryHi, Word entryLo) |
setTLB: |
mvts $4,TLB_INDEX |
mvts $5,TLB_ENTRY_HI |
mvts $6,TLB_ENTRY_LO |
tbwi |
jr $31 |
|
; void wrtRndTLB(Word entryHi, Word entryLo) |
wrtRndTLB: |
mvts $4,TLB_ENTRY_HI |
mvts $5,TLB_ENTRY_LO |
tbwr |
jr $31 |
|
; Word probeTLB(Word entryHi) |
probeTLB: |
mvts $4,TLB_ENTRY_HI |
tbs |
mvfs $2,TLB_INDEX |
jr $31 |
|
; void wait(int n) |
wait: |
j wait2 |
wait1: |
add $4,$4,$0 |
sub $4,$4,1 |
wait2: |
bne $4,$0,wait1 |
jr $31 |
/eco32/trunk/hwtests/jalrtest/jalrtest.s
0,0 → 1,36
; |
; jalrtest.s -- test the special case 'jalr $31' |
; |
|
; One of the following 4 possibilities is displayed: |
; 0 = jump not executed, return address not stored in $31 |
; 1 = jump was executed, return address not stored in $31 |
; 2 = jump not executed, return address stored in $31 |
; 3 = jump was executed, return address stored in $31 |
|
.set io_base,0xF0300000 |
|
add $16,$0,x |
add $31,$0,$16 |
jalr $31 |
add $4,$0,0 |
j y |
x: |
add $4,$0,1 |
y: |
beq $31,$16,z |
add $4,$4,2 |
z: |
add $4,$4,0x30 |
jal out |
halt: |
j halt |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/jalrtest/Makefile
0,0 → 1,27
# |
# Makefile for jalrtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: jalrtest.exo |
|
install: jalrtest.exo |
|
jalrtest.exo: jalrtest.bin |
$(BUILD)/bin/bin2exo 0 jalrtest.bin jalrtest.exo |
|
jalrtest.bin: jalrtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o jalrtest.bin jalrtest.o |
|
jalrtest.o: jalrtest.s |
$(BUILD)/bin/as -o jalrtest.o jalrtest.s |
|
run: jalrtest.bin |
$(BUILD)/bin/sim -i -t 1 -r jalrtest.bin |
|
clean: |
rm -f *~ jalrtest.o jalrtest.bin jalrtest.exo |
/eco32/trunk/hwtests/xcptest/serial.s
0,0 → 1,98
; |
; serial.s -- the serial line interface |
; |
|
;*************************************************************** |
|
.set ser0base,0xF0300000 ; serial line 0 base address |
.set ser1base,0xF0300010 ; serial line 1 base address |
|
.export serinit ; initialize serial interface |
|
.export ser0inchk ; line 0 input check |
.export ser0in ; line 0 input |
.export ser0outchk ; line 0 output check |
.export ser0out ; line 0 output |
|
.export ser1inchk ; line 1 input check |
.export ser1in ; line 1 input |
.export ser1outchk ; line 1 output check |
.export ser1out ; line 1 output |
|
;*************************************************************** |
|
.code |
.align 4 |
|
serinit: |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser0inchk: |
add $8,$0,ser0base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser0in: |
add $8,$0,ser0base |
ser0in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser0in1 |
ldw $2,$8,4 |
jr $31 |
|
ser0outchk: |
add $8,$0,ser0base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser0out: |
add $8,$0,ser0base |
ser0out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser0out1 |
stw $4,$8,12 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser1inchk: |
add $8,$0,ser1base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser1in: |
add $8,$0,ser1base |
ser1in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser1in1 |
ldw $2,$8,4 |
jr $31 |
|
ser1outchk: |
add $8,$0,ser1base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser1out: |
add $8,$0,ser1base |
ser1out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser1out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/xcptest/start.h
0,0 → 1,102
/* |
* start.h -- startup and support routines |
*/ |
|
|
#ifndef _START_H_ |
#define _START_H_ |
|
|
typedef struct { |
Word reg[32]; /* general purpose registers */ |
Word psw; /* PSW */ |
Word tlbIndex; /* TLB index register */ |
Word tlbHi; /* TLB EntryHi register */ |
Word tlbLo; /* TLB EntryLo register */ |
} InterruptContext; |
|
|
int cin(void); |
void cout(char c); |
|
void xtest1(InterruptContext *icp); |
extern Word xtest1x; |
void xtest2(InterruptContext *icp); |
extern Word xtest2x; |
void xtest3(InterruptContext *icp); |
extern Word xtest3x; |
void xtest4(InterruptContext *icp); |
extern Word xtest4x; |
void xtest5(InterruptContext *icp); |
extern Word xtest5x; |
void xtest6(InterruptContext *icp); |
extern Word xtest6x; |
void xtest7(InterruptContext *icp); |
extern Word xtest7x; |
void xtest8(InterruptContext *icp); |
extern Word xtest8x; |
void xtest9(InterruptContext *icp); |
extern Word xtest9x; |
void xtest10(InterruptContext *icp); |
extern Word xtest10x; |
void xtest11(InterruptContext *icp); |
extern Word xtest11x; |
void xtest12(InterruptContext *icp); |
extern Word xtest12x; |
void xtest13(InterruptContext *icp); |
extern Word xtest13x; |
void xtest14(InterruptContext *icp); |
extern Word xtest14x; |
void xtest15(InterruptContext *icp); |
extern Word xtest15x; |
void xtest16(InterruptContext *icp); |
extern Word xtest16x; |
void xtest17(InterruptContext *icp); |
extern Word xtest17x; |
void xtest18(InterruptContext *icp); |
extern Word xtest18x; |
void xtest19(InterruptContext *icp); |
extern Word xtest19x; |
void xtest20(InterruptContext *icp); |
extern Word xtest20x; |
void xtest21(InterruptContext *icp); |
extern Word xtest21x; |
void xtest22(InterruptContext *icp); |
extern Word xtest22x; |
void xtest23(InterruptContext *icp); |
extern Word xtest23x; |
void xtest24(InterruptContext *icp); |
extern Word xtest24x; |
void xtest25(InterruptContext *icp); |
extern Word xtest25x; |
void xtest26(InterruptContext *icp); |
extern Word xtest26x; |
void xtest27(InterruptContext *icp); |
extern Word xtest27x; |
void xtest28(InterruptContext *icp); |
extern Word xtest28x; |
void xtest29(InterruptContext *icp); |
extern Word xtest29x; |
void xtest30(InterruptContext *icp); |
extern Word xtest30x; |
void xtest31(InterruptContext *icp); |
extern Word xtest31x; |
void xtest32(InterruptContext *icp); |
extern Word xtest32x; |
void xtest33(InterruptContext *icp); |
extern Word xtest33x; |
void xtest34(InterruptContext *icp); |
extern Word xtest34x; |
void xtest35(InterruptContext *icp); |
extern Word xtest35x; |
void xtest36(InterruptContext *icp); |
extern Word xtest36x; |
void xtest37(InterruptContext *icp); |
extern Word xtest37x; |
|
Word getTLB_HI(int index); |
Word getTLB_LO(int index); |
void setTLB(int index, Word entryHi, Word entryLo); |
|
|
#endif /* _START_H_ */ |
/eco32/trunk/hwtests/xcptest/main.c
0,0 → 1,272
/* |
* main.c -- the main program |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "start.h" |
|
|
Word userMissTaken; |
|
|
static InterruptContext initial = { |
/* regs */ |
0x00000011, 0x11111112, 0x22222213, 0x33333314, |
0x44444415, 0x55555516, 0x66666617, 0x77777718, |
0x88888819, 0x9999991A, 0xAAAAAA1B, 0xBBBBBB1C, |
0xCCCCCC1D, 0xDDDDDD1E, 0xEEEEEE1F, 0xFFFFFF10, |
0x00000021, 0x11111122, 0x22222223, 0x33333324, |
0x44444425, 0x55555526, 0x66666627, 0x77777728, |
0x88888829, 0x9999992A, 0xAAAAAA2B, 0xBBBBBB2C, |
0xCCCCCC2D, 0xDDDDDD2E, 0xEEEEEE2F, 0xFFFFFF20, |
/* PSW */ |
0x03FF5678, |
/* TLB index */ |
0x87654321, |
/* TLB EntryHi */ |
0x9ABCDEF0, |
/* TLB EntryLo */ |
0x0FEDCBA9 |
}; |
|
static InterruptContext ic; |
|
|
static char *errorMessage[] = { |
/* 0 */ "no error", |
/* 1 */ "general register clobbered", |
/* 2 */ "write to register 0 succeeded", |
/* 3 */ "locus of exception incorrect", |
/* 4 */ "TLB register clobbered", |
/* 5 */ "vector bit incorrect", |
/* 6 */ "user mode bits incorrect", |
/* 7 */ "interrupt enable bits incorrect", |
/* 8 */ "wrong exception number", |
/* 9 */ "interrupt mask bits clobbered", |
/* 10 */ "ISR entry was 'user miss'", |
/* 11 */ "ISR entry was not 'user miss'", |
}; |
|
|
static void flushTLB(void) { |
Word invalPage; |
int i; |
|
invalPage = 0xC0000000; |
for (i = 0; i < 32; i++) { |
setTLB(i, invalPage, 0); |
invalPage += (1 << 12); |
} |
} |
|
|
static void check(unsigned int *res1, unsigned int *res2, |
Word expectedEntryHi) { |
int i; |
|
*res1 = 0; |
*res2 = 0; |
for (i = 0; i < 32; i++) { |
if (ic.reg[i] != initial.reg[i]) { |
*res1 |= (1 << i); |
} |
} |
if ((ic.psw & 0x0FFFFFFF) != (initial.psw & 0x0FFFFFFF)) { |
*res2 |= (1 << 0); |
} |
if ((ic.tlbIndex & 0x0000001F) != (initial.tlbIndex & 0x0000001F)) { |
*res2 |= (1 << 1); |
} |
if ((ic.tlbHi & 0xFFFFF000) != (expectedEntryHi & 0xFFFFF000)) { |
*res2 |= (1 << 2); |
} |
if ((ic.tlbLo & 0x3FFFF003) != (initial.tlbLo & 0x3FFFF003)) { |
*res2 |= (1 << 3); |
} |
} |
|
|
static int execTest(void (*run)(InterruptContext *icp), |
Word *expectedLocus, |
int expectedException, |
Bool execInUserMode, |
Bool clobberEntryHi, |
Bool shouldTakeUserMiss) { |
unsigned int res1, res2; |
int result; |
Word *locus; |
|
if (execInUserMode) { |
initial.psw |= 1 << 26; |
} |
ic = initial; |
flushTLB(); |
userMissTaken = 0xFFFFFFFF; |
(*run)(&ic); |
if (execInUserMode) { |
locus = (Word *) (0xC0000000 | ic.reg[30]); |
} else { |
locus = (Word *) ic.reg[30]; |
} |
if (!clobberEntryHi) { |
check(&res1, &res2, initial.tlbHi); |
} else { |
if (shouldTakeUserMiss) { |
check(&res1, &res2, initial.reg[3]); |
} else { |
check(&res1, &res2, initial.reg[11]); |
} |
} |
result = 0; |
if (((ic.psw >> 16) & 0x1F) != expectedException) { |
result = 8; |
} else |
if (!shouldTakeUserMiss && userMissTaken != 0) { |
result = 10; |
} else |
if (shouldTakeUserMiss && userMissTaken != (Word) &userMissTaken) { |
result = 11; |
} else |
if (res1 != 0x50000001) { |
result = 1; |
} else |
if (ic.reg[0] != 0x00000000) { |
result = 2; |
} else |
if (locus != expectedLocus) { |
result = 3; |
} else |
if (res2 != 0x00000001) { |
result = 4; |
} else |
if (((ic.psw >> 27) & 0x01) != ((initial.psw >> 27) & 0x01)) { |
result = 5; |
} else |
if (((ic.psw >> 24) & 0x07) != ((initial.psw >> 25) & 0x03)) { |
result = 6; |
} else |
if (((ic.psw >> 21) & 0x07) != ((initial.psw >> 22) & 0x03)) { |
result = 7; |
} else |
if (((ic.psw >> 0) & 0xFF) != ((initial.psw >> 0) & 0xFF)) { |
result = 9; |
} |
if (execInUserMode) { |
initial.psw &= ~(1 << 26); |
} |
return result; |
} |
|
|
static struct { |
char *name; |
void (*run)(InterruptContext *icp); |
Word *locus; |
int exception; |
Bool execInUserMode; |
Bool clobberEntryHi; |
Bool shouldTakeUserMiss; |
} tests[] = { |
{ "Trap instr test:\t\t\t", |
xtest1, &xtest1x, 20, false, false, false }, |
{ "Illegal instr test:\t\t\t", |
xtest2, &xtest2x, 17, false, false, false }, |
{ "Divide instr test 1 (div):\t\t", |
xtest3, &xtest3x, 19, false, false, false }, |
{ "Divide instr test 2 (divi):\t\t", |
xtest4, &xtest4x, 19, false, false, false }, |
{ "Divide instr test 3 (divu):\t\t", |
xtest5, &xtest5x, 19, false, false, false }, |
{ "Divide instr test 4 (divui):\t\t", |
xtest6, &xtest6x, 19, false, false, false }, |
{ "Divide instr test 5 (rem):\t\t", |
xtest7, &xtest7x, 19, false, false, false }, |
{ "Divide instr test 6 (remi):\t\t", |
xtest8, &xtest8x, 19, false, false, false }, |
{ "Divide instr test 7 (remu):\t\t", |
xtest9, &xtest9x, 19, false, false, false }, |
{ "Divide instr test 8 (remui):\t\t", |
xtest10, &xtest10x, 19, false, false, false }, |
{ "Bus timeout test 1 (fetch):\t\t", |
xtest11, &xtest11x, 16, false, false, false }, |
{ "Bus timeout test 2 (load):\t\t", |
xtest12, &xtest12x, 16, false, false, false }, |
{ "Bus timeout test 3 (store):\t\t", |
xtest13, &xtest13x, 16, false, false, false }, |
{ "Privileged instr test 1 (rfx):\t\t", |
xtest14, &xtest14x, 18, true, false, false }, |
{ "Privileged instr test 2 (mvts):\t\t", |
xtest15, &xtest15x, 18, true, false, false }, |
{ "Privileged instr test 3 (tb..):\t\t", |
xtest16, &xtest16x, 18, true, false, false }, |
{ "Privileged address test 1 (fetch):\t", |
xtest17, &xtest17x, 25, true, false, false }, |
{ "Privileged address test 2 (load):\t", |
xtest18, &xtest18x, 25, true, false, false }, |
{ "Privileged address test 3 (store):\t", |
xtest19, &xtest19x, 25, true, false, false }, |
{ "Illegal address test 1 (fetch):\t\t", |
xtest20, &xtest20x, 24, false, false, false }, |
{ "Illegal address test 2 (fetch):\t\t", |
xtest21, &xtest21x, 24, false, false, false }, |
{ "Illegal address test 3 (ldw):\t\t", |
xtest22, &xtest22x, 24, false, false, false }, |
{ "Illegal address test 4 (ldw):\t\t", |
xtest23, &xtest23x, 24, false, false, false }, |
{ "Illegal address test 5 (ldh):\t\t", |
xtest24, &xtest24x, 24, false, false, false }, |
{ "Illegal address test 6 (stw):\t\t", |
xtest25, &xtest25x, 24, false, false, false }, |
{ "Illegal address test 7 (stw):\t\t", |
xtest26, &xtest26x, 24, false, false, false }, |
{ "Illegal address test 8 (sth):\t\t", |
xtest27, &xtest27x, 24, false, false, false }, |
{ "TLB user miss test 1 (fetch):\t\t", |
xtest28, &xtest28x, 21, false, true, true }, |
{ "TLB user miss test 2 (load):\t\t", |
xtest29, &xtest29x, 21, false, true, true }, |
{ "TLB user miss test 3 (store):\t\t", |
xtest30, &xtest30x, 21, false, true, true }, |
{ "TLB kernel miss test 1 (fetch):\t\t", |
xtest31, &xtest31x, 21, false, true, false }, |
{ "TLB kernel miss test 2 (load):\t\t", |
xtest32, &xtest32x, 21, false, true, false }, |
{ "TLB kernel miss test 3 (store):\t\t", |
xtest33, &xtest33x, 21, false, true, false }, |
{ "TLB invalid test 1 (fetch):\t\t", |
xtest34, &xtest34x, 23, false, true, false }, |
{ "TLB invalid test 2 (load):\t\t", |
xtest35, &xtest35x, 23, false, true, false }, |
{ "TLB invalid test 3 (store):\t\t", |
xtest36, &xtest36x, 23, false, true, false }, |
{ "TLB wrtprot test (store):\t\t", |
xtest37, &xtest37x, 22, false, true, false }, |
}; |
|
|
int main(void) { |
int i; |
int result; |
|
printf("\nStart of exception tests.\n\n"); |
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { |
printf("%s", tests[i].name); |
result = execTest(tests[i].run, |
tests[i].locus, |
tests[i].exception, |
tests[i].execInUserMode, |
tests[i].clobberEntryHi, |
tests[i].shouldTakeUserMiss); |
if (result == 0) { |
printf("ok"); |
} else { |
printf("failed (%s)", errorMessage[result]); |
} |
printf("\n"); |
} |
printf("\nEnd of exception tests.\n"); |
while (1) ; |
return 0; |
} |
/eco32/trunk/hwtests/xcptest/end.s
0,0 → 1,19
; |
; end.s -- end-of-segment labels |
; |
|
.export _ecode |
.export _edata |
.export _ebss |
|
.code |
.align 4 |
_ecode: |
|
.data |
.align 4 |
_edata: |
|
.bss |
.align 4 |
_ebss: |
/eco32/trunk/hwtests/xcptest/lib.c
0,0 → 1,636
/* |
* lib.c -- the library |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "stdarg.h" |
#include "start.h" |
|
|
/**************************************************************/ |
|
|
/* |
* This is only for debugging. |
* Place a breakpoint at the very beginning of this routine |
* and call it wherever you want to break execution. |
*/ |
void debugBreak(void) { |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the length of a string (without terminating null character). |
*/ |
int strlen(const char *s) { |
const char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
return p - s; |
} |
|
|
/* |
* Compare two strings. |
* Return a number < 0, = 0, or > 0 iff the first string is less |
* than, equal to, or greater than the second one, respectively. |
*/ |
int strcmp(const char *s, const char *t) { |
while (*s == *t) { |
if (*s == '\0') { |
return 0; |
} |
s++; |
t++; |
} |
return *s - *t; |
} |
|
|
/* |
* Copy string t to string s (includes terminating null character). |
*/ |
char *strcpy(char *s, const char *t) { |
char *p; |
|
p = s; |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Append string t to string s. |
*/ |
char *strcat(char *s, const char *t) { |
char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Locate character c in string s. |
*/ |
char *strchr(const char *s, char c) { |
while (*s != c) { |
if (*s == '\0') { |
return NULL; |
} |
s++; |
} |
return (char *) s; |
} |
|
|
/* |
* Extract the next token from the string s, delimited |
* by any character from the delimiter string t. |
*/ |
char *strtok(char *s, const char *t) { |
static char *p; |
char *q; |
|
if (s != NULL) { |
p = s; |
} else { |
p++; |
} |
while (*p != '\0' && strchr(t, *p) != NULL) { |
p++; |
} |
if (*p == '\0') { |
return NULL; |
} |
q = p++; |
while (*p != '\0' && strchr(t, *p) == NULL) { |
p++; |
} |
if (*p != '\0') { |
*p = '\0'; |
} else { |
p--; |
} |
return q; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Determine if a character is 'white space'. |
*/ |
static Bool isspace(char c) { |
Bool res; |
|
switch (c) { |
case ' ': |
case '\f': |
case '\n': |
case '\r': |
case '\t': |
case '\v': |
res = true; |
break; |
default: |
res = false; |
break; |
} |
return res; |
} |
|
|
/* |
* Check for valid digit, and convert to value. |
*/ |
static Bool checkDigit(char c, int base, int *value) { |
if (c >= '0' && c <= '9') { |
*value = c - '0'; |
} else |
if (c >= 'A' && c <= 'Z') { |
*value = c - 'A' + 10; |
} else |
if (c >= 'a' && c <= 'z') { |
*value = c - 'a' + 10; |
} else { |
return false; |
} |
return *value < base; |
} |
|
|
/* |
* Convert initial part of string to unsigned long integer. |
*/ |
unsigned long strtoul(const char *s, char **endp, int base) { |
unsigned long res; |
int sign; |
int digit; |
|
res = 0; |
while (isspace(*s)) { |
s++; |
} |
if (*s == '+') { |
sign = 1; |
s++; |
} else |
if (*s == '-') { |
sign = -1; |
s++; |
} else { |
sign = 1; |
} |
if (base == 0 || base == 16) { |
if (*s == '0' && |
(*(s + 1) == 'x' || *(s + 1) == 'X')) { |
/* base is 16 */ |
s += 2; |
base = 16; |
} else { |
/* base is 0 or 16, but number does not start with "0x" */ |
if (base == 0) { |
if (*s == '0') { |
s++; |
base = 8; |
} else { |
base = 10; |
} |
} else { |
/* take base as is */ |
} |
} |
} else { |
/* take base as is */ |
} |
while (checkDigit(*s, base, &digit)) { |
res *= base; |
res += digit; |
s++; |
} |
if (endp != NULL) { |
*endp = (char *) s; |
} |
return sign * res; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Exchange two array items of a given size. |
*/ |
static void xchg(char *p, char *q, int size) { |
char t; |
|
while (size--) { |
t = *p; |
*p++ = *q; |
*q++ = t; |
} |
} |
|
|
/* |
* This is a recursive version of quicksort. |
*/ |
static void sort(char *l, char *r, int size, |
int (*cmp)(const void *, const void *)) { |
char *i; |
char *j; |
char *x; |
|
i = l; |
j = r; |
x = l + (((r - l) / size) / 2) * size; |
do { |
while (cmp(i, x) < 0) { |
i += size; |
} |
while (cmp(x, j) < 0) { |
j -= size; |
} |
if (i <= j) { |
/* exchange array elements i and j */ |
/* attention: update x if it is one of these */ |
if (x == i) { |
x = j; |
} else |
if (x == j) { |
x = i; |
} |
xchg(i, j, size); |
i += size; |
j -= size; |
} |
} while (i <= j); |
if (l < j) { |
sort(l, j, size, cmp); |
} |
if (i < r) { |
sort(i, r, size, cmp); |
} |
} |
|
|
/* |
* External interface for the quicksort algorithm. |
*/ |
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void*)) { |
sort((char *) base, (char *) base + (n - 1) * size, size, cmp); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Input a character from the console. |
*/ |
char getchar(void) { |
return cin(); |
} |
|
|
/* |
* Output a character on the console. |
* Replace LF by CR/LF. |
*/ |
void putchar(char c) { |
if (c == '\n') { |
cout('\r'); |
} |
cout(c); |
} |
|
|
/* |
* Output a string on the console. |
* Replace LF by CR/LF. |
*/ |
void puts(const char *s) { |
while (*s != '\0') { |
putchar(*s); |
s++; |
} |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in base 10. |
*/ |
static int countPrintn(long n) { |
long a; |
int res; |
|
res = 0; |
if (n < 0) { |
res++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
res += countPrintn(a); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in base 10. |
*/ |
static void *printn(void *(*emit)(void *, char), void *arg, |
int *nchar, long n) { |
long a; |
|
if (n < 0) { |
arg = emit(arg, '-'); |
(*nchar)++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
arg = printn(emit, arg, nchar, a); |
} |
arg = emit(arg, n % 10 + '0'); |
(*nchar)++; |
return arg; |
} |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in a given base. |
*/ |
static int countPrintu(unsigned long n, unsigned long b) { |
unsigned long a; |
int res; |
|
res = 0; |
a = n / b; |
if (a != 0) { |
res += countPrintu(a, b); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in a given base. |
*/ |
static void *printu(void *(*emit)(void *, char), void *arg, |
int *nchar, unsigned long n, unsigned long b, |
Bool upperCase) { |
unsigned long a; |
|
a = n / b; |
if (a != 0) { |
arg = printu(emit, arg, nchar, a, b, upperCase); |
} |
if (upperCase) { |
arg = emit(arg, "0123456789ABCDEF"[n % b]); |
(*nchar)++; |
} else { |
arg = emit(arg, "0123456789abcdef"[n % b]); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* Output a number of filler characters. |
*/ |
static void *fill(void *(*emit)(void *, char), void *arg, |
int *nchar, int numFillers, char filler) { |
while (numFillers-- > 0) { |
arg = emit(arg, filler); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* This function does the real work of formatted printing. |
*/ |
static int doPrintf(void *(*emit)(void *, char), void *arg, |
const char *fmt, va_list ap) { |
int nchar; |
char c; |
int n; |
long ln; |
unsigned int u; |
unsigned long lu; |
char *s; |
Bool negFlag; |
char filler; |
int width, count; |
|
nchar = 0; |
while (1) { |
while ((c = *fmt++) != '%') { |
if (c == '\0') { |
return nchar; |
} |
arg = emit(arg, c); |
nchar++; |
} |
c = *fmt++; |
if (c == '-') { |
negFlag = true; |
c = *fmt++; |
} else { |
negFlag = false; |
} |
if (c == '0') { |
filler = '0'; |
c = *fmt++; |
} else { |
filler = ' '; |
} |
width = 0; |
while (c >= '0' && c <= '9') { |
width *= 10; |
width += c - '0'; |
c = *fmt++; |
} |
if (c == 'd') { |
n = va_arg(ap, int); |
count = countPrintn(n); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, n); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
u = va_arg(ap, int); |
count = countPrintu(u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'l') { |
c = *fmt++; |
if (c == 'd') { |
ln = va_arg(ap, long); |
count = countPrintn(ln); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, ln); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
lu = va_arg(ap, long); |
count = countPrintu(lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else { |
arg = emit(arg, 'l'); |
nchar++; |
arg = emit(arg, c); |
nchar++; |
} |
} else |
if (c == 's') { |
s = va_arg(ap, char *); |
count = strlen(s); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
while ((c = *s++) != '\0') { |
arg = emit(arg, c); |
nchar++; |
} |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'c') { |
c = va_arg(ap, char); |
arg = emit(arg, c); |
nchar++; |
} else { |
arg = emit(arg, c); |
nchar++; |
} |
} |
/* never reached */ |
return 0; |
} |
|
|
/* |
* Emit a character to the console. |
*/ |
static void *emitToConsole(void *dummy, char c) { |
putchar(c); |
return dummy; |
} |
|
|
/* |
* Formatted output with a variable argument list. |
*/ |
static int vprintf(const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToConsole, NULL, fmt, ap); |
return n; |
} |
|
|
/* |
* Formatted output. |
*/ |
int printf(const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vprintf(fmt, ap); |
va_end(ap); |
return n; |
} |
|
|
/* |
* Emit a character to a buffer. |
*/ |
static void *emitToBuffer(void *bufptr, char c) { |
*(char *)bufptr = c; |
return (char *) bufptr + 1; |
} |
|
|
/* |
* Formatted output into a buffer with a variable argument list. |
*/ |
static int vsprintf(char *s, const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToBuffer, s, fmt, ap); |
s[n] = '\0'; |
return n; |
} |
|
|
/* |
* Formatted output into a buffer. |
*/ |
int sprintf(char *s, const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vsprintf(s, fmt, ap); |
va_end(ap); |
return n; |
} |
/eco32/trunk/hwtests/xcptest/stdarg.h
0,0 → 1,41
/* |
* stdarg.h -- variable argument lists |
*/ |
|
|
#ifndef _STDARG_H_ |
#define _STDARG_H_ |
|
|
typedef char *va_list; |
|
|
static float __va_arg_tmp; |
|
|
#define va_start(list, start) \ |
((void)((list) = (sizeof(start)<4 ? \ |
(char *)((int *)&(start)+1) : (char *)(&(start)+1)))) |
|
#define __va_arg(list, mode, n) \ |
(__typecode(mode)==1 && sizeof(mode)==4 ? \ |
(__va_arg_tmp = *(double *)(&(list += \ |
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ |
*(mode *)&__va_arg_tmp) : \ |
*(mode *)(&(list += \ |
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) |
|
#define _bigendian_va_arg(list, mode, n) \ |
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ |
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ |
__va_arg(list, mode, n)) |
|
#define va_end(list) ((void)0) |
|
#define va_arg(list, mode) \ |
(sizeof(mode)==8 ? \ |
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ |
_bigendian_va_arg(list, mode, 3U)) |
|
|
#endif /* _STDARG_H_ */ |
/eco32/trunk/hwtests/xcptest/lib.h
0,0 → 1,32
/* |
* lib.h -- the library |
*/ |
|
|
#ifndef _LIB_H_ |
#define _LIB_H_ |
|
|
void debugBreak(void); |
|
int strlen(const char *s); |
int strcmp(const char *s, const char *t); |
char *strcpy(char *s, const char *t); |
char *strcat(char *s, const char *t); |
char *strchr(const char *s, char c); |
char *strtok(char *s, const char *t); |
|
unsigned long strtoul(const char *s, char **endp, int base); |
|
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void *)); |
|
char getchar(void); |
void putchar(char c); |
void puts(const char *s); |
|
int printf(const char *fmt, ...); |
int sprintf(char *s, const char *fmt, ...); |
|
|
#endif /* _LIB_H_ */ |
/eco32/trunk/hwtests/xcptest/Makefile
0,0 → 1,27
# |
# Makefile for xcptest ROM |
# |
|
BUILD = ../../build |
|
XCPTEST_SRC = start.s main.c lib.c serial.s end.s |
|
.PHONY: all install run clean |
|
all: xcptest.exo |
|
install: xcptest.exo |
|
xcptest.exo: xcptest.bin |
$(BUILD)/bin/bin2exo 0 xcptest.bin xcptest.exo |
|
xcptest.bin: $(XCPTEST_SRC) |
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ |
-Wl-m -Wlxcptest.map -o xcptest.bin $(XCPTEST_SRC) |
|
run: xcptest.bin |
$(BUILD)/bin/sim -i -t 1 -r xcptest.bin |
|
clean: |
rm -f *~ |
rm -f xcptest.map xcptest.bin xcptest.exo |
/eco32/trunk/hwtests/xcptest/common.h
0,0 → 1,27
/* |
* common.h -- common definitions |
*/ |
|
|
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
|
#define PAGE_SHIFT 12 /* log2 of page size */ |
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ |
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ |
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ |
|
|
typedef enum { false, true } Bool; /* truth values */ |
|
|
typedef unsigned int Word; /* 32 bit quantities */ |
typedef unsigned short Half; /* 16 bit quantities */ |
typedef unsigned char Byte; /* 8 bit quantities */ |
|
|
#define NULL ((void *) 0) |
|
|
#endif /* _COMMON_H_ */ |
/eco32/trunk/hwtests/xcptest/start.s
0,0 → 1,2755
; |
; start.s -- startup and support routines |
; |
|
.set dmapaddr,0xC0000000 ; base of directly mapped addresses |
.set stacktop,0xC0400000 ; monitor stack is at top of memory |
|
.set PSW,0 ; reg # of PSW |
.set TLB_INDEX,1 ; reg # of TLB Index |
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi |
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo |
.set TLB_ENTRIES,32 ; number of TLB entries |
|
;*************************************************************** |
|
.import _ecode |
.import _edata |
.import _ebss |
|
.import serinit |
.import ser0in |
.import ser0out |
|
.import main |
.import userMissTaken |
|
.export _bcode |
.export _bdata |
.export _bbss |
|
.export cin |
.export cout |
|
.export xtest1 |
.export xtest1x |
.export xtest2 |
.export xtest2x |
.export xtest3 |
.export xtest3x |
.export xtest4 |
.export xtest4x |
.export xtest5 |
.export xtest5x |
.export xtest6 |
.export xtest6x |
.export xtest7 |
.export xtest7x |
.export xtest8 |
.export xtest8x |
.export xtest9 |
.export xtest9x |
.export xtest10 |
.export xtest10x |
.export xtest11 |
.export xtest11x |
.export xtest12 |
.export xtest12x |
.export xtest13 |
.export xtest13x |
.export xtest14 |
.export xtest14x |
.export xtest15 |
.export xtest15x |
.export xtest16 |
.export xtest16x |
.export xtest17 |
.export xtest17x |
.export xtest18 |
.export xtest18x |
.export xtest19 |
.export xtest19x |
.export xtest20 |
.export xtest20x |
.export xtest21 |
.export xtest21x |
.export xtest22 |
.export xtest22x |
.export xtest23 |
.export xtest23x |
.export xtest24 |
.export xtest24x |
.export xtest25 |
.export xtest25x |
.export xtest26 |
.export xtest26x |
.export xtest27 |
.export xtest27x |
.export xtest28 |
.export xtest28x |
.export xtest29 |
.export xtest29x |
.export xtest30 |
.export xtest30x |
.export xtest31 |
.export xtest31x |
.export xtest32 |
.export xtest32x |
.export xtest33 |
.export xtest33x |
.export xtest34 |
.export xtest34x |
.export xtest35 |
.export xtest35x |
.export xtest36 |
.export xtest36x |
.export xtest37 |
.export xtest37x |
|
.export getTLB_HI |
.export getTLB_LO |
.export setTLB |
|
;*************************************************************** |
|
.code |
_bcode: |
|
.data |
_bdata: |
|
.bss |
_bbss: |
|
;*************************************************************** |
|
.code |
.align 4 |
|
reset: |
j start |
|
interrupt: |
j isr |
|
userMiss: |
j umsr |
|
;*************************************************************** |
|
.code |
.align 4 |
|
cin: |
j ser0in |
|
cout: |
j ser0out |
|
;*************************************************************** |
|
.code |
.align 4 |
|
start: |
; force CPU into a defined state |
mvts $0,PSW ; disable interrupts and user mode |
|
; initialize TLB |
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries |
add $8,$0,dmapaddr ; by impossible virtual page number |
add $9,$0,$0 |
add $10,$0,TLB_ENTRIES |
tlbloop: |
mvts $8,TLB_ENTRY_HI |
mvts $9,TLB_INDEX |
tbwi |
add $8,$8,0x1000 ; all entries must be different |
add $9,$9,1 |
bne $9,$10,tlbloop |
|
; copy data segment |
add $10,$0,_bdata ; lowest dst addr to be written to |
add $8,$0,_edata ; one above the top dst addr |
sub $9,$8,$10 ; $9 = size of data segment |
add $9,$9,_ecode ; data is waiting right after code |
j cpytest |
cpyloop: |
ldw $11,$9,0 ; src addr in $9 |
stw $11,$8,0 ; dst addr in $8 |
cpytest: |
sub $8,$8,4 ; downward |
sub $9,$9,4 |
bgeu $8,$10,cpyloop |
|
; clear bss segment |
add $8,$0,_bbss ; start with first word of bss |
add $9,$0,_ebss ; this is one above the top |
j clrtest |
clrloop: |
stw $0,$8,0 ; dst addr in $8 |
add $8,$8,4 ; upward |
clrtest: |
bltu $8,$9,clrloop |
|
; now do some useful work |
add $29,$0,stacktop ; setup monitor stack |
jal serinit ; init serial interface |
jal main ; enter command loop |
|
; main should never return |
j start ; just to be sure... |
|
;*************************************************************** |
|
xtest1: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest1x: |
trap |
j halt |
.syn |
|
xtest2: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest2x: |
.word 0x1E << 26 |
j halt |
.syn |
|
xtest3: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest3x: |
div $5,$7,$0 |
j halt |
.syn |
|
xtest4: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest4x: |
div $5,$7,0 |
j halt |
.syn |
|
xtest5: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest5x: |
divu $5,$7,$0 |
j halt |
.syn |
|
xtest6: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest6x: |
divu $5,$7,0 |
j halt |
.syn |
|
xtest7: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest7x: |
rem $5,$7,$0 |
j halt |
.syn |
|
xtest8: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest8x: |
rem $5,$7,0 |
j halt |
.syn |
|
xtest9: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest9x: |
remu $5,$7,$0 |
j halt |
.syn |
|
xtest10: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest10x: |
remu $5,$7,0 |
j halt |
.syn |
|
xtest11: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest11x: |
.set xtest11x,0xFFFFFF10 |
jr $15 |
j halt |
.syn |
|
xtest12: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest12x: |
ldw $5,$15,0 |
j halt |
.syn |
|
xtest13: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest13x: |
stw $5,$15,0 |
j halt |
.syn |
|
xtest14: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest14v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest14v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest14x: |
rfx |
j halt |
.syn |
|
xtest15: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest15v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest15v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest15x: |
mvts $0,PSW |
j halt |
.syn |
|
xtest16: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest16v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest16v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest16x: |
tbs |
j halt |
.syn |
|
xtest17: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest17v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest17v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest17x: |
.set xtest17x,0xFFFFFF10 |
jr $15 |
j halt |
.syn |
|
xtest18: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest18v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest18v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest18x: |
ldw $5,$15,0 |
j halt |
.syn |
|
xtest19: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $16,$0,xtest19v ; switch to virtual addressing |
add $8,$0,11 |
mvts $8,TLB_INDEX |
and $8,$16,0x3FFFF000 |
mvts $8,TLB_ENTRY_HI |
and $8,$16,0x3FFFF000 |
or $8,$8,3 |
mvts $8,TLB_ENTRY_LO |
tbwi |
mvfs $8,TLB_INDEX ; we could cross a page boundary |
add $8,$8,1 |
mvts $8,TLB_INDEX |
mvfs $8,TLB_ENTRY_HI |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_HI |
mvfs $8,TLB_ENTRY_LO |
add $8,$8,0x1000 |
mvts $8,TLB_ENTRY_LO |
tbwi |
and $16,$16,0x3FFFFFFF |
jr $16 |
xtest19v: |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest19x: |
stw $5,$15,0 |
j halt |
.syn |
|
xtest20: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest20x: |
.set xtest20x,0x11111122 |
jr $17 |
j halt |
.syn |
|
xtest21: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest21x: |
.set xtest21x,0x00000021 |
jr $16 |
j halt |
.syn |
|
xtest22: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest22x: |
ldw $5,$15,2 |
j halt |
.syn |
|
xtest23: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest23x: |
ldw $5,$15,1 |
j halt |
.syn |
|
xtest24: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest24x: |
ldh $5,$15,1 |
j halt |
.syn |
|
xtest25: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest25x: |
stw $5,$15,2 |
j halt |
.syn |
|
xtest26: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest26x: |
stw $5,$15,1 |
j halt |
.syn |
|
xtest27: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest27x: |
sth $5,$15,1 |
j halt |
.syn |
|
xtest28: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest28x: |
.set xtest28x,0x33333314 |
jr $3 |
j halt |
.syn |
|
xtest29: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest29x: |
ldw $5,$3,0 |
j halt |
.syn |
|
xtest30: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest30x: |
stw $5,$3,0 |
j halt |
.syn |
|
xtest31: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest31x: |
.set xtest31x,0xBBBBBB1C |
jr $11 |
j halt |
.syn |
|
xtest32: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest32x: |
ldw $5,$11,0 |
j halt |
.syn |
|
xtest33: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest33x: |
stw $5,$11,0 |
j halt |
.syn |
|
xtest34: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $8,$0,11 ; construct TLB entry |
mvts $8,TLB_INDEX |
add $8,$0,0xBBBBBB1C |
and $8,$8,0xFFFFF000 |
mvts $8,TLB_ENTRY_HI |
add $8,$0,0 |
mvts $8,TLB_ENTRY_LO |
tbwi |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
;xtest34x: |
.set xtest34x,0xBBBBBB1C |
jr $11 |
j halt |
.syn |
|
xtest35: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $8,$0,11 ; construct TLB entry |
mvts $8,TLB_INDEX |
add $8,$0,0xBBBBBB1C |
and $8,$8,0xFFFFF000 |
mvts $8,TLB_ENTRY_HI |
add $8,$0,0 |
mvts $8,TLB_ENTRY_LO |
tbwi |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest35x: |
ldw $5,$11,0 |
j halt |
.syn |
|
xtest36: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $8,$0,11 ; construct TLB entry |
mvts $8,TLB_INDEX |
add $8,$0,0xBBBBBB1C |
and $8,$8,0xFFFFF000 |
mvts $8,TLB_ENTRY_HI |
add $8,$0,0 |
mvts $8,TLB_ENTRY_LO |
tbwi |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest36x: |
stw $5,$11,0 |
j halt |
.syn |
|
xtest37: |
mvts $0,PSW |
add $8,$0,returnState |
stw $4,$8,0*4 ; pointer to interrupt context |
stw $31,$8,1*4 ; return address |
stw $29,$8,2*4 ; stack pointer |
stw $16,$8,3*4 ; local variables |
stw $17,$8,4*4 |
stw $18,$8,5*4 |
stw $19,$8,6*4 |
stw $20,$8,7*4 |
stw $21,$8,8*4 |
stw $22,$8,9*4 |
stw $23,$8,10*4 |
add $8,$0,11 ; construct TLB entry |
mvts $8,TLB_INDEX |
add $8,$0,0xBBBBBB1C |
and $8,$8,0xFFFFF000 |
mvts $8,TLB_ENTRY_HI |
add $8,$0,1 |
mvts $8,TLB_ENTRY_LO |
tbwi |
.nosyn |
add $28,$4,$0 |
ldw $8,$28,33*4 ; tlbIndex |
mvts $8,TLB_INDEX |
ldw $8,$28,34*4 ; tlbWntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $8,$28,35*4 ; tlbEntryLo |
mvts $8,TLB_ENTRY_LO |
;ldw $0,$28,0*4 ; registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
;ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,32*4 ; psw |
mvts $28,PSW |
xtest37x: |
stw $5,$11,0 |
j halt |
.syn |
|
; last resort if the exception did not trigger |
halt: |
j halt |
|
;*************************************************************** |
|
; Word getTLB_HI(int index) |
getTLB_HI: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_HI |
jr $31 |
|
; Word getTLB_LO(int index) |
getTLB_LO: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_LO |
jr $31 |
|
; void setTLB(int index, Word entryHi, Word entryLo) |
setTLB: |
mvts $4,TLB_INDEX |
mvts $5,TLB_ENTRY_HI |
mvts $6,TLB_ENTRY_LO |
tbwi |
jr $31 |
|
;*************************************************************** |
|
; general interrupt entry |
isr: |
.nosyn |
ldhi $28,userMissTaken ; remember entry point |
or $28,$28,userMissTaken |
stw $0,$28,0 |
j common |
|
; TLB user miss entry |
umsr: |
.nosyn |
ldhi $28,userMissTaken ; remember entry point |
or $28,$28,userMissTaken |
stw $28,$28,0 |
j common |
|
common: |
ldhi $28,returnState |
or $28,$28,returnState |
ldw $28,$28,0 ; pointer to interrupt context |
stw $0,$28,0*4 ; registers |
stw $1,$28,1*4 |
stw $2,$28,2*4 |
stw $3,$28,3*4 |
stw $4,$28,4*4 |
stw $5,$28,5*4 |
stw $6,$28,6*4 |
stw $7,$28,7*4 |
stw $8,$28,8*4 |
stw $9,$28,9*4 |
stw $10,$28,10*4 |
stw $11,$28,11*4 |
stw $12,$28,12*4 |
stw $13,$28,13*4 |
stw $14,$28,14*4 |
stw $15,$28,15*4 |
stw $16,$28,16*4 |
stw $17,$28,17*4 |
stw $18,$28,18*4 |
stw $19,$28,19*4 |
stw $20,$28,20*4 |
stw $21,$28,21*4 |
stw $22,$28,22*4 |
stw $23,$28,23*4 |
stw $24,$28,24*4 |
stw $25,$28,25*4 |
stw $26,$28,26*4 |
stw $27,$28,27*4 |
stw $28,$28,28*4 |
stw $29,$28,29*4 |
stw $30,$28,30*4 |
stw $31,$28,31*4 |
mvfs $8,PSW |
stw $8,$28,32*4 ; psw |
mvfs $8,TLB_INDEX |
stw $8,$28,33*4 ; tlbIndex |
mvfs $8,TLB_ENTRY_HI |
stw $8,$28,34*4 ; tlbEntryHi |
mvfs $8,TLB_ENTRY_LO |
stw $8,$28,35*4 ; tlbEntryLo |
.syn |
add $8,$0,returnState |
ldw $4,$8,0*4 ; pointer to interrupt context |
ldw $31,$8,1*4 ; return address |
ldw $29,$8,2*4 ; stack pointer |
ldw $16,$8,3*4 ; local variables |
ldw $17,$8,4*4 |
ldw $18,$8,5*4 |
ldw $19,$8,6*4 |
ldw $20,$8,7*4 |
ldw $21,$8,8*4 |
ldw $22,$8,9*4 |
ldw $23,$8,10*4 |
jr $31 |
|
.bss |
.align 4 |
|
; monitor state |
; stored when leaving to execute a user program |
; loaded when re-entering the monitor |
returnState: |
.word 0 ; pointer to interrupt context |
.word 0 ; $31 (return address) |
.word 0 ; $29 (stack pointer) |
.word 0 ; $16 (local variable) |
.word 0 ; $17 (local variable) |
.word 0 ; $18 (local variable) |
.word 0 ; $19 (local variable) |
.word 0 ; $20 (local variable) |
.word 0 ; $21 (local variable) |
.word 0 ; $22 (local variable) |
.word 0 ; $23 (local variable) |
/eco32/trunk/hwtests/irqtest/irqtest.s
0,0 → 1,95
; |
; irqtest.s -- test interrupts |
; |
|
.set stacktop,0xC0001000 |
.set tmr_base,0xF0000000 |
.set io_base,0xF0300000 |
|
reset: |
j start |
|
interrupt: |
j tmrisr |
|
userMiss: |
j userMiss |
|
start: |
add $29,$0,stacktop |
add $8,$0,tmr_base |
add $9,$0,1000 |
stw $9,$8,4 |
add $9,$0,0x02 |
stw $9,$8,0 |
add $9,$0,0x00804000 |
mvts $9,0 |
add $7,$0,'a'-10 |
loop: |
j loop |
|
tmrisr: |
add $7,$7,1 |
add $9,$0,'z'+1 |
bne $7,$9,noinit |
add $7,$0,'a' |
noinit: |
add $4,$7,$0 |
jal out |
add $8,$0,tmr_base |
add $9,$0,0x02 |
stw $9,$8,0 |
add $4,$0,' ' |
jal out |
add $4,$0,' ' |
jal out |
mvfs $5,0 |
add $6,$0,'S' |
jal show |
add $4,$0,' ' |
jal out |
add $4,$0,' ' |
jal out |
add $5,$30,$0 |
add $6,$0,'R' |
jal show |
add $4,$0,0x0D |
jal out |
add $4,$0,0x0A |
jal out |
rfx |
|
show: |
sub $29,$29,4 |
stw $31,$29,0 |
add $4,$6,$0 |
jal out |
add $4,$0,' ' |
jal out |
add $16,$0,32 |
digit: |
and $17,$5,0x80000000 |
bne $17,$0,one |
zero: |
add $4,$0,'0' |
jal out |
j next |
one: |
add $4,$0,'1' |
jal out |
next: |
sll $5,$5,1 |
sub $16,$16,1 |
bne $16,$0,digit |
ldw $31,$29,0 |
add $29,$29,4 |
jr $31 |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/irqtest/Makefile
0,0 → 1,27
# |
# Makefile for irqtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: irqtest.exo |
|
install: irqtest.exo |
|
irqtest.exo: irqtest.bin |
$(BUILD)/bin/bin2exo 0 irqtest.bin irqtest.exo |
|
irqtest.bin: irqtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o irqtest.bin irqtest.o |
|
irqtest.o: irqtest.s |
$(BUILD)/bin/as -o irqtest.o irqtest.s |
|
run: irqtest.bin |
$(BUILD)/bin/sim -i -t 1 -r irqtest.bin |
|
clean: |
rm -f *~ irqtest.o irqtest.bin irqtest.exo |
/eco32/trunk/hwtests/multest/mkmultest.c
0,0 → 1,131
/* |
* mkmultest.c -- generate multiply test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
unsigned mul(unsigned x, unsigned y) { |
return (unsigned) ((signed) x * (signed) y); |
} |
|
|
unsigned mulu(unsigned x, unsigned y) { |
return x * y; |
} |
|
|
unsigned nums[] = { |
0x00000000, |
0x00000001, |
0x00000002, |
0x00000003, |
0x0000FFFC, |
0x0000FFFD, |
0x0000FFFE, |
0x0000FFFF, |
0x00010000, |
0x00010001, |
0x00010002, |
0x00010003, |
0x7FFFFFFC, |
0x7FFFFFFD, |
0x7FFFFFFE, |
0x7FFFFFFF, |
0x80000000, |
0x80000001, |
0x80000002, |
0x80000003, |
0x8000FFFC, |
0x8000FFFD, |
0x8000FFFE, |
0x8000FFFF, |
0x80010000, |
0x80010001, |
0x80010002, |
0x80010003, |
0xFFFFFFFC, |
0xFFFFFFFD, |
0xFFFFFFFE, |
0xFFFFFFFF, |
}; |
|
int snums = sizeof(nums) / sizeof(nums[0]); |
|
|
struct { |
char *name; |
unsigned (*func)(unsigned x, unsigned y); |
} ops[] = { |
{ "mul", mul }, |
{ "mulu", mulu }, |
}; |
|
int sops = sizeof(ops) / sizeof(ops[0]); |
|
|
int chooseReg(void) { |
int r; |
|
r = (rand() >> 8) % 16; |
return r + 8; |
} |
|
|
void chooseRegs(int *r1, int *r2, int *r3, int *r4) { |
*r1 = chooseReg(); |
do { |
*r2 = chooseReg(); |
} while (*r2 == *r1); |
do { |
*r3 = chooseReg(); |
} while (*r3 == *r2 || *r3 == *r1); |
do { |
*r4 = chooseReg(); |
} while (*r4 == *r3 || *r4 == *r2 || *r4 == *r1); |
} |
|
|
int newLabel(void) { |
static int lbl = 1000; |
return lbl++; |
} |
|
|
int main(void) { |
int i, j, k; |
unsigned res; |
int r1, r2, r3, r4; |
int lbl; |
|
printf("\tadd\t$7,$0,'.'\n"); |
for (i = 0; i < snums; i++) { |
for (j = 0; j < snums; j++) { |
for (k = 0; k < sops; k++) { |
res = ops[k].func(nums[i], nums[j]); |
chooseRegs(&r1, &r2, &r3, &r4); |
lbl = newLabel(); |
printf("\tadd\t$%d,$0,0x%08X\n", r1, nums[i]); |
printf("\tadd\t$%d,$0,0x%08X\n", r2, nums[j]); |
printf("\t%s\t$%d,$%d,$%d\n", ops[k].name, r3, r1, r2); |
printf("\tadd\t$%d,$0,0x%08X\n", r4, res); |
printf("\tbeq\t$%d,$%d,L%d\n", r3, r4, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
} |
} |
} |
printf("out:\n"); |
printf("\tadd\t$6,$0,0xF0300000\n"); |
printf("out1:\n"); |
printf("\tldw\t$5,$6,8\n"); |
printf("\tand\t$5,$5,1\n"); |
printf("\tbeq\t$5,$0,out1\n"); |
printf("\tstw\t$7,$6,12\n"); |
printf("halt:\n"); |
printf("\tj\thalt\n"); |
return 0; |
} |
/eco32/trunk/hwtests/multest/Makefile
0,0 → 1,33
# |
# Makefile for multest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: multest.exo |
|
install: multest.exo |
|
multest.exo: multest.bin |
$(BUILD)/bin/bin2exo 0 multest.bin multest.exo |
|
multest.bin: multest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o multest.bin multest.o |
|
multest.o: multest.s |
$(BUILD)/bin/as -o multest.o multest.s |
|
multest.s: mkmultest |
./mkmultest > multest.s |
|
mkmultest: mkmultest.c |
gcc -m32 -g -Wall -o mkmultest mkmultest.c |
|
run: multest.bin |
$(BUILD)/bin/sim -i -t 1 -r multest.bin |
|
clean: |
rm -f *~ mkmultest multest.s multest.o |
rm -f multest.bin multest.exo |
/eco32/trunk/hwtests/ldtest/ldtest.s
0,0 → 1,86
; |
; ld.s -- test load instructions |
; |
|
.set io_base,0xF0300000 |
|
add $7,$0,'.' |
add $3,$0,w1 |
|
t0: |
ldw $2,$3,0 |
add $4,$0,0x68795E3C |
beq $2,$4,t1 |
add $7,$0,'?' |
|
t1: |
ldw $2,$3,4 |
add $4,$0,0x6879DEBC |
beq $2,$4,t2 |
add $7,$0,'?' |
|
t2: |
ldh $2,$3,2 |
add $4,$0,0x00005E3C |
beq $2,$4,t3 |
add $7,$0,'?' |
|
t3: |
ldh $2,$3,6 |
add $4,$0,0xFFFFDEBC |
beq $2,$4,t4 |
add $7,$0,'?' |
|
t4: |
ldhu $2,$3,2 |
add $4,$0,0x00005E3C |
beq $2,$4,t5 |
add $7,$0,'?' |
|
t5: |
ldhu $2,$3,6 |
add $4,$0,0x0000DEBC |
beq $2,$4,t6 |
add $7,$0,'?' |
|
t6: |
ldb $2,$3,3 |
add $4,$0,0x0000003C |
beq $2,$4,t7 |
add $7,$0,'?' |
|
t7: |
ldb $2,$3,7 |
add $4,$0,0xFFFFFFBC |
beq $2,$4,t8 |
add $7,$0,'?' |
|
t8: |
ldbu $2,$3,3 |
add $4,$0,0x0000003C |
beq $2,$4,t9 |
add $7,$0,'?' |
|
t9: |
ldbu $2,$3,7 |
add $4,$0,0x000000BC |
beq $2,$4,tx |
add $7,$0,'?' |
|
tx: |
jal out |
halt: |
j halt |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $7,$8,12 |
jr $31 |
|
.align 4 |
w1: .word 0x68795E3C |
w2: .word 0x6879DEBC |
/eco32/trunk/hwtests/ldtest/Makefile
0,0 → 1,26
# |
# Makefile for ldtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: ldtest.exo |
|
install: ldtest.exo |
|
ldtest.exo: ldtest.bin |
$(BUILD)/bin/bin2exo 0 ldtest.bin ldtest.exo |
|
ldtest.bin: ldtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o ldtest.bin ldtest.o |
|
ldtest.o: ldtest.s |
$(BUILD)/bin/as -o ldtest.o ldtest.s |
|
run: ldtest.bin |
$(BUILD)/bin/sim -i -t 1 -r ldtest.bin |
|
clean: |
rm -f *~ ldtest.o ldtest.bin ldtest.exo |
/eco32/trunk/hwtests/memtest1/memtest1.s
0,0 → 1,306
; |
; memtest1.s -- memory test |
; |
|
; $2 temporary |
; $3 tbl address |
; $4 mem address |
; $7 character to output |
; $8 I/O base |
; $10 reference value |
|
.set mem_base,0xC0000000 |
.set io_base,0xF0300000 |
|
; |
; write memory (words) |
; |
wwrite: |
add $4,$0,mem_base |
add $3,$0,tbl |
ldw $2,$3,0 |
stw $2,$4,0 |
add $7,$0,'.' |
jal out |
ldw $2,$3,4 |
stw $2,$4,4 |
add $7,$0,'.' |
jal out |
ldw $2,$3,8 |
stw $2,$4,8 |
add $7,$0,'.' |
jal out |
ldw $2,$3,12 |
stw $2,$4,12 |
add $7,$0,'.' |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; read memory (words) |
; |
wread0: |
ldw $10,$3,0 |
ldw $2,$4,0 |
bne $10,$2,wread0n |
add $7,$0,'.' |
jal out |
j wread1 |
wread0n: |
add $7,$0,'?' |
jal out |
wread1: |
ldw $10,$3,4 |
ldw $2,$4,4 |
bne $10,$2,wread1n |
add $7,$0,'.' |
jal out |
j wread2 |
wread1n: |
add $7,$0,'?' |
jal out |
wread2: |
ldw $10,$3,8 |
ldw $2,$4,8 |
bne $10,$2,wread2n |
add $7,$0,'.' |
jal out |
j wread3 |
wread2n: |
add $7,$0,'?' |
jal out |
wread3: |
ldw $10,$3,12 |
ldw $2,$4,12 |
bne $10,$2,wread3n |
add $7,$0,'.' |
jal out |
j wread4 |
wread3n: |
add $7,$0,'?' |
jal out |
wread4: |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; write memory (halfwords) |
; |
hwrite: |
add $4,$0,mem_base |
add $3,$0,tbl |
ldhu $2,$3,16 |
sth $2,$4,16 |
add $7,$0,'.' |
jal out |
ldhu $2,$3,18 |
sth $2,$4,18 |
add $7,$0,'.' |
jal out |
ldhu $2,$3,20 |
sth $2,$4,20 |
add $7,$0,'.' |
jal out |
ldhu $2,$3,22 |
sth $2,$4,22 |
add $7,$0,'.' |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; read memory (halfwords) |
; |
hread0: |
ldhu $10,$3,16 |
ldhu $2,$4,16 |
bne $10,$2,hread0n |
add $7,$0,'.' |
jal out |
j hread1 |
hread0n: |
add $7,$0,'?' |
jal out |
hread1: |
ldhu $10,$3,18 |
ldhu $2,$4,18 |
bne $10,$2,hread1n |
add $7,$0,'.' |
jal out |
j hread2 |
hread1n: |
add $7,$0,'?' |
jal out |
hread2: |
ldhu $10,$3,20 |
ldhu $2,$4,20 |
bne $10,$2,hread2n |
add $7,$0,'.' |
jal out |
j hread3 |
hread2n: |
add $7,$0,'?' |
jal out |
hread3: |
ldhu $10,$3,22 |
ldhu $2,$4,22 |
bne $10,$2,hread3n |
add $7,$0,'.' |
jal out |
j hread4 |
hread3n: |
add $7,$0,'?' |
jal out |
hread4: |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; write memory (bytes) |
; |
bwrite: |
add $4,$0,mem_base |
add $3,$0,tbl |
ldbu $2,$3,32 |
stb $2,$4,32 |
add $7,$0,'.' |
jal out |
ldbu $2,$3,33 |
stb $2,$4,33 |
add $7,$0,'.' |
jal out |
ldbu $2,$3,34 |
stb $2,$4,34 |
add $7,$0,'.' |
jal out |
ldbu $2,$3,35 |
stb $2,$4,35 |
add $7,$0,'.' |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; read memory (bytes) |
; |
bread0: |
ldbu $10,$3,32 |
ldbu $2,$4,32 |
bne $10,$2,bread0n |
add $7,$0,'.' |
jal out |
j bread1 |
bread0n: |
add $7,$0,'?' |
jal out |
bread1: |
ldbu $10,$3,33 |
ldbu $2,$4,33 |
bne $10,$2,bread1n |
add $7,$0,'.' |
jal out |
j bread2 |
bread1n: |
add $7,$0,'?' |
jal out |
bread2: |
ldbu $10,$3,34 |
ldbu $2,$4,34 |
bne $10,$2,bread2n |
add $7,$0,'.' |
jal out |
j bread3 |
bread2n: |
add $7,$0,'?' |
jal out |
bread3: |
ldbu $10,$3,35 |
ldbu $2,$4,35 |
bne $10,$2,bread3n |
add $7,$0,'.' |
jal out |
j bread4 |
bread3n: |
add $7,$0,'?' |
jal out |
bread4: |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
add $7,$0,0x0D |
jal out |
add $7,$0,0x0A |
jal out |
; |
; finally, halt |
; |
halt: |
j halt |
|
; |
; output on terminal |
; |
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $7,$8,12 |
jr $31 |
|
; |
; table of random values |
; |
.align 4 |
tbl: |
.byte 0x45,0x23,0x98,0x48,0xDC,0x5C,0x94,0x58 |
.byte 0x1F,0x7C,0x58,0xD7,0x41,0x1E,0xA9,0xE1 |
.byte 0x00,0x62,0x08,0x27,0x23,0xE9,0xCD,0x43 |
.byte 0x0F,0x25,0xF9,0x72,0xC2,0xD7,0xC4,0x07 |
.byte 0xFB,0x5D,0x50,0xD7,0xBA,0xE4,0x30,0xD9 |
.byte 0x61,0x89,0xB1,0xA3,0xA8,0x5A,0x84,0xA8 |
.byte 0xBD,0x8C,0xD0,0xE0,0x76,0x9E,0x24,0x86 |
.byte 0xC4,0x1D,0xF8,0x86,0xF5,0xBD,0x8D,0xF0 |
.byte 0x1A,0xDD,0xC8,0xD4,0xC2,0xF8,0xAD,0x23 |
.byte 0x82,0x5F,0xC6,0x2A,0xB9,0x4A,0xD3,0x77 |
.byte 0xD7,0xA4,0x58,0x4E,0x42,0x7C,0xD4,0x06 |
.byte 0x9A,0xCC,0x8D,0x8F,0x89,0x1B,0x7F,0xA4 |
.byte 0xF9,0x48,0x78,0xBB,0x40,0x26,0xDE,0xC3 |
.byte 0x85,0xA5,0xED,0x3F,0xF0,0xC1,0xB7,0xC7 |
.byte 0x65,0x0F,0x15,0xA8,0x8C,0xE9,0xAF,0x26 |
.byte 0xB6,0x3C,0xB6,0x40,0x57,0x35,0xE4,0x50 |
.byte 0x7E,0x5D,0x0B,0xBF,0x84,0xEA,0x82,0x0A |
.byte 0x8F,0x70,0x4A,0x7F,0x31,0x02,0x47,0x96 |
.byte 0x12,0x5D,0x3F,0x9E,0x47,0xEE,0xC5,0xFD |
.byte 0x2B,0x7B,0x3E,0x82,0xB1,0x23,0xD3,0x2F |
.byte 0x81,0xDF,0xEE,0x06,0xCA,0x70,0x11,0x59 |
.byte 0xE0,0x5B,0xD9,0x11,0x5E,0x21,0xA8,0x70 |
.byte 0x7E,0xE7,0x0E,0xC5,0xD6,0xD4,0xC3,0x01 |
.byte 0x4F,0x01,0x84,0x01,0x24,0x57,0x30,0xA5 |
.byte 0x37,0x1E,0xAC,0x01,0x8F,0xBD,0x5A,0x70 |
.byte 0x18,0x34,0x82,0x77,0x55,0x2A,0xE7,0xD3 |
.byte 0x12,0xF6,0x99,0xE8,0xCA,0x5C,0xEA,0x1A |
.byte 0x5D,0x6E,0x1B,0x82,0xC5,0x4B,0x28,0xFD |
.byte 0x6A,0xD4,0xFE,0xFA,0x91,0x59,0x6A,0xAA |
.byte 0x8D,0xEC,0x21,0xE3,0x17,0x09,0xB7,0x29 |
.byte 0xFF,0x50,0x12,0xC9,0xAC,0xFC,0xE3,0x0A |
.byte 0x6B,0xFF,0x8D,0x31,0x4A,0xB5,0x2E,0xB5 |
.byte 0x8A |
augment: |
.byte 0x45,0x23,0x98 |
/eco32/trunk/hwtests/memtest1/Makefile
0,0 → 1,27
# |
# Makefile for memtest1 ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: memtest1.exo |
|
install: memtest1.exo |
|
memtest1.exo: memtest1.bin |
$(BUILD)/bin/bin2exo 0 memtest1.bin memtest1.exo |
|
memtest1.bin: memtest1.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o memtest1.bin memtest1.o |
|
memtest1.o: memtest1.s |
$(BUILD)/bin/as -o memtest1.o memtest1.s |
|
run: memtest1.bin |
$(BUILD)/bin/sim -i -t 1 -r memtest1.bin |
|
clean: |
rm -f *~ memtest1.o memtest1.bin memtest1.exo |
/eco32/trunk/hwtests/tools/bin2exo/bin2exo.c
0,0 → 1,82
/* |
* bin2exo.c -- convert binary data to Motorola S-records |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
exit(1); |
} |
|
|
int main(int argc, char *argv[]) { |
char *endptr; |
unsigned int loadAddr; |
FILE *infile; |
FILE *outfile; |
int numBytes, i; |
int c; |
unsigned char lineData[16]; |
unsigned int chksum; |
|
if (argc != 4) { |
printf("Usage: %s <load addr, hex> <input file> <output file>\n", |
argv[0]); |
exit(1); |
} |
loadAddr = strtoul(argv[1], &endptr, 16); |
if (*endptr != '\0') { |
error("illegal load address %s", argv[1]); |
} |
infile = fopen(argv[2], "rb"); |
if (infile == NULL) { |
error("cannot open input file %s", argv[2]); |
} |
outfile = fopen(argv[3], "wt"); |
if (outfile == NULL) { |
error("cannot open output file %s", argv[3]); |
} |
while (1) { |
chksum = 0; |
for (numBytes = 0; numBytes < 16; numBytes++) { |
c = fgetc(infile); |
if (c == EOF) { |
break; |
} |
lineData[numBytes] = c; |
chksum += c; |
} |
if (numBytes == 0) { |
break; |
} |
fprintf(outfile, "S2%02X%06X", numBytes + 4, loadAddr); |
for (i = 0; i < numBytes; i++) { |
fprintf(outfile, "%02X", lineData[i]); |
} |
chksum += numBytes + 4; |
chksum += ((loadAddr >> 0) & 0xFF) + |
((loadAddr >> 8) & 0xFF) + |
((loadAddr >> 16) & 0xFF); |
fprintf(outfile, "%02X\n", 0xFF - (chksum & 0xFF)); |
loadAddr += numBytes; |
if (c == EOF) { |
break; |
} |
} |
fprintf(outfile, "S804000000FB\n"); |
fclose(infile); |
fclose(outfile); |
return 0; |
} |
/eco32/trunk/hwtests/tools/bin2exo/Makefile
0,0 → 1,19
# |
# Makefile for binary to S-record converter |
# |
|
BUILD = ../../../build |
|
.PHONY: all install clean |
|
all: bin2exo |
|
install: bin2exo |
mkdir -p $(BUILD)/bin |
cp bin2exo $(BUILD)/bin |
|
bin2exo: bin2exo.c |
gcc -m32 -g -Wall -o bin2exo bin2exo.c |
|
clean: |
rm -f *~ bin2exo |
/eco32/trunk/hwtests/tools/bit2exo/bit2exo.c
0,0 → 1,186
/* |
* bit2exo.c -- convert Xilinx bitfile data to Motorola S-records |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
|
|
unsigned char bitHeader[13] = { |
0x00, 0x09, 0x0F, 0xF0, |
0x0F, 0xF0, 0x0F, 0xF0, |
0x0F, 0xF0, 0x00, 0x00, |
0x01 |
}; |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
exit(1); |
} |
|
|
unsigned int getCount2(FILE *infile) { |
unsigned char b1, b2; |
|
b1 = fgetc(infile); |
b2 = fgetc(infile); |
return ((unsigned int) b1 << 8) | (unsigned int) b2; |
} |
|
|
unsigned int getCount4(FILE *infile) { |
unsigned char b1, b2, b3, b4; |
|
b1 = fgetc(infile); |
b2 = fgetc(infile); |
b3 = fgetc(infile); |
b4 = fgetc(infile); |
return ((unsigned int) b1 << 24) | ((unsigned int) b2 << 16) | |
((unsigned int) b3 << 8) | ((unsigned int) b4 << 0); |
} |
|
|
void show(char *name, FILE *infile, int count) { |
int c; |
|
printf("%s", name); |
while (count--) { |
c = fgetc(infile); |
if (c >= 0x20 && c <= 0x7E) { |
printf("%c", c); |
} |
} |
printf("\n"); |
} |
|
|
unsigned char mirror(unsigned char n) { |
unsigned char m; |
int i; |
|
m = 0; |
for (i = 0; i < 8; i++) { |
m <<= 1; |
if (n & 1) { |
m |= 1; |
} |
n >>= 1; |
} |
return m; |
} |
|
|
int main(int argc, char *argv[]) { |
char *endptr; |
unsigned int loadAddr; |
FILE *infile; |
FILE *outfile; |
int numBytes, i; |
int c; |
unsigned char lineData[16]; |
unsigned int chksum; |
int totalBytes; |
|
if (argc != 4) { |
printf("Usage: %s <load addr, hex> <input file> <output file>\n", |
argv[0]); |
printf(" ROM quadrant 0: load addr = 0x000000\n"); |
printf(" ROM quadrant 1: load addr = 0x080000\n"); |
printf(" ROM quadrant 2: load addr = 0x100000\n"); |
printf(" ROM quadrant 3: load addr = 0x180000\n"); |
exit(1); |
} |
loadAddr = strtoul(argv[1], &endptr, 16); |
if (*endptr != '\0') { |
error("illegal load address %s", argv[1]); |
} |
infile = fopen(argv[2], "rb"); |
if (infile == NULL) { |
error("cannot open input file %s", argv[2]); |
} |
outfile = fopen(argv[3], "wt"); |
if (outfile == NULL) { |
error("cannot open output file %s", argv[3]); |
} |
/* 13 bytes header */ |
for (i = 0; i < 13; i++) { |
if (fgetc(infile) != bitHeader[i]) { |
error("input file header is not a '.bit' header"); |
} |
} |
/* section 'a' */ |
if (fgetc(infile) != 'a') { |
error("section 'a' not found"); |
} |
i = getCount2(infile); |
show("design name:\t\t", infile, i); |
/* section 'b' */ |
if (fgetc(infile) != 'b') { |
error("section 'b' not found"); |
} |
i = getCount2(infile); |
show("part name:\t\t", infile, i); |
/* section 'c' */ |
if (fgetc(infile) != 'c') { |
error("section 'c' not found"); |
} |
i = getCount2(infile); |
show("creation date:\t\t", infile, i); |
/* section 'd' */ |
if (fgetc(infile) != 'd') { |
error("section 'd' not found"); |
} |
i = getCount2(infile); |
show("creation time:\t\t", infile, i); |
/* section 'e' */ |
if (fgetc(infile) != 'e') { |
error("section 'e' not found"); |
} |
i = getCount4(infile); |
printf("bit stream size:\t0x%08X\n", i); |
totalBytes = 0; |
while (1) { |
chksum = 0; |
for (numBytes = 0; numBytes < 16; numBytes++) { |
c = fgetc(infile); |
if (c == EOF) { |
break; |
} |
c = mirror(c & 0xFF); |
lineData[numBytes] = c; |
chksum += c; |
} |
if (numBytes == 0) { |
break; |
} |
totalBytes += numBytes; |
fprintf(outfile, "S2%02X%06X", numBytes + 4, loadAddr); |
for (i = 0; i < numBytes; i++) { |
fprintf(outfile, "%02X", lineData[i]); |
} |
chksum += numBytes + 4; |
chksum += ((loadAddr >> 0) & 0xFF) + |
((loadAddr >> 8) & 0xFF) + |
((loadAddr >> 16) & 0xFF); |
fprintf(outfile, "%02X\n", 0xFF - (chksum & 0xFF)); |
loadAddr += numBytes; |
if (c == EOF) { |
break; |
} |
} |
fprintf(outfile, "S804000000FB\n"); |
fclose(infile); |
fclose(outfile); |
printf("bytes converted:\t0x%08X\n", totalBytes); |
return 0; |
} |
/eco32/trunk/hwtests/tools/bit2exo/Makefile
0,0 → 1,19
# |
# Makefile for bitfile to S-record converter |
# |
|
BUILD = ../../../build |
|
.PHONY: all install clean |
|
all: bit2exo |
|
install: bit2exo |
mkdir -p $(BUILD)/bin |
cp bit2exo $(BUILD)/bin |
|
bit2exo: bit2exo.c |
gcc -m32 -g -Wall -o bit2exo bit2exo.c |
|
clean: |
rm -f *~ bit2exo |
/eco32/trunk/hwtests/tools/Makefile
0,0 → 1,25
# |
# Makefile for building the ROM tools |
# |
|
BUILD = ../../build |
|
DIRS = bin2exo bit2exo |
|
.PHONY: all install clean |
|
all: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i all ; \ |
done |
|
install: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i install ; \ |
done |
|
clean: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i clean ; \ |
done |
rm -f *~ |
/eco32/trunk/hwtests/kbdtest/serial.s
0,0 → 1,98
; |
; serial.s -- the serial line interface |
; |
|
;*************************************************************** |
|
.set ser0base,0xF0300000 ; serial line 0 base address |
.set ser1base,0xF0300010 ; serial line 1 base address |
|
.export serinit ; initialize serial interface |
|
.export ser0inchk ; line 0 input check |
.export ser0in ; line 0 input |
.export ser0outchk ; line 0 output check |
.export ser0out ; line 0 output |
|
.export ser1inchk ; line 1 input check |
.export ser1in ; line 1 input |
.export ser1outchk ; line 1 output check |
.export ser1out ; line 1 output |
|
;*************************************************************** |
|
.code |
.align 4 |
|
serinit: |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser0inchk: |
add $8,$0,ser0base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser0in: |
add $8,$0,ser0base |
ser0in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser0in1 |
ldw $2,$8,4 |
jr $31 |
|
ser0outchk: |
add $8,$0,ser0base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser0out: |
add $8,$0,ser0base |
ser0out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser0out1 |
stw $4,$8,12 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
ser1inchk: |
add $8,$0,ser1base |
ldw $2,$8,0 |
and $2,$2,1 |
jr $31 |
|
ser1in: |
add $8,$0,ser1base |
ser1in1: |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,ser1in1 |
ldw $2,$8,4 |
jr $31 |
|
ser1outchk: |
add $8,$0,ser1base |
ldw $2,$8,8 |
and $2,$2,1 |
jr $31 |
|
ser1out: |
add $8,$0,ser1base |
ser1out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,ser1out1 |
stw $4,$8,12 |
jr $31 |
/eco32/trunk/hwtests/kbdtest/start.h
0,0 → 1,36
/* |
* start.h -- startup and support routines |
*/ |
|
|
#ifndef _START_H_ |
#define _START_H_ |
|
|
typedef struct { |
Word ic_reg[32]; /* general purpose registers */ |
Word ic_tlbhi; /* TLB EntryHi */ |
Word ic_psw; /* PSW */ |
} InterruptContext; |
|
typedef void (*ISR)(int irq, InterruptContext *icp); |
|
|
int cin(void); |
void cout(char c); |
|
Word getTLB_HI(int index); |
Word getTLB_LO(int index); |
void setTLB(int index, Word entryHi, Word entryLo); |
void wrtRndTLB(Word entryHi, Word entryLo); |
Word probeTLB(Word entryHi); |
void wait(int n); |
void enable(void); |
void disable(void); |
Word getMask(void); |
Word setMask(Word mask); |
ISR getISR(int irq); |
ISR setISR(int irq, ISR isr); |
|
|
#endif /* _START_H_ */ |
/eco32/trunk/hwtests/kbdtest/main.c
0,0 → 1,129
/* |
* main.c -- the main program |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "start.h" |
|
|
int charAvail = 0; |
char charRead; |
|
|
/**************************************************************/ |
|
|
/* |
* Interrupt and exception messages which will be shown if |
* the corresponding interrupt or exception is not handled. |
*/ |
char *exceptionCause[32] = { |
/* 00 */ "terminal 0 transmitter interrupt", |
/* 01 */ "terminal 0 receiver interrupt", |
/* 02 */ "terminal 1 transmitter interrupt", |
/* 03 */ "terminal 1 receiver interrupt", |
/* 04 */ "keyboard interrupt", |
/* 05 */ "unknown interrupt 5", |
/* 06 */ "unknown interrupt 6", |
/* 07 */ "unknown interrupt 7", |
/* 08 */ "disk interrupt", |
/* 09 */ "unknown interrupt 9", |
/* 10 */ "unknown interrupt 10", |
/* 11 */ "unknown interrupt 11", |
/* 12 */ "unknown interrupt 12", |
/* 13 */ "unknown interrupt 13", |
/* 14 */ "timer interrupt", |
/* 15 */ "unknown interrupt 15", |
/* 16 */ "bus timeout exception", |
/* 17 */ "illegal instruction exception", |
/* 18 */ "privileged instruction exception", |
/* 19 */ "divide instruction exception", |
/* 20 */ "trap instruction exception", |
/* 21 */ "TLB miss exception", |
/* 22 */ "TLB write exception", |
/* 23 */ "TLB invalid exception", |
/* 24 */ "illegal address exception", |
/* 25 */ "privileged address exception", |
/* 26 */ "unknown exception 26", |
/* 27 */ "unknown exception 27", |
/* 28 */ "unknown exception 28", |
/* 29 */ "unknown exception 29", |
/* 30 */ "unknown exception 30", |
/* 31 */ "unknown exception 31" |
}; |
|
|
/* |
* This is the default interrupt service routine. |
* It simply panics with a message that tells the cause. |
*/ |
void defaultISR(int irq, InterruptContext *icp) { |
printf("**** %s ****\n", exceptionCause[irq]); |
while (1) ; |
} |
|
|
/* |
* Initialize all interrupts and exceptions to the default ISR. |
* Enable interrupts. |
*/ |
void initInterrupts(void) { |
int i; |
|
for (i = 0; i < 32; i++) { |
setISR(i, defaultISR); |
} |
enable(); |
} |
|
|
/**************************************************************/ |
|
|
void kbdISR(int irq, InterruptContext *icp) { |
unsigned int *p; |
|
p = (unsigned int *) 0xF0200000; |
charRead = *(p + 1); |
charAvail = 1; |
} |
|
|
void kbdEnable(void) { |
unsigned int *p; |
|
p = (unsigned int *) 0xF0200000; |
*p = 2; |
} |
|
|
int main(void) { |
unsigned char c; |
int n; |
|
printf("Keyboard Test:\n"); |
printf("initializing interrupts...\n"); |
initInterrupts(); |
printf("setting kbd ISR...\n"); |
setISR(4, kbdISR); |
printf("enabling kbd interrupt mask bit...\n"); |
setMask(getMask() | (1 << 4)); |
printf("enabling interrupts in kbd controller...\n"); |
kbdEnable(); |
n = 0; |
while (1) { |
while (charAvail == 0) ; |
disable(); |
c = charRead; |
charAvail = 0; |
enable(); |
printf("%02X ", c); |
if (++n == 24) { |
n = 0; |
printf("\n"); |
} |
} |
return 0; |
} |
/eco32/trunk/hwtests/kbdtest/end.s
0,0 → 1,19
; |
; end.s -- end-of-segment labels |
; |
|
.export _ecode |
.export _edata |
.export _ebss |
|
.code |
.align 4 |
_ecode: |
|
.data |
.align 4 |
_edata: |
|
.bss |
.align 4 |
_ebss: |
/eco32/trunk/hwtests/kbdtest/lib.c
0,0 → 1,624
/* |
* lib.c -- the library |
*/ |
|
|
#include "common.h" |
#include "lib.h" |
#include "stdarg.h" |
#include "start.h" |
|
|
/**************************************************************/ |
|
|
/* |
* This is only for debugging. |
* Place a breakpoint at the very beginning of this routine |
* and call it wherever you want to break execution. |
*/ |
void debugBreak(void) { |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the length of a string (without terminating null character). |
*/ |
int strlen(const char *s) { |
const char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
return p - s; |
} |
|
|
/* |
* Compare two strings. |
* Return a number < 0, = 0, or > 0 iff the first string is less |
* than, equal to, or greater than the second one, respectively. |
*/ |
int strcmp(const char *s, const char *t) { |
while (*s == *t) { |
if (*s == '\0') { |
return 0; |
} |
s++; |
t++; |
} |
return *s - *t; |
} |
|
|
/* |
* Copy string t to string s (includes terminating null character). |
*/ |
char *strcpy(char *s, const char *t) { |
char *p; |
|
p = s; |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Append string t to string s. |
*/ |
char *strcat(char *s, const char *t) { |
char *p; |
|
p = s; |
while (*p != '\0') { |
p++; |
} |
while ((*p = *t) != '\0') { |
p++; |
t++; |
} |
return s; |
} |
|
|
/* |
* Locate character c in string s. |
*/ |
char *strchr(const char *s, char c) { |
while (*s != c) { |
if (*s == '\0') { |
return NULL; |
} |
s++; |
} |
return (char *) s; |
} |
|
|
/* |
* Extract the next token from the string s, delimited |
* by any character from the delimiter string t. |
*/ |
char *strtok(char *s, const char *t) { |
static char *p; |
char *q; |
|
if (s != NULL) { |
p = s; |
} else { |
p++; |
} |
while (*p != '\0' && strchr(t, *p) != NULL) { |
p++; |
} |
if (*p == '\0') { |
return NULL; |
} |
q = p++; |
while (*p != '\0' && strchr(t, *p) == NULL) { |
p++; |
} |
if (*p != '\0') { |
*p = '\0'; |
} else { |
p--; |
} |
return q; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Determine if a character is 'white space'. |
*/ |
static Bool isspace(char c) { |
Bool res; |
|
switch (c) { |
case ' ': |
case '\f': |
case '\n': |
case '\r': |
case '\t': |
case '\v': |
res = true; |
break; |
default: |
res = false; |
break; |
} |
return res; |
} |
|
|
/* |
* Check for valid digit, and convert to value. |
*/ |
static Bool checkDigit(char c, int base, int *value) { |
if (c >= '0' && c <= '9') { |
*value = c - '0'; |
} else |
if (c >= 'A' && c <= 'Z') { |
*value = c - 'A' + 10; |
} else |
if (c >= 'a' && c <= 'z') { |
*value = c - 'a' + 10; |
} else { |
return false; |
} |
return *value < base; |
} |
|
|
/* |
* Convert initial part of string to unsigned long integer. |
*/ |
unsigned long strtoul(const char *s, char **endp, int base) { |
unsigned long res; |
int sign; |
int digit; |
|
res = 0; |
while (isspace(*s)) { |
s++; |
} |
if (*s == '+') { |
sign = 1; |
s++; |
} else |
if (*s == '-') { |
sign = -1; |
s++; |
} else { |
sign = 1; |
} |
if (base == 0 || base == 16) { |
if (*s == '0' && |
(*(s + 1) == 'x' || *(s + 1) == 'X')) { |
/* base is 16 */ |
s += 2; |
base = 16; |
} else { |
/* base is 0 or 16, but number does not start with "0x" */ |
if (base == 0) { |
if (*s == '0') { |
s++; |
base = 8; |
} else { |
base = 10; |
} |
} else { |
/* take base as is */ |
} |
} |
} else { |
/* take base as is */ |
} |
while (checkDigit(*s, base, &digit)) { |
res *= base; |
res += digit; |
s++; |
} |
if (endp != NULL) { |
*endp = (char *) s; |
} |
return sign * res; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Exchange two array items of a given size. |
*/ |
static void xchg(char *p, char *q, int size) { |
char t; |
|
while (size--) { |
t = *p; |
*p++ = *q; |
*q++ = t; |
} |
} |
|
|
/* |
* This is a recursive version of quicksort. |
*/ |
static void sort(char *l, char *r, int size, |
int (*cmp)(const void *, const void *)) { |
char *i; |
char *j; |
char *x; |
|
i = l; |
j = r; |
x = l + (((r - l) / size) / 2) * size; |
do { |
while (cmp(i, x) < 0) { |
i += size; |
} |
while (cmp(x, j) < 0) { |
j -= size; |
} |
if (i <= j) { |
/* exchange array elements i and j */ |
/* attention: update x if it is one of these */ |
if (x == i) { |
x = j; |
} else |
if (x == j) { |
x = i; |
} |
xchg(i, j, size); |
i += size; |
j -= size; |
} |
} while (i <= j); |
if (l < j) { |
sort(l, j, size, cmp); |
} |
if (i < r) { |
sort(i, r, size, cmp); |
} |
} |
|
|
/* |
* External interface for the quicksort algorithm. |
*/ |
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void*)) { |
sort((char *) base, (char *) base + (n - 1) * size, size, cmp); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Input a character from the console. |
*/ |
char getchar(void) { |
return cin(); |
} |
|
|
/* |
* Output a character on the console. |
* Replace LF by CR/LF. |
*/ |
void putchar(char c) { |
if (c == '\n') { |
cout('\r'); |
} |
cout(c); |
} |
|
|
/**************************************************************/ |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in base 10. |
*/ |
static int countPrintn(long n) { |
long a; |
int res; |
|
res = 0; |
if (n < 0) { |
res++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
res += countPrintn(a); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in base 10. |
*/ |
static void *printn(void *(*emit)(void *, char), void *arg, |
int *nchar, long n) { |
long a; |
|
if (n < 0) { |
arg = emit(arg, '-'); |
(*nchar)++; |
n = -n; |
} |
a = n / 10; |
if (a != 0) { |
arg = printn(emit, arg, nchar, a); |
} |
arg = emit(arg, n % 10 + '0'); |
(*nchar)++; |
return arg; |
} |
|
|
/* |
* Count the number of characters needed to represent |
* a given number in a given base. |
*/ |
static int countPrintu(unsigned long n, unsigned long b) { |
unsigned long a; |
int res; |
|
res = 0; |
a = n / b; |
if (a != 0) { |
res += countPrintu(a, b); |
} |
return res + 1; |
} |
|
|
/* |
* Output a number in a given base. |
*/ |
static void *printu(void *(*emit)(void *, char), void *arg, |
int *nchar, unsigned long n, unsigned long b, |
Bool upperCase) { |
unsigned long a; |
|
a = n / b; |
if (a != 0) { |
arg = printu(emit, arg, nchar, a, b, upperCase); |
} |
if (upperCase) { |
arg = emit(arg, "0123456789ABCDEF"[n % b]); |
(*nchar)++; |
} else { |
arg = emit(arg, "0123456789abcdef"[n % b]); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* Output a number of filler characters. |
*/ |
static void *fill(void *(*emit)(void *, char), void *arg, |
int *nchar, int numFillers, char filler) { |
while (numFillers-- > 0) { |
arg = emit(arg, filler); |
(*nchar)++; |
} |
return arg; |
} |
|
|
/* |
* This function does the real work of formatted printing. |
*/ |
static int doPrintf(void *(*emit)(void *, char), void *arg, |
const char *fmt, va_list ap) { |
int nchar; |
char c; |
int n; |
long ln; |
unsigned int u; |
unsigned long lu; |
char *s; |
Bool negFlag; |
char filler; |
int width, count; |
|
nchar = 0; |
while (1) { |
while ((c = *fmt++) != '%') { |
if (c == '\0') { |
return nchar; |
} |
arg = emit(arg, c); |
nchar++; |
} |
c = *fmt++; |
if (c == '-') { |
negFlag = true; |
c = *fmt++; |
} else { |
negFlag = false; |
} |
if (c == '0') { |
filler = '0'; |
c = *fmt++; |
} else { |
filler = ' '; |
} |
width = 0; |
while (c >= '0' && c <= '9') { |
width *= 10; |
width += c - '0'; |
c = *fmt++; |
} |
if (c == 'd') { |
n = va_arg(ap, int); |
count = countPrintn(n); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, n); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
u = va_arg(ap, int); |
count = countPrintu(u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, u, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'l') { |
c = *fmt++; |
if (c == 'd') { |
ln = va_arg(ap, long); |
count = countPrintn(ln); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printn(emit, arg, &nchar, ln); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { |
lu = va_arg(ap, long); |
count = countPrintu(lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
arg = printu(emit, arg, &nchar, lu, |
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), |
c == 'X'); |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else { |
arg = emit(arg, 'l'); |
nchar++; |
arg = emit(arg, c); |
nchar++; |
} |
} else |
if (c == 's') { |
s = va_arg(ap, char *); |
count = strlen(s); |
if (width > 0 && !negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
while ((c = *s++) != '\0') { |
arg = emit(arg, c); |
nchar++; |
} |
if (width > 0 && negFlag) { |
arg = fill(emit, arg, &nchar, width - count, filler); |
} |
} else |
if (c == 'c') { |
c = va_arg(ap, char); |
arg = emit(arg, c); |
nchar++; |
} else { |
arg = emit(arg, c); |
nchar++; |
} |
} |
/* never reached */ |
return 0; |
} |
|
|
/* |
* Emit a character to the console. |
*/ |
static void *emitToConsole(void *dummy, char c) { |
putchar(c); |
return dummy; |
} |
|
|
/* |
* Formatted output with a variable argument list. |
*/ |
static int vprintf(const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToConsole, NULL, fmt, ap); |
return n; |
} |
|
|
/* |
* Formatted output. |
*/ |
int printf(const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vprintf(fmt, ap); |
va_end(ap); |
return n; |
} |
|
|
/* |
* Emit a character to a buffer. |
*/ |
static void *emitToBuffer(void *bufptr, char c) { |
*(char *)bufptr = c; |
return (char *) bufptr + 1; |
} |
|
|
/* |
* Formatted output into a buffer with a variable argument list. |
*/ |
static int vsprintf(char *s, const char *fmt, va_list ap) { |
int n; |
|
n = doPrintf(emitToBuffer, s, fmt, ap); |
s[n] = '\0'; |
return n; |
} |
|
|
/* |
* Formatted output into a buffer. |
*/ |
int sprintf(char *s, const char *fmt, ...) { |
int n; |
va_list ap; |
|
va_start(ap, fmt); |
n = vsprintf(s, fmt, ap); |
va_end(ap); |
return n; |
} |
/eco32/trunk/hwtests/kbdtest/stdarg.h
0,0 → 1,41
/* |
* stdarg.h -- variable argument lists |
*/ |
|
|
#ifndef _STDARG_H_ |
#define _STDARG_H_ |
|
|
typedef char *va_list; |
|
|
static float __va_arg_tmp; |
|
|
#define va_start(list, start) \ |
((void)((list) = (sizeof(start)<4 ? \ |
(char *)((int *)&(start)+1) : (char *)(&(start)+1)))) |
|
#define __va_arg(list, mode, n) \ |
(__typecode(mode)==1 && sizeof(mode)==4 ? \ |
(__va_arg_tmp = *(double *)(&(list += \ |
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ |
*(mode *)&__va_arg_tmp) : \ |
*(mode *)(&(list += \ |
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) |
|
#define _bigendian_va_arg(list, mode, n) \ |
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ |
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ |
__va_arg(list, mode, n)) |
|
#define va_end(list) ((void)0) |
|
#define va_arg(list, mode) \ |
(sizeof(mode)==8 ? \ |
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ |
_bigendian_va_arg(list, mode, 3U)) |
|
|
#endif /* _STDARG_H_ */ |
/eco32/trunk/hwtests/kbdtest/lib.h
0,0 → 1,31
/* |
* lib.h -- the library |
*/ |
|
|
#ifndef _LIB_H_ |
#define _LIB_H_ |
|
|
void debugBreak(void); |
|
int strlen(const char *s); |
int strcmp(const char *s, const char *t); |
char *strcpy(char *s, const char *t); |
char *strcat(char *s, const char *t); |
char *strchr(const char *s, char c); |
char *strtok(char *s, const char *t); |
|
unsigned long strtoul(const char *s, char **endp, int base); |
|
void qsort(void *base, int n, int size, |
int (*cmp)(const void *, const void *)); |
|
char getchar(void); |
void putchar(char c); |
|
int printf(const char *fmt, ...); |
int sprintf(char *s, const char *fmt, ...); |
|
|
#endif /* _LIB_H_ */ |
/eco32/trunk/hwtests/kbdtest/Makefile
0,0 → 1,27
# |
# Makefile for kbdtest ROM |
# |
|
BUILD = ../../build |
|
KBDTEST_SRC = start.s main.c lib.c serial.s end.s |
|
.PHONY: all install run clean |
|
all: kbdtest.exo |
|
install: kbdtest.exo |
|
kbdtest.exo: kbdtest.bin |
$(BUILD)/bin/bin2exo 0 kbdtest.bin kbdtest.exo |
|
kbdtest.bin: $(KBDTEST_SRC) |
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ |
-Wl-m -Wlkbdtest.map -o kbdtest.bin $(KBDTEST_SRC) |
|
run: kbdtest.bin |
$(BUILD)/bin/sim -i -c -t 1 -r kbdtest.bin |
|
clean: |
rm -f *~ |
rm -f kbdtest.map kbdtest.bin kbdtest.exo |
/eco32/trunk/hwtests/kbdtest/start.s
0,0 → 1,384
; |
; start.s -- startup and support routines |
; |
|
.set dmapaddr,0xC0000000 ; base of directly mapped addresses |
.set stacktop,0xC0400000 ; monitor stack is at top of memory |
|
.set ICNTXT_SIZE,34 * 4 ; size of interrupt context |
|
.set PSW,0 ; reg # of PSW |
.set V_SHIFT,27 ; interrupt vector ctrl bit |
.set V,1 << V_SHIFT |
.set UM_SHIFT,26 ; curr user mode ctrl bit |
.set UM,1 << UM_SHIFT |
.set PUM_SHIFT,25 ; prev user mode ctrl bit |
.set PUM,1 << PUM_SHIFT |
.set OUM_SHIFT,24 ; old user mode ctrl bit |
.set OUM,1 << OUM_SHIFT |
.set IE_SHIFT,23 ; curr int enable ctrl bit |
.set IE,1 << IE_SHIFT |
.set PIE_SHIFT,22 ; prev int enable ctrl bit |
.set PIE,1 << PIE_SHIFT |
.set OIE_SHIFT,21 ; old int enable ctrl bit |
.set OIE,1 << OIE_SHIFT |
|
.set TLB_INDEX,1 ; reg # of TLB Index |
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi |
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo |
.set TLB_ENTRIES,32 ; number of TLB entries |
|
;*************************************************************** |
|
.import _ecode |
.import _edata |
.import _ebss |
|
.import serinit |
.import ser0in |
.import ser0out |
|
.import main |
|
.export _bcode |
.export _bdata |
.export _bbss |
|
.export cin |
.export cout |
|
.export getTLB_HI |
.export getTLB_LO |
.export setTLB |
.export wrtRndTLB |
.export probeTLB |
.export wait |
|
.export enable |
.export disable |
.export getMask |
.export setMask |
.export getISR |
.export setISR |
|
;*************************************************************** |
|
.code |
_bcode: |
|
.data |
_bdata: |
|
.bss |
_bbss: |
|
;*************************************************************** |
|
.code |
.align 4 |
|
reset: |
j start |
|
interrupt: |
j isr |
|
userMiss: |
j userMiss |
|
;*************************************************************** |
|
.code |
.align 4 |
|
cin: |
j ser0in |
|
cout: |
j ser0out |
|
;*************************************************************** |
|
.code |
.align 4 |
|
start: |
; force CPU into a defined state |
mvts $0,PSW ; disable interrupts and user mode |
|
; initialize TLB |
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries |
add $8,$0,dmapaddr ; by impossible virtual page number |
add $9,$0,$0 |
add $10,$0,TLB_ENTRIES |
tlbloop: |
mvts $8,TLB_ENTRY_HI |
mvts $9,TLB_INDEX |
tbwi |
add $8,$8,0x1000 ; all entries must be different |
add $9,$9,1 |
bne $9,$10,tlbloop |
|
; copy data segment |
add $10,$0,_bdata ; lowest dst addr to be written to |
add $8,$0,_edata ; one above the top dst addr |
sub $9,$8,$10 ; $9 = size of data segment |
add $9,$9,_ecode ; data is waiting right after code |
j cpytest |
cpyloop: |
ldw $11,$9,0 ; src addr in $9 |
stw $11,$8,0 ; dst addr in $8 |
cpytest: |
sub $8,$8,4 ; downward |
sub $9,$9,4 |
bgeu $8,$10,cpyloop |
|
; clear bss segment |
add $8,$0,_bbss ; start with first word of bss |
add $9,$0,_ebss ; this is one above the top |
j clrtest |
clrloop: |
stw $0,$8,0 ; dst addr in $8 |
add $8,$8,4 ; upward |
clrtest: |
bltu $8,$9,clrloop |
|
; now do some useful work |
add $29,$0,stacktop ; setup monitor stack |
jal serinit ; init serial interface |
jal main ; enter command loop |
|
; main should never return |
j start ; just to be sure... |
|
;*************************************************************** |
|
; Word getTLB_HI(int index) |
getTLB_HI: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_HI |
jr $31 |
|
; Word getTLB_LO(int index) |
getTLB_LO: |
mvts $4,TLB_INDEX |
tbri |
mvfs $2,TLB_ENTRY_LO |
jr $31 |
|
; void setTLB(int index, Word entryHi, Word entryLo) |
setTLB: |
mvts $4,TLB_INDEX |
mvts $5,TLB_ENTRY_HI |
mvts $6,TLB_ENTRY_LO |
tbwi |
jr $31 |
|
; void wrtRndTLB(Word entryHi, Word entryLo) |
wrtRndTLB: |
mvts $4,TLB_ENTRY_HI |
mvts $5,TLB_ENTRY_LO |
tbwr |
jr $31 |
|
; Word probeTLB(Word entryHi) |
probeTLB: |
mvts $4,TLB_ENTRY_HI |
tbs |
mvfs $2,TLB_INDEX |
jr $31 |
|
; void wait(int n) |
wait: |
j wait2 |
wait1: |
add $4,$4,$0 |
sub $4,$4,1 |
wait2: |
bne $4,$0,wait1 |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
; void enable(void) |
enable: |
mvfs $8,PSW |
or $8,$8,IE |
mvts $8,PSW |
jr $31 |
|
; void disable(void) |
disable: |
mvfs $8,PSW |
and $8,$8,~IE |
mvts $8,PSW |
jr $31 |
|
; U32 getMask(void) |
getMask: |
mvfs $8,PSW |
and $2,$8,0x0000FFFF ; return lower 16 bits only |
jr $31 |
|
; U32 setMask(U32 mask) |
setMask: |
mvfs $8,PSW |
and $2,$8,0x0000FFFF ; return lower 16 bits only |
and $4,$4,0x0000FFFF ; use lower 16 bits only |
and $8,$8,0xFFFF0000 |
or $8,$8,$4 |
mvts $8,PSW |
jr $31 |
|
; ISR getISR(int irq) |
getISR: |
sll $4,$4,2 |
ldw $2,$4,irqsrv |
jr $31 |
|
; ISR setISR(int irq, ISR isr) |
setISR: |
sll $4,$4,2 |
ldw $2,$4,irqsrv |
stw $5,$4,irqsrv |
jr $31 |
|
;*************************************************************** |
|
.code |
.align 4 |
|
; general interrupt service routine |
; only register $28 is available for bootstrapping |
isr: |
.nosyn |
add $28,$29,$0 |
sub $28,$28,ICNTXT_SIZE ; $28 points to interrupt context |
stw $0,$28,0*4 ; save registers |
stw $1,$28,1*4 |
stw $2,$28,2*4 |
stw $3,$28,3*4 |
stw $4,$28,4*4 |
stw $5,$28,5*4 |
stw $6,$28,6*4 |
stw $7,$28,7*4 |
stw $8,$28,8*4 |
stw $9,$28,9*4 |
stw $10,$28,10*4 |
stw $11,$28,11*4 |
stw $12,$28,12*4 |
stw $13,$28,13*4 |
stw $14,$28,14*4 |
stw $15,$28,15*4 |
stw $16,$28,16*4 |
stw $17,$28,17*4 |
stw $18,$28,18*4 |
stw $19,$28,19*4 |
stw $20,$28,20*4 |
stw $21,$28,21*4 |
stw $22,$28,22*4 |
stw $23,$28,23*4 |
stw $24,$28,24*4 |
stw $25,$28,25*4 |
stw $26,$28,26*4 |
stw $27,$28,27*4 |
stw $28,$28,28*4 |
stw $29,$28,29*4 |
stw $30,$28,30*4 |
stw $31,$28,31*4 |
mvfs $8,TLB_ENTRY_HI ; save TLB EntryHi |
stw $8,$28,32*4 |
mvfs $8,PSW ; save PSW |
stw $8,$28,33*4 |
add $29,$28,$0 ; $29 is required to hold sp |
.syn |
add $5,$29,$0 ; $5 = pointer to interrupt context |
slr $4,$8,16 ; $4 = IRQ number |
and $4,$4,0x1F |
sll $8,$4,2 ; $8 = 4 * IRQ number |
ldw $8,$8,irqsrv ; get addr of service routine |
jalr $8 ; call service routine |
.nosyn |
mvts $0,PSW ; ISR may have enabled interrupts |
add $28,$29,$0 ; $28 points to interrupt context |
ldw $8,$28,32*4 ; restore TLB EntryHi |
mvts $8,TLB_ENTRY_HI |
ldw $0,$28,0*4 ; restore registers |
ldw $1,$28,1*4 |
ldw $2,$28,2*4 |
ldw $3,$28,3*4 |
ldw $4,$28,4*4 |
ldw $5,$28,5*4 |
ldw $6,$28,6*4 |
ldw $7,$28,7*4 |
ldw $8,$28,8*4 |
ldw $9,$28,9*4 |
ldw $10,$28,10*4 |
ldw $11,$28,11*4 |
ldw $12,$28,12*4 |
ldw $13,$28,13*4 |
ldw $14,$28,14*4 |
ldw $15,$28,15*4 |
ldw $16,$28,16*4 |
ldw $17,$28,17*4 |
ldw $18,$28,18*4 |
ldw $19,$28,19*4 |
ldw $20,$28,20*4 |
ldw $21,$28,21*4 |
ldw $22,$28,22*4 |
ldw $23,$28,23*4 |
ldw $24,$28,24*4 |
ldw $25,$28,25*4 |
ldw $26,$28,26*4 |
ldw $27,$28,27*4 |
ldw $28,$28,28*4 |
ldw $29,$28,29*4 |
ldw $30,$28,30*4 |
ldw $31,$28,31*4 |
ldw $28,$28,33*4 ; restore PSW |
mvts $28,PSW |
rfx ; done |
.syn |
|
;*************************************************************** |
|
.data |
.align 4 |
|
irqsrv: |
.word 0 ; 00: terminal 0 transmitter interrupt |
.word 0 ; 01: terminal 0 receiver interrupt |
.word 0 ; 02: terminal 1 transmitter interrupt |
.word 0 ; 03: terminal 1 receiver interrupt |
.word 0 ; 04: keyboard interrupt |
.word 0 ; 05: unused |
.word 0 ; 06: unused |
.word 0 ; 07: unused |
.word 0 ; 08: disk interrupt |
.word 0 ; 09: unused |
.word 0 ; 10: unused |
.word 0 ; 11: unused |
.word 0 ; 12: unused |
.word 0 ; 13: unused |
.word 0 ; 14: timer interrupt |
.word 0 ; 15: unused |
.word 0 ; 16: bus timeout exception |
.word 0 ; 17: illegal instruction exception |
.word 0 ; 18: privileged instruction exception |
.word 0 ; 19: divide instruction exception |
.word 0 ; 20: trap instruction exception |
.word 0 ; 21: TLB miss exception |
.word 0 ; 22: TLB write exception |
.word 0 ; 23: TLB invalid exception |
.word 0 ; 24: illegal address exception |
.word 0 ; 25: privileged address exception |
.word 0 ; 26: unused |
.word 0 ; 27: unused |
.word 0 ; 28: unused |
.word 0 ; 29: unused |
.word 0 ; 30: unused |
.word 0 ; 31: unused |
/eco32/trunk/hwtests/kbdtest/common.h
0,0 → 1,27
/* |
* common.h -- common definitions |
*/ |
|
|
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
|
#define PAGE_SHIFT 12 /* log2 of page size */ |
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ |
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ |
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ |
|
|
typedef enum { false, true } Bool; /* truth values */ |
|
|
typedef unsigned int Word; /* 32 bit quantities */ |
typedef unsigned short Half; /* 16 bit quantities */ |
typedef unsigned char Byte; /* 8 bit quantities */ |
|
|
#define NULL ((void *) 0) |
|
|
#endif /* _COMMON_H_ */ |
/eco32/trunk/hwtests/memtest2/memtest2.s
0,0 → 1,169
; |
; memtest2.s -- memory test |
; |
|
; $2 temporary |
; $3 tbl address |
; $4 mem address |
; $5 tbl count |
; $6 mem count |
; $7 error |
; $8 I/O base |
; $9 value read |
; $10 reference value |
|
.set mem_base,0xC0000000 |
.set mem_size,1024*1024 |
.set io_base,0xF0300000 |
|
; |
; write memory |
; |
write: |
add $4,$0,mem_base |
add $6,$0,mem_size |
add $3,$0,tbl |
add $5,$0,257 |
wrloop: |
ldbu $2,$3,0 |
stb $2,$4,0 |
add $3,$3,1 |
sub $5,$5,1 |
bne $5,$0,wrloop1 |
add $3,$0,tbl |
add $5,$0,257 |
wrloop1: |
add $4,$4,1 |
sub $6,$6,1 |
bne $6,$0,wrloop |
; |
; read memory |
; |
read: |
add $4,$0,mem_base |
add $6,$0,mem_size |
add $3,$0,tbl |
add $5,$0,257 |
add $7,$0,0 |
rdloop: |
; always check byte |
byte: |
ldbu $9,$4,0 |
ldbu $10,$3,0 |
beq $9,$10,byteok |
add $7,$0,1 |
byteok: |
; possibly check halfword |
half: |
and $2,$4,1 |
bne $2,$0,halfok |
ldhu $9,$4,0 |
ldbu $10,$3,0 |
jal shft8 |
ldbu $2,$3,1 |
or $10,$10,$2 |
beq $9,$10,halfok |
add $7,$0,1 |
halfok: |
; possibly check word |
word: |
and $2,$4,3 |
bne $2,$0,wordok |
ldw $9,$4,0 |
ldbu $10,$3,0 |
jal shft8 |
ldbu $2,$3,1 |
or $10,$10,$2 |
jal shft8 |
ldbu $2,$3,2 |
or $10,$10,$2 |
jal shft8 |
ldbu $2,$3,3 |
or $10,$10,$2 |
beq $9,$10,wordok |
add $7,$0,1 |
wordok: |
; next address |
add $3,$3,1 |
sub $5,$5,1 |
bne $5,$0,rdloop1 |
add $3,$0,tbl |
add $5,$0,257 |
rdloop1: |
add $4,$4,1 |
sub $6,$6,1 |
bne $6,$0,rdloop |
; |
; show result |
; |
bne $7,$0,error |
ok: |
add $7,$0,'.' |
jal out |
j halt |
error: |
add $7,$0,'?' |
jal out |
j halt |
; |
; finally, halt |
; |
halt: |
j halt |
|
shft8: |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
add $10,$10,$10 |
jr $31 |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $7,$8,12 |
jr $31 |
|
tbl: |
.byte 0x45,0x23,0x98,0x48,0xDC,0x5C,0x94,0x58 |
.byte 0x1F,0x7C,0x58,0xD7,0x41,0x1E,0xA9,0xE1 |
.byte 0x00,0x62,0x08,0x27,0x23,0xE9,0xCD,0x43 |
.byte 0x0F,0x25,0xF9,0x72,0xC2,0xD7,0xC4,0x07 |
.byte 0xFB,0x5D,0x50,0xD7,0xBA,0xE4,0x30,0xD9 |
.byte 0x61,0x89,0xB1,0xA3,0xA8,0x5A,0x84,0xA8 |
.byte 0xBD,0x8C,0xD0,0xE0,0x76,0x9E,0x24,0x86 |
.byte 0xC4,0x1D,0xF8,0x86,0xF5,0xBD,0x8D,0xF0 |
.byte 0x1A,0xDD,0xC8,0xD4,0xC2,0xF8,0xAD,0x23 |
.byte 0x82,0x5F,0xC6,0x2A,0xB9,0x4A,0xD3,0x77 |
.byte 0xD7,0xA4,0x58,0x4E,0x42,0x7C,0xD4,0x06 |
.byte 0x9A,0xCC,0x8D,0x8F,0x89,0x1B,0x7F,0xA4 |
.byte 0xF9,0x48,0x78,0xBB,0x40,0x26,0xDE,0xC3 |
.byte 0x85,0xA5,0xED,0x3F,0xF0,0xC1,0xB7,0xC7 |
.byte 0x65,0x0F,0x15,0xA8,0x8C,0xE9,0xAF,0x26 |
.byte 0xB6,0x3C,0xB6,0x40,0x57,0x35,0xE4,0x50 |
.byte 0x7E,0x5D,0x0B,0xBF,0x84,0xEA,0x82,0x0A |
.byte 0x8F,0x70,0x4A,0x7F,0x31,0x02,0x47,0x96 |
.byte 0x12,0x5D,0x3F,0x9E,0x47,0xEE,0xC5,0xFD |
.byte 0x2B,0x7B,0x3E,0x82,0xB1,0x23,0xD3,0x2F |
.byte 0x81,0xDF,0xEE,0x06,0xCA,0x70,0x11,0x59 |
.byte 0xE0,0x5B,0xD9,0x11,0x5E,0x21,0xA8,0x70 |
.byte 0x7E,0xE7,0x0E,0xC5,0xD6,0xD4,0xC3,0x01 |
.byte 0x4F,0x01,0x84,0x01,0x24,0x57,0x30,0xA5 |
.byte 0x37,0x1E,0xAC,0x01,0x8F,0xBD,0x5A,0x70 |
.byte 0x18,0x34,0x82,0x77,0x55,0x2A,0xE7,0xD3 |
.byte 0x12,0xF6,0x99,0xE8,0xCA,0x5C,0xEA,0x1A |
.byte 0x5D,0x6E,0x1B,0x82,0xC5,0x4B,0x28,0xFD |
.byte 0x6A,0xD4,0xFE,0xFA,0x91,0x59,0x6A,0xAA |
.byte 0x8D,0xEC,0x21,0xE3,0x17,0x09,0xB7,0x29 |
.byte 0xFF,0x50,0x12,0xC9,0xAC,0xFC,0xE3,0x0A |
.byte 0x6B,0xFF,0x8D,0x31,0x4A,0xB5,0x2E,0xB5 |
.byte 0x8A |
augment: |
.byte 0x45,0x23,0x98 |
/eco32/trunk/hwtests/memtest2/Makefile
0,0 → 1,27
# |
# Makefile for memtest2 ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: memtest2.exo |
|
install: memtest2.exo |
|
memtest2.exo: memtest2.bin |
$(BUILD)/bin/bin2exo 0 memtest2.bin memtest2.exo |
|
memtest2.bin: memtest2.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o memtest2.bin memtest2.o |
|
memtest2.o: memtest2.s |
$(BUILD)/bin/as -o memtest2.o memtest2.s |
|
run: memtest2.bin |
$(BUILD)/bin/sim -i -t 1 -r memtest2.bin |
|
clean: |
rm -f *~ memtest2.o memtest2.bin memtest2.exo |
/eco32/trunk/hwtests/sregtest/sregtest.s
0,0 → 1,48
; |
; sregtest.s -- test special register transfer instructions |
; |
|
.set io_base,0xF0300000 |
|
add $7,$0,'.' |
|
add $11,$0,0x1E67C536 |
mvts $11,1 |
add $12,$0,0xB45FCC78 |
mvts $12,2 |
add $13,$0,0x1FCB0BC5 |
mvts $13,3 |
|
mvfs $8,1 |
xor $9,$8,$11 |
and $9,$9,0x0000001F |
beq $9,$0,lbl1 |
add $7,$0,'?' |
lbl1: |
|
mvfs $8,2 |
xor $9,$8,$12 |
and $9,$9,0xFFFFF000 |
beq $9,$0,lbl2 |
add $7,$0,'?' |
lbl2: |
|
mvfs $8,3 |
xor $9,$8,$13 |
and $9,$9,0x3FFFF003 |
beq $9,$0,lbl3 |
add $7,$0,'?' |
lbl3: |
|
jal out |
halt: |
j halt |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $7,$8,12 |
jr $31 |
/eco32/trunk/hwtests/sregtest/Makefile
0,0 → 1,26
# |
# Makefile for sregtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: sregtest.exo |
|
install: sregtest.exo |
|
sregtest.exo: sregtest.bin |
$(BUILD)/bin/bin2exo 0 sregtest.bin sregtest.exo |
|
sregtest.bin: sregtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o sregtest.bin sregtest.o |
|
sregtest.o: sregtest.s |
$(BUILD)/bin/as -o sregtest.o sregtest.s |
|
run: sregtest.bin |
$(BUILD)/bin/sim -i -t 1 -r sregtest.bin |
|
clean: |
rm -f *~ sregtest.o sregtest.bin sregtest.exo |
/eco32/trunk/hwtests/tmrtest/tmrtest.s
0,0 → 1,33
; |
; tmrtest.s -- test timer |
; |
|
.set tmr_base,0xF0000000 |
.set io_base,0xF0300000 |
|
add $8,$0,tmr_base |
add $9,$0,1000 |
stw $9,$8,4 |
add $7,$0,'a'-10 |
again: |
jal out |
wait: |
add $8,$0,tmr_base |
ldw $9,$8,0 |
and $9,$9,1 |
beq $9,$0,wait |
stw $0,$8,0 |
add $7,$7,1 |
add $9,$0,'z'+1 |
bne $7,$9,again |
add $7,$0,'a' |
j again |
|
out: |
add $8,$0,io_base |
out1: |
ldw $9,$8,8 |
and $9,$9,1 |
beq $9,$0,out1 |
stw $7,$8,12 |
jr $31 |
/eco32/trunk/hwtests/tmrtest/Makefile
0,0 → 1,27
# |
# Makefile for tmrtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: tmrtest.exo |
|
install: tmrtest.exo |
|
tmrtest.exo: tmrtest.bin |
$(BUILD)/bin/bin2exo 0 tmrtest.bin tmrtest.exo |
|
tmrtest.bin: tmrtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o tmrtest.bin tmrtest.o |
|
tmrtest.o: tmrtest.s |
$(BUILD)/bin/as -o tmrtest.o tmrtest.s |
|
run: tmrtest.bin |
$(BUILD)/bin/sim -i -t 1 -r tmrtest.bin |
|
clean: |
rm -f *~ tmrtest.o tmrtest.bin tmrtest.exo |
/eco32/trunk/hwtests/brtest/mkbrtest.c
0,0 → 1,166
/* |
* mkbrtest.c -- generate branch test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
typedef int Bool; |
|
|
Bool eq(unsigned x, unsigned y) { |
return x == y; |
} |
|
|
Bool ne(unsigned x, unsigned y) { |
return x != y; |
} |
|
|
Bool gt(unsigned x, unsigned y) { |
return (signed) x > (signed) y; |
} |
|
|
Bool ge(unsigned x, unsigned y) { |
return (signed) x >= (signed) y; |
} |
|
|
Bool lt(unsigned x, unsigned y) { |
return (signed) x < (signed) y; |
} |
|
|
Bool le(unsigned x, unsigned y) { |
return (signed) x <= (signed) y; |
} |
|
|
Bool gtu(unsigned x, unsigned y) { |
return x > y; |
} |
|
|
Bool geu(unsigned x, unsigned y) { |
return x >= y; |
} |
|
|
Bool ltu(unsigned x, unsigned y) { |
return x < y; |
} |
|
|
Bool leu(unsigned x, unsigned y) { |
return x <= y; |
} |
|
|
unsigned nums[] = { |
0x00000000, |
0x00000001, |
0x00000002, |
0x00000003, |
0x7FFFFFFC, |
0x7FFFFFFD, |
0x7FFFFFFE, |
0x7FFFFFFF, |
0x80000000, |
0x80000001, |
0x80000002, |
0x80000003, |
0xFFFFFFFC, |
0xFFFFFFFD, |
0xFFFFFFFE, |
0xFFFFFFFF, |
}; |
|
int snums = sizeof(nums) / sizeof(nums[0]); |
|
|
struct { |
char *name; |
Bool (*func)(unsigned x, unsigned y); |
} ops[] = { |
{ "eq", eq }, |
{ "ne", ne }, |
{ "gt", gt }, |
{ "ge", ge }, |
{ "lt", lt }, |
{ "le", le }, |
{ "gtu", gtu }, |
{ "geu", geu }, |
{ "ltu", ltu }, |
{ "leu", leu }, |
}; |
|
int sops = sizeof(ops) / sizeof(ops[0]); |
|
|
int chooseReg(void) { |
int r; |
|
r = (rand() >> 8) % 16; |
return r + 8; |
} |
|
|
void chooseRegs(int *r1, int *r2) { |
*r1 = chooseReg(); |
do { |
*r2 = chooseReg(); |
} while (*r2 == *r1); |
} |
|
|
int newLabel(void) { |
static int lbl = 1000; |
return lbl++; |
} |
|
|
int main(void) { |
int i, j, k; |
Bool res; |
int r1, r2; |
int lbl1, lbl2; |
|
printf("\tadd\t$7,$0,'.'\n"); |
for (i = 0; i < snums; i++) { |
for (j = 0; j < snums; j++) { |
for (k = 0; k < sops; k++) { |
res = ops[k].func(nums[i], nums[j]); |
chooseRegs(&r1, &r2); |
lbl1 = newLabel(); |
printf("\tadd\t$%d,$0,0x%08X\n", r1, nums[i]); |
printf("\tadd\t$%d,$0,0x%08X\n", r2, nums[j]); |
printf("\tb%s\t$%d,$%d,L%d\n", ops[k].name, r1, r2, lbl1); |
if (res) { |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl1); |
} else { |
lbl2 = newLabel(); |
printf("\tj\tL%d\n", lbl2); |
printf("L%d:\n", lbl1); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl2); |
} |
} |
} |
} |
printf("out:\n"); |
printf("\tadd\t$6,$0,0xF0300000\n"); |
printf("out1:\n"); |
printf("\tldw\t$5,$6,8\n"); |
printf("\tand\t$5,$5,1\n"); |
printf("\tbeq\t$5,$0,out1\n"); |
printf("\tstw\t$7,$6,12\n"); |
printf("halt:\n"); |
printf("\tj\thalt\n"); |
return 0; |
} |
/eco32/trunk/hwtests/brtest/Makefile
0,0 → 1,33
# |
# Makefile for brtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: brtest.exo |
|
install: brtest.exo |
|
brtest.exo: brtest.bin |
$(BUILD)/bin/bin2exo 0 brtest.bin brtest.exo |
|
brtest.bin: brtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o brtest.bin brtest.o |
|
brtest.o: brtest.s |
$(BUILD)/bin/as -o brtest.o brtest.s |
|
brtest.s: mkbrtest |
./mkbrtest > brtest.s |
|
mkbrtest: mkbrtest.c |
gcc -m32 -g -Wall -o mkbrtest mkbrtest.c |
|
run: brtest.bin |
$(BUILD)/bin/sim -i -t 1 -r brtest.bin |
|
clean: |
rm -f *~ mkbrtest brtest.s brtest.o |
rm -f brtest.bin brtest.exo |
/eco32/trunk/hwtests/looptest/mklooptest.c
0,0 → 1,31
/* |
* mklooptest.c -- generate loop test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
int main(void) { |
int i; |
|
printf("start:\n"); |
for (i = 0; i < 100; i++) { |
printf("\tadd\t$1,$2,$3\n"); |
printf("\tadd\t$1,$2,0x5555\n"); |
printf("\tsub\t$4,$5,$6\n"); |
printf("\tsub\t$4,$5,0xAAAA\n"); |
printf("\tand\t$7,$8,$9\n"); |
printf("\tand\t$7,$8,0x5555\n"); |
printf("\tor\t$10,$11,$12\n"); |
printf("\tor\t$10,$11,0xAAAA\n"); |
printf("\txor\t$13,$14,$15\n"); |
printf("\txor\t$13,$14,0x5555\n"); |
printf("\txnor\t$16,$17,$18\n"); |
printf("\txnor\t$16,$17,0xAAAA\n"); |
} |
printf("\tj\tstart\n"); |
return 0; |
} |
/eco32/trunk/hwtests/looptest/Makefile
0,0 → 1,34
# |
# Makefile for looptest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: looptest.exo |
|
install: looptest.exo |
|
looptest.exo: looptest.bin |
$(BUILD)/bin/bin2exo 0 looptest.bin looptest.exo |
|
looptest.bin: looptest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 \ |
-o looptest.bin looptest.o |
|
looptest.o: looptest.s |
$(BUILD)/bin/as -o looptest.o looptest.s |
|
looptest.s: mklooptest |
./mklooptest > looptest.s |
|
mklooptest: mklooptest.c |
gcc -m32 -g -Wall -o mklooptest mklooptest.c |
|
run: looptest.bin |
$(BUILD)/bin/sim -i -t 1 -r looptest.bin |
|
clean: |
rm -f *~ mklooptest looptest.s looptest.o |
rm -f looptest.bin looptest.exo |
/eco32/trunk/hwtests/shtest/mkshtest.c
0,0 → 1,200
/* |
* mkshtest.c -- generate shift test program |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
#define N0 ((unsigned) 0x48E6F0B2) |
#define N1 ((unsigned) 0xC8E6F0B3) |
|
|
int chooseReg(void) { |
int r; |
|
r = (rand() >> 8) % 16; |
return r + 8; |
} |
|
|
void chooseRegs(int *r1, int *r2, int *r3, int *r4) { |
*r1 = chooseReg(); |
do { |
*r2 = chooseReg(); |
} while (*r2 == *r1); |
do { |
*r3 = chooseReg(); |
} while (*r3 == *r2 || *r3 == *r1); |
do { |
*r4 = chooseReg(); |
} while (*r4 == *r3 || *r4 == *r2 || *r4 == *r1); |
} |
|
|
int newLabel(void) { |
static int lbl = 1000; |
return lbl++; |
} |
|
|
unsigned sar(unsigned n, int shamt) { |
unsigned mask; |
|
mask = (n & 0x80000000) ? ~((unsigned) 0xFFFFFFFF >> shamt) : 0x00000000; |
return mask | (n >> shamt); |
} |
|
|
int main(void) { |
int shamt; |
int src; |
int sha; |
int dst; |
int ref; |
int lbl; |
|
printf("\tadd\t$7,$0,'.'\n"); |
for (shamt = 0; shamt < 32; shamt++) { |
/* sll, N0 */ |
printf("\t; sll, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tsll\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N0 << shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* slli, N0 */ |
printf("\t; slli, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tsll\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N0 << shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* sll, N1 */ |
printf("\t; sll, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tsll\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N1 << shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* slli, N1 */ |
printf("\t; slli, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tsll\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N1 << shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
|
/* slr, N0 */ |
printf("\t; slr, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tslr\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N0 >> shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* slri, N0 */ |
printf("\t; slri, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tslr\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N0 >> shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* slr, N1 */ |
printf("\t; slr, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tslr\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N1 >> shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* slri, N1 */ |
printf("\t; slri, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tslr\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, N1 >> shamt); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
|
/* sar, N0 */ |
printf("\t; sar, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tsar\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, sar(N0, shamt)); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* sari, N0 */ |
printf("\t; sari, n0\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N0); |
printf("\tsar\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, sar(N0, shamt)); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* sar, N1 */ |
printf("\t; sar, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tadd\t$%d,$0,%d\n", sha, shamt); |
printf("\tsar\t$%d,$%d,$%d\n", dst, src, sha); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, sar(N1, shamt)); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
/* sari, N1 */ |
printf("\t; sari, n1\n"); |
chooseRegs(&src, &sha, &dst, &ref); |
printf("\tadd\t$%d,$0,0x%08X\n", src, N1); |
printf("\tsar\t$%d,$%d,%d\n", dst, src, shamt); |
printf("\tadd\t$%d,$0,0x%08X\n", ref, sar(N1, shamt)); |
lbl = newLabel(); |
printf("\tbeq\t$%d,$%d,L%d\n", dst, ref, lbl); |
printf("\tadd\t$7,$0,'?'\n"); |
printf("L%d:\n", lbl); |
} |
printf("out:\n"); |
printf("\tadd\t$6,$0,0xF0300000\n"); |
printf("out1:\n"); |
printf("\tldw\t$5,$6,8\n"); |
printf("\tand\t$5,$5,1\n"); |
printf("\tbeq\t$5,$0,out1\n"); |
printf("\tstw\t$7,$6,12\n"); |
printf("halt:\n"); |
printf("\tj\thalt\n"); |
return 0; |
} |
/eco32/trunk/hwtests/shtest/Makefile
0,0 → 1,33
# |
# Makefile for shtest ROM |
# |
|
BUILD = ../../build |
|
.PHONY: all install run clean |
|
all: shtest.exo |
|
install: shtest.exo |
|
shtest.exo: shtest.bin |
$(BUILD)/bin/bin2exo 0 shtest.bin shtest.exo |
|
shtest.bin: shtest.o |
$(BUILD)/bin/ld -h -rc 0xE0000000 -o shtest.bin shtest.o |
|
shtest.o: shtest.s |
$(BUILD)/bin/as -o shtest.o shtest.s |
|
shtest.s: mkshtest |
./mkshtest > shtest.s |
|
mkshtest: mkshtest.c |
gcc -m32 -g -Wall -o mkshtest mkshtest.c |
|
run: shtest.bin |
$(BUILD)/bin/sim -i -t 1 -r shtest.bin |
|
clean: |
rm -f *~ mkshtest shtest.s shtest.o |
rm -f shtest.bin shtest.exo |
/eco32/trunk/hwtests/Makefile
0,0 → 1,27
# |
# Makefile for building hardware test ROMs |
# |
|
BUILD = ../build |
|
DIRS = tools serial looptest ldtest memtest1 memtest2 shtest brtest \ |
tmrtest multest divtest remtest sregtest tlbtest irqtest xcptest \ |
dsptest kbdtest jalrtest |
|
.PHONY: all install clean |
|
all: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i all ; \ |
done |
|
install: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i install ; \ |
done |
|
clean: |
for i in $(DIRS) ; do \ |
$(MAKE) -C $$i clean ; \ |
done |
rm -f *~ |
/eco32/trunk/Makefile
4,7 → 4,7
|
VERSION = 0.22 |
|
DIRS = doc binutils sim simtest fpga |
DIRS = doc binutils sim simtest fpga hwtests |
BUILD = `pwd`/build |
|
.PHONY: all compiler builddir clean dist |