riscv

an RV32I simulator and related experiments
git clone http://frotz.net/git/riscv.git
Log | Files | Refs | README

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