main.c (4394B)
1 #include <stdint.h> 2 #include <inttypes.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 //#include "disasm.h" 8 #include "exec.h" 9 #include "mem.h" 10 #include "disasm.h" 11 12 typedef enum { 13 MODE_RUN, 14 MODE_STEP 15 } emu_mode_t; 16 17 static void 18 load_program(uint8_t *mem) 19 { 20 /* program */ 21 uint32_t arr[] = { 22 0xfff00093, // addi x1, x0, -1 23 0xfff04113, // xori x2, x0, -1 24 0xfff06193, // ori x3, x0, -1 25 0xfff17213, // andi x4, x2, -1 26 0xfff02293, // slti x5, x0, -1 27 0xfff03313 // sltiu x6, x0, -1 28 /* 29 0xfff00093, // li ra,-1 30 0xfff04113, // not sp,zero 31 0xfff06193, // ori gp,zero,-1 32 0xfff17213, // andi tp,sp,-1 33 0xfff02293, // slti t0,zero,-1 34 0xfff03313, // sltiu t1,zero,-1 35 0x00100073 // ebreak 36 */ 37 /* 38 0x00700513, // addi x10, x0, 7 39 0x00451513, // slli x10, x10, 4 40 0x00d50513, // addi x10, x10, 13 41 0x05554513, // xori x10, x10, 0x55 42 0xff750513, // addi x10, x10, -9 43 0x00100073 // ebreak 44 */ 45 /* 46 0x10000593, //li a1,256 47 0xfff00513, //li a0,-1 48 0x00a58023, //sb a0,0(a1) 49 0x0005c503, //lbu a0,0(a1) 50 0x00150513, //addi a0,a0,1 51 0x00a59123, //sh a0,2(a1) 52 0x00259503, //lh a0,2(a1) 53 0xeff50513, //addi a0,a0,-257 54 0x00a58223, //sb a0,4(a1) 55 0x00458503, //lb a0,4(a1) 56 0x00a59323, //sh a0,6(a1) 57 0x00659503, //lh a0,6(a1) 58 0x0065d503, //lhu a0,6(a1) 59 0x00150513, //addi a0,a0,1 60 0x00a5a423, //sw a0,8(a1) 61 0x00000513, //li a0,0 62 0x0085a503, //lw a0,8(a1) 63 0x00000593, //li a1,0 64 0x00100073 //ebreak 65 */ 66 /* 67 0x00200093, // addi x1, x0, 2 68 0x00000113, // addi x2, x0, 0 69 0x05c00193, // addi x3, x0, 0x5c 70 0x00110113, // addi x2, x2, 1 71 0x0021a023, // sw x2, 0(x3) 72 0x00418193, // addi x3, x3, 4 73 0xfff08093, // addi x1, x1, -1 74 0xfe0098e3, // bne x1, x0, -16 75 0x00100073 // ebreak 76 */ 77 78 }; 79 80 size_t len = sizeof(arr) / sizeof(arr[0]); 81 82 int b = 0; /*byte*/ 83 for (size_t i=0; i<len; i++) { 84 85 mem[b+0] = (uint8_t)(arr[i] >> 0); 86 mem[b+1] = (uint8_t)(arr[i] >> 8); 87 mem[b+2] = (uint8_t)(arr[i] >> 16); 88 mem[b+3] = (uint8_t)(arr[i] >> 24); 89 90 b+=4; 91 } 92 } 93 94 static emu_mode_t 95 trap_handler(cpu_state_t *cpu) 96 { 97 if (cpu->status == CPU_TRAPPED) { 98 printf("CPU trapped\n"); 99 switch(cpu->trap.cause) { 100 case TRAP_EBREAK: 101 printf("Code reached breakpoint\n"); 102 break; 103 case TRAP_ECALL: 104 printf("Code ECALL\n"); 105 break; 106 case TRAP_ILLEGAL_INSTRUCTION: 107 printf("Illegal instruction\n"); 108 break; 109 case TRAP_INSTRUCTION_MISALIGNED: 110 printf("Instruction misaligned\n"); 111 break; 112 case TRAP_INSTRUCTION_ACCESS_FAULT: 113 printf("Instruction access fault\n"); 114 break; 115 case TRAP_NONE: 116 printf("No trap cause\n"); 117 break; 118 } 119 return MODE_STEP; 120 } 121 return MODE_RUN; 122 } 123 124 static emu_mode_t 125 debugger(cpu_state_t *cpu, uint8_t *mem) 126 { 127 printf("PC 0x%x>", cpu->pc); 128 char line[256]; 129 if (!fgets(line, sizeof(line), stdin)) { 130 fprintf(stderr, "Error reading" 131 "interactive input\n"); 132 } 133 134 if (strncmp(line, "s", 1) == 0 || 135 strncmp(line, "step", 4) == 0 || 136 strncmp(line, "n", 1) == 0 || 137 strncmp(line, "next", 4) == 0) { 138 139 uint32_t inst = load_u32_le(mem, cpu->pc); /* load little endian */ 140 disassemble_instruction(inst); 141 cpu_step(cpu, mem); 142 143 trap_handler(cpu); 144 145 } else if (strncmp(line, "r", 1) == 0 || 146 strncmp(line, "registers", 9) == 0) { 147 printf("Registers:\n"); 148 for (int i=0; i<32; i++) { 149 printf("0x%x: 0x%x\n", i, cpu->x[i]); 150 } 151 } else if (strncmp(line, "m", 1) == 0 || 152 strncmp(line, "memory", 6) == 0) { 153 printf("Memory:\n"); 154 for (uint32_t i=0; i<128; i+=4) { 155 if (cpu->pc == i) { 156 printf("-> "); 157 } else { 158 printf(" "); 159 } 160 printf("0x%.8x: 0x%.2x 0x%.2x 0x%.2x 0x%.2x ", 161 i, mem[i], mem[i+1], mem[i+2], mem[i+3]); 162 disassemble_instruction(load_u32_le(mem,i)); 163 } 164 } else if (strncmp(line, "ip", 2) == 0 || 165 strncmp(line, "pc", 2) == 0) { 166 printf("Instruction poiter:\n"); 167 printf("PC: %" PRIu32 "\n", cpu->pc); 168 } else if (strncmp(line, "e", 1) == 0) { 169 return MODE_RUN; 170 } 171 172 return MODE_STEP; 173 } 174 175 int 176 main() 177 { 178 cpu_state_t cpu = {0}; 179 180 uint8_t mem[MEMSIZE] = {0}; 181 182 load_program(mem); 183 184 /* fetch & run */ 185 emu_mode_t mode = MODE_STEP; 186 187 while (1) { 188 if (mode == MODE_RUN) { 189 cpu_step(&cpu, mem); 190 mode = trap_handler(&cpu); 191 } else { 192 mode = debugger(&cpu, mem); 193 } 194 } 195 196 return 0; 197 }