Cores, decoder, uart, ioports - lots of changes
[simavr] / simavr / sim / simavr.c
1 /*
2         simavr.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <getopt.h>
30 #include "simavr.h"
31 #include "sim_elf.h"
32
33 #include "sim_core.h"
34 #include "avr_eeprom.h"
35
36 void hdump(const char *w, uint8_t *b, size_t l)
37 {
38         uint32_t i;
39         if (l < 16) {
40                 printf("%s: ",w);
41                 for (i = 0; i < l; i++) printf("%02x",b[i]);
42         } else {
43                 printf("%s:\n",w);
44                 for (i = 0; i < l; i++) {
45                         if (!(i & 0x1f)) printf("    ");
46                         printf("%02x",b[i]);
47                         if ((i & 0x1f) == 0x1f) {
48                                 printf(" ");
49                                 printf("\n");
50                         }
51                 }
52         }
53         printf("\n");
54 }
55
56
57
58 int avr_init(avr_t * avr)
59 {
60         avr->flash = malloc(avr->flashend + 1);
61         memset(avr->flash, 0xff, avr->flashend + 1);
62         avr->data = malloc(avr->ramend + 1);
63         memset(avr->data, 0, avr->ramend + 1);
64
65         // cpu is in limbo before init is finished.
66         avr->state = cpu_Limbo;
67         avr->frequency = 1000000;       // can be overriden via avr_mcu_section
68         if (avr->init)
69                 avr->init(avr);
70         avr->state = cpu_Running;
71         avr_reset(avr); 
72         return 0;
73 }
74
75 void avr_reset(avr_t * avr)
76 {
77         memset(avr->data, 0x0, avr->ramend + 1);
78         _avr_sp_set(avr, avr->ramend);
79         avr->pc = 0;
80         for (int i = 0; i < 8; i++)
81                 avr->sreg[i] = 0;
82         if (avr->reset)
83                 avr->reset(avr);
84
85         avr_io_t * port = avr->io_port;
86         while (port) {
87                 if (port->reset)
88                         port->reset(avr, port);
89                 port = port->next;
90         }
91
92 }
93
94 int avr_ioctl(avr_t *avr, uint32_t ctl, void * io_param)
95 {
96         avr_io_t * port = avr->io_port;
97         int res = -1;
98         while (port && res == -1) {
99                 if (port->ioctl)
100                         res = port->ioctl(avr, port, ctl, io_param);
101                 port = port->next;
102         }
103         return res;
104 }
105
106 void avr_register_io(avr_t *avr, avr_io_t * io)
107 {
108         io->next = avr->io_port;
109         avr->io_port = io;
110 }
111
112 void avr_register_io_read(avr_t *avr, uint8_t addr, avr_io_read_t readp, void * param)
113 {
114         avr->ior[AVR_DATA_TO_IO(addr)].param = param;
115         avr->ior[AVR_DATA_TO_IO(addr)].r = readp;
116 }
117
118 void avr_register_io_write(avr_t *avr, uint8_t addr, avr_io_write_t writep, void * param)
119 {
120         avr->iow[AVR_DATA_TO_IO(addr)].param = param;
121         avr->iow[AVR_DATA_TO_IO(addr)].w = writep;
122 }
123
124 void avr_register_vector(avr_t *avr, avr_int_vector_t * vector)
125 {
126         if (vector->vector)
127                 avr->vector[vector->vector] = vector;
128 }
129
130 int avr_has_pending_interupts(avr_t * avr)
131 {
132         return avr->pending[0] || avr->pending[1];
133 }
134
135 int avr_is_interupt_pending(avr_t * avr, avr_int_vector_t * vector)
136 {
137         return avr->pending[vector->vector >> 5] & (1 << (vector->vector & 0x1f));
138 }
139
140 int avr_raise_interupt(avr_t * avr, avr_int_vector_t * vector)
141 {
142         if (!vector || !vector->vector)
143                 return 0;
144 //      printf("%s raising %d\n", __FUNCTION__, vector->vector);
145         // always mark the 'raised' flag to one, even if the interuot is disabled
146         // this allow "pooling" for the "raised" flag, like for non-interupt
147         // driven UART and so so. These flags are often "write one to clear"
148         if (vector->raised.reg)
149                 avr_regbit_set(avr, vector->raised);
150         if (vector->enable.reg) {
151                 if (!avr_regbit_get(avr, vector->enable))
152                         return 0;
153         }
154         if (!avr_is_interupt_pending(avr, vector)) {
155                 if (!avr->pending_wait)
156                         avr->pending_wait = 2;          // latency on interupts ??
157                 avr->pending[vector->vector >> 5] |= (1 << (vector->vector & 0x1f));
158
159                 if (avr->state != cpu_Running) {
160                 //      printf("Waking CPU due to interrupt\n");
161                         avr->state = cpu_Running;       // in case we were sleeping
162                 }
163         }
164         // return 'raised' even if it was already pending
165         return 1;
166 }
167
168 static void avr_clear_interupt(avr_t * avr, int v)
169 {
170         avr_int_vector_t * vector = avr->vector[v];
171         avr->pending[v >> 5] &= ~(1 << (v & 0x1f));
172         if (!vector)
173                 return;
174         printf("%s cleared %d\n", __FUNCTION__, vector->vector);
175         if (vector->raised.reg)
176                 avr_regbit_clear(avr, vector->raised);
177 }
178
179 void avr_init_irq(avr_t * avr, avr_irq_t * irq, uint32_t base, uint32_t count)
180 {
181         memset(irq, 0, sizeof(avr_irq_t) * count);
182
183         for (int i = 0; i < count; i++)
184                 irq[i].irq = base + i;
185 }
186
187 avr_irq_t * avr_alloc_irq(avr_t * avr, uint32_t base, uint32_t count)
188 {
189         avr_irq_t * irq = (avr_irq_t*)malloc(sizeof(avr_irq_t) * count);
190         avr_init_irq(avr, irq, base, count);
191         return irq;
192 }
193
194 void avr_irq_register_notify(avr_t * avr, avr_irq_t * irq, avr_irq_notify_t notify, void * param)
195 {
196         if (!irq || !notify)
197                 return;
198         
199         avr_irq_hook_t *hook = irq->hook;
200         while (hook) {
201                 if (hook->notify == notify && hook->param == param)
202                         return; // already there
203                 hook = hook->next;
204         }
205         hook = malloc(sizeof(avr_irq_hook_t));
206         memset(hook, 0, sizeof(avr_irq_hook_t));
207         hook->next = irq->hook;
208         hook->notify = notify;
209         hook->param = param;
210         irq->hook = hook;
211 }
212
213 void avr_raise_irq(avr_t * avr, avr_irq_t * irq, uint32_t value)
214 {
215         if (!irq || irq->value == value)
216                 return ;
217         avr_irq_hook_t *hook = irq->hook;
218         while (hook) {
219                 if (hook->notify) {
220                         if (hook->busy == 0) {
221                                 hook->busy++;
222                                 hook->notify(avr, irq, value, hook->param);
223                                 hook->busy--;
224                         }
225                 }
226                 hook = hook->next;
227         }
228         irq->value = value;
229 }
230
231 static void _avr_irq_connect(avr_t * avr, avr_irq_t * irq, uint32_t value, void * param)
232 {
233         avr_irq_t * dst = (avr_irq_t*)param;
234         avr_raise_irq(avr, dst, value != 0);
235 }
236
237 void avr_connect_irq(avr_t * avr, avr_irq_t * src, avr_irq_t * dst)
238 {
239         avr_irq_register_notify(avr, src, _avr_irq_connect, dst);
240 }
241
242 void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address)
243 {
244         memcpy(avr->flash + address, code, size);
245 }
246
247 void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
248 {
249         if (addr > avr->ramend) {
250                 printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n",
251                                 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
252                 CRASH();
253         }
254         if (addr < 32) {
255                 printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n",
256                                 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
257                 CRASH();
258         }
259 #if AVR_STACK_WATCH
260         /*
261          * this checks that the current "function" is not doctoring the stack frame that is located
262          * higher on the stack than it should be. It's a sign of code that has overrun it's stack
263          * frame and is munching on it's own return address.
264          */
265         if (avr->stack_frame_index > 1 && addr > avr->stack_frame[avr->stack_frame_index-2].sp) {
266                 printf("\e[31m%04x : munching stack SP %04x, A=%04x <= %02x\e[0m\n", avr->pc, _avr_sp_get(avr), addr, v);
267         }
268 #endif
269         avr->data[addr] = v;
270 }
271
272 uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
273 {
274         if (addr > avr->ramend) {
275                 printf("*** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n",
276                                 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
277                 CRASH();
278         }
279         return avr->data[addr];
280 }
281
282 /*
283  * check wether interupts are pending. I so, check if the interupt "latency" is reached,
284  * and if so triggers the handlers and jump to the vector.
285  */
286 static void avr_service_interupts(avr_t * avr)
287 {
288         if (!avr->sreg[S_I])
289                 return;
290
291         if (avr_has_pending_interupts(avr)) {
292                 if (avr->pending_wait) {
293                         avr->pending_wait--;
294                         if (avr->pending_wait == 0) {
295                                 int done = 0;
296                                 for (int bi = 0; bi < 2 && !done; bi++) if (avr->pending[bi]) {
297                                         for (int ii = 0; ii < 32 && !done; ii++)
298                                                 if (avr->pending[bi] & (1 << ii)) {
299
300                                                         int v = (bi * 32) + ii; // vector
301
302                                                 //      printf("%s calling %d\n", __FUNCTION__, v);
303                                                         _avr_push16(avr, avr->pc >> 1);
304                                                         avr->sreg[S_I] = 0;
305                                                         avr->pc = v * avr->vector_size;
306
307                                                         avr_clear_interupt(avr, v);
308                                                         done++;
309                                                         break;
310                                                 }
311                                         break;
312                                 }
313                         }
314                 } else
315                         avr->pending_wait = 2;  // for next one...
316         }
317 }
318
319
320 int avr_run(avr_t * avr)
321 {
322         if (avr->state == cpu_Stopped)
323                 return avr->state;
324
325         uint16_t new_pc = avr->pc;
326
327         if (avr->state == cpu_Running) {
328                 new_pc = avr_run_one(avr);
329                 avr_dump_state(avr);
330         } else
331                 avr->cycle ++;
332
333         // re-synth the SREG
334         //SREG();
335         // if we just re-enabled the interrupts...
336         if (avr->sreg[S_I] && !(avr->data[R_SREG] & (1 << S_I))) {
337         //      printf("*** %s: Renabling interupts\n", __FUNCTION__);
338                 avr->pending_wait++;
339         }
340         avr_io_t * port = avr->io_port;
341         while (port) {
342                 if (port->run)
343                         port->run(avr, port);
344                 port = port->next;
345         }
346
347         avr->pc = new_pc;
348
349         if (avr->state == cpu_Sleeping) {
350                 if (!avr->sreg[S_I]) {
351                         printf("simavr: sleeping with interupts off, quitting gracefuly\n");
352                         exit(0);
353                 }
354                 usleep(500);
355                 long sleep = (float)avr->frequency * (1.0f / 500.0f);
356                 avr->cycle += sleep;
357         //      avr->state = cpu_Running;
358         }
359         // Interrupt servicing might change the PC too
360         if (avr->state == cpu_Running || avr->state == cpu_Sleeping) {
361                 avr_service_interupts(avr);
362
363                 avr->data[R_SREG] = 0;
364                 for (int i = 0; i < 8; i++)
365                         if (avr->sreg[i] > 1) {
366                                 printf("** Invalid SREG!!\n");
367                                 CRASH();
368                         } else if (avr->sreg[i])
369                                 avr->data[R_SREG] |= (1 << i);
370         }
371         return avr->state;
372 }
373
374 extern avr_kind_t tiny85;
375 extern avr_kind_t mega48,mega88,mega168;
376 extern avr_kind_t mega644;
377
378 avr_kind_t * avr_kind[] = {
379         &tiny85,
380         &mega48,
381         &mega88,
382         &mega168,
383         &mega644,
384         NULL
385 };
386
387 void display_usage()
388 {
389         printf("usage: simavr [-t] [-m <device>] [-f <frequency>] firmware\n");
390         printf("       -t: run full scale decoder trace\n");
391         exit(1);
392 }
393
394 int main(int argc, char *argv[])
395 {
396         elf_firmware_t f;
397         long f_cpu = 0;
398         int trace = 0;
399         char name[16] = "";
400         int option_count;
401         int option_index = 0;
402
403         struct option long_options[] = {
404                 {"help", no_argument, 0, 'h'},
405                 {"mcu", required_argument, 0, 'm'},
406                 {"freq", required_argument, 0, 'f'},
407                 {"trace", no_argument, 0, 't'},
408                 {0, 0, 0, 0}
409         };
410
411         if (argc == 1)
412                 display_usage();
413
414         while ((option_count = getopt_long(argc, argv, "thm:f:", long_options, &option_index)) != -1) {
415                 switch (option_count) {
416                         case 'h':
417                                 display_usage();
418                                 break;
419                         case 'm':
420                                 strcpy(name, optarg);
421                                 break;
422                         case 'f':
423                                 f_cpu = atoi(optarg);
424                                 break;
425                         case 't':
426                                 trace++;
427                                 break;
428                 }
429         }
430
431         elf_read_firmware(argv[argc-1], &f);
432
433         if (strlen(name))
434                 strcpy(f.mmcu.name, name);
435         if (f_cpu)
436                 f.mmcu.f_cpu = f_cpu;
437
438         printf("firmware %s f=%ld mmcu=%s\n", argv[argc-1], f.mmcu.f_cpu, f.mmcu.name);
439
440         avr_kind_t * maker = NULL;
441         for (int i = 0; avr_kind[i] && !maker; i++) {
442                 for (int j = 0; avr_kind[i]->names[j]; j++)
443                         if (!strcmp(avr_kind[i]->names[j], f.mmcu.name)) {
444                                 maker = avr_kind[i];
445                                 break;
446                         }
447         }
448         if (!maker) {
449                 fprintf(stderr, "%s: AVR '%s' now known\n", argv[0], f.mmcu.name);
450                 exit(1);
451         }
452
453         avr_t * avr = maker->make();
454         printf("Starting %s - flashend %04x ramend %04x e2end %04x\n", avr->mmcu, avr->flashend, avr->ramend, avr->e2end);
455         avr_init(avr);
456         avr->frequency = f.mmcu.f_cpu;
457         avr->codeline = f.codeline;
458         avr_loadcode(avr, f.flash, f.flashsize, 0);
459         avr->codeend = f.flashsize - f.datasize;
460         if (f.eeprom && f.eesize) {
461                 avr_eeprom_desc_t d = { .ee = f.eeprom, .offset = 0, .size = f.eesize };
462                 avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &d);
463         }
464         avr->trace = trace;
465
466         for (long long i = 0; i < 8000000*10; i++)
467 //      for (long long i = 0; i < 80000; i++)
468                 avr_run(avr);
469         
470 }