rvmain.c (3130B)
1 // Copyright 2019, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <stdio.h> 5 #include <stdint.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <fcntl.h> 10 #include <sys/stat.h> 11 12 #include "rvsim.h" 13 #include "iocall.h" 14 15 uint32_t ior32(uint32_t addr) { 16 return 0xffffffff; 17 } 18 19 void iow32(uint32_t addr, uint32_t val) { 20 } 21 22 uint32_t iocall(void* ctx, uint32_t n, const uint32_t args[8]) { 23 rvstate_t* s = ctx; 24 switch (n) { 25 case IOCALL_DPUTC: { 26 uint8_t x = args[0]; 27 if (write(1, &x, 1)) { return -1; } 28 return 0; 29 } 30 case IOCALL_OPEN: { // (path, flags, mode) -> fd/error 31 void* ptr = rvsim_dma(s, args[0], 1024); 32 if (ptr == NULL) return -1; 33 if (memchr(ptr, 0, 1024) == NULL) return -1; 34 return open(ptr, args[1], args[2]); 35 } 36 case IOCALL_CLOSE: { // (fd) -> 0/error 37 return close(args[0]); 38 } 39 case IOCALL_READ: { // (fd, ptr, len) -> len/error 40 void* ptr = rvsim_dma(s, args[1], args[2]); 41 if (ptr == NULL) return -1; 42 return read(args[0], ptr, args[2]); 43 } 44 case IOCALL_WRITE: { // (fd, ptr, len) -> len/error 45 void* ptr = rvsim_dma(s, args[1], args[2]); 46 if (ptr == NULL) return -1; 47 return write(args[0], ptr, args[2]); 48 } 49 default: 50 return -1; 51 } 52 } 53 54 int load_image(const char* fn, uint8_t* ptr, size_t sz) { 55 struct stat s; 56 int fd = open(fn, O_RDONLY); 57 if (fd < 0) return -1; 58 if (fstat(fd, &s) < 0) return -1; 59 if (s.st_size > sz) return -1; 60 sz = s.st_size; 61 while (sz > 0) { 62 ssize_t r = read(fd, ptr, sz); 63 if (r <= 0) { 64 close(fd); 65 return -1; 66 } 67 ptr += r; 68 sz -= r; 69 } 70 close(fd); 71 fprintf(stderr, "image: %ld bytes\n", s.st_size); 72 return 0; 73 } 74 75 int main(int argc, char** argv) { 76 const char* fn = NULL; 77 const char* dumpfn = NULL; 78 uint32_t dumpfrom = 0, dumpto = 0; 79 while (argc > 1) { 80 argc--; 81 argv++; 82 if (argv[0][0] != '-') { 83 if (fn != NULL) { 84 fprintf(stderr, "error: multiple inputs\n"); 85 return -1; 86 } 87 fn = argv[0]; 88 continue; 89 } 90 if (!strncmp(argv[0],"-dump=",6)) { 91 dumpfn = argv[0] + 6; 92 continue; 93 } 94 if (!strncmp(argv[0],"-from=",6)) { 95 dumpfrom = strtoul(argv[0] + 6, NULL, 16); 96 continue; 97 } 98 if (!strncmp(argv[0],"-to=",4)) { 99 dumpto = strtoul(argv[0] + 4, NULL, 16); 100 continue; 101 } 102 fprintf(stderr, "error: unknown argument: %s\n", argv[0]); 103 return -1; 104 } 105 void* memory; 106 uint32_t membase = 0x80000000; 107 uint32_t memsize = 0x01000000; 108 rvstate_t* s; 109 110 if (rvsim_init(&s, NULL)) { 111 fprintf(stderr, "error: cannot initialize simulator\n"); 112 return -1; 113 } 114 if ((memory = rvsim_dma(s, membase, memsize)) == NULL) { 115 fprintf(stderr, "error: cannot access sim memory\n"); 116 return -1; 117 } 118 if (load_image(fn, memory, memsize) < 0) { 119 fprintf(stderr, "error: failed to load '%s'\n", fn); 120 return -1; 121 } 122 rvsim_exec(s, membase); 123 124 if (dumpfn && (dumpto > dumpfrom)) { 125 FILE* fp; 126 if ((fp = fopen(dumpfn, "w")) == NULL) { 127 fprintf(stderr, "error: failed to open '%s' to write\n", dumpfn); 128 return -1; 129 } 130 for (uint32_t n = dumpfrom; n < dumpto; n += 4) { 131 uint32_t v = rvsim_rd32(s, n); 132 fprintf(fp, "%08x\n", v); 133 } 134 fclose(fp); 135 } 136 return 0; 137 } 138