OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/tags/eco32-0.24/hwtests/tlbtest
    from Rev 150 to Rev 211
    Reverse comparison

Rev 150 → Rev 211

/README
0,0 → 1,?rev2len?
This is a test for the TLB. It shows a report on serial line 0.
/serial.s
0,0 → 1,98
;
; serial.s -- the serial line interface
;
 
;***************************************************************
 
.set ser0base,0xF0300000 ; serial line 0 base address
.set ser1base,0xF0301000 ; 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
/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 -S2 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
/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_ */
/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;
}
/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:
/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;
}
/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_ */
/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_ */
/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_ */
/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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.