Compare commits
8 Commits
tools
...
mz-startup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0705e54ab | ||
|
|
459e3f09ea | ||
|
|
a0d4e7f517 | ||
|
|
dc1a7a5f25 | ||
|
|
17f417f519 | ||
|
|
8871099aab | ||
|
|
6a2230d867 | ||
|
|
688209e604 |
@@ -216,7 +216,8 @@ const struct optable optable [] = {
|
|||||||
{ 0x04110000, "bal", FAOFF18 | FDSLOT },
|
{ 0x04110000, "bal", FAOFF18 | FDSLOT },
|
||||||
{ 0x10000000, "beq", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
{ 0x10000000, "beq", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
||||||
{ 0x50000000, "beql", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
{ 0x50000000, "beql", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
||||||
{ 0x50000000, "beqz", FRS1 | FOFF18 | FDSLOT },
|
{ 0x10000000, "beqz", FRS1 | FOFF18 | FDSLOT },
|
||||||
|
{ 0x50000000, "beqzl", FRS1 | FOFF18 | FDSLOT },
|
||||||
{ 0x04010000, "bgez", FRS1 | FOFF18 | FDSLOT },
|
{ 0x04010000, "bgez", FRS1 | FOFF18 | FDSLOT },
|
||||||
{ 0x04110000, "bgezal", FRS1 | FOFF18 | FDSLOT },
|
{ 0x04110000, "bgezal", FRS1 | FOFF18 | FDSLOT },
|
||||||
{ 0x04130000, "bgezall", FRS1 | FOFF18 | FDSLOT },
|
{ 0x04130000, "bgezall", FRS1 | FOFF18 | FDSLOT },
|
||||||
@@ -231,7 +232,8 @@ const struct optable optable [] = {
|
|||||||
{ 0x04020000, "bltzl", FRS1 | FOFF18 | FDSLOT },
|
{ 0x04020000, "bltzl", FRS1 | FOFF18 | FDSLOT },
|
||||||
{ 0x14000000, "bne", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
{ 0x14000000, "bne", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
||||||
{ 0x54000000, "bnel", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
{ 0x54000000, "bnel", FRS1 | FRT2 | FOFF18 | FDSLOT },
|
||||||
{ 0x54000000, "bnez", FRS1 | FOFF18 | FDSLOT },
|
{ 0x14000000, "bnez", FRS1 | FOFF18 | FDSLOT },
|
||||||
|
{ 0x54000000, "bnezl", FRS1 | FOFF18 | FDSLOT },
|
||||||
{ 0x0000000d, "break", FCODE16 },
|
{ 0x0000000d, "break", FCODE16 },
|
||||||
{ 0x70000021, "clo", FRD1 | FRS2 | FRTD | FMOD },
|
{ 0x70000021, "clo", FRD1 | FRS2 | FRTD | FMOD },
|
||||||
{ 0x70000020, "clz", FRD1 | FRS2 | FRTD | FMOD },
|
{ 0x70000020, "clz", FRD1 | FRS2 | FRTD | FMOD },
|
||||||
@@ -1271,6 +1273,9 @@ void emit_li (opcode, relinfo)
|
|||||||
} else if (value >= -0x8000) {
|
} else if (value >= -0x8000) {
|
||||||
/* addiu d, $zero, value */
|
/* addiu d, $zero, value */
|
||||||
opcode |= 0x24000000 | (value & 0xffff);
|
opcode |= 0x24000000 | (value & 0xffff);
|
||||||
|
} else if ((value & 0xffff) == 0) {
|
||||||
|
/* lui d, value[31:16] */
|
||||||
|
opcode |= 0x3c000000 | (value >> 16);
|
||||||
} else {
|
} else {
|
||||||
/* lui d, value[31:16]
|
/* lui d, value[31:16]
|
||||||
* ori d, d, value[15:0]) */
|
* ori d, d, value[15:0]) */
|
||||||
@@ -1627,6 +1632,9 @@ foff16: expr_flags = 0;
|
|||||||
} else if (offset >= -0x8000) {
|
} else if (offset >= -0x8000) {
|
||||||
/* addiu $1, $zero, value */
|
/* addiu $1, $zero, value */
|
||||||
emitword (0x24010000 | (offset & 0xffff), &relabs, 1);
|
emitword (0x24010000 | (offset & 0xffff), &relabs, 1);
|
||||||
|
} else if ((offset & 0xffff) == 0) {
|
||||||
|
/* lui $1, value[31:16] */
|
||||||
|
emitword (0x3c010000 | (offset >> 16), &relabs, 1);
|
||||||
} else {
|
} else {
|
||||||
/* lui $1, value[31:16]
|
/* lui $1, value[31:16]
|
||||||
* ori $1, $1, value[15:0]) */
|
* ori $1, $1, value[15:0]) */
|
||||||
@@ -2158,7 +2166,7 @@ void pass1 ()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LCOMM:
|
case LCOMM:
|
||||||
/* .comm name,len */
|
/* .comm name,len[,alignment] */
|
||||||
if (getlex (&cval) != LNAME)
|
if (getlex (&cval) != LNAME)
|
||||||
uerror ("bad parameter of .comm");
|
uerror ("bad parameter of .comm");
|
||||||
cval = lookname();
|
cval = lookname();
|
||||||
@@ -2369,18 +2377,28 @@ int findlabel (int addr, int sym)
|
|||||||
|
|
||||||
void middle ()
|
void middle ()
|
||||||
{
|
{
|
||||||
register int i, snum;
|
register int i, snum, nbytes;
|
||||||
|
|
||||||
stlength = 0;
|
stlength = 0;
|
||||||
for (snum=0, i=0; i<stabfree; i++) {
|
for (snum=0, i=0; i<stabfree; i++) {
|
||||||
/* Without -u option, undefined symbol is considered external */
|
switch (stab[i].n_type) {
|
||||||
if (stab[i].n_type == N_UNDF) {
|
case N_UNDF:
|
||||||
|
/* Without -u option, undefined symbol is considered external */
|
||||||
if (uflag)
|
if (uflag)
|
||||||
uerror ("name undefined", stab[i].n_name);
|
uerror ("name undefined", stab[i].n_name);
|
||||||
stab[i].n_type |= N_EXT;
|
stab[i].n_type |= N_EXT;
|
||||||
|
break;
|
||||||
|
case N_COMM:
|
||||||
|
/* Allocate a local common block */
|
||||||
|
nbytes = stab[i].n_value;
|
||||||
|
stab[i].n_value = count[SBSS];
|
||||||
|
stab[i].n_type = N_BSS;
|
||||||
|
count[SBSS] += nbytes;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (xflags)
|
if (xflags)
|
||||||
newindex[i] = snum;
|
newindex[i] = snum;
|
||||||
|
|
||||||
if (! xflags || (stab[i].n_type & N_EXT) ||
|
if (! xflags || (stab[i].n_type & N_EXT) ||
|
||||||
(Xflag && ! IS_LOCAL(&stab[i])))
|
(Xflag && ! IS_LOCAL(&stab[i])))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ include $(TOPSRC)/target.mk
|
|||||||
#include $(TOPSRC)/cross.mk
|
#include $(TOPSRC)/cross.mk
|
||||||
#CFLAGS = -DCROSS
|
#CFLAGS = -DCROSS
|
||||||
|
|
||||||
OBJS = cpp.o cpy.o token.o
|
OBJS = cpp.o cpy.o token.o doprnt.o
|
||||||
MAN = cpp.0
|
MAN = cpp.0
|
||||||
MANSRC = cpp.1
|
MANSRC = cpp.1
|
||||||
|
|
||||||
LDFLAGS += -g
|
LDFLAGS += -g
|
||||||
|
|
||||||
CFLAGS += -Werror -Wall -Os
|
CFLAGS += -Werror -Wall -Os
|
||||||
CFLAGS += -DCPP_DEBUG -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
|
#CFLAGS += -DCPP_DEBUG -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
|
||||||
|
CFLAGS += -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
|
||||||
|
|
||||||
all: cpp $(MAN)
|
all: cpp $(MAN)
|
||||||
|
|
||||||
|
|||||||
@@ -1309,6 +1309,7 @@ expdef(const uchar *vp, struct recur *rp, int gotwarn)
|
|||||||
uchar *sptr;
|
uchar *sptr;
|
||||||
int narg, c, i, plev, snuff, instr;
|
int narg, c, i, plev, snuff, instr;
|
||||||
int ellips = 0, shot = gotwarn;
|
int ellips = 0, shot = gotwarn;
|
||||||
|
size_t allocsz;
|
||||||
|
|
||||||
DPRINT(("expdef rp %s\n", (rp ? (const char *)rp->sp->namep : "")));
|
DPRINT(("expdef rp %s\n", (rp ? (const char *)rp->sp->namep : "")));
|
||||||
c = sloscan();
|
c = sloscan();
|
||||||
@@ -1321,7 +1322,10 @@ expdef(const uchar *vp, struct recur *rp, int gotwarn)
|
|||||||
} else
|
} else
|
||||||
narg = vp[1];
|
narg = vp[1];
|
||||||
|
|
||||||
args = malloc(sizeof(uchar *) * (narg+ellips));
|
// The code depends on malloc(0) returning a non-NULL pointer, which is not guaranteed.
|
||||||
|
// Workaround it.
|
||||||
|
allocsz = sizeof(uchar *) * ((narg+ellips) ? (narg+ellips) : 1);
|
||||||
|
args = malloc(allocsz);
|
||||||
if (args == NULL)
|
if (args == NULL)
|
||||||
error("expdef: out of mem");
|
error("expdef: out of mem");
|
||||||
|
|
||||||
|
|||||||
203
src/cmd/cpp/doprnt.c
Normal file
203
src/cmd/cpp/doprnt.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2013, Alexey Frunze
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
The views and conclusions contained in the software and documentation are those
|
||||||
|
of the authors and should not be interpreted as representing official policies,
|
||||||
|
either expressed or implied, of the FreeBSD Project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int _doprnt (char const *fmt, va_list pp, FILE *stream)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
const char* p;
|
||||||
|
const char* phex = "0123456789abcdef";
|
||||||
|
char s[1/*sign*/+10/*magnitude*/+1/*\0*/]; // up to 11 octal digits in 32-bit numbers
|
||||||
|
char* pc;
|
||||||
|
int n, sign, msign;
|
||||||
|
int minlen = 0, len;
|
||||||
|
int leadchar;
|
||||||
|
|
||||||
|
for (p = fmt; *p != '\0'; p++)
|
||||||
|
{
|
||||||
|
if (*p != '%' || p[1] == '%')
|
||||||
|
{
|
||||||
|
fputc(*p, stream);
|
||||||
|
p = p + (*p == '%');
|
||||||
|
cnt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
minlen = 0;
|
||||||
|
msign = 0;
|
||||||
|
if (*p == '+') { msign = 1; p++; }
|
||||||
|
else if (*p == '-') { msign = -1; p++; }
|
||||||
|
leadchar = ' ';
|
||||||
|
if (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
if (*p == '0')
|
||||||
|
leadchar = '0';
|
||||||
|
while (*p >= '0' && *p <= '9')
|
||||||
|
minlen = minlen * 10 + *p++ - '0';
|
||||||
|
if (msign < 0)
|
||||||
|
minlen = -minlen;
|
||||||
|
msign = 0;
|
||||||
|
}
|
||||||
|
if (!msign)
|
||||||
|
{
|
||||||
|
if (*p == '+') { msign = 1; p++; }
|
||||||
|
else if (*p == '-') { msign = -1; p++; }
|
||||||
|
}
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case 'c':
|
||||||
|
while (minlen > 1) { fputc(' ', stream); cnt++; minlen--; }
|
||||||
|
fputc(va_arg(pp, int), stream);
|
||||||
|
while (-minlen > 1) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
cnt++;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
pc = va_arg(pp, char*);
|
||||||
|
len = 0;
|
||||||
|
if (pc)
|
||||||
|
len = strlen(pc);
|
||||||
|
while (minlen > len) { fputc(' ', stream); cnt++; minlen--; }
|
||||||
|
if (len)
|
||||||
|
while (*pc != '\0')
|
||||||
|
{
|
||||||
|
fputc(*pc++, stream);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
case 'd':
|
||||||
|
pc = &s[sizeof s - 1];
|
||||||
|
*pc = '\0';
|
||||||
|
len = 0;
|
||||||
|
n = va_arg(pp, int);
|
||||||
|
sign = 1 - 2 * (n < 0);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*--pc = '0' + (n - n / 10 * 10) * sign;
|
||||||
|
n = n / 10;
|
||||||
|
len++;
|
||||||
|
} while (n);
|
||||||
|
if (sign < 0)
|
||||||
|
{
|
||||||
|
*--pc = '-';
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
else if (msign > 0)
|
||||||
|
{
|
||||||
|
*--pc = '+';
|
||||||
|
len++;
|
||||||
|
msign = 0;
|
||||||
|
}
|
||||||
|
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
|
||||||
|
while (*pc != '\0')
|
||||||
|
{
|
||||||
|
fputc(*pc++, stream);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
pc = &s[sizeof s - 1];
|
||||||
|
*pc = '\0';
|
||||||
|
len = 0;
|
||||||
|
n = va_arg(pp, int);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned nn = n;
|
||||||
|
*--pc = '0' + nn % 10;
|
||||||
|
n = nn / 10;
|
||||||
|
len++;
|
||||||
|
} while (n);
|
||||||
|
if (msign > 0)
|
||||||
|
{
|
||||||
|
*--pc = '+';
|
||||||
|
len++;
|
||||||
|
msign = 0;
|
||||||
|
}
|
||||||
|
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
|
||||||
|
while (*pc != '\0')
|
||||||
|
{
|
||||||
|
fputc(*pc++, stream);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
phex = "0123456789ABCDEF";
|
||||||
|
// fallthrough
|
||||||
|
case 'p':
|
||||||
|
case 'x':
|
||||||
|
pc = &s[sizeof s - 1];
|
||||||
|
*pc = '\0';
|
||||||
|
len = 0;
|
||||||
|
n = va_arg(pp, int);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*--pc = phex[n & 0xF];
|
||||||
|
n = (n >> 4) & ((1 << (8 * sizeof n - 4)) - 1); // drop sign-extended bits
|
||||||
|
len++;
|
||||||
|
} while (n);
|
||||||
|
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
|
||||||
|
while (*pc != '\0')
|
||||||
|
{
|
||||||
|
fputc(*pc++, stream);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
pc = &s[sizeof s - 1];
|
||||||
|
*pc = '\0';
|
||||||
|
len = 0;
|
||||||
|
n = va_arg(pp, int);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*--pc = '0' + (n & 7);
|
||||||
|
n = (n >> 3) & ((1 << (8 * sizeof n - 3)) - 1); // drop sign-extended bits
|
||||||
|
len++;
|
||||||
|
} while (n);
|
||||||
|
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
|
||||||
|
while (*pc != '\0')
|
||||||
|
{
|
||||||
|
fputc(*pc++, stream);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
@@ -6401,7 +6401,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
|||||||
int hasInit = tok == '=';
|
int hasInit = tok == '=';
|
||||||
int needsGlobalInit = isGlobal & !external;
|
int needsGlobalInit = isGlobal & !external;
|
||||||
int sz = GetDeclSize(lastSyntaxPtr, 0);
|
int sz = GetDeclSize(lastSyntaxPtr, 0);
|
||||||
int localAllocSize = 0;
|
|
||||||
int skipLabel = 0;
|
int skipLabel = 0;
|
||||||
int initLabel = 0;
|
int initLabel = 0;
|
||||||
|
|
||||||
@@ -6525,7 +6524,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
|||||||
// update its offset in the offset token
|
// update its offset in the offset token
|
||||||
SyntaxStack[lastSyntaxPtr + 1][1] = CurFxnLocalOfs;
|
SyntaxStack[lastSyntaxPtr + 1][1] = CurFxnLocalOfs;
|
||||||
|
|
||||||
localAllocSize = oldOfs - CurFxnLocalOfs;
|
|
||||||
if (CurFxnMinLocalOfs > CurFxnLocalOfs)
|
if (CurFxnMinLocalOfs > CurFxnLocalOfs)
|
||||||
CurFxnMinLocalOfs = CurFxnLocalOfs;
|
CurFxnMinLocalOfs = CurFxnLocalOfs;
|
||||||
|
|
||||||
@@ -6878,7 +6876,9 @@ void AddFxnParamSymbols(int SyntaxPtr)
|
|||||||
if (tok == tokIdent)
|
if (tok == tokIdent)
|
||||||
{
|
{
|
||||||
int sz;
|
int sz;
|
||||||
|
#ifndef NO_ANNOTATIONS
|
||||||
int paramPtr;
|
int paramPtr;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (i + 1 >= SyntaxStackCnt)
|
if (i + 1 >= SyntaxStackCnt)
|
||||||
//error("Internal error: AddFxnParamSymbols(): Invalid input\n");
|
//error("Internal error: AddFxnParamSymbols(): Invalid input\n");
|
||||||
@@ -6896,7 +6896,9 @@ void AddFxnParamSymbols(int SyntaxPtr)
|
|||||||
|
|
||||||
// Let's calculate this parameter's relative on-stack location
|
// Let's calculate this parameter's relative on-stack location
|
||||||
CurFxnParamOfs = (CurFxnParamOfs + SizeOfWord - 1) / SizeOfWord * SizeOfWord;
|
CurFxnParamOfs = (CurFxnParamOfs + SizeOfWord - 1) / SizeOfWord * SizeOfWord;
|
||||||
|
#ifndef NO_ANNOTATIONS
|
||||||
paramPtr = SyntaxStackCnt;
|
paramPtr = SyntaxStackCnt;
|
||||||
|
#endif
|
||||||
PushSyntax2(SyntaxStack[i][0], SyntaxStack[i][1]);
|
PushSyntax2(SyntaxStack[i][0], SyntaxStack[i][1]);
|
||||||
PushSyntax2(tokLocalOfs, CurFxnParamOfs);
|
PushSyntax2(tokLocalOfs, CurFxnParamOfs);
|
||||||
CurFxnParamOfs += sz;
|
CurFxnParamOfs += sz;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#
|
#
|
||||||
# Startup code for Microchip PIC32 microcontrollers.
|
# Startup code for Microchip PIC32 microcontrollers.
|
||||||
# Using HID bootloader.
|
# Based on the MIPS application note:
|
||||||
|
# "Boot-CPS: Example Boot Code for MIPS® Cores".
|
||||||
#
|
#
|
||||||
# Copyright (C) 2010 Serge Vakulenko, <serge@vak.ru>
|
# Copyright (C) 2010-2014 Serge Vakulenko, <serge@vak.ru>
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and distribute this software
|
# Permission to use, copy, modify, and distribute this software
|
||||||
# and its documentation for any purpose and without fee is hereby
|
# and its documentation for any purpose and without fee is hereby
|
||||||
@@ -24,86 +25,350 @@
|
|||||||
#
|
#
|
||||||
#include "machine/io.h"
|
#include "machine/io.h"
|
||||||
|
|
||||||
#define UBASE 0x7f008000 /* User space base address */
|
#define UBASE 0x7f008000 /* User space base address */
|
||||||
|
|
||||||
.set noreorder
|
/*
|
||||||
.set mips32r2
|
* MIPS Coprocessor 0 register numbers
|
||||||
.set nomips16
|
*/
|
||||||
|
#define C0_INDEX $0
|
||||||
|
#define C0_ENTRYLO0 $2
|
||||||
|
#define C0_ENTRYLO1 $3
|
||||||
|
#define C0_PAGEMASK $5
|
||||||
|
#define C0_WIRED $6
|
||||||
|
#define C0_COUNT $9
|
||||||
|
#define C0_ENTRYHI $10
|
||||||
|
#define C0_COMPARE $11
|
||||||
|
#define C0_STATUS $12
|
||||||
|
#define C0_SRSCTL $12,2
|
||||||
|
#define C0_CAUSE $13
|
||||||
|
#define C0_EPC $14
|
||||||
|
#define C0_CONFIG $16
|
||||||
|
#define C0_CONFIG1 $16,1
|
||||||
|
#define C0_CONFIG7 $16,7
|
||||||
|
#define C0_WATCHLO $18
|
||||||
|
#define C0_WATCHHI $19
|
||||||
|
#define C0_DEBUG $23
|
||||||
|
#define C0_DEPC $24
|
||||||
|
#define C0_ITAGLO $28
|
||||||
|
#define C0_DTAGLO $28,2
|
||||||
|
#define C0_ERRPC $30
|
||||||
|
|
||||||
.extern u
|
/*
|
||||||
.extern u_end
|
* MIPS Config1 register
|
||||||
.extern u0
|
*/
|
||||||
.extern main
|
#define CFG1_MMUSSHIFT 25 // mmu size - 1
|
||||||
.extern exception
|
#define CFG1_ISSHIFT 22 // icache lines 64<<n
|
||||||
|
#define CFG1_ILSHIFT 19 // icache line size 2<<n
|
||||||
|
#define CFG1_IASHIFT 16 // icache ways - 1
|
||||||
|
#define CFG1_DSSHIFT 13 // dcache lines 64<<n
|
||||||
|
#define CFG1_DLSHIFT 10 // dcache line size 2<<n
|
||||||
|
#define CFG1_DASHIFT 7 // dcache ways - 1
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set mips32r2
|
||||||
|
.set nomips16
|
||||||
|
|
||||||
|
.extern u
|
||||||
|
.extern u_end
|
||||||
|
.extern u0
|
||||||
|
.extern main
|
||||||
|
.extern exception
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Reset vector: main entry point
|
# Reset vector: main entry point
|
||||||
#
|
#
|
||||||
.section .startup,"ax",@progbits
|
.section .startup,"ax",@progbits
|
||||||
.org 0
|
.org 0
|
||||||
.type _reset_vector_, @function
|
.type _reset_vector_, @function
|
||||||
_reset_vector_: .globl _reset_vector_
|
_reset_vector_: .globl _reset_vector_
|
||||||
|
|
||||||
.set noat
|
.set noat
|
||||||
move $1, $zero # Clear all regs
|
mtc0 $0, C0_COUNT # Clear cp0 Count (Used to measure boot time.)
|
||||||
move $2, $zero
|
#if 0
|
||||||
move $3, $zero
|
//
|
||||||
move $4, $zero
|
// Check for NMI exception.
|
||||||
move $5, $zero
|
//
|
||||||
move $6, $zero
|
check_nmi: # Check whether we are here due to a reset or NMI.
|
||||||
move $7, $zero
|
mfc0 $s1, C0_STATUS # Read Status
|
||||||
move $8, $zero
|
ext $s1, $s1, 19, 1 # extract NMI
|
||||||
move $9, $zero
|
beqz $s1, init_gpr # Branch if this is NOT an NMI exception.
|
||||||
move $10, $zero
|
nop
|
||||||
move $11, $zero
|
|
||||||
move $12, $zero
|
|
||||||
move $13, $zero
|
|
||||||
move $14, $zero
|
|
||||||
move $15, $zero
|
|
||||||
move $16, $zero
|
|
||||||
move $17, $zero
|
|
||||||
move $18, $zero
|
|
||||||
move $19, $zero
|
|
||||||
move $20, $zero
|
|
||||||
move $21, $zero
|
|
||||||
move $22, $zero
|
|
||||||
move $23, $zero
|
|
||||||
move $24, $zero
|
|
||||||
move $25, $zero
|
|
||||||
move $26, $zero
|
|
||||||
move $27, $zero
|
|
||||||
move $28, $zero
|
|
||||||
move $29, $zero
|
|
||||||
move $30, $zero
|
|
||||||
move $31, $zero
|
|
||||||
mtlo $zero
|
|
||||||
mthi $zero
|
|
||||||
.set at
|
|
||||||
|
|
||||||
la $sp, u_end - 16 # Stack at end of U area
|
# Call nmi_exception().
|
||||||
|
la $sp, _stack-16 # Set up stack base.
|
||||||
|
la $gp, _gp # GP register value defined by linker script.
|
||||||
|
la $s1, nmi_exception # Call user-defined NMI handler.
|
||||||
|
jalr $s1
|
||||||
|
nop
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// Set all GPRs of all register sets to predefined state.
|
||||||
|
//
|
||||||
|
init_gpr:
|
||||||
|
li $1, 0xdeadbeef # 0xdeadbeef stands out, kseg2 mapped, odd.
|
||||||
|
|
||||||
|
# Determine how many shadow sets are implemented (in addition to the base register set.)
|
||||||
|
# the first time thru the loop it will initialize using $1 set above.
|
||||||
|
# At the bottom og the loop, 1 is subtract from $30
|
||||||
|
# and loop back to next_shadow_set to start the next loop and the next lowest set number.
|
||||||
|
mfc0 $29, C0_SRSCTL # read SRSCtl
|
||||||
|
ext $30, $29, 26, 4 # extract HSS
|
||||||
|
|
||||||
|
next_shadow_set: # set PSS to shadow set to be initialized
|
||||||
|
ins $29, $30, 6, 4 # insert PSS
|
||||||
|
mtc0 $29, C0_SRSCTL # write SRSCtl
|
||||||
|
|
||||||
|
wrpgpr $1, $1
|
||||||
|
wrpgpr $2, $1
|
||||||
|
wrpgpr $3, $1
|
||||||
|
wrpgpr $4, $1
|
||||||
|
wrpgpr $5, $1
|
||||||
|
wrpgpr $6, $1
|
||||||
|
wrpgpr $7, $1
|
||||||
|
wrpgpr $8, $1
|
||||||
|
wrpgpr $9, $1
|
||||||
|
wrpgpr $10, $1
|
||||||
|
wrpgpr $11, $1
|
||||||
|
wrpgpr $12, $1
|
||||||
|
wrpgpr $13, $1
|
||||||
|
wrpgpr $14, $1
|
||||||
|
wrpgpr $15, $1
|
||||||
|
wrpgpr $16, $1
|
||||||
|
wrpgpr $17, $1
|
||||||
|
wrpgpr $18, $1
|
||||||
|
wrpgpr $19, $1
|
||||||
|
wrpgpr $20, $1
|
||||||
|
wrpgpr $21, $1
|
||||||
|
wrpgpr $22, $1
|
||||||
|
wrpgpr $23, $1
|
||||||
|
wrpgpr $24, $1
|
||||||
|
wrpgpr $25, $1
|
||||||
|
wrpgpr $26, $1
|
||||||
|
wrpgpr $27, $1
|
||||||
|
wrpgpr $28, $1
|
||||||
|
beqz $30, init_cp0
|
||||||
|
wrpgpr $29, $1
|
||||||
|
|
||||||
|
wrpgpr $30, $1
|
||||||
|
wrpgpr $31, $1
|
||||||
|
b next_shadow_set
|
||||||
|
add $30, -1 # Decrement to the next lower number
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init CP0 Status, Count, Compare, Watch*, and Cause.
|
||||||
|
//
|
||||||
|
init_cp0:
|
||||||
|
# Initialize Status
|
||||||
|
li $v1, 0x00400404 # (M_StatusIM | M_StatusERL | M_StatusBEV)
|
||||||
|
mtc0 $v1, C0_STATUS # write Status
|
||||||
|
|
||||||
|
# Initialize Watch registers if implemented.
|
||||||
|
mfc0 $v0, C0_CONFIG1 # read Config1
|
||||||
|
ext $v1, $v0, 3, 1 # extract bit 3 WR (Watch registers implemented)
|
||||||
|
beq $v1, $zero, done_wr
|
||||||
|
li $v1, 0x7 # (M_WatchHiI | M_WatchHiR | M_WatchHiW)
|
||||||
|
|
||||||
|
# Clear Watch Status bits and disable watch exceptions
|
||||||
|
mtc0 $v1, C0_WATCHHI # write WatchHi0
|
||||||
|
mfc0 $v0, C0_WATCHHI # read WatchHi0
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO # clear WatchLo0
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 1 # write WatchHi1
|
||||||
|
mfc0 $v0, C0_WATCHHI, 1 # read WatchHi1
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 1 # clear WatchLo1
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 2 # write WatchHi2
|
||||||
|
mfc0 $v0, C0_WATCHHI, 2 # read WatchHi2
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 2 # clear WatchLo2
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 3 # write WatchHi3
|
||||||
|
mfc0 $v0, C0_WATCHHI, 3 # read WatchHi3
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 3 # clear WatchLo3
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 4 # write WatchHi4
|
||||||
|
mfc0 $v0, C0_WATCHHI, 4 # read WatchHi4
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 4 # clear WatchLo4
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 5 # write WatchHi5
|
||||||
|
mfc0 $v0, C0_WATCHHI, 5 # read WatchHi5
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 5 # clear WatchLo5
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 6 # write WatchHi6
|
||||||
|
mfc0 $v0, C0_WATCHHI, 6 # read WatchHi6
|
||||||
|
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||||
|
mtc0 $zero, C0_WATCHLO, 6 # clear WatchLo6
|
||||||
|
|
||||||
|
mtc0 $v1, C0_WATCHHI, 7 # write WatchHi7
|
||||||
|
mtc0 $zero, C0_WATCHLO, 7 # clear WatchLo7
|
||||||
|
|
||||||
|
done_wr:
|
||||||
|
# Clear WP bit to avoid watch exception upon user code entry, IV, and software interrupts.
|
||||||
|
mtc0 $zero, C0_CAUSE # clear Cause: init AFTER init of WatchHi/Lo registers.
|
||||||
|
|
||||||
|
# Clear timer interrupt. (Count was cleared at the reset vector to allow timing boot.)
|
||||||
|
b init_tlb # Jump over exception vectors
|
||||||
|
mtc0 $zero, C0_COMPARE # clear Compare
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear TLB: generate unique EntryHi contents per entry pair.
|
||||||
|
//
|
||||||
|
init_tlb:
|
||||||
|
# Determine if we have a TLB
|
||||||
|
mfc0 $v1, C0_CONFIG # read Config
|
||||||
|
ext $v1, $v1, 7, 3 # extract MT field
|
||||||
|
li $a3, 0x1 # load a 1 to check against
|
||||||
|
bne $v1, $a3, init_icache
|
||||||
|
|
||||||
|
# Config1MMUSize == Number of TLB entries - 1
|
||||||
|
mfc0 $v0, C0_CONFIG1 # Config1
|
||||||
|
ext $v1, $v0, CFG1_MMUSSHIFT, 6 # extract MMU Size
|
||||||
|
mtc0 $zero, C0_ENTRYLO0 # clear EntryLo0
|
||||||
|
mtc0 $zero, C0_ENTRYLO1 # clear EntryLo1
|
||||||
|
mtc0 $zero, C0_PAGEMASK # clear PageMask
|
||||||
|
mtc0 $zero, C0_WIRED # clear Wired
|
||||||
|
li $a0, 0x80000000
|
||||||
|
|
||||||
|
next_tlb_entry:
|
||||||
|
mtc0 $v1, C0_INDEX # write Index
|
||||||
|
mtc0 $a0, C0_ENTRYHI # write EntryHi
|
||||||
|
ehb
|
||||||
|
tlbwi
|
||||||
|
add $a0, 2<<13 # Add 8K to the address to avoid TLB conflict with previous entry
|
||||||
|
|
||||||
|
bne $v1, $zero, next_tlb_entry
|
||||||
|
add $v1, -1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear L1 instruction cache.
|
||||||
|
//
|
||||||
|
init_icache:
|
||||||
|
# Determine how big the I-cache is
|
||||||
|
mfc0 $v0, C0_CONFIG1 # read Config1
|
||||||
|
ext $v1, $v0, CFG1_ILSHIFT, 3 # extract I-cache line size
|
||||||
|
beq $v1, $zero, done_icache # Skip ahead if no I-cache
|
||||||
|
nop
|
||||||
|
|
||||||
|
mfc0 $s1, C0_CONFIG7 # Read Config7
|
||||||
|
ext $s1, $s1, 18, 1 # extract HCI
|
||||||
|
bnez $s1, done_icache # Skip when Hardware Cache Initialization bit set
|
||||||
|
|
||||||
|
li $a2, 2
|
||||||
|
sllv $v1, $a2, $v1 # Now have true I-cache line size in bytes
|
||||||
|
|
||||||
|
ext $a0, $v0, CFG1_ISSHIFT, 3 # extract IS
|
||||||
|
li $a2, 64
|
||||||
|
sllv $a0, $a2, $a0 # I-cache sets per way
|
||||||
|
|
||||||
|
ext $a1, $v0, CFG1_IASHIFT, 3 # extract I-cache Assoc - 1
|
||||||
|
add $a1, 1
|
||||||
|
mul $a0, $a0, $a1 # Total number of sets
|
||||||
|
lui $a2, 0x8000 # Get a KSeg0 address for cacheops
|
||||||
|
|
||||||
|
mtc0 $zero, C0_ITAGLO # Clear ITagLo register
|
||||||
|
move $a3, $a0
|
||||||
|
|
||||||
|
next_icache_tag:
|
||||||
|
# Index Store Tag Cache Op
|
||||||
|
# Will invalidate the tag entry, clear the lock bit, and clear the LRF bit
|
||||||
|
cache 0x8, 0($a2) # ICIndexStTag
|
||||||
|
add $a3, -1 # Decrement set counter
|
||||||
|
bne $a3, $zero, next_icache_tag
|
||||||
|
add $a2, $v1 # Get next line address
|
||||||
|
done_icache:
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable cacheability of kseg0 segment.
|
||||||
|
// Need to switch to kseg1, modify kseg0 CCA, then switch back.
|
||||||
|
//
|
||||||
|
la $a2, enable_k0_cache
|
||||||
|
li $a1, 0xf
|
||||||
|
ins $a2, $a1, 29, 1 # changed to KSEG1 address by setting bit 29
|
||||||
|
jr $a2
|
||||||
|
nop
|
||||||
|
|
||||||
|
enable_k0_cache:
|
||||||
|
# Set CCA for kseg0 to cacheable.
|
||||||
|
# NOTE! This code must be executed in KSEG1 (not KSEG0 uncached)
|
||||||
|
mfc0 $v0, C0_CONFIG # read C0_Config
|
||||||
|
li $v1, 3 # CCA for single-core processors
|
||||||
|
ins $v0, $v1, 0, 3 # instert K0
|
||||||
|
mtc0 $v0, C0_CONFIG # write C0_Config
|
||||||
|
|
||||||
|
la $a2, init_dcache
|
||||||
|
jr $a2 # switch back to KSEG0
|
||||||
|
ehb
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the L1 data cache
|
||||||
|
//
|
||||||
|
init_dcache:
|
||||||
|
mfc0 $v0, C0_CONFIG1 # read C0_Config1
|
||||||
|
ext $v1, $v0, CFG1_DLSHIFT, 3 # extract D-cache line size
|
||||||
|
beq $v1, $zero, done_dcache # Skip ahead if no D-cache
|
||||||
|
nop
|
||||||
|
|
||||||
|
mfc0 $s1, C0_CONFIG7 # Read Config7
|
||||||
|
ext $s1, $s1, 18, 1 # extract HCI
|
||||||
|
bnez $s1, done_dcache # Skip when Hardware Cache Initialization bit set
|
||||||
|
|
||||||
|
li $a2, 2
|
||||||
|
sllv $v1, $a2, $v1 # Now have true D-cache line size in bytes
|
||||||
|
|
||||||
|
ext $a0, $v0, CFG1_DSSHIFT, 3 # extract DS
|
||||||
|
li $a2, 64
|
||||||
|
sllv $a0, $a2, $a0 # D-cache sets per way
|
||||||
|
|
||||||
|
ext $a1, $v0, CFG1_DASHIFT, 3 # extract D-cache Assoc - 1
|
||||||
|
add $a1, 1
|
||||||
|
mul $a0, $a0, $a1 # Get total number of sets
|
||||||
|
lui $a2, 0x8000 # Get a KSeg0 address for cacheops
|
||||||
|
|
||||||
|
mtc0 $zero, C0_ITAGLO # Clear ITagLo/DTagLo registers
|
||||||
|
mtc0 $zero, C0_DTAGLO
|
||||||
|
move $a3, $a0
|
||||||
|
|
||||||
|
next_dcache_tag:
|
||||||
|
# Index Store Tag Cache Op
|
||||||
|
# Will invalidate the tag entry, clear the lock bit, and clear the LRF bit
|
||||||
|
cache 0x9, 0($a2) # DCIndexStTag
|
||||||
|
add $a3, -1 # Decrement set counter
|
||||||
|
bne $a3, $zero, next_dcache_tag
|
||||||
|
add $a2, $v1 # Get next line address
|
||||||
|
done_dcache:
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call main() function.
|
||||||
|
//
|
||||||
|
la $sp, u_end - 16 # Stack at end of U area
|
||||||
la $a0, main
|
la $a0, main
|
||||||
jalr $a0 # Jump to main()
|
jalr $a0 # Jump to main()
|
||||||
lui $gp, 0x8000 # Set global pointer (delay slot)
|
lui $gp, 0x8000 # Set global pointer (delay slot)
|
||||||
|
|
||||||
la $k0, UBASE
|
la $k0, UBASE
|
||||||
mtc0 $k0, $C0_EPC # Entry to user code.
|
mtc0 $k0, C0_EPC # Entry to user code.
|
||||||
|
|
||||||
mfc0 $k0, $C0_STATUS
|
mfc0 $k0, C0_STATUS
|
||||||
ori $k0, $k0, ST_UM | ST_EXL | ST_IE # Set user mode and enable interrupts
|
ori $k0, $k0, ST_UM | ST_EXL | ST_IE # Set user mode and enable interrupts
|
||||||
mtc0 $k0, $C0_STATUS # Put SR back
|
mtc0 $k0, C0_STATUS # Put SR back
|
||||||
ehb
|
ehb
|
||||||
eret # PC <= EPC; EXL <= 0
|
eret # PC <= EPC; EXL <= 0
|
||||||
nop # just to be safe
|
nop # just to be safe
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Secondary entry point for RetroBSD bootloader.
|
# Secondary entry point for RetroBSD bootloader.
|
||||||
#
|
#
|
||||||
.section .exception,"ax",@progbits
|
.section .exception,"ax",@progbits
|
||||||
_exception_base_: .globl _exception_base_
|
_exception_base_: .globl _exception_base_
|
||||||
|
|
||||||
.org 0
|
.org 0
|
||||||
.type _entry_vector_, @function
|
.type _entry_vector_, @function
|
||||||
_entry_vector_: .globl _entry_vector_
|
_entry_vector_: .globl _entry_vector_
|
||||||
la $k0, _reset_vector_
|
la $k0, _reset_vector_
|
||||||
jr $k0
|
jr $k0
|
||||||
@@ -112,204 +377,204 @@ _entry_vector_: .globl _entry_vector_
|
|||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Exception vector: handle interrupts and exceptions
|
# Exception vector: handle interrupts and exceptions
|
||||||
#
|
#
|
||||||
.org 0x200
|
.org 0x200
|
||||||
.type _exception_vector_, @function
|
.type _exception_vector_, @function
|
||||||
_exception_vector_: .globl _exception_vector_
|
_exception_vector_: .globl _exception_vector_
|
||||||
|
|
||||||
mfc0 $k0, $C0_STATUS
|
mfc0 $k0, C0_STATUS
|
||||||
andi $k1, $k0, ST_UM # Check user mode
|
andi $k1, $k0, ST_UM # Check user mode
|
||||||
beqz $k1, kernel_exception
|
beqz $k1, kernel_exception
|
||||||
move $k1, $sp
|
move $k1, $sp
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exception in user mode: switch stack.
|
# Exception in user mode: switch stack.
|
||||||
#
|
#
|
||||||
user_exception:
|
user_exception:
|
||||||
la $sp, u_end # Stack at end of U area
|
la $sp, u_end # Stack at end of U area
|
||||||
kernel_exception:
|
kernel_exception:
|
||||||
addi $sp, -16-FRAME_WORDS*4 # Allocate space for registers
|
addi $sp, -16-FRAME_WORDS*4 # Allocate space for registers
|
||||||
save_regs:
|
save_regs:
|
||||||
sw $k0, (16+FRAME_STATUS*4) ($sp)
|
sw $k0, (16+FRAME_STATUS*4) ($sp)
|
||||||
sw $k1, (16+FRAME_SP*4) ($sp)
|
sw $k1, (16+FRAME_SP*4) ($sp)
|
||||||
|
|
||||||
.set noat
|
.set noat
|
||||||
sw $1, (16+FRAME_R1*4) ($sp) # Save general registers
|
sw $1, (16+FRAME_R1*4) ($sp) # Save general registers
|
||||||
sw $2, (16+FRAME_R2*4) ($sp)
|
sw $2, (16+FRAME_R2*4) ($sp)
|
||||||
sw $3, (16+FRAME_R3*4) ($sp)
|
sw $3, (16+FRAME_R3*4) ($sp)
|
||||||
sw $4, (16+FRAME_R4*4) ($sp)
|
sw $4, (16+FRAME_R4*4) ($sp)
|
||||||
sw $5, (16+FRAME_R5*4) ($sp)
|
sw $5, (16+FRAME_R5*4) ($sp)
|
||||||
sw $6, (16+FRAME_R6*4) ($sp)
|
sw $6, (16+FRAME_R6*4) ($sp)
|
||||||
sw $7, (16+FRAME_R7*4) ($sp)
|
sw $7, (16+FRAME_R7*4) ($sp)
|
||||||
sw $8, (16+FRAME_R8*4) ($sp)
|
sw $8, (16+FRAME_R8*4) ($sp)
|
||||||
sw $9, (16+FRAME_R9*4) ($sp)
|
sw $9, (16+FRAME_R9*4) ($sp)
|
||||||
sw $10, (16+FRAME_R10*4) ($sp)
|
sw $10, (16+FRAME_R10*4) ($sp)
|
||||||
sw $11, (16+FRAME_R11*4) ($sp)
|
sw $11, (16+FRAME_R11*4) ($sp)
|
||||||
sw $12, (16+FRAME_R12*4) ($sp)
|
sw $12, (16+FRAME_R12*4) ($sp)
|
||||||
sw $13, (16+FRAME_R13*4) ($sp)
|
sw $13, (16+FRAME_R13*4) ($sp)
|
||||||
sw $14, (16+FRAME_R14*4) ($sp)
|
sw $14, (16+FRAME_R14*4) ($sp)
|
||||||
sw $15, (16+FRAME_R15*4) ($sp)
|
sw $15, (16+FRAME_R15*4) ($sp)
|
||||||
sw $16, (16+FRAME_R16*4) ($sp)
|
sw $16, (16+FRAME_R16*4) ($sp)
|
||||||
sw $17, (16+FRAME_R17*4) ($sp)
|
sw $17, (16+FRAME_R17*4) ($sp)
|
||||||
sw $18, (16+FRAME_R18*4) ($sp)
|
sw $18, (16+FRAME_R18*4) ($sp)
|
||||||
sw $19, (16+FRAME_R19*4) ($sp)
|
sw $19, (16+FRAME_R19*4) ($sp)
|
||||||
sw $20, (16+FRAME_R20*4) ($sp)
|
sw $20, (16+FRAME_R20*4) ($sp)
|
||||||
sw $21, (16+FRAME_R21*4) ($sp)
|
sw $21, (16+FRAME_R21*4) ($sp)
|
||||||
sw $22, (16+FRAME_R22*4) ($sp)
|
sw $22, (16+FRAME_R22*4) ($sp)
|
||||||
sw $23, (16+FRAME_R23*4) ($sp)
|
sw $23, (16+FRAME_R23*4) ($sp)
|
||||||
sw $24, (16+FRAME_R24*4) ($sp)
|
sw $24, (16+FRAME_R24*4) ($sp)
|
||||||
sw $25, (16+FRAME_R25*4) ($sp)
|
sw $25, (16+FRAME_R25*4) ($sp)
|
||||||
# Skip $26 - K0
|
# Skip $26 - K0
|
||||||
# Skip $27 - K1
|
# Skip $27 - K1
|
||||||
sw $28, (16+FRAME_GP*4) ($sp)
|
sw $28, (16+FRAME_GP*4) ($sp)
|
||||||
# Skip $29 - SP
|
# Skip $29 - SP
|
||||||
sw $30, (16+FRAME_FP*4) ($sp)
|
sw $30, (16+FRAME_FP*4) ($sp)
|
||||||
sw $31, (16+FRAME_RA*4) ($sp)
|
sw $31, (16+FRAME_RA*4) ($sp)
|
||||||
.set at
|
.set at
|
||||||
|
|
||||||
mfhi $k0 # Save special registers
|
mfhi $k0 # Save special registers
|
||||||
sw $k0, (16+FRAME_HI*4) ($sp)
|
sw $k0, (16+FRAME_HI*4) ($sp)
|
||||||
|
|
||||||
mflo $k0
|
mflo $k0
|
||||||
sw $k0, (16+FRAME_LO*4) ($sp)
|
sw $k0, (16+FRAME_LO*4) ($sp)
|
||||||
|
|
||||||
mfc0 $k0, $C0_EPC
|
mfc0 $k0, C0_EPC
|
||||||
sw $k0, (16+FRAME_PC*4) ($sp)
|
sw $k0, (16+FRAME_PC*4) ($sp)
|
||||||
|
|
||||||
move $a0, $sp
|
move $a0, $sp
|
||||||
addi $a0, 16 # Arg 0: saved regs.
|
addi $a0, 16 # Arg 0: saved regs.
|
||||||
jal exception # Call C code.
|
jal exception # Call C code.
|
||||||
lui $gp, 0x8000 # Set global pointer (delay slot)
|
lui $gp, 0x8000 # Set global pointer (delay slot)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Restore CPU state and return from interrupt.
|
# Restore CPU state and return from interrupt.
|
||||||
#
|
#
|
||||||
restore_regs:
|
restore_regs:
|
||||||
lw $a0, (16+FRAME_LO*4) ($sp) # Load HI, LO registers
|
lw $a0, (16+FRAME_LO*4) ($sp) # Load HI, LO registers
|
||||||
mtlo $a0
|
mtlo $a0
|
||||||
lw $a0, (16+FRAME_HI*4) ($sp)
|
lw $a0, (16+FRAME_HI*4) ($sp)
|
||||||
mthi $a0
|
mthi $a0
|
||||||
|
|
||||||
.set noat
|
.set noat
|
||||||
lw $1, (16+FRAME_R1*4) ($sp) # Load general registers
|
lw $1, (16+FRAME_R1*4) ($sp) # Load general registers
|
||||||
lw $2, (16+FRAME_R2*4) ($sp)
|
lw $2, (16+FRAME_R2*4) ($sp)
|
||||||
lw $3, (16+FRAME_R3*4) ($sp)
|
lw $3, (16+FRAME_R3*4) ($sp)
|
||||||
lw $4, (16+FRAME_R4*4) ($sp)
|
lw $4, (16+FRAME_R4*4) ($sp)
|
||||||
lw $5, (16+FRAME_R5*4) ($sp)
|
lw $5, (16+FRAME_R5*4) ($sp)
|
||||||
lw $6, (16+FRAME_R6*4) ($sp)
|
lw $6, (16+FRAME_R6*4) ($sp)
|
||||||
lw $7, (16+FRAME_R7*4) ($sp)
|
lw $7, (16+FRAME_R7*4) ($sp)
|
||||||
lw $8, (16+FRAME_R8*4) ($sp)
|
lw $8, (16+FRAME_R8*4) ($sp)
|
||||||
lw $9, (16+FRAME_R9*4) ($sp)
|
lw $9, (16+FRAME_R9*4) ($sp)
|
||||||
lw $10, (16+FRAME_R10*4) ($sp)
|
lw $10, (16+FRAME_R10*4) ($sp)
|
||||||
lw $11, (16+FRAME_R11*4) ($sp)
|
lw $11, (16+FRAME_R11*4) ($sp)
|
||||||
lw $12, (16+FRAME_R12*4) ($sp)
|
lw $12, (16+FRAME_R12*4) ($sp)
|
||||||
lw $13, (16+FRAME_R13*4) ($sp)
|
lw $13, (16+FRAME_R13*4) ($sp)
|
||||||
lw $14, (16+FRAME_R14*4) ($sp)
|
lw $14, (16+FRAME_R14*4) ($sp)
|
||||||
lw $15, (16+FRAME_R15*4) ($sp)
|
lw $15, (16+FRAME_R15*4) ($sp)
|
||||||
lw $16, (16+FRAME_R16*4) ($sp)
|
lw $16, (16+FRAME_R16*4) ($sp)
|
||||||
lw $17, (16+FRAME_R17*4) ($sp)
|
lw $17, (16+FRAME_R17*4) ($sp)
|
||||||
lw $18, (16+FRAME_R18*4) ($sp)
|
lw $18, (16+FRAME_R18*4) ($sp)
|
||||||
lw $19, (16+FRAME_R19*4) ($sp)
|
lw $19, (16+FRAME_R19*4) ($sp)
|
||||||
lw $20, (16+FRAME_R20*4) ($sp)
|
lw $20, (16+FRAME_R20*4) ($sp)
|
||||||
lw $21, (16+FRAME_R21*4) ($sp)
|
lw $21, (16+FRAME_R21*4) ($sp)
|
||||||
lw $22, (16+FRAME_R22*4) ($sp)
|
lw $22, (16+FRAME_R22*4) ($sp)
|
||||||
lw $23, (16+FRAME_R23*4) ($sp)
|
lw $23, (16+FRAME_R23*4) ($sp)
|
||||||
lw $24, (16+FRAME_R24*4) ($sp)
|
lw $24, (16+FRAME_R24*4) ($sp)
|
||||||
lw $25, (16+FRAME_R25*4) ($sp)
|
lw $25, (16+FRAME_R25*4) ($sp)
|
||||||
# Skip $26 - K0
|
# Skip $26 - K0
|
||||||
# Skip $27 - K1
|
# Skip $27 - K1
|
||||||
lw $28, (16+FRAME_GP*4) ($sp)
|
lw $28, (16+FRAME_GP*4) ($sp)
|
||||||
# Skip $29 - SP
|
# Skip $29 - SP
|
||||||
lw $30, (16+FRAME_FP*4) ($sp)
|
lw $30, (16+FRAME_FP*4) ($sp)
|
||||||
.set at
|
.set at
|
||||||
|
|
||||||
# Do not use k0/k1 here, as interrupts are still enabled
|
# Do not use k0/k1 here, as interrupts are still enabled
|
||||||
lw $31, (16+FRAME_STATUS*4) ($sp) # K0 = saved status
|
lw $31, (16+FRAME_STATUS*4) ($sp) # K0 = saved status
|
||||||
ori $31, ST_EXL # Set EXL
|
ori $31, ST_EXL # Set EXL
|
||||||
mtc0 $31, $C0_STATUS # put SR back: disable interrupts
|
mtc0 $31, C0_STATUS # put SR back: disable interrupts
|
||||||
ehb
|
ehb
|
||||||
|
|
||||||
lw $k0, (16+FRAME_PC*4) ($sp) # K0 = EPC
|
lw $k0, (16+FRAME_PC*4) ($sp) # K0 = EPC
|
||||||
mtc0 $k0, $C0_EPC # put PC in EPC
|
mtc0 $k0, C0_EPC # put PC in EPC
|
||||||
ext $k1, $31, 27, 1 # get RP bit: single-step request
|
ext $k1, $31, 27, 1 # get RP bit: single-step request
|
||||||
|
|
||||||
lw $31, (16+FRAME_RA*4) ($sp)
|
lw $31, (16+FRAME_RA*4) ($sp)
|
||||||
lw $sp, (16+FRAME_SP*4) ($sp) # Restore stack
|
lw $sp, (16+FRAME_SP*4) ($sp) # Restore stack
|
||||||
|
|
||||||
# Return from exception
|
# Return from exception
|
||||||
bnez $k1, debug_request # single-step request
|
bnez $k1, debug_request # single-step request
|
||||||
ehb
|
ehb
|
||||||
eret # PC <= EPC; EXL <= 0
|
eret # PC <= EPC; EXL <= 0
|
||||||
debug_request:
|
debug_request:
|
||||||
sdbbp # enter debug mode
|
sdbbp # enter debug mode
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Debug exception processing.
|
# Debug exception processing.
|
||||||
#
|
#
|
||||||
.org 0x480
|
.org 0x480
|
||||||
.type _debug_vector_, @function
|
.type _debug_vector_, @function
|
||||||
_debug_vector_: .globl _debug_vector_
|
_debug_vector_: .globl _debug_vector_
|
||||||
|
|
||||||
mfc0 $k0, $C0_DEPC
|
mfc0 $k0, C0_DEPC
|
||||||
la $k1, debug_request
|
la $k1, debug_request
|
||||||
bne $k0, $k1, single_step_done
|
bne $k0, $k1, single_step_done
|
||||||
nop
|
nop
|
||||||
|
|
||||||
# single step request
|
# single step request
|
||||||
mfc0 $k0, $C0_DEBUG
|
mfc0 $k0, C0_DEBUG
|
||||||
ori $k0, DB_SST # set SST bit
|
ori $k0, DB_SST # set SST bit
|
||||||
mtc0 $k0, $C0_DEBUG
|
mtc0 $k0, C0_DEBUG
|
||||||
|
|
||||||
mfc0 $k1, $C0_EPC
|
mfc0 $k1, C0_EPC
|
||||||
mtc0 $k1, $C0_DEPC # DEPC <= EPC
|
mtc0 $k1, C0_DEPC # DEPC <= EPC
|
||||||
mfc0 $k0, $C0_STATUS
|
mfc0 $k0, C0_STATUS
|
||||||
xori $k0, ST_EXL # Clear EXL
|
xori $k0, ST_EXL # Clear EXL
|
||||||
mtc0 $k0, $C0_STATUS
|
mtc0 $k0, C0_STATUS
|
||||||
ehb
|
ehb
|
||||||
deret # PC <= DEPC; DM <= 0
|
deret # PC <= DEPC; DM <= 0
|
||||||
|
|
||||||
single_step_done:
|
single_step_done:
|
||||||
mtc0 $k0, $C0_EPC # EPC <= DEPC
|
mtc0 $k0, C0_EPC # EPC <= DEPC
|
||||||
|
|
||||||
la $k1, _exception_vector_
|
la $k1, _exception_vector_
|
||||||
mtc0 $k1, $C0_DEPC # DEPC <= exception handler
|
mtc0 $k1, C0_DEPC # DEPC <= exception handler
|
||||||
|
|
||||||
mfc0 $k0, $C0_DEBUG
|
mfc0 $k0, C0_DEBUG
|
||||||
sw $k0, c0_debug # save Debug register
|
sw $k0, c0_debug # save Debug register
|
||||||
ori $k0, DB_SST
|
ori $k0, DB_SST
|
||||||
xori $k0, DB_SST # clear SST bit
|
xori $k0, DB_SST # clear SST bit
|
||||||
mtc0 $k0, $C0_DEBUG
|
mtc0 $k0, C0_DEBUG
|
||||||
|
|
||||||
mfc0 $k1, $C0_STATUS
|
mfc0 $k1, C0_STATUS
|
||||||
ori $k1, ST_EXL # Set EXL
|
ori $k1, ST_EXL # Set EXL
|
||||||
mtc0 $k1, $C0_STATUS
|
mtc0 $k1, C0_STATUS
|
||||||
ehb
|
ehb
|
||||||
deret # PC <= DEPC; DM <= 0
|
deret # PC <= DEPC; DM <= 0
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Icode is copied out to process 1 to exec /sbin/init.
|
# Icode is copied out to process 1 to exec /sbin/init.
|
||||||
# If the exec fails, process 1 exits.
|
# If the exec fails, process 1 exits.
|
||||||
#
|
#
|
||||||
.globl icode, icodeend
|
.globl icode, icodeend
|
||||||
.type icode, @function
|
.type icode, @function
|
||||||
.type icodeend, @function
|
.type icodeend, @function
|
||||||
icode:
|
icode:
|
||||||
la $a0, UBASE
|
la $a0, UBASE
|
||||||
move $a1, $a0
|
move $a1, $a0
|
||||||
addi $a0, etcinit - icode
|
addi $a0, etcinit - icode
|
||||||
addi $a1, argv - icode
|
addi $a1, argv - icode
|
||||||
syscall 11 # SYS_execv
|
syscall 11 # SYS_execv
|
||||||
move $a0, $v0
|
move $a0, $v0
|
||||||
syscall 1 # SYS_exit
|
syscall 1 # SYS_exit
|
||||||
etcinit:
|
etcinit:
|
||||||
.ascii "/sbin/init\0"
|
.ascii "/sbin/init\0"
|
||||||
initflags:
|
initflags:
|
||||||
.ascii "-\0" # ASCII initflags
|
.ascii "-\0" # ASCII initflags
|
||||||
argv:
|
argv:
|
||||||
.word etcinit + 6 - icode + UBASE # address of "init\0"
|
.word etcinit + 6 - icode + UBASE # address of "init\0"
|
||||||
.word initflags - icode + UBASE # init options
|
.word initflags - icode + UBASE # init options
|
||||||
.word 0
|
.word 0
|
||||||
|
|
||||||
icodeend: nop
|
icodeend: nop
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# int setjmp (label_t *env);
|
# int setjmp (label_t *env);
|
||||||
@@ -317,22 +582,22 @@ icodeend: nop
|
|||||||
# Setjmp(env) will save the process' current register variables, stack
|
# Setjmp(env) will save the process' current register variables, stack
|
||||||
# and program counter context and return a zero.
|
# and program counter context and return a zero.
|
||||||
#
|
#
|
||||||
.type setjmp, @function
|
.type setjmp, @function
|
||||||
setjmp: .globl setjmp
|
setjmp: .globl setjmp
|
||||||
sw $s0, (0 * 4) ($a0) # save register variables s0-s8
|
sw $s0, (0 * 4) ($a0) # save register variables s0-s8
|
||||||
sw $s1, (1 * 4) ($a0)
|
sw $s1, (1 * 4) ($a0)
|
||||||
sw $s2, (2 * 4) ($a0)
|
sw $s2, (2 * 4) ($a0)
|
||||||
sw $s3, (3 * 4) ($a0)
|
sw $s3, (3 * 4) ($a0)
|
||||||
sw $s4, (4 * 4) ($a0)
|
sw $s4, (4 * 4) ($a0)
|
||||||
sw $s5, (5 * 4) ($a0)
|
sw $s5, (5 * 4) ($a0)
|
||||||
sw $s6, (6 * 4) ($a0)
|
sw $s6, (6 * 4) ($a0)
|
||||||
sw $s7, (7 * 4) ($a0)
|
sw $s7, (7 * 4) ($a0)
|
||||||
sw $s8, (8 * 4) ($a0) # frame pointer
|
sw $s8, (8 * 4) ($a0) # frame pointer
|
||||||
sw $ra, (9 * 4) ($a0) # return address
|
sw $ra, (9 * 4) ($a0) # return address
|
||||||
sw $gp, (10 * 4) ($a0) # global data pointer
|
sw $gp, (10 * 4) ($a0) # global data pointer
|
||||||
sw $sp, (11 * 4) ($a0) # stack pointer
|
sw $sp, (11 * 4) ($a0) # stack pointer
|
||||||
j $ra
|
j $ra
|
||||||
move $v0, $zero # return a zero for the setjmp call
|
move $v0, $zero # return a zero for the setjmp call
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# void longjmp (memaddr uaddr, label_t *env);
|
# void longjmp (memaddr uaddr, label_t *env);
|
||||||
@@ -346,60 +611,60 @@ setjmp: .globl setjmp
|
|||||||
# This longjmp differs from the longjmp found in the standard library -
|
# This longjmp differs from the longjmp found in the standard library -
|
||||||
# it's actually closer to the resume routine of the 4.3BSD kernel.
|
# it's actually closer to the resume routine of the 4.3BSD kernel.
|
||||||
#
|
#
|
||||||
.type longjmp, @function
|
.type longjmp, @function
|
||||||
longjmp: .globl longjmp
|
longjmp: .globl longjmp
|
||||||
|
|
||||||
di # can't let anything in till we get a valid stack...
|
di # can't let anything in till we get a valid stack...
|
||||||
|
|
||||||
la $v0, u # pointer to &u
|
la $v0, u # pointer to &u
|
||||||
beq $v0, $a0, 2f # if uaddr == &u...
|
beq $v0, $a0, 2f # if uaddr == &u...
|
||||||
nop # ...no need to remap U area
|
nop # ...no need to remap U area
|
||||||
|
|
||||||
la $a3, u_end # pointer to &u + USIZE
|
la $a3, u_end # pointer to &u + USIZE
|
||||||
la $a0, u0 # pointer to &u0
|
la $a0, u0 # pointer to &u0
|
||||||
|
|
||||||
lw $v1, 0($v0) # u.u_procp
|
lw $v1, 0($v0) # u.u_procp
|
||||||
sw $a0, 60($v1) # u.u_procp->p_addr = &u0
|
sw $a0, 60($v1) # u.u_procp->p_addr = &u0
|
||||||
|
|
||||||
# exchange contents of u and u0
|
# exchange contents of u and u0
|
||||||
move $v1, $v0
|
move $v1, $v0
|
||||||
1:
|
1:
|
||||||
lw $t1, 0($v1)
|
lw $t1, 0($v1)
|
||||||
lw $t0, 0($a0)
|
lw $t0, 0($a0)
|
||||||
sw $t0, 0($v1)
|
sw $t0, 0($v1)
|
||||||
sw $t1, 0($a0)
|
sw $t1, 0($a0)
|
||||||
lw $t1, 4($v1)
|
lw $t1, 4($v1)
|
||||||
lw $t0, 4($a0)
|
lw $t0, 4($a0)
|
||||||
sw $t0, 4($v1)
|
sw $t0, 4($v1)
|
||||||
sw $t1, 4($a0)
|
sw $t1, 4($a0)
|
||||||
lw $t1, 8($v1)
|
lw $t1, 8($v1)
|
||||||
lw $t0, 8($a0)
|
lw $t0, 8($a0)
|
||||||
sw $t0, 8($v1)
|
sw $t0, 8($v1)
|
||||||
sw $t1, 8($a0)
|
sw $t1, 8($a0)
|
||||||
lw $t1, 12($v1)
|
lw $t1, 12($v1)
|
||||||
lw $t0, 12($a0)
|
lw $t0, 12($a0)
|
||||||
sw $t0, 12($v1)
|
sw $t0, 12($v1)
|
||||||
sw $t1, 12($a0)
|
sw $t1, 12($a0)
|
||||||
addiu $v1, $v1, 16
|
addiu $v1, $v1, 16
|
||||||
bne $a3, $v1, 1b
|
bne $a3, $v1, 1b
|
||||||
addiu $a0, $a0, 16
|
addiu $a0, $a0, 16
|
||||||
|
|
||||||
lw $v1, 0($v0) # u.u_procp
|
lw $v1, 0($v0) # u.u_procp
|
||||||
sw $v0, 60($v1) # u.u_procp->p_addr = &u
|
sw $v0, 60($v1) # u.u_procp->p_addr = &u
|
||||||
2:
|
2:
|
||||||
lw $s0, (0 * 4) ($a1) # restore register variables s0-s8
|
lw $s0, (0 * 4) ($a1) # restore register variables s0-s8
|
||||||
lw $s1, (1 * 4) ($a1)
|
lw $s1, (1 * 4) ($a1)
|
||||||
lw $s2, (2 * 4) ($a1)
|
lw $s2, (2 * 4) ($a1)
|
||||||
lw $s3, (3 * 4) ($a1)
|
lw $s3, (3 * 4) ($a1)
|
||||||
lw $s4, (4 * 4) ($a1)
|
lw $s4, (4 * 4) ($a1)
|
||||||
lw $s5, (5 * 4) ($a1)
|
lw $s5, (5 * 4) ($a1)
|
||||||
lw $s6, (6 * 4) ($a1)
|
lw $s6, (6 * 4) ($a1)
|
||||||
lw $s7, (7 * 4) ($a1)
|
lw $s7, (7 * 4) ($a1)
|
||||||
lw $s8, (8 * 4) ($a1) # frame pointer
|
lw $s8, (8 * 4) ($a1) # frame pointer
|
||||||
lw $ra, (9 * 4) ($a1) # return address
|
lw $ra, (9 * 4) ($a1) # return address
|
||||||
lw $gp, (10 * 4) ($a1) # global data pointer
|
lw $gp, (10 * 4) ($a1) # global data pointer
|
||||||
lw $sp, (11 * 4) ($a1) # stack pointer
|
lw $sp, (11 * 4) ($a1) # stack pointer
|
||||||
|
|
||||||
ei # release interrupts
|
ei # release interrupts
|
||||||
j $ra # transfer back to setjmp()
|
j $ra # transfer back to setjmp()
|
||||||
li $v0, 1 # return value of 1
|
li $v0, 1 # return value of 1
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ endif
|
|||||||
# You can build it from sources, as described on page
|
# You can build it from sources, as described on page
|
||||||
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
|
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
|
||||||
ifndef GCCPREFIX
|
ifndef GCCPREFIX
|
||||||
ifeq (/usr/local/mips-gcc-4.7.2/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.7.2/bin/mips-elf-gcc))
|
ifeq (/usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc))
|
||||||
GCCPREFIX = /usr/local/mips-gcc-4.7.2/bin/mips-elf-
|
GCCPREFIX = /usr/local/mips-gcc-4.8.1/bin/mips-elf-
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -194,22 +194,38 @@ startup()
|
|||||||
*/
|
*/
|
||||||
INTCON = 0; /* Interrupt Control */
|
INTCON = 0; /* Interrupt Control */
|
||||||
IPTMR = 0; /* Temporal Proximity Timer */
|
IPTMR = 0; /* Temporal Proximity Timer */
|
||||||
IFS(0) =
|
|
||||||
PIC32_IPC_IP0(2) | PIC32_IPC_IP1(1) |
|
|
||||||
PIC32_IPC_IP2(1) | PIC32_IPC_IP3(1) |
|
|
||||||
PIC32_IPC_IS0(0) | PIC32_IPC_IS1(0) |
|
|
||||||
PIC32_IPC_IS2(0) | PIC32_IPC_IS3(0) ;
|
|
||||||
|
|
||||||
IFS(1) = IFS(2) = 0; /* Interrupt Flag Status */
|
/* Interrupt Flag Status */
|
||||||
IEC(0) = IEC(1) = IEC(2) = 0; /* Interrupt Enable Control */
|
IFS(0) = PIC32_IPC_IP0(2) | PIC32_IPC_IP1(1) |
|
||||||
IPC(0) = IPC(1) = IPC(2) = IPC(3) = /* Interrupt Priority Control */
|
PIC32_IPC_IP2(1) | PIC32_IPC_IP3(1) |
|
||||||
IPC(4) = IPC(5) = IPC(6) = IPC(7) =
|
PIC32_IPC_IS0(0) | PIC32_IPC_IS1(0) |
|
||||||
IPC(8) = IPC(9) = IPC(10) = IPC(11) =
|
PIC32_IPC_IS2(0) | PIC32_IPC_IS3(0) ;
|
||||||
IPC(12) =
|
IFS(1) = 0;
|
||||||
PIC32_IPC_IP0(1) | PIC32_IPC_IP1(1) |
|
IFS(2) = 0;
|
||||||
PIC32_IPC_IP2(1) | PIC32_IPC_IP3(1) |
|
|
||||||
PIC32_IPC_IS0(0) | PIC32_IPC_IS1(0) |
|
/* Interrupt Enable Control */
|
||||||
PIC32_IPC_IS2(0) | PIC32_IPC_IS3(0) ;
|
IEC(0) = 0;
|
||||||
|
IEC(1) = 0;
|
||||||
|
IEC(2) = 0;
|
||||||
|
|
||||||
|
/* Interrupt Priority Control */
|
||||||
|
unsigned ipc = PIC32_IPC_IP0(1) | PIC32_IPC_IP1(1) |
|
||||||
|
PIC32_IPC_IP2(1) | PIC32_IPC_IP3(1) |
|
||||||
|
PIC32_IPC_IS0(0) | PIC32_IPC_IS1(0) |
|
||||||
|
PIC32_IPC_IS2(0) | PIC32_IPC_IS3(0) ;
|
||||||
|
IPC(0) = ipc;
|
||||||
|
IPC(1) = ipc;
|
||||||
|
IPC(2) = ipc;
|
||||||
|
IPC(3) = ipc;
|
||||||
|
IPC(4) = ipc;
|
||||||
|
IPC(5) = ipc;
|
||||||
|
IPC(6) = ipc;
|
||||||
|
IPC(7) = ipc;
|
||||||
|
IPC(8) = ipc;
|
||||||
|
IPC(9) = ipc;
|
||||||
|
IPC(10) = ipc;
|
||||||
|
IPC(11) = ipc;
|
||||||
|
IPC(12) = ipc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup wait states.
|
* Setup wait states.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
/*--------------------------------------
|
/*--------------------------------------
|
||||||
* Coprocessor 0 registers.
|
* Coprocessor 0 registers.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
#define C0_HWRENA 7 /* Enable RDHWR in non-privileged mode */
|
#define C0_HWRENA 7 /* Enable RDHWR in non-privileged mode */
|
||||||
#define C0_BADVADDR 8 /* Virtual address of last exception */
|
#define C0_BADVADDR 8 /* Virtual address of last exception */
|
||||||
#define C0_COUNT 9 /* Processor cycle count */
|
#define C0_COUNT 9 /* Processor cycle count */
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
#define C0_DEPC 24 /* Program counter at last debug exception */
|
#define C0_DEPC 24 /* Program counter at last debug exception */
|
||||||
#define C0_ERROREPC 30 /* Program counter at last error */
|
#define C0_ERROREPC 30 /* Program counter at last error */
|
||||||
#define C0_DESAVE 31 /* Debug handler scratchpad register */
|
#define C0_DESAVE 31 /* Debug handler scratchpad register */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status register.
|
* Status register.
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ endif
|
|||||||
# You can build it from sources, as described on page
|
# You can build it from sources, as described on page
|
||||||
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
|
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
|
||||||
ifndef GCCPREFIX
|
ifndef GCCPREFIX
|
||||||
ifeq (/usr/local/mips-gcc-4.7.2/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.7.2/bin/mips-elf-gcc))
|
ifeq (/usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc))
|
||||||
GCCPREFIX = /usr/local/mips-gcc-4.7.2/bin/mips-elf-
|
GCCPREFIX = /usr/local/mips-gcc-4.8.1/bin/mips-elf-
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
INCLUDES =
|
INCLUDES =
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1684,7 +1684,8 @@ static int rdpgpr_op (cpu_mips_t * cpu, mips_insn_t insn)
|
|||||||
int rt = bits (insn, 16, 20);
|
int rt = bits (insn, 16, 20);
|
||||||
int rd = bits (insn, 11, 15);
|
int rd = bits (insn, 11, 15);
|
||||||
|
|
||||||
printf ("%08x: unsupported RDPGPR $%u,$%u instruction.\n", cpu->pc, rd, rt);
|
/* Only one GPR set supported: RDPGPR works as move. */
|
||||||
|
cpu->reg_set (cpu, rd, cpu->gpr[rt]);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1693,7 +1694,8 @@ static int wrpgpr_op (cpu_mips_t * cpu, mips_insn_t insn)
|
|||||||
int rt = bits (insn, 16, 20);
|
int rt = bits (insn, 16, 20);
|
||||||
int rd = bits (insn, 11, 15);
|
int rd = bits (insn, 11, 15);
|
||||||
|
|
||||||
printf ("%08x: unsupported WRPGPR $%u,$%u instruction.\n", cpu->pc, rd, rt);
|
/* Only one GPR set supported: WRPGPR works as move. */
|
||||||
|
cpu->reg_set (cpu, rd, cpu->gpr[rt]);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ unimpl: fprintf (stderr,
|
|||||||
return cp0->reg[cp0_reg];
|
return cp0->reg[cp0_reg];
|
||||||
case 1: /* IntCtl */
|
case 1: /* IntCtl */
|
||||||
return cp0->intctl_reg;
|
return cp0->intctl_reg;
|
||||||
|
case 2: /* SRSCtl */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
goto unimpl;
|
goto unimpl;
|
||||||
|
|
||||||
@@ -172,6 +174,8 @@ void mips_cp0_set_reg (cpu_mips_t * cpu, u_int cp0_reg, u_int sel,
|
|||||||
case 1: /* IntCtl */
|
case 1: /* IntCtl */
|
||||||
cp0->intctl_reg = val;
|
cp0->intctl_reg = val;
|
||||||
break;
|
break;
|
||||||
|
case 2: /* SRSCtl */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto unimpl;
|
goto unimpl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user