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 return mem->cell + addr;
00184 }
00185
00186 static int
00187 mem_is_io_reg (Memory *mem, int addr)
00188 {
00189 return ((addr > mem->gpwr_end) && (addr <= mem->io_reg_end));
00190 }
00191
00192 static char *
00193 mem_get_name (Memory *mem, int addr)
00194 {
00195 return mem->cell[addr].name;
00196 }
00197
00198 void
00199 mem_set_addr_name (Memory *mem, int addr, char *name)
00200 {
00201 mem->cell[addr].name = name;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 uint8_t
00212 mem_read (Memory *mem, int addr)
00213 {
00214 MemoryCell *cell = mem_get_cell (mem, addr);
00215
00216 if (cell->vdev == NULL)
00217 {
00218 char *name = mem_get_name (mem, addr);
00219
00220 if (name)
00221 {
00222 avr_warning ("**** Attempt to read invalid %s: %s at 0x%04x\n",
00223 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00224 name, addr);
00225 }
00226 else
00227 {
00228 avr_warning ("**** Attempt to read invalid %s: 0x%04x\n",
00229 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00230 addr);
00231 }
00232
00233 return 0;
00234 }
00235
00236 return (vdev_read (cell->vdev, addr) & cell->rd_mask);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 void
00247 mem_write (Memory *mem, int addr, uint8_t val)
00248 {
00249 MemoryCell *cell = mem_get_cell (mem, addr);
00250
00251 if (cell->vdev == NULL)
00252 {
00253 char *name = mem_get_name (mem, addr);
00254
00255 if (name)
00256 {
00257 avr_warning ("**** Attempt to write invalid %s: %s at 0x%04x\n",
00258 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00259 name, addr);
00260 }
00261 else
00262 {
00263 avr_warning ("**** Attempt to write invalid %s: 0x%04x\n",
00264 mem_is_io_reg (mem, addr) ? "io reg" : "mem addr",
00265 addr);
00266 }
00267
00268 return;
00269 }
00270
00271
00272
00273 if (mem_is_io_reg (mem, addr))
00274 display_io_reg (addr - (mem->gpwr_end + 1), val & cell->wr_mask);
00275
00276 vdev_write (cell->vdev, addr, val & cell->wr_mask);
00277 }
00278
00279
00280
00281
00282
00283 void
00284 mem_reset (Memory *mem)
00285 {
00286 int i;
00287
00288 for (i = 0; i < mem->xram_end; i++)
00289 {
00290 MemoryCell *cell = mem_get_cell (mem, i);
00291
00292 if (cell->vdev)
00293 vdev_reset (cell->vdev);
00294 }
00295 }
00296
00297 static void
00298 mem_reg_dump_core (Memory *mem, FILE * f_core)
00299 {
00300 int i, j;
00301
00302 fprintf (f_core, "General Purpose Register Dump:\n");
00303 for (i = 0; i < 32; i += 8)
00304 {
00305 for (j = i; j < (i + 8); j++)
00306 fprintf (f_core, "r%02d=%02x ", j, mem_read (mem, j));
00307 fprintf (f_core, "\n");
00308 }
00309 fprintf (f_core, "\n");
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 void
00322 mem_io_fetch (Memory *mem, int addr, uint8_t * val, char *buf, int bufsiz)
00323 {
00324 MemoryCell *cell;
00325
00326 if (mem_is_io_reg (mem, addr))
00327 {
00328 cell = mem_get_cell (mem, addr);
00329
00330 if (cell->name == NULL)
00331 {
00332 strncpy (buf, "Reserved", bufsiz);
00333 *val = 0;
00334 }
00335 else
00336 {
00337 strncpy (buf, cell->name, bufsiz);
00338
00339 if (cell->vdev)
00340 {
00341
00342
00343
00344
00345
00346 *val = (vdev_read (cell->vdev, addr) & cell->rd_mask);
00347 }
00348 else
00349 {
00350 *val = 0;
00351 }
00352 }
00353 }
00354 else
00355 {
00356 *val = 0;
00357 strncpy (buf, "NOT AN IO REG", bufsiz);
00358 }
00359 }
00360
00361 static void
00362 mem_io_reg_dump_core (Memory *mem, FILE * f_core)
00363 {
00364 int i, j;
00365 char name[80];
00366 uint8_t val;
00367
00368 int begin = mem->gpwr_end + 1;
00369 int end = mem->io_reg_end;
00370 int half = (end - begin) / 2;
00371 int mid = begin + half;
00372
00373 fprintf (f_core, "IO Register Dump:\n");
00374 for (i = begin; i < mid; i++)
00375 {
00376 for (j = i; j < end; j += half)
00377 {
00378 memset (name, '\0', sizeof (name));
00379 mem_io_fetch (mem, j, &val, name, sizeof (name) - 1);
00380
00381 fprintf (f_core, "%02x : %-10s : 0x%02x ", j - half,
00382 name, val);
00383 }
00384 fprintf (f_core, "\n");
00385 }
00386 fprintf (f_core, "\n");
00387 }
00388
00389 static void
00390 mem_sram_display (Memory *mem, FILE * f_core, int base, int size)
00391 {
00392 int i;
00393 int dup = 0;
00394 int ndat = 16;
00395 char line[80];
00396 char last_line[80];
00397 char buf[80];
00398 line[0] = last_line[0] = '\0';
00399
00400 for (i = base; i < (base + size); i++)
00401 {
00402 if (((i % ndat) == 0) && strlen (line))
00403 {
00404 if (strncmp (line, last_line, 80) == 0)
00405 {
00406 dup++;
00407 }
00408 else
00409 {
00410 if (dup > 0)
00411 fprintf (f_core, " -- last line repeats --\n");
00412 fprintf (f_core, "%04x : %s\n", i - ndat, line);
00413 dup = 0;
00414 }
00415 strncpy (last_line, line, 80);
00416 line[0] = '\0';
00417 }
00418 snprintf (buf, 80, "%02x ", mem_read (mem, i));
00419 strncat (line, buf, 80);
00420 }
00421 if (dup > 0)
00422 {
00423 fprintf (f_core, " -- last line repeats --\n");
00424 fprintf (f_core, "%04x : %s\n", i - ndat, line);
00425 }
00426 fprintf (f_core, "\n");
00427 }
00428
00429 static void
00430 mem_sram_dump_core (Memory *mem, FILE * f_core)
00431 {
00432 int size, base;
00433
00434
00435
00436
00437
00438 if (mem->io_reg_end == mem->sram_end)
00439 return;
00440
00441 fprintf (f_core, "Internal SRAM Memory Dump:\n");
00442 base = mem->io_reg_end + 1;
00443 size = mem->sram_end - base + 1;
00444 mem_sram_display (mem, f_core, base, size);
00445
00446
00447
00448
00449
00450 if (mem->sram_end == mem->xram_end)
00451 return;
00452
00453 fprintf (f_core, "External SRAM Memory Dump:\n");
00454 base = mem->sram_end + 1;
00455 size = mem->xram_end - base + 1;
00456 mem_sram_display (mem, f_core, base, size);
00457
00458 }
00459
00460 #if 0
00461
00462
00463
00464
00465 static void
00466 mem_eeprom_dump_core (Memory *mem, FILE * f_core)
00467 {
00468 VDevice *dev = mem_get_vdevice_by_name (mem, "EEProm");
00469
00470 if (dev != NULL)
00471 eeprom_dump_core ((EEProm *)dev, f_core);
00472 }
00473 #endif
00474
00475
00476
00477
00478
00479
00480
00481
00482 void
00483 mem_dump_core (Memory *mem, FILE * f_core)
00484 {
00485 mem_reg_dump_core (mem, f_core);
00486 mem_io_reg_dump_core (mem, f_core);
00487 mem_sram_dump_core (mem, f_core);
00488
00489 }