Line 25... |
Line 25... |
#include <stdio.h>
|
#include <stdio.h>
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#include "config.h"
|
#include "config.h"
|
|
|
|
#ifdef HAVE_INTTYPES_H
|
|
#include <inttypes.h>
|
|
#endif
|
|
|
|
#include "port.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
|
|
|
#include "arch.h"
|
#include "parse.h"
|
#include "parse.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "labels.h"
|
#include "labels.h"
|
#include "arch.h"
|
|
#include "execute.h"
|
#include "execute.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "except.h"
|
#include "except.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
#include "opcode/or32.h"
|
#include "opcode/or32.h"
|
Line 48... |
Line 54... |
extern unsigned long reg[];
|
extern unsigned long reg[];
|
extern char *disassembled;
|
extern char *disassembled;
|
|
|
/* This is an abstract+physical memory array rather than only physical
|
/* This is an abstract+physical memory array rather than only physical
|
memory array */
|
memory array */
|
static unsigned long *simmem32;
|
static uint32_t *simmem32;
|
|
|
/* Pointer to memory area descriptions that are assigned to individual
|
/* Pointer to memory area descriptions that are assigned to individual
|
peripheral devices. */
|
peripheral devices. */
|
struct dev_memarea *dev_list;
|
struct dev_memarea *dev_list;
|
|
|
Line 64... |
Line 70... |
|
|
/* These are set by mmu if cache inhibit bit is set for current acces. */
|
/* These are set by mmu if cache inhibit bit is set for current acces. */
|
int data_ci, insn_ci;
|
int data_ci, insn_ci;
|
|
|
/* Virtual address of current access. */
|
/* Virtual address of current access. */
|
unsigned long cur_vadd;
|
oraddr_t cur_vadd;
|
|
|
/* Calculates bit mask to fit the data */
|
/* Calculates bit mask to fit the data */
|
unsigned long bit_mask (unsigned long data) {
|
unsigned int bit_mask (uint32_t data) {
|
int i = 0;
|
int i = 0;
|
data--;
|
data--;
|
while (data >> i)
|
while (data >> i)
|
data |= 1 << i++;
|
data |= 1 << i++;
|
return data;
|
return data;
|
}
|
}
|
|
|
/* Register read and write function for a memory area.
|
/* Register read and write function for a memory area.
|
addr is inside the area, if addr & addr_mask == addr_compare
|
addr is inside the area, if addr & addr_mask == addr_compare
|
(used also by peripheral devices like 16450 UART etc.) */
|
(used also by peripheral devices like 16450 UART etc.) */
|
void register_memoryarea_mask(unsigned long addr_mask, unsigned long addr_compare,
|
void register_memoryarea_mask(oraddr_t addr_mask, oraddr_t addr_compare,
|
unsigned long size, unsigned granularity, unsigned mc_dev,
|
uint32_t size, unsigned granularity, unsigned mc_dev,
|
unsigned long (readfunc)(unsigned long),
|
uint32_t (readfunc)(oraddr_t),
|
void (writefunc)(unsigned long, unsigned long))
|
void (writefunc)(oraddr_t, uint32_t))
|
{
|
{
|
struct dev_memarea **pptmp;
|
struct dev_memarea **pptmp;
|
unsigned long size_mask = bit_mask (size);
|
unsigned int size_mask = bit_mask (size);
|
int found_error = 0;
|
int found_error = 0;
|
addr_compare &= addr_mask;
|
addr_compare &= addr_mask;
|
|
|
debug(5, "addr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
|
debug(5, "addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %08"PRIx32", gran %iB\n",
|
|
addr_mask, addr_compare, addr_compare | bit_mask (size), size,
|
|
granularity);
|
/* Go to the end of the list. */
|
/* Go to the end of the list. */
|
for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
|
for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
|
if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
|
if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
|
|| (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
|
|| (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
|
if (!found_error) {
|
if (!found_error) {
|
fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
|
fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
|
fprintf (stderr, "\taddr & %08lx == %08lx to %08lx, size %08lx, gran %iB\n",
|
fprintf (stderr, "\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
|
|
", size %08"PRIx32", gran %iB\n",
|
addr_mask, addr_compare, addr_compare | bit_mask (size), size,
|
addr_mask, addr_compare, addr_compare | bit_mask (size), size,
|
granularity);
|
granularity);
|
}
|
}
|
found_error = 1;
|
found_error = 1;
|
fprintf (stderr, "and\taddr & %08lx == %08lx to %08lx, size %08lx, gran %liB\n",
|
fprintf (stderr, "and\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
|
|
", size %08"PRIx32", gran %iB\n",
|
(*pptmp)->addr_mask, (*pptmp)->addr_compare,
|
(*pptmp)->addr_mask, (*pptmp)->addr_compare,
|
(*pptmp)->addr_compare | (*pptmp)->size_mask,
|
(*pptmp)->addr_compare | (*pptmp)->size_mask,
|
(*pptmp)->size, (*pptmp)->granularity);
|
(*pptmp)->size, (*pptmp)->granularity);
|
}
|
}
|
|
|
Line 134... |
Line 144... |
fit the nearest 2^n aligment.
|
fit the nearest 2^n aligment.
|
(used also by peripheral devices like 16450 UART etc.)
|
(used also by peripheral devices like 16450 UART etc.)
|
If mc_dev is 1, this means that this device will be checked first for match
|
If mc_dev is 1, this means that this device will be checked first for match
|
and will be accessed in case in overlaping memory spaces.
|
and will be accessed in case in overlaping memory spaces.
|
Only one device can have this set to 1 (used for memory controller) */
|
Only one device can have this set to 1 (used for memory controller) */
|
void register_memoryarea(unsigned long addr,
|
void register_memoryarea(oraddr_t addr, uint32_t size, unsigned granularity,
|
unsigned long size, unsigned granularity, unsigned mc_dev,
|
unsigned mc_dev,
|
unsigned long (readfunc)(unsigned long),
|
uint32_t (readfunc)(oraddr_t),
|
void (writefunc)(unsigned long, unsigned long))
|
void (writefunc)(oraddr_t, uint32_t))
|
{
|
{
|
unsigned long size_mask = bit_mask (size);
|
unsigned int size_mask = bit_mask (size);
|
unsigned long addr_mask = ~size_mask;
|
unsigned int addr_mask = ~size_mask;
|
register_memoryarea_mask (addr_mask, addr & addr_mask,
|
register_memoryarea_mask (addr_mask, addr & addr_mask,
|
size_mask + 1, granularity, mc_dev,
|
size_mask + 1, granularity, mc_dev,
|
readfunc, writefunc);
|
readfunc, writefunc);
|
}
|
}
|
|
|
|
|
/* Check if access is to registered area of memory. */
|
/* Check if access is to registered area of memory. */
|
inline struct dev_memarea *verify_memoryarea(unsigned long addr)
|
inline struct dev_memarea *verify_memoryarea(oraddr_t addr)
|
{
|
{
|
struct dev_memarea *ptmp;
|
struct dev_memarea *ptmp;
|
|
|
/* Check memory controller space first */
|
/* Check memory controller space first */
|
if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
|
if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
|
Line 176... |
Line 186... |
}
|
}
|
return cur_area = NULL;
|
return cur_area = NULL;
|
}
|
}
|
|
|
/* Finds the memory area for the address and adjust the read and write delays for it. */
|
/* Finds the memory area for the address and adjust the read and write delays for it. */
|
void adjust_rw_delay(unsigned long memaddr, unsigned long delayr, unsigned long delayw)
|
void adjust_rw_delay(oraddr_t memaddr, unsigned int delayr, unsigned int delayw)
|
{
|
{
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
cur_area->delayr = delayr;
|
cur_area->delayr = delayr;
|
cur_area->delayw = delayw;
|
cur_area->delayw = delayw;
|
}
|
}
|
Line 188... |
Line 198... |
|
|
/* for cpu accesses
|
/* for cpu accesses
|
*
|
*
|
* STATISTICS: check cpu/common/parse.c
|
* STATISTICS: check cpu/common/parse.c
|
*/
|
*/
|
inline unsigned long evalsim_mem32(unsigned long memaddr)
|
inline uint32_t evalsim_mem32(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem32_atomic(memaddr, 1));
|
return(evalsim_mem32_atomic(memaddr, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline unsigned long evalsim_mem32_void(unsigned long memaddr)
|
inline uint32_t evalsim_mem32_void(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem32_atomic(memaddr, 0));
|
return(evalsim_mem32_atomic(memaddr, 0));
|
}
|
}
|
|
|
unsigned long evalsim_mem32_atomic(unsigned long memaddr, int cpu_access)
|
uint32_t evalsim_mem32_atomic(oraddr_t memaddr, int cpu_access)
|
{
|
{
|
unsigned long temp = 0;
|
uint32_t temp = 0;
|
|
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch(cur_area->granularity) {
|
switch(cur_area->granularity) {
|
case 4:
|
case 4:
|
temp = cur_area->readfunc(memaddr);
|
temp = cur_area->readfunc(memaddr);
|
Line 232... |
Line 242... |
}
|
}
|
return temp;
|
return temp;
|
}
|
}
|
|
|
/* for cpu accesses */
|
/* for cpu accesses */
|
inline unsigned short evalsim_mem16(unsigned long memaddr)
|
inline uint16_t evalsim_mem16(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem16_atomic(memaddr, 1));
|
return(evalsim_mem16_atomic(memaddr, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline unsigned short evalsim_mem16_void(unsigned long memaddr)
|
inline uint16_t evalsim_mem16_void(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem16_atomic(memaddr, 0));
|
return(evalsim_mem16_atomic(memaddr, 0));
|
}
|
}
|
|
|
unsigned short evalsim_mem16_atomic(unsigned long memaddr, int cpu_access)
|
uint16_t evalsim_mem16_atomic(oraddr_t memaddr, int cpu_access)
|
{
|
{
|
unsigned long temp = 0;
|
uint32_t temp = 0;
|
|
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch(cur_area->granularity) {
|
switch(cur_area->granularity) {
|
case 1:
|
case 1:
|
temp = cur_area->readfunc(memaddr) << 8;
|
temp = cur_area->readfunc(memaddr) << 8;
|
Line 261... |
Line 271... |
temp = cur_area->readfunc(memaddr);
|
temp = cur_area->readfunc(memaddr);
|
if (cpu_access)
|
if (cpu_access)
|
runtime.sim.mem_cycles += cur_area->delayr;
|
runtime.sim.mem_cycles += cur_area->delayr;
|
break;
|
break;
|
case 4:
|
case 4:
|
temp = evalsim_mem32_atomic (memaddr & ~3ul, cpu_access);
|
temp = evalsim_mem32_atomic (memaddr & ~UINT32_C(3), cpu_access);
|
if (memaddr & 2)
|
if (memaddr & 2)
|
temp &= 0xffff;
|
temp &= 0xffff;
|
else
|
else
|
temp >>= 16;
|
temp >>= 16;
|
break;
|
break;
|
Line 279... |
Line 289... |
}
|
}
|
return temp;
|
return temp;
|
}
|
}
|
|
|
/* for cpu accesses */
|
/* for cpu accesses */
|
inline unsigned char evalsim_mem8(unsigned long memaddr)
|
inline uint8_t evalsim_mem8(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem8_atomic(memaddr, 1));
|
return(evalsim_mem8_atomic(memaddr, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline unsigned char evalsim_mem8_void(unsigned long memaddr)
|
inline uint8_t evalsim_mem8_void(oraddr_t memaddr)
|
{
|
{
|
return(evalsim_mem8_atomic(memaddr, 0));
|
return(evalsim_mem8_atomic(memaddr, 0));
|
}
|
}
|
|
|
unsigned char evalsim_mem8_atomic(unsigned long memaddr, int cpu_access)
|
uint8_t evalsim_mem8_atomic(oraddr_t memaddr, int cpu_access)
|
{
|
{
|
unsigned long temp = 0;
|
uint32_t temp = 0;
|
|
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch(cur_area->granularity) {
|
switch(cur_area->granularity) {
|
case 1:
|
case 1:
|
temp = cur_area->readfunc(memaddr);
|
temp = cur_area->readfunc(memaddr);
|
if (cpu_access)
|
if (cpu_access)
|
runtime.sim.mem_cycles += cur_area->delayr;
|
runtime.sim.mem_cycles += cur_area->delayr;
|
break;
|
break;
|
case 2:
|
case 2:
|
temp = evalsim_mem16_atomic (memaddr & ~1ul, cpu_access);
|
temp = evalsim_mem16_atomic (memaddr & ~ADDR_C(1), cpu_access);
|
if (memaddr & 1)
|
if (memaddr & 1)
|
temp &= 0xff;
|
temp &= 0xff;
|
else
|
else
|
temp >>= 8;
|
temp >>= 8;
|
break;
|
break;
|
case 4:
|
case 4:
|
temp = evalsim_mem32_atomic (memaddr & ~3ul, cpu_access);
|
temp = evalsim_mem32_atomic (memaddr & ~ADDR_C(3), cpu_access);
|
temp >>= 8 * (3 - (memaddr & 3));
|
temp >>= 8 * (3 - (memaddr & 3));
|
temp &= 0xff;
|
temp &= 0xff;
|
break;
|
break;
|
default:
|
default:
|
/* if you add new memory granularity be sure to check the formula
|
/* if you add new memory granularity be sure to check the formula
|
Line 326... |
Line 336... |
return temp;
|
return temp;
|
}
|
}
|
|
|
/* Returns 32-bit values from mem array. Big endian version.
|
/* Returns 32-bit values from mem array. Big endian version.
|
*
|
*
|
* this function is only used in dump_memory() below, so it's
|
* this function is only used in dumpmemory() below, so it's
|
* safe to asume it's for simulator purposes access only,
|
* safe to asume it's for simulator purposes access only,
|
* hence the use of eval_mem32_void()
|
* hence the use of eval_mem32_void()
|
*
|
*
|
* STATISTICS OK.
|
* STATISTICS OK.
|
*/
|
*/
|
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
|
static uint32_t read_mem(oraddr_t memaddr, int* breakpoint)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
|
|
cur_vadd = memaddr;
|
cur_vadd = memaddr;
|
if (config.debug.enabled)
|
if (config.debug.enabled)
|
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
|
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
|
temp = evalsim_mem32_void(memaddr);
|
temp = evalsim_mem32_void(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
|
|
if (!pending.valid && cur_area->log)
|
if (!pending.valid && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> read %08lx\n", memaddr, temp);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> read %08"PRIx32"\n", memaddr, temp);
|
if (config.debug.enabled)
|
if (config.debug.enabled)
|
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
|
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
|
return temp;
|
return temp;
|
}
|
}
|
|
|
/* Returns 32-bit values from mem array. Big endian version.
|
/* Returns 32-bit values from mem array. Big endian version.
|
*
|
*
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
*/
|
*/
|
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
|
uint32_t eval_mem32(oraddr_t memaddr,int* breakpoint)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
|
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_32 | MPROF_READ);
|
mprofile (memaddr, MPROF_32 | MPROF_READ);
|
|
|
if (memaddr & 3) {
|
if (memaddr & 3) {
|
Line 383... |
Line 394... |
if (config.dc.enabled)
|
if (config.dc.enabled)
|
temp = dc_simulate_read(memaddr, 4);
|
temp = dc_simulate_read(memaddr, 4);
|
else {
|
else {
|
temp = evalsim_mem32(memaddr);
|
temp = evalsim_mem32(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 398... |
Line 410... |
|
|
/* for simulator accesses, the ones that cpu wouldn't do
|
/* for simulator accesses, the ones that cpu wouldn't do
|
*
|
*
|
* STATISTICS OK
|
* STATISTICS OK
|
*/
|
*/
|
unsigned long eval_direct32(unsigned long memaddr, int *breakpoint,
|
uint32_t eval_direct32(oraddr_t memaddr, int *breakpoint, int through_mmu,
|
int through_mmu, int through_dc)
|
int through_dc)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
|
|
if (memaddr & 3) {
|
if (memaddr & 3) {
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
return 0;
|
return 0;
|
}
|
}
|
Line 418... |
Line 430... |
if (through_dc)
|
if (through_dc)
|
temp = dc_simulate_read(memaddr, 4);
|
temp = dc_simulate_read(memaddr, 4);
|
else {
|
else {
|
temp = evalsim_mem32_void(memaddr);
|
temp = evalsim_mem32_void(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx) in eval_direct32()\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR
|
|
") in eval_direct32()\n", memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 432... |
Line 445... |
|
|
/* Returns 32-bit values from mem array. Big endian version.
|
/* Returns 32-bit values from mem array. Big endian version.
|
*
|
*
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
*/
|
*/
|
unsigned long eval_insn(unsigned long memaddr,int* breakpoint)
|
uint32_t eval_insn(oraddr_t memaddr,int* breakpoint)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
|
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_32 | MPROF_FETCH);
|
mprofile (memaddr, MPROF_32 | MPROF_FETCH);
|
// memaddr = simulate_ic_mmu_fetch(memaddr);
|
// memaddr = simulate_ic_mmu_fetch(memaddr);
|
cur_vadd = pc;
|
cur_vadd = pc;
|
Line 453... |
Line 466... |
if (config.ic.enabled)
|
if (config.ic.enabled)
|
temp = ic_simulate_fetch(memaddr);
|
temp = ic_simulate_fetch(memaddr);
|
else {
|
else {
|
temp = evalsim_mem32(memaddr);
|
temp = evalsim_mem32(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 469... |
Line 483... |
|
|
/* Returns 16-bit values from mem array. Big endian version.
|
/* Returns 16-bit values from mem array. Big endian version.
|
*
|
*
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
*/
|
*/
|
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
|
uint16_t eval_mem16(oraddr_t memaddr,int* breakpoint)
|
{
|
{
|
unsigned short temp;
|
uint16_t temp;
|
|
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_16 | MPROF_READ);
|
mprofile (memaddr, MPROF_16 | MPROF_READ);
|
|
|
if (memaddr & 1) {
|
if (memaddr & 1) {
|
Line 495... |
Line 509... |
if (config.dc.enabled)
|
if (config.dc.enabled)
|
temp = (unsigned short)dc_simulate_read(memaddr, 2);
|
temp = (unsigned short)dc_simulate_read(memaddr, 2);
|
else {
|
else {
|
temp = evalsim_mem16(memaddr);
|
temp = evalsim_mem16(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 510... |
Line 525... |
|
|
/* for simulator accesses, the ones that cpu wouldn't do
|
/* for simulator accesses, the ones that cpu wouldn't do
|
*
|
*
|
* STATISTICS OK.
|
* STATISTICS OK.
|
*/
|
*/
|
unsigned short eval_direct16(unsigned long memaddr, int *breakpoint,
|
uint16_t eval_direct16(oraddr_t memaddr, int *breakpoint, int through_mmu,
|
int through_mmu, int through_dc)
|
int through_dc)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
|
|
if (memaddr & 1) {
|
if (memaddr & 1) {
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
return 0;
|
return 0;
|
}
|
}
|
Line 530... |
Line 545... |
if (through_dc)
|
if (through_dc)
|
temp = dc_simulate_read(memaddr, 2);
|
temp = dc_simulate_read(memaddr, 2);
|
else {
|
else {
|
temp = evalsim_mem16_void(memaddr);
|
temp = evalsim_mem16_void(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx) in eval_direct16()\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR
|
|
") in eval_direct16()\n", memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 544... |
Line 560... |
|
|
/* Returns 8-bit values from mem array.
|
/* Returns 8-bit values from mem array.
|
*
|
*
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
* STATISTICS OK (only used for cpu_access, that is architectural access)
|
*/
|
*/
|
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
|
uint8_t eval_mem8(oraddr_t memaddr,int* breakpoint)
|
{
|
{
|
unsigned char temp;
|
uint8_t temp;
|
|
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_8 | MPROF_READ);
|
mprofile (memaddr, MPROF_8 | MPROF_READ);
|
|
|
if (config.debug.enabled)
|
if (config.debug.enabled)
|
Line 565... |
Line 581... |
if (config.dc.enabled)
|
if (config.dc.enabled)
|
temp = (unsigned char)dc_simulate_read(memaddr, 1);
|
temp = (unsigned char)dc_simulate_read(memaddr, 1);
|
else {
|
else {
|
temp = evalsim_mem8(memaddr);
|
temp = evalsim_mem8(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
|
|
Line 580... |
Line 597... |
|
|
/* for simulator accesses, the ones that cpu wouldn't do
|
/* for simulator accesses, the ones that cpu wouldn't do
|
*
|
*
|
* STATISTICS OK.
|
* STATISTICS OK.
|
*/
|
*/
|
unsigned char eval_direct8(unsigned long memaddr, int *breakpoint,
|
uint8_t eval_direct8(oraddr_t memaddr, int *breakpoint, int through_mmu,
|
int through_mmu, int through_dc)
|
int through_dc)
|
{
|
{
|
unsigned char temp;
|
uint8_t temp;
|
|
|
cur_vadd = memaddr;
|
cur_vadd = memaddr;
|
|
|
if (through_mmu)
|
if (through_mmu)
|
memaddr = peek_into_dtlb(memaddr, 0, through_dc);
|
memaddr = peek_into_dtlb(memaddr, 0, through_dc);
|
Line 595... |
Line 612... |
if (through_dc)
|
if (through_dc)
|
temp = (unsigned char)dc_simulate_read(memaddr, 1);
|
temp = (unsigned char)dc_simulate_read(memaddr, 1);
|
else {
|
else {
|
temp = evalsim_mem8_void(memaddr);
|
temp = evalsim_mem8_void(memaddr);
|
if (!cur_area) {
|
if (!cur_area) {
|
PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx) in eval_direct8()\n", memaddr);
|
PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR
|
|
") in eval_direct8()\n", memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
temp = 0;
|
temp = 0;
|
}
|
}
|
}
|
}
|
return temp;
|
return temp;
|
}
|
}
|
|
|
/* for cpu accesses */
|
/* for cpu accesses */
|
inline void setsim_mem32(unsigned long memaddr, unsigned long value)
|
inline void setsim_mem32(oraddr_t memaddr, uint32_t value)
|
{
|
{
|
return(setsim_mem32_atomic(memaddr, value, 1));
|
return(setsim_mem32_atomic(memaddr, value, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline void setsim_mem32_void(unsigned long memaddr, unsigned long value)
|
inline void setsim_mem32_void(oraddr_t memaddr, uint32_t value)
|
{
|
{
|
return(setsim_mem32_atomic(memaddr, value, 0));
|
return(setsim_mem32_atomic(memaddr, value, 0));
|
}
|
}
|
|
|
void setsim_mem32_atomic(unsigned long memaddr, unsigned long value, int cpu_access)
|
void setsim_mem32_atomic(oraddr_t memaddr, uint32_t value, int cpu_access)
|
{
|
{
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch(cur_area->granularity) {
|
switch(cur_area->granularity) {
|
case 4:
|
case 4:
|
cur_area->writefunc(memaddr, value);
|
cur_area->writefunc(memaddr, value);
|
Line 646... |
Line 664... |
*/
|
*/
|
PRINTF("unknown/unhandled memory granularuty\n");
|
PRINTF("unknown/unhandled memory granularuty\n");
|
exit(-1);
|
exit(-1);
|
}
|
}
|
} else {
|
} else {
|
PRINTF("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
}
|
}
|
}
|
}
|
|
|
/* for cpu accesses */
|
/* for cpu accesses */
|
inline void setsim_mem16(unsigned long memaddr, unsigned short value)
|
inline void setsim_mem16(oraddr_t memaddr, uint16_t value)
|
{
|
{
|
return(setsim_mem16_atomic(memaddr, value, 1));
|
return(setsim_mem16_atomic(memaddr, value, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline void setsim_mem16_void(unsigned long memaddr, unsigned short value)
|
inline void setsim_mem16_void(oraddr_t memaddr, uint16_t value)
|
{
|
{
|
return(setsim_mem16_atomic(memaddr, value, 0));
|
return(setsim_mem16_atomic(memaddr, value, 0));
|
}
|
}
|
|
|
void setsim_mem16_atomic(unsigned long memaddr, unsigned short value, int cpu_access)
|
void setsim_mem16_atomic(oraddr_t memaddr, uint16_t value, int cpu_access)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch(cur_area->granularity) {
|
switch(cur_area->granularity) {
|
case 1:
|
case 1:
|
cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
|
cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
|
cur_area->writefunc(memaddr + 1, value & 0xFF);
|
cur_area->writefunc(memaddr + 1, value & 0xFF);
|
Line 680... |
Line 699... |
cur_area->writefunc(memaddr, value & 0xFFFF);
|
cur_area->writefunc(memaddr, value & 0xFFFF);
|
if (cpu_access)
|
if (cpu_access)
|
runtime.sim.mem_cycles += cur_area->delayw;
|
runtime.sim.mem_cycles += cur_area->delayw;
|
break;
|
break;
|
case 4:
|
case 4:
|
temp = evalsim_mem32_void(memaddr & ~3ul);
|
temp = evalsim_mem32_void(memaddr & ~ADDR_C(3));
|
temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
|
temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
|
temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
|
temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
|
setsim_mem32_atomic(memaddr & ~3ul, temp, cpu_access);
|
setsim_mem32_atomic(memaddr & ~ADDR_C(3), temp, cpu_access);
|
break;
|
break;
|
default:
|
default:
|
/* if you add new memory granularity be sure to check the formula
|
/* if you add new memory granularity be sure to check the formula
|
* below for the read delay and fix it if necessery
|
* below for the read delay and fix it if necessery
|
*/
|
*/
|
PRINTF("unknown/unhandled memory granularuty\n");
|
PRINTF("unknown/unhandled memory granularuty\n");
|
exit(-1);
|
exit(-1);
|
}
|
}
|
} else {
|
} else {
|
PRINTF("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
}
|
}
|
}
|
}
|
|
|
/* for cpu accesses */
|
/* for cpu accesses */
|
inline void setsim_mem8(unsigned long memaddr, unsigned char value)
|
inline void setsim_mem8(oraddr_t memaddr, uint8_t value)
|
{
|
{
|
return(setsim_mem8_atomic(memaddr, value, 1));
|
return(setsim_mem8_atomic(memaddr, value, 1));
|
}
|
}
|
|
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
/* for simulator accesses, the ones that cpu wouldn't do */
|
inline void setsim_mem8_void(unsigned long memaddr, unsigned char value)
|
inline void setsim_mem8_void(oraddr_t memaddr, uint8_t value)
|
{
|
{
|
return(setsim_mem8_atomic(memaddr, value, 0));
|
return(setsim_mem8_atomic(memaddr, value, 0));
|
}
|
}
|
|
|
void setsim_mem8_atomic(unsigned long memaddr, unsigned char value, int cpu_access)
|
void setsim_mem8_atomic(oraddr_t memaddr, uint8_t value, int cpu_access)
|
{
|
{
|
unsigned long temp;
|
uint32_t temp;
|
if (verify_memoryarea(memaddr)) {
|
if (verify_memoryarea(memaddr)) {
|
switch (cur_area->granularity) {
|
switch (cur_area->granularity) {
|
case 1:
|
case 1:
|
cur_area->writefunc(memaddr, value);
|
cur_area->writefunc(memaddr, value);
|
if (cpu_access)
|
if (cpu_access)
|
runtime.sim.mem_cycles += cur_area->delayw;
|
runtime.sim.mem_cycles += cur_area->delayw;
|
break;
|
break;
|
case 2:
|
case 2:
|
temp = evalsim_mem16_void (memaddr & ~1ul);
|
temp = evalsim_mem16_void (memaddr & ~ADDR_C(1));
|
temp &= 0xff << ((memaddr & 1) ? 8 : 0);
|
temp &= 0xff << ((memaddr & 1) ? 8 : 0);
|
temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
|
temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
|
setsim_mem16_atomic (memaddr & ~1ul, temp, cpu_access);
|
setsim_mem16_atomic (memaddr & ~ADDR_C(1), temp, cpu_access);
|
break;
|
break;
|
case 4:
|
case 4:
|
temp = evalsim_mem32_void (memaddr & ~3ul);
|
temp = evalsim_mem32_void (memaddr & ~ADDR_C(3));
|
temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
|
temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
|
temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
|
temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
|
setsim_mem32_atomic (memaddr & ~3ul, temp, cpu_access);
|
setsim_mem32_atomic (memaddr & ~ADDR_C(3), temp, cpu_access);
|
break;
|
break;
|
}
|
}
|
} else {
|
} else {
|
PRINTF("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
|
PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
|
|
memaddr);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
except_handle(EXCEPT_BUSERR, cur_vadd);
|
}
|
}
|
}
|
}
|
|
|
/* Set mem, 32-bit. Big endian version.
|
/* Set mem, 32-bit. Big endian version.
|
Line 746... |
Line 767... |
* STATISTICS OK. (the only suspicious usage is in toplevel.c,
|
* STATISTICS OK. (the only suspicious usage is in toplevel.c,
|
* where this instruction is used for patching memory,
|
* where this instruction is used for patching memory,
|
* wether this is cpu or architectual access is yet to
|
* wether this is cpu or architectual access is yet to
|
* be decided)
|
* be decided)
|
*/
|
*/
|
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
|
void set_mem32(oraddr_t memaddr, uint32_t value, int* breakpoint)
|
{
|
{
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_32 | MPROF_WRITE);
|
mprofile (memaddr, MPROF_32 | MPROF_WRITE);
|
|
|
if (memaddr & 3) {
|
if (memaddr & 3) {
|
Line 770... |
Line 791... |
}
|
}
|
|
|
dc_simulate_write(memaddr, value, 4);
|
dc_simulate_write(memaddr, value, 4);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> write %08lx\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %08"PRIx32"\n", memaddr,
|
|
value);
|
}
|
}
|
|
|
/*
|
/*
|
* STATISTICS NOT OK.
|
* STATISTICS NOT OK.
|
*/
|
*/
|
void set_direct32(unsigned long memaddr, unsigned long value,int* breakpoint,
|
void set_direct32(oraddr_t memaddr, uint32_t value,int* breakpoint,
|
int through_mmu, int through_dc)
|
int through_mmu, int through_dc)
|
{
|
{
|
|
|
if (memaddr & 3) {
|
if (memaddr & 3) {
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
Line 802... |
Line 824... |
if (!through_dc)
|
if (!through_dc)
|
PRINTF("WARNING: statistics might not be OK\n");
|
PRINTF("WARNING: statistics might not be OK\n");
|
dc_simulate_write(memaddr, value, 4);
|
dc_simulate_write(memaddr, value, 4);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> DIRECT write %08lx\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %08"PRIx32"\n",
|
|
memaddr, value);
|
}
|
}
|
|
|
|
|
/* Set mem, 16-bit. Big endian version. */
|
/* Set mem, 16-bit. Big endian version. */
|
|
|
void set_mem16(unsigned long memaddr, unsigned short value, int* breakpoint)
|
void set_mem16(oraddr_t memaddr, uint16_t value, int* breakpoint)
|
{
|
{
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_16 | MPROF_WRITE);
|
mprofile (memaddr, MPROF_16 | MPROF_WRITE);
|
|
|
if (memaddr & 1) {
|
if (memaddr & 1) {
|
Line 832... |
Line 855... |
}
|
}
|
|
|
dc_simulate_write(memaddr, (unsigned long)value, 2);
|
dc_simulate_write(memaddr, (unsigned long)value, 2);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> write %08x\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %04"PRIx16"\n", memaddr,
|
|
value);
|
}
|
}
|
|
|
/*
|
/*
|
* STATISTICS NOT OK.
|
* STATISTICS NOT OK.
|
*/
|
*/
|
void set_direct16(unsigned long memaddr, unsigned short value, int* breakpoint,
|
void set_direct16(oraddr_t memaddr, uint16_t value, int* breakpoint,
|
int through_mmu, int through_dc)
|
int through_mmu, int through_dc)
|
{
|
{
|
|
|
if (memaddr & 1) {
|
if (memaddr & 1) {
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
|
Line 863... |
Line 887... |
if (!through_dc)
|
if (!through_dc)
|
PRINTF("WARNING: statistics might not be OK\n");
|
PRINTF("WARNING: statistics might not be OK\n");
|
dc_simulate_write(memaddr, value, 2);
|
dc_simulate_write(memaddr, value, 2);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> DIRECT write %08x\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %04"PRIx16"\n",
|
|
memaddr, value);
|
}
|
}
|
|
|
/* Set mem, 8-bit. */
|
/* Set mem, 8-bit. */
|
|
|
void set_mem8(unsigned long memaddr, unsigned char value, int* breakpoint)
|
void set_mem8(oraddr_t memaddr, uint8_t value, int* breakpoint)
|
{
|
{
|
if (config.sim.mprofile)
|
if (config.sim.mprofile)
|
mprofile (memaddr, MPROF_8 | MPROF_WRITE);
|
mprofile (memaddr, MPROF_8 | MPROF_WRITE);
|
|
|
cur_vadd = memaddr;
|
cur_vadd = memaddr;
|
Line 886... |
Line 911... |
}
|
}
|
|
|
dc_simulate_write(memaddr, (unsigned long)value, 1);
|
dc_simulate_write(memaddr, (unsigned long)value, 1);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08lx] -> write %08x\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %02"PRIx8"\n", memaddr,
|
|
value);
|
}
|
}
|
|
|
/*
|
/*
|
* STATISTICS NOT OK.
|
* STATISTICS NOT OK.
|
*/
|
*/
|
void set_direct8(unsigned long memaddr, unsigned char value, int* breakpoint,
|
void set_direct8(oraddr_t memaddr, uint8_t value, int* breakpoint,
|
int through_mmu, int through_dc)
|
int through_mmu, int through_dc)
|
{
|
{
|
|
|
cur_vadd = memaddr;
|
cur_vadd = memaddr;
|
|
|
Line 912... |
Line 938... |
if (!through_dc)
|
if (!through_dc)
|
PRINTF("WARNING: statistics might not be OK\n");
|
PRINTF("WARNING: statistics might not be OK\n");
|
dc_simulate_write(memaddr, value, 1);
|
dc_simulate_write(memaddr, value, 1);
|
|
|
if (cur_area && cur_area->log)
|
if (cur_area && cur_area->log)
|
fprintf (cur_area->log, "[%08x] -> DIRECT write %08x\n", memaddr, value);
|
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
|
|
memaddr, value);
|
}
|
}
|
|
|
|
|
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
|
void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
|
{
|
{
|
unsigned int i, j;
|
oraddr_t i, j;
|
struct label_entry *tmp;
|
struct label_entry *tmp;
|
int ilen = disasm ? 4 : 16;
|
int ilen = disasm ? 4 : 16;
|
|
|
for(i = from; i < to; i += ilen) {
|
for(i = from; i < to; i += ilen) {
|
PRINTF("%.8x: ", i);
|
PRINTF("%"PRIxADDR": ", i);
|
for (j = 0; j < ilen;) {
|
for (j = 0; j < ilen;) {
|
int data = -1;
|
|
if (!disasm) {
|
if (!disasm) {
|
tmp = NULL;
|
tmp = NULL;
|
if (verify_memoryarea(i+j)) {
|
if (verify_memoryarea(i+j)) {
|
struct label_entry *entry;
|
struct label_entry *entry;
|
entry = get_label(i + j);
|
entry = get_label(i + j);
|
if (entry)
|
if (entry)
|
PRINTF("(%s)", entry->name);
|
PRINTF("(%s)", entry->name);
|
PRINTF("%02x ", data = evalsim_mem8(i+j));
|
PRINTF("%02"PRIx8" ", evalsim_mem8(i + j));
|
} else PRINTF("XX ");
|
} else PRINTF("XX ");
|
j++;
|
j++;
|
} else {
|
} else {
|
int breakpoint;
|
int breakpoint;
|
unsigned int _insn = read_mem(i, &breakpoint);
|
uint32_t _insn = read_mem(i, &breakpoint);
|
int index = insn_decode (_insn);
|
int index = insn_decode (_insn);
|
int len = insn_len (index);
|
int len = insn_len (index);
|
|
|
tmp = NULL;
|
tmp = NULL;
|
if (verify_memoryarea(i+j)) {
|
if (verify_memoryarea(i+j)) {
|
struct label_entry *entry;
|
struct label_entry *entry;
|
entry = get_label(i + j);
|
entry = get_label(i + j);
|
if (entry)
|
if (entry)
|
PRINTF("(%s)", entry->name);
|
PRINTF("(%s)", entry->name);
|
|
|
PRINTF(": %08lx ", (unsigned long)_insn);
|
PRINTF(": %08"PRIx32" ", _insn);
|
if (index >= 0) {
|
if (index >= 0) {
|
disassemble_insn (_insn);
|
disassemble_insn (_insn);
|
PRINTF(" %s", disassembled);
|
PRINTF(" %s", disassembled);
|
} else
|
} else
|
PRINTF("<invalid>");
|
PRINTF("<invalid>");
|
Line 964... |
Line 990... |
if (nl)
|
if (nl)
|
PRINTF ("\n");
|
PRINTF ("\n");
|
}
|
}
|
}
|
}
|
|
|
unsigned long simmem_read_word(unsigned long addr) {
|
uint32_t simmem_read_word(oraddr_t addr) {
|
return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
|
return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
|
}
|
}
|
|
|
void simmem_write_word(unsigned long addr, unsigned long value) {
|
void simmem_write_word(oraddr_t addr, uint32_t value) {
|
simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
|
simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
|
}
|
}
|
|
|
unsigned long simmem_read_zero(unsigned long addr) {
|
uint32_t simmem_read_zero(oraddr_t addr) {
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
|
fprintf (stderr, "WARNING: memory read from non-read memory area 0x%"
|
|
PRIxADDR".\n", addr);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
void simmem_write_null(unsigned long addr, unsigned long value) {
|
void simmem_write_null(oraddr_t addr, uint32_t value) {
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
fprintf (stderr, "WARNING: memory write to 0x%08lx, non-write memory area (value 0x%08lx).\n", addr, value);
|
fprintf (stderr, "WARNING: memory write to 0x%"PRIxADDR", non-write memory area (value 0x%08"PRIx32").\n", addr, value);
|
}
|
}
|
|
|
/* Initialize memory table from a config struct */
|
/* Initialize memory table from a config struct */
|
|
|
void init_memory_table ()
|
void init_memory_table ()
|
{
|
{
|
unsigned long memory_needed = 0;
|
uint32_t memory_needed = 0;
|
|
|
/* If nothing was defined, use default memory block */
|
/* If nothing was defined, use default memory block */
|
if (config.memory.nmemories) {
|
if (config.memory.nmemories) {
|
int i;
|
int i;
|
for (i = 0; i < config.memory.nmemories; i++) {
|
for (i = 0; i < config.memory.nmemories; i++) {
|
unsigned long start = config.memory.table[i].baseaddr;
|
oraddr_t start = config.memory.table[i].baseaddr;
|
unsigned long length = config.memory.table[i].size;
|
uint32_t length = config.memory.table[i].size;
|
char *type = config.memory.table[i].name;
|
char *type = config.memory.table[i].name;
|
int rd = config.memory.table[i].delayr;
|
int rd = config.memory.table[i].delayr;
|
int wd = config.memory.table[i].delayw;
|
int wd = config.memory.table[i].delayw;
|
int ce = config.memory.table[i].ce;
|
int ce = config.memory.table[i].ce;
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
|
debug (1, "%"PRIxADDR" %08"PRIx32" (%"PRIi32" KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
|
start, length, length >> 10, type, ce, rd, wd);
|
start, length, length >> 10, type, ce, rd, wd);
|
register_memoryarea(start, length, 4, 0, &simmem_read_word, &simmem_write_word);
|
register_memoryarea(start, length, 4, 0, &simmem_read_word,
|
|
&simmem_write_word);
|
cur_area->misc = memory_needed;
|
cur_area->misc = memory_needed;
|
cur_area->chip_select = ce;
|
cur_area->chip_select = ce;
|
cur_area->valid = 1;
|
cur_area->valid = 1;
|
cur_area->delayw = wd;
|
cur_area->delayw = wd;
|
cur_area->delayr = rd;
|
cur_area->delayr = rd;
|
if (config.memory.table[i].log[0] != '\0') {
|
if (config.memory.table[i].log[0] != '\0') {
|
if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
|
if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
|
fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
|
fprintf (stderr, "WARNING: Cannot open '%s'.\n",
|
|
config.memory.table[i].log);
|
} else
|
} else
|
cur_area->log = NULL;
|
cur_area->log = NULL;
|
memory_needed += cur_area->size;
|
memory_needed += cur_area->size;
|
}
|
}
|
PRINTF ("\n");
|
PRINTF ("\n");
|
} else {
|
} else {
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
|
fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
|
register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0, &simmem_read_word, &simmem_write_word);
|
register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0,
|
|
&simmem_read_word, &simmem_write_word);
|
cur_area->misc = memory_needed;
|
cur_area->misc = memory_needed;
|
cur_area->chip_select = 0;
|
cur_area->chip_select = 0;
|
cur_area->valid = 1;
|
cur_area->valid = 1;
|
cur_area->delayw = 1;
|
cur_area->delayw = 1;
|
cur_area->delayr = 1;
|
cur_area->delayr = 1;
|
cur_area->log = NULL;
|
cur_area->log = NULL;
|
memory_needed += cur_area->size;
|
memory_needed += cur_area->size;
|
}
|
}
|
|
|
simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
|
simmem32 = (uint32_t *) malloc (sizeof (uint32_t) * ((memory_needed + 3) / 4));
|
if (!simmem32) {
|
if (!simmem32) {
|
fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
|
fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
|
exit (-1);
|
exit (-1);
|
}
|
}
|
}
|
}
|
Line 1079... |
Line 1109... |
{
|
{
|
struct dev_memarea *ptmp;
|
struct dev_memarea *ptmp;
|
|
|
/* Check list of registered devices. */
|
/* Check list of registered devices. */
|
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
|
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
|
PRINTF ("addr & %08lx == %08lx to %08lx, size %08lx, gran %liB\n",
|
PRINTF ("addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %"PRIx32
|
|
", gran %iB\n",
|
ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
|
ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
|
ptmp->size, ptmp->granularity);
|
ptmp->size, ptmp->granularity);
|
PRINTF ("\t");
|
PRINTF ("\t");
|
if (ptmp->delayr >= 0)
|
if (ptmp->delayr >= 0)
|
PRINTF ("read delay = %i cycles, ", ptmp->delayr);
|
PRINTF ("read delay = %i cycles, ", ptmp->delayr);
|