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 (
void)
00067 {
00068 Memory *mem;
00069
00070 mem =
avr_new (Memory, 1);
00071
mem_construct (mem);
00072
class_overload_destroy ((AvrClass *)mem,
mem_destroy);
00073
00074
return mem;
00075 }
00076
00077
00078
00079
void
00080 mem_construct (Memory *mem)
00081 {
00082
if (mem == NULL)
00083
avr_error (
"passed null ptr");
00084
00085
class_construct ((AvrClass *)mem);
00086
00087 mem->dev = NULL;
00088 }
00089
00090
00091
00092
void
00093 mem_destroy (
void *mem)
00094 {
00095 Memory *
this = (Memory *)mem;
00096
00097
if (mem == NULL)
00098
return;
00099
00100
dlist_delete_all (this->dev);
00101
00102
class_destroy (mem);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
void
00114 mem_attach (Memory *mem, VDevice *dev)
00115 {
00116
if (mem == NULL)
00117
avr_error (
"passed null ptr");
00118
00119
if (dev == NULL)
00120
avr_error (
"attempt to attach null device");
00121
00122
00123 mem->dev =
dlist_add_head (mem->dev, (AvrClass *)dev);
00124 }
00125
00126
00127
00128 VDevice *
00129 mem_get_vdevice_by_addr (Memory *mem,
int addr)
00130 {
00131
return (VDevice *)
dlist_lookup (mem->dev, (AvrClass *)&addr,
00132
vdev_addr_cmp);
00133 }
00134
00135
00136
00137 VDevice *
00138 mem_get_vdevice_by_name (Memory *mem,
char *name)
00139 {
00140
return (VDevice *)
dlist_lookup (mem->dev, (AvrClass *)name,
00141
vdev_name_cmp);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 uint8_t
00152 mem_read (Memory *mem,
int addr)
00153 {
00154 VDevice *dev =
mem_get_vdevice_by_addr (mem, addr);
00155
00156
if (dev == NULL)
00157 {
00158
avr_warning (
"**** Attempt to read invalid addr: 0x%04x\n", addr);
00159
return 0;
00160 }
00161
00162
return vdev_read (dev, addr);
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
void
00173 mem_write (Memory *mem,
int addr, uint8_t val)
00174 {
00175 VDevice *dev =
mem_get_vdevice_by_addr (mem, addr);
00176
00177
if (dev == NULL)
00178 {
00179
avr_warning (
"**** Attempt to write invalid addr: 0x%04x\n", addr);
00180
return;
00181 }
00182
00183
00184
00185
if ((addr >= IO_REG_ADDR_BEGIN) && (addr < IO_REG_ADDR_END))
00186
display_io_reg (addr - IO_REG_ADDR_BEGIN, val);
00187
00188
vdev_write (dev, addr, val);
00189 }
00190
00191
static int
00192 mem_reset_iter_func (AvrClass *data,
void *user_data)
00193 {
00194
vdev_reset ((VDevice *)data);
00195
return 0;
00196 }
00197
00198
00199
00200
00201
00202
void
00203 mem_reset (Memory *mem)
00204 {
00205 mem->dev =
dlist_iterator (mem->dev, mem_reset_iter_func, NULL);
00206 }
00207
00208
static void
00209 mem_reg_dump_core (Memory *mem, FILE * f_core)
00210 {
00211
int i, j;
00212
00213 fprintf (f_core,
"General Purpose Register Dump:\n");
00214
for (i = 0; i < 32; i += 8)
00215 {
00216
for (j = i; j < (i + 8); j++)
00217 fprintf (f_core,
"r%02d=%02x ", j, mem_read (mem, j));
00218 fprintf (f_core,
"\n");
00219 }
00220 fprintf (f_core,
"\n");
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
void
00233 mem_io_fetch (Memory *mem,
int addr, uint8_t * val,
char *buf,
int bufsiz)
00234 {
00235 VDevice *dev;
00236
int is_port;
00237
00238
if ((addr < IO_REG_ADDR_BEGIN) || (addr >= IO_REG_ADDR_END))
00239 {
00240 *val = 0;
00241 strncpy (buf,
"NOT AN IO REG", bufsiz);
00242 }
00243
else
00244 {
00245 dev =
mem_get_vdevice_by_addr (mem, addr);
00246
if (dev == NULL)
00247 {
00248 strncpy (buf,
"Reserved", bufsiz);
00249 *val = 0;
00250 }
00251
else
00252 {
00253 strncpy (buf,
vdev_get_reg_name (dev, addr), bufsiz);
00254
00255 is_port = 0;
00256
if (strncmp (
vdev_get_name (dev),
"PORT", 4) == 0)
00257 {
00258 is_port = 1;
00259
port_ext_disable ((Port *)dev);
00260 }
00261 *val =
vdev_read (dev, addr);
00262
if (is_port)
00263
port_ext_enable ((Port *)dev);
00264 }
00265 }
00266 }
00267
00268
static void
00269 mem_io_reg_dump_core (Memory *mem, FILE * f_core)
00270 {
00271
int i, j;
00272
char name[80];
00273 uint8_t val;
00274
00275
int begin = IO_REG_ADDR_BEGIN;
00276
int end = IO_REG_ADDR_END;
00277
int half = (end - begin) / 2;
00278
int mid = begin + half;
00279
00280 fprintf (f_core,
"IO Register Dump:\n");
00281
for (i = begin; i < mid; i++)
00282 {
00283
for (j = i; j < end; j += half)
00284 {
00285 memset (name,
'\0',
sizeof (name));
00286
mem_io_fetch (mem, j, &val, name,
sizeof (name) - 1);
00287
00288 fprintf (f_core,
"%02x : %-10s : 0x%02x ", j - half,
00289 name, val);
00290 }
00291 fprintf (f_core,
"\n");
00292 }
00293 fprintf (f_core,
"\n");
00294 }
00295
00296
static void
00297 mem_sram_display (VDevice *dev, FILE * f_core,
int base,
int size)
00298 {
00299
int i;
00300
int dup = 0;
00301
int ndat = 16;
00302
char line[80];
00303
char last_line[80];
00304
char buf[80];
00305 line[0] = last_line[0] =
'\0';
00306
00307
for (i = base; i < (base + size); i++)
00308 {
00309
if (((i % ndat) == 0) && strlen (line))
00310 {
00311
if (strncmp (line, last_line, 80) == 0)
00312 {
00313 dup++;
00314 }
00315
else
00316 {
00317
if (dup > 0)
00318 fprintf (f_core,
" -- last line repeats --\n");
00319 fprintf (f_core,
"%04x : %s\n", i - ndat, line);
00320 dup = 0;
00321 }
00322 strncpy (last_line, line, 80);
00323 line[0] =
'\0';
00324 }
00325 snprintf (buf, 80,
"%02x ", vdev_read (dev, i));
00326 strncat (line, buf, 80);
00327 }
00328
if (dup > 0)
00329 {
00330 fprintf (f_core,
" -- last line repeats --\n");
00331 fprintf (f_core,
"%04x : %s\n", i - ndat, line);
00332 }
00333 fprintf (f_core,
"\n");
00334 }
00335
00336
static void
00337 mem_sram_dump_core (Memory *mem, FILE * f_core)
00338 {
00339 VDevice *dev;
00340
int size, base;
00341
00342
00343
00344
00345 dev =
mem_get_vdevice_by_name (mem,
"SRAM");
00346
if (dev == NULL)
00347
return;
00348
00349 fprintf (f_core,
"Internal SRAM Memory Dump:\n");
00350 base =
vdev_get_base (dev);
00351 size =
vdev_get_size (dev);
00352 mem_sram_display (dev, f_core, base, size);
00353
00354
00355
00356
00357
00358 dev =
mem_get_vdevice_by_name (mem,
"ESRAM");
00359
if (dev == NULL)
00360
return;
00361
00362 fprintf (f_core,
"External SRAM Memory Dump:\n");
00363 base =
vdev_get_base (dev);
00364 size =
vdev_get_size (dev);
00365 mem_sram_display (dev, f_core, base, size);
00366
00367 }
00368
00369
static void
00370 mem_eeprom_dump_core (Memory *mem, FILE * f_core)
00371 {
00372 VDevice *dev =
mem_get_vdevice_by_name (mem,
"EEProm");
00373
00374
if (dev != NULL)
00375 eeprom_dump_core ((EEProm *)dev, f_core);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
void
00386 mem_dump_core (Memory *mem, FILE * f_core)
00387 {
00388 mem_reg_dump_core (mem, f_core);
00389 mem_io_reg_dump_core (mem, f_core);
00390 mem_sram_dump_core (mem, f_core);
00391 mem_eeprom_dump_core (mem, f_core);
00392 }