From 26711b3dfbbe538bcbc8ed5824559898f82366b0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 11 Apr 2017 11:21:24 +0100 Subject: test11: Update to tapit output format Update test11 to the tapit output format. (Much of the code for handling faults is copied across from test13.) Signed-off-by: Peter Maydell --- Makefile | 2 +- test11-buserr.c | 291 +++++++++++++++++++++++++++----------------------------- 2 files changed, 141 insertions(+), 152 deletions(-) diff --git a/Makefile b/Makefile index e04badd..e423eba 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ test7-kern.elf: cortexm.ld common.ld setup.o armv7m.o init-m.o testme.o test7.o test8-kern.elf: cortexm.ld common.ld setup.o armv7m.o init-m.o testme.o test8.o inst_skip.o test9-kern.elf: cortexm.ld common.ld setup.o armv7m.o init-m-test9.o testme.o test9.o test10-kern.elf:cortexm.ld common.ld setup.o armv7m.o init-m.o testme.o test10.o -test11-kern.elf:cortexm.ld common.ld setup.o armv7m.o init-m.o test11-buserr.o inst_skip.o +test11-kern.elf:cortexm.ld common.ld setup.o armv7m.o init-m.o testme.o test11-buserr.o inst_skip.o test12-kern.elf:cortexm.ld common.ld setup.o test12.o test13-kern.elf:cortexm.ld common.ld setup.o armv7m.o init-m.o test13-undef.o inst_skip.o testme.o test14-kern.elf: cortexm.ld common.ld setup.o armv7m.o init-m.o testme.o test14.o diff --git a/test11-buserr.c b/test11-buserr.c index 7b5bf08..c48972b 100644 --- a/test11-buserr.c +++ b/test11-buserr.c @@ -1,50 +1,97 @@ /* See how various faults are reported and recovered */ #include "armv7m.h" +#include "testme.h" void inst_skip(uint32_t *sp); static volatile unsigned fault_type; -static -void check_fault(unsigned expect) +static volatile unsigned fsr; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +const char *faultnames[] = { + "None", + "Mem", + "Bus", + "Usage", +}; + +typedef struct FSRMapEntry { + unsigned int bit; + const char *name; +} FSRMapEntry; + +static const FSRMapEntry fsrmap[] = { + { 0x1, "IACCVIOL" }, + { 0x2, "DACCVIOL" }, + { 0x8, "MUNSTKERR" }, + { 0x10, "MSTKERR" }, + { 0x20, "MLSPERR" }, + { 0x80, "MMARVALID" }, + { 0x100, "IBUSERR" }, + { 0x200, "PRECISERR" }, + { 0x400, "IMPRECISERR" }, + { 0x800, "UNSTKERR" }, + { 0x1000, "STKERR" }, + { 0x2000, "LSPERR" }, + { 0x8000, "BFARVALID" }, + { 0x10000, "UNDEFINSTR" }, + { 0x20000, "INVSTATE" }, + { 0x40000, "INVPC" }, + { 0x80000, "NOCP" }, + { 0x1000000, "UNALIGNED" }, + { 0x2000000, "DIVBYZERO" }, +}; + +/* Only reports the first set bit! */ +const char *fsrbit(unsigned int fsr) { - unsigned actual = fault_type; - puts("# Fault: "); - switch(actual) { - case 0: puts("None\n"); break; - case 1: puts("Mem\n"); break; - case 2: puts("Bus\n"); break; - case 3: puts("Usage\n"); break; - default: puthex(actual); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fsrmap); i++) { + if (fsr & fsrmap[i].bit) { + return fsrmap[i].name; + } } + return "reserved"; +} + +const char *faultname(unsigned int faultnum) +{ + return faultnum < ARRAY_SIZE(faultnames) ? faultnames[faultnum] : "unknown"; +} + +static void check_fault(unsigned expect, unsigned expectfsr) +{ + unsigned actual = fault_type; + + //testDiag("Fault: %s FSR: %x (%s)", faultname(actual), fsr, fsrbit(fsr)); + + testEqI(expect, actual, "fault type"); + testEqI(expectfsr, fsr, "FSR"); - if(expect!=actual) - puts("not "); - puts("ok - "); - puthex(actual); - puts(" = "); - puthex(expect); - putc('\n'); fault_type = 0; + fsr = 0; } -static -void set_fault(unsigned actual) +static void set_fault(unsigned actual, unsigned fsrval) { - if(fault_type) { - puts("Secondary fault "); - puthex(actual); - putc('\n'); - } else + testDiag("%sFault: %x (%s) FSR: %x (%s)", + fault_type ? "Secondary " : "", + actual, faultname(actual), fsrval, fsrbit(fsrval)); + if (!fault_type) { fault_type = actual; + fsr = fsrval; + } } static void hard(void) { - puts("Unexpected HardFault\n"); + testDiag("Unexpected HardFault"); abort(); } @@ -52,48 +99,25 @@ void bus(uint32_t *sp) { uint32_t sts, addr; - set_fault(2); - sts = in32(SCB(0xd28)); + set_fault(2, sts); addr= in32(SCB(0xd38)); out32(SCB(0xd28), 0xff00); /* W1C */ out32(SCB(0xd38), 0); - puts("BusFault: "); - puthex(sts); - putc(' '); if(sts&0x8000) { - puthex(addr); - putc(' '); + testDiag("BFARVALID set, BFAR is 0x%x", addr); } - if(sts&0x1000) - puts("STKERR "); - if(sts&0x0800) - puts("UNSTKERR "); - if(sts&0x0400) - puts("IMPRECISERR "); - if(sts&0x0200) - puts("PRECISERR "); - if(sts&0x0100) - puts("IBUSERR "); - - putc('\n'); if(sts&0x0300) { /* precise faults would return to the faulting * instruction, which would then fault again * since we change nothing, so skip it. */ - puts("From: "); - puthex(sp[6]); if(sp[6]<0xfffffff0) inst_skip(sp); - } else { - puts("From before: "); - puthex(sp[6]); } - putc('\n'); if(sp[6]>=0xf0000000) { /* evil hack since we know this was a bx instruction */ @@ -112,34 +136,17 @@ void mem(uint32_t *sp) { uint32_t sts, addr; - set_fault(1); - sts = in32(SCB(0xd28)); + + set_fault(1, sts); + addr= in32(SCB(0xd34)); out32(SCB(0xd28), 0xff); /* W1C */ - puts("MemFault: "); - puthex(sts); - putc(' '); - if(sts&0x80) { - puthex(addr); - putc(' '); + if (sts&0x80) { + testDiag("MMARVALID set, MMFAR is 0x%x", addr); } - if(sts&0x08) - puts("MSTKERR "); - if(sts&0x04) - puts("MUNSTKERR "); - if(sts&0x02) - puts("DACCVIOL "); - if(sts&0x01) - puts("IACCVIOL "); - - putc('\n'); - - puts("From: "); - puthex(sp[6]); - putc('\n'); if(sp[6]>=0xf0000000) { /* evil hack since we know this was a bx instruction */ @@ -161,31 +168,11 @@ void usage(uint32_t *sp) { uint32_t sts; - set_fault(1); - sts = in32(SCB(0xd28)); - out32(SCB(0xd28), 0xffff0000); /* W1C */ + set_fault(1, sts); - puts("UsageFault: "); - if(sts&0x2000000) - puts("DIVBYZERO "); - if(sts&0x1000000) - puts("UNALIGNED "); - if(sts&0x80000) - puts("NOCP "); - if(sts&0x40000) - puts("INVPC "); - if(sts&0x20000) - puts("INVSTATE "); - if(sts&0x10000) - puts("UNDEFINSTR "); - - putc('\n'); - - puts("From: "); - puthex(sp[6]); - putc('\n'); + out32(SCB(0xd28), 0xffff0000); /* W1C */ if(sts&0x20000) { abort(); /* attempt to execute ARM mode */ @@ -221,74 +208,76 @@ void main(void) run_table.usage = usage_entry; run_table.hard = hard; + testInit(32); + out32(SCB(0xd24), 0x70000); /* Enable Bus, Mem, and Usage Faults */ - puts("# w/o MPU, hits background mapping\n"); + testDiag("# w/o MPU, hits background mapping"); - puts("1. Cause BusFault 0xe1000ff0\n"); + testDiag("1. Cause BusFault 0xe1000ff0"); out32((void*)0xe1000ff0, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("2. Another BusFault 0x10000000\n"); + testDiag("2. Another BusFault 0x10000000"); out32((void*)0x10000000, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("3. Another BusFault 0x01000000\n"); + testDiag("3. Another BusFault 0x01000000"); out32((void*)0x01000000, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("4. Another BusFault 0xfffffffe\n"); + testDiag("4. Another BusFault 0xfffffffe"); out32((void*)0xfffffffe, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("5.1 MemFault (jump to 0xf1000001)\n"); + testDiag("5.1 MemFault (jump to 0xf1000001)"); jumpff(0xf1000001); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x1); + testDiag("Back in Main"); - puts("5. MemFault (jump to 0xfffffff9)\n"); + testDiag("5. MemFault (jump to 0xfffffff9)"); jumpff(0xfffffff9); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x1); + testDiag("Back in Main"); - puts("# Enable MPU, but not for privlaged" - " still hits background mapping\n"); + testDiag("# Enable MPU, but not for privlaged" + " still hits background mapping"); enable_mpu(1,0,0); - puts("6. Cause BusFault 0xe1000ff0\n"); + testDiag("6. Cause BusFault 0xe1000ff0"); out32((void*)0xe1000ff0, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("7. Another BusFault 0x10000000\n"); + testDiag("7. Another BusFault 0x10000000"); out32((void*)0x10000000, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("8. Another BusFault 0x01000000\n"); + testDiag("8. Another BusFault 0x01000000"); out32((void*)0x01000000, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("9. Another BusFault 0xfffffffe\n"); + testDiag("9. Another BusFault 0xfffffffe"); out32((void*)0xfffffffe, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); // this jump works, and TI has hidden so data here -// puts("5. MemFault (jump to 0x01000001)\n"); +// testDiag("5. MemFault (jump to 0x01000001)"); // jumpff(0x01000001); -// check_fault(1); -// puts("Back in Main\n"); +// check_fault(1, 0x1); +// testDiag("Back in Main"); - puts("10. MemFault (jump to 0xfffffff9)\n"); + testDiag("10. MemFault (jump to 0xfffffff9)"); jumpff(0xfffffff9); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x1); + testDiag("Back in Main"); // ROM region is made larger than actual rom to pass through 0x05000000 set_mpu(0, 0x00000000, 0x08000000, MPU_NORMAL|MPU_RORO); @@ -298,39 +287,39 @@ void main(void) // Allow through access to unconnected address space set_mpu(4, 0xe100e000, 0x00001000, MPU_DEVICE|MPU_RWRW|MPU_XN); - puts("# Enable MPU, including privlaged\n"); + testDiag("# Enable MPU, including privlaged"); enable_mpu(1,1,0); // MPU allows through, but no one is home == BusFault - puts("11. Cause BusFault 0xe1000ff0\n"); + testDiag("11. Cause BusFault 0xe1000ff0"); out32((void*)0xe1000ff0, 0); - check_fault(2); - puts("Back in Main\n"); + check_fault(2, 0x200); + testDiag("Back in Main"); - puts("12. Another MemFault 0x10000000\n"); + testDiag("12. Another MemFault 0x10000000"); out32((void*)0x10000000, 0); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x82); + testDiag("Back in Main"); // MPU allows through, no one is home, but still MemFault...? - puts("13. Another MemFault 0x05000000\n"); + testDiag("13. Another MemFault 0x05000000"); out32((void*)0x05000000, 0); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x82); + testDiag("Back in Main"); - puts("14. Another MemFault 0xfffffffe\n"); + testDiag("14. Another MemFault 0xfffffffe"); out32((void*)0xfffffffe, 0); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x82); + testDiag("Back in Main"); // this jump works, and TI has hidden so data here -// puts("5. MemFault (jump to 0x01000001)\n"); +// testDiag("5. MemFault (jump to 0x01000001)"); // jumpff(0x01000001); // check_fault(1); -// puts("Back in Main\n"); +// testDiag("Back in Main"); - puts("15. MemFault (jump to 0xfffffff9)\n"); + testDiag("15. MemFault (jump to 0xfffffff9)"); jumpff(0xfffffff9); - check_fault(1); - puts("Back in Main\n"); + check_fault(1, 0x1); + testDiag("Back in Main"); } -- cgit v1.2.3