diff options
Diffstat (limited to '410user/progs/swexn_rampage.c')
| -rw-r--r-- | 410user/progs/swexn_rampage.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/410user/progs/swexn_rampage.c b/410user/progs/swexn_rampage.c new file mode 100644 index 0000000..4203e6d --- /dev/null +++ b/410user/progs/swexn_rampage.c @@ -0,0 +1,96 @@ +/** + * @file swexn_rampage.c + * @author de0u + * @brief Tests a simple use case for swexn + * @public yes + * @for p3 + */ + +#include <stddef.h> +#include <stdlib.h> +#include <syscall.h> +#include "410_tests.h" + +#define USER_MEM_START 0x01000000 +#define KERNEL_BOTTOM 0x00100000 // 1 megabyte; below there lie dragons + +#define ENOUGH 410 + +DEF_TEST_NAME("swexn_rampage:"); + +#define STAQ_SIZE (4096) +static char exn_staq[STAQ_SIZE]; +#define EXN_STAQ_TOP ((void *)(&exn_staq[STAQ_SIZE-7])) + +void install(void); +void rampage(void); +void handler(void *arg, ureg_t *uregs); + +static unsigned int *top_addr = (unsigned int *)USER_MEM_START - sizeof (unsigned int); + +static int events = 0; + +static unsigned int start_ticks; + +void install(void) +{ + int ret; + + ret = swexn(EXN_STAQ_TOP, handler, NULL, NULL); + if (ret < 0) { + REPORT_MISC("swexn call rejected"); + REPORT_END_FAIL; + exit(-1); + } +} + +void rampage(void) +{ + unsigned int *ip; + + for (ip = top_addr; ip > (unsigned int *)KERNEL_BOTTOM; ip--) + *ip = 0; + + REPORT_END_FAIL; // as if +} + +void handler(void *arg, ureg_t *uregs) +{ + if (uregs->cause != SWEXN_CAUSE_PAGEFAULT) { + report_fmt("bad cause %d", uregs->cause); + REPORT_END_FAIL; + exit(-1); + } + if (uregs->cr2 != (unsigned int) top_addr) { + report_fmt("bad addr 0x%x", uregs->cr2); + REPORT_END_FAIL; + exit(-1); + } + + TEST_PROG_PROGRESS; + + if (++events == ENOUGH) { + report_fmt("ticks %d", get_ticks() - start_ticks); + REPORT_END_SUCCESS; + exit(0); + } + + sleep(15); + + install(); + rampage(); +} + +int main() +{ + REPORT_START_CMPLT; + + start_ticks = get_ticks(); + + install(); + rampage(); + + REPORT_MISC("handler not run?"); + REPORT_END_FAIL; + exit(-1); +} |
