00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include "avrerror.h"
00041 #include "avrmalloc.h"
00042 #include "avrclass.h"
00043 #include "utils.h"
00044 #include "callback.h"
00045 #include "op_names.h"
00046
00047 #include "storage.h"
00048 #include "flash.h"
00049
00050 #include "vdevs.h"
00051 #include "memory.h"
00052 #include "stack.h"
00053 #include "register.h"
00054 #include "sram.h"
00055 #include "eeprom.h"
00056 #include "timers.h"
00057 #include "ports.h"
00058
00059 #include "avrcore.h"
00060
00061 #include "display.h"
00062
00063
00064
00065 Memory *
00066 mem_new (int gpwr_end, int io_reg_end, int sram_end, int xram_end)
00067 {
00068 Memory *mem;
00069
00070 mem = avr_new0 (Memory, 1);
00071 mem_construct (mem, gpwr_end, io_reg_end, sram_end, xram_end);
00072 class_overload_destroy ((AvrClass *)mem, mem_destroy);
00073
00074 return mem;
00075 }
00076
00077
00078
00079 void
00080 mem_construct (Memory *mem, int gpwr_end, int io_reg_end, int sram_end,
00081 int xram_end)
00082 {
00083 if (mem == NULL)
00084 avr_error ("passed null ptr");
00085
00086 mem->gpwr_end = gpwr_end;
00087 mem->io_reg_end = io_reg_end;
00088 mem->sram_end = sram_end;
00089 mem->xram_end = xram_end;
00090
00091 mem->cell = avr_new0 (MemoryCell, xram_end + 1);
00092
00093 class_construct ((AvrClass *)mem);
00094 }
00095
00096
00097
00098 void
00099 mem_destroy (void *mem)
00100 {
00101 int i;
00102
00103 Memory *this = (Memory *)mem;
00104
00105 if (mem == NULL)
00106 return;
00107
00108 for (i = 0; i < this->xram_end; i++)
00109 {
00110 if (this->cell[i].vdev)
00111 {
00112 class_unref ((AvrClass *)this->cell[i].vdev);
00113 }
00114 }
00115
00116 avr_free (this->cell);
00117
00118 class_destroy (mem);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void
00130 mem_attach (Memory *mem, int addr, char *name, VDevice *vdev, int flags,
00131 uint8_t reset_value, uint8_t rd_mask, uint8_t wr_mask)
00132 {
00133 MemoryCell *cell;
00134
00135 if (mem == NULL)
00136 avr_error ("passed null ptr");
00137
00138 if (vdev == NULL)
00139 avr_error ("attempt to attach null device");
00140
00141 if ((addr < 0) || (addr > mem->xram_end))
00142 avr_error ("address out of range");
00143
00144 cell = &mem->cell[addr];
00145
00146 cell->name = name;
00147 cell->flags = flags;
00148 cell->reset_value = reset_value;
00149 cell->rd_mask = rd_mask;
00150 cell->wr_mask = wr_mask;
00151
00152 class_ref ((AvrClass *)vdev);
00153 cell->vdev = vdev;
00154 }
00155
00156
00157
00158 VDevice *
00159 mem_get_vdevice_by_addr (Memory *mem, int addr)
00160 {
00161 return mem->cell[addr].vdev;
00162 }
00163
00164
00165
00166
00167
00168 VDevice *
00169 mem_get_vdevice_by_name (Memory *mem, char *name)
00170 {
00171 #if 0
00172 return (VDevice *)dlist_lookup (mem->dev, (AvrClass *)name,
00173 vdev_name_cmp);
00174 #else
00175 avr_error ("use of deprecated interface");
00176 return NULL;
00177 #endif
00178 }
00179
00180 static MemoryCell *
00181 mem_get_cell (Memory *mem, int addr)
00182 {
00183
00184
00185
00186
00187
00188 if ((addr < 0) || (addr > mem->xram_end))
00189 addr = mem->xram_end - 1;
00190
00191 return mem->cell + addr;
00192 }
00193
00194 static int
00195 mem_is_io_reg (Memory *mem, int addr)
00196 {
00197 return ((addr > mem->gpwr_end) && (addr <= mem->io_reg_end));
00198 }
00199
00200 static char *
00201 mem_get_name (Memory *mem, int addr)
00202 {
00203 return mem->cell[addr].name;
00204 }
00205
00206 void
00207 mem_set_addr_name (Memory *mem, int addr, char *name)
00208 {
00209 mem->cell[addr].name = name;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 uint8_t
00220 mem_read (Memory *mem, int addr)
00221 {
00222 MemoryCell *cell = mem_get_cell (mem, addr);
00223
00224 if (cell->vdev == NULL)
00225 {
00226 char *name = mem_get_name (mem, addr);
00227
00228 if (name)
00229 {
00230 avr_warning ("**** Attempt to read invalid %s: %s at 0x%04x\n",
00231 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00232 name, addr);
00233 }
00234 else
00235 {
00236 avr_warning ("**** Attempt to read invalid %s: 0x%04x\n",
00237 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00238 addr);
00239 }
00240
00241 return 0;
00242 }
00243
00244 return (vdev_read (cell->vdev, addr) & cell->rd_mask);
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254 void
00255 mem_write (Memory *mem, int addr, uint8_t val)
00256 {
00257 MemoryCell *cell = mem_get_cell (mem, addr);
00258
00259 if (cell->vdev == NULL)
00260 {
00261 char *name = mem_get_name (mem, addr);
00262
00263 if (name)
00264 {
00265 avr_warning ("**** Attempt to write invalid %s: %s at 0x%04x\n",
00266 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00267 name, addr);
00268 }
00269 else
00270 {
00271 avr_warning ("**** Attempt to write invalid %s: 0x%04x\n",
00272 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00273 addr);
00274 }
00275
00276 return;
00277 }
00278
00279
00280
00281 if (mem_is_io_reg (mem, addr))
00282 display_io_reg (addr - (mem->gpwr_end + 1), val & cell->wr_mask);
00283
00284 vdev_write (cell->vdev, addr, val & cell->wr_mask);
00285 }
00286
00287
00288
00289
00290
00291 void
00292 mem_reset (Memory *mem)
00293 {
00294 int i;
00295
00296 for (i = 0; i < mem->xram_end; i++)
00297 {
00298 MemoryCell *cell = mem_get_cell (mem, i);
00299
00300 if (cell->vdev)
00301 vdev_reset (cell->vdev);
00302 }
00303 }
00304
00305 static void
00306 mem_reg_dump_core (Memory *mem, FILE * f_core)
00307 {
00308 int i, j;
00309
00310 fprintf (f_core, "General Purpose Register Dump:\n");
00311 for (i = 0; i < 32; i += 8)
00312 {
00313 for (j = i; j < (i + 8); j++)
00314 fprintf (f_core, "r%02d=%02x ", j, mem_read (mem, j));
00315 fprintf (f_core, "\n");
00316 }
00317 fprintf (f_core, "\n");
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void
00330 mem_io_fetch (Memory *mem, int addr, uint8_t * val, char *buf, int bufsiz)
00331 {
00332 MemoryCell *cell;
00333
00334 if (mem_is_io_reg (mem, addr))
00335 {
00336 cell = mem_get_cell (mem, addr);
00337
00338 if (cell->name == NULL)
00339 {
00340 strncpy (buf, "Reserved", bufsiz);
00341 *val = 0;
00342 }
00343 else
00344 {
00345 strncpy (buf, cell->name, bufsiz);
00346
00347 if (cell->vdev)
00348 {
00349
00350
00351
00352
00353
00354 *val = (vdev_read (cell->vdev, addr) & cell->rd_mask);
00355 }
00356 else
00357 {
00358 *val = 0;
00359 }
00360 }
00361 }
00362 else
00363 {
00364 *val = 0;
00365 strncpy (buf, "NOT AN IO REG", bufsiz);
00366 }
00367 }
00368
00369 static void
00370 mem_io_reg_dump_core (Memory *mem, FILE * f_core)
00371 {
00372 unsigned int i, j;
00373 char name[80];
00374 uint8_t val;
00375
00376 unsigned int begin = (unsigned)mem->gpwr_end + 1;
00377 unsigned int end = (unsigned)mem->io_reg_end;
00378 unsigned int half = (end - begin + 1) / 2;
00379 unsigned int mid = begin + half;
00380
00381 fprintf (f_core, "IO Register Dump:\n");
00382 for (i = begin; i < mid; i++)
00383 {
00384 for (j = i; j <= end; j += half)
00385 {
00386 memset (name, '\0', sizeof (name));
00387 mem_io_fetch (mem, j, &val, name, sizeof (name) - 1);
00388
00389 fprintf (f_core, "%02x : %-10s : 0x%02x ", j,
00390 name, val);
00391 }
00392 fprintf (f_core, "\n");
00393 }
00394 fprintf (f_core, "\n");
00395 }
00396
00397 static void
00398 mem_sram_display (Memory *mem, FILE * f_core, int base, int size)
00399 {
00400 int i;
00401 int dup = 0;
00402 int ndat = 16;
00403 char line[80];
00404 char last_line[80];
00405 char buf[80];
00406 line[0] = last_line[0] = '\0';
00407
00408 for (i = base; i < (base + size); i++)
00409 {
00410 if (((i % ndat) == 0) && strlen (line))
00411 {
00412 if (strncmp (line, last_line, 80) == 0)
00413 {
00414 dup++;
00415 }
00416 else
00417 {
00418 if (dup > 0)
00419 fprintf (f_core, " -- last line repeats --\n");
00420 fprintf (f_core, "%04x : %s\n", i - ndat, line);
00421 dup = 0;
00422 }
00423 strncpy (last_line, line, 80);
00424 line[0] = '\0';
00425 }
00426 snprintf (buf, 80, "%02x ", mem_read (mem, i));
00427 strncat (line, buf, 80);
00428 }
00429 if (dup > 0)
00430 {
00431 fprintf (f_core, " -- last line repeats --\n");
00432 fprintf (f_core, "%04x : %s\n", i - ndat, line);
00433 }
00434 fprintf (f_core, "\n");
00435 }
00436
00437 static void
00438 mem_sram_dump_core (Memory *mem, FILE * f_core)
00439 {
00440 int size, base;
00441
00442
00443
00444
00445
00446 if (mem->io_reg_end == mem->sram_end)
00447 return;
00448
00449 fprintf (f_core, "Internal SRAM Memory Dump:\n");
00450 base = mem->io_reg_end + 1;
00451 size = mem->sram_end - base + 1;
00452 mem_sram_display (mem, f_core, base, size);
00453
00454
00455
00456
00457
00458 if (mem->sram_end == mem->xram_end)
00459 return;
00460
00461 fprintf (f_core, "External SRAM Memory Dump:\n");
00462 base = mem->sram_end + 1;
00463 size = mem->xram_end - base + 1;
00464 mem_sram_display (mem, f_core, base, size);
00465
00466 }
00467
00468 #if 0
00469
00470
00471
00472
00473 static void
00474 mem_eeprom_dump_core (Memory *mem, FILE * f_core)
00475 {
00476 VDevice *dev = mem_get_vdevice_by_name (mem, "EEProm");
00477
00478 if (dev != NULL)
00479 eeprom_dump_core ((EEProm *)dev, f_core);
00480 }
00481 #endif
00482
00483
00484
00485
00486
00487
00488
00489
00490 void
00491 mem_dump_core (Memory *mem, FILE * f_core)
00492 {
00493 mem_reg_dump_core (mem, f_core);
00494 mem_io_reg_dump_core (mem, f_core);
00495 mem_sram_dump_core (mem, f_core);
00496
00497 }