You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
3.7 KiB
C

#include <stdint.h>
#include <stdio.h>
#include "bios.h"
#ifdef PRINTF
#include "liblitex.h"
//static char printbuf[1000]; // make this a pointer with address a define
//const char* printbuf = (char *)0x12000;
#ifndef PRINTBUF
#define PRINTBUF 0x0001C000
#endif
//static int printbuf_ptr = 0;
static char *printbuf_ptr = (char *)PRINTBUF;
void putchar_handler(char c) {
//printbuf[printbuf_ptr++] = c;
//*(printbuf + printbuf_ptr++) = c;
*printbuf_ptr++ = c;
}
#endif
// arci stuff
//void tst_done(unsigned int rc);
void tst_done(unsigned int rc);
// in kernel (for constant locs)
extern void tst_pass(void);
extern void tst_fail(int i);
/*
void tst_pass(void);
void tst_fail(int i);
void tst_fail(int i) {
while(1) {}
}
void tst_pass(void) {
while(1) {}
}
*/
//inline unsigned int checkResult(unsigned int r) __attribute__((always_inline));
unsigned int checkResult(unsigned int r);
extern unsigned int tst_start;
extern unsigned int tst_end;
extern unsigned int tst_inits;
extern unsigned int tst_results;
extern unsigned int tst_expects;
int main(int tid) {
int *p;
int *fdata = &_fdata;
unsigned int *inits = &tst_inits;
if (tid != 0) {
return -1;
}
// r/w memory init
// copy
for (p = &_fdata_rom; p < &_edata_rom; p++){
*(fdata++) = *p;
}
// zero
for (p = &_fbss; p < &_ebss; p++) {
*(p++) = 0;
}
#ifdef PRINTF
console_set_write_hook(putchar_handler);
putchar('w');
putchar('t');
putchar('f');
putchar('\n');
printf("main(%i)\n", tid);
#endif
// core init
set_epcr(0x03000000); // icm=gicm=1
set_dec(0);
set_tbh(0);
set_tbl(0);
set_tsr(0xFE000000); // mask: clear enw,wis,wrs,dis,fis,udis
set_xucr0(get_xucr0() & ~0x00000200); // set tcs=0
set_tsr(0);
set_tcr(0); // disable all timers
// thread enable
// set_tens(0x3);
// run a .tst
// danger! once r1 is whacked, any c code like bad int handler, etc. needs
// to make sure it has a safe stack for calls
asm (
"mr 3,%0\n"
//"lis 4,init_tst@h\n"
//"ori 4,4,init_tst@l\n"
//"mtctr 4\n"
//"bcctr\n"
"b init_tst\n"
: // outputs
: "r"(inits) // inputs
: "r3" // clobbers
);
while(1) {}
return 0;
}
#define MAGIC 0x08675309
// r1 has been restored to where it was for 'b init_tst' above
void tst_done(unsigned int rc) {
unsigned int i, ok = 1;
unsigned int act, exp;
if (rc != MAGIC) {
tst_fail(0x80000000);
}
// check GPR & CR
for (i = 0; i < 32; i++) {
act = *(&tst_results + i);
exp = *(&tst_expects + i);
ok = ok && (act == exp);
if (!ok) {
tst_fail(i);
}
}
// check XER - a2o not compliant right now (only so/ov/ca/len)
i = 33;
act = *(&tst_results + i);
exp = *(&tst_expects + i) & 0xE000007F;
ok = ok && (act == exp);
if (!ok) {
tst_fail(i);
}
// check CLT - skip tar, a2o doesn't have usermode sprg to use for save reg, so using tar
//for (i = 34; i < 37; i++) {
for (i = 34; i < 36; i++) {
act = *(&tst_results + i);
exp = *(&tst_expects + i);
ok = ok && (act == exp);
if (!ok) {
tst_fail(i);
}
}
// could get back to kernel
tst_pass();
while (1) {}
}
// these are branched to! but if fun, they assume r1 is stack!!!!
// tst is ended with sc to return to priv mode; then save results
void int_sc(int code, int srr0) {
asm (
"b tst_end\n"
: // outputs
: // inputs
: // clobbers
);
}
void int_unhandled(void) {
while(1) {}
}