Line 53... |
Line 53... |
struct dev_memarea *dev_list;
|
struct dev_memarea *dev_list;
|
|
|
/* Temporary variable to increase speed. */
|
/* Temporary variable to increase speed. */
|
struct dev_memarea *cur_area;
|
struct dev_memarea *cur_area;
|
|
|
|
/* Pointer to memory controller device descriptor. */
|
|
struct dev_memarea *mc_area = (struct dev_memarea *)0;
|
|
|
/* 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;
|
unsigned long cur_vadd;
|
Line 72... |
Line 75... |
|
|
/* 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(unsigned long addr_mask, unsigned long addr_compare,
|
unsigned long size, unsigned granularity,
|
unsigned long size, unsigned granularity, unsigned mc_dev,
|
unsigned long (readfunc)(unsigned long),
|
unsigned long (readfunc)(unsigned long),
|
void (writefunc)(unsigned long, unsigned long))
|
void (writefunc)(unsigned long, unsigned long))
|
{
|
{
|
struct dev_memarea **pptmp;
|
struct dev_memarea **pptmp;
|
unsigned long size_mask = bit_mask (size);
|
unsigned long size_mask = bit_mask (size);
|
Line 99... |
Line 102... |
|
|
if (found_error)
|
if (found_error)
|
exit (-1);
|
exit (-1);
|
|
|
cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
|
cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
|
|
|
|
if (mc_dev)
|
|
mc_area = *pptmp;
|
|
|
(*pptmp)->addr_mask = addr_mask;
|
(*pptmp)->addr_mask = addr_mask;
|
(*pptmp)->addr_compare = addr_compare;
|
(*pptmp)->addr_compare = addr_compare;
|
(*pptmp)->size = size;
|
(*pptmp)->size = size;
|
(*pptmp)->size_mask = size_mask;
|
(*pptmp)->size_mask = size_mask;
|
(*pptmp)->granularity = granularity;
|
(*pptmp)->granularity = granularity;
|
Line 115... |
Line 122... |
}
|
}
|
|
|
/* Register read and write function for a memory area.
|
/* Register read and write function for a memory area.
|
Memory areas should be aligned. Memory area is rounded up to
|
Memory areas should be aligned. Memory area is rounded up to
|
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
|
|
and will be accessed in case in overlaping memory spaces.
|
|
Only one device can have this set to 1 (used for memory controller) */
|
void register_memoryarea(unsigned long addr,
|
void register_memoryarea(unsigned long addr,
|
unsigned long size, unsigned granularity,
|
unsigned long size, unsigned granularity, unsigned mc_dev,
|
unsigned long (readfunc)(unsigned long),
|
unsigned long (readfunc)(unsigned long),
|
void (writefunc)(unsigned long, unsigned long))
|
void (writefunc)(unsigned long, unsigned long))
|
{
|
{
|
unsigned long size_mask = bit_mask (size);
|
unsigned long size_mask = bit_mask (size);
|
unsigned long addr_mask = ~size_mask;
|
unsigned long addr_mask = ~size_mask;
|
register_memoryarea_mask (addr_mask, addr & addr_mask,
|
register_memoryarea_mask (addr_mask, addr & addr_mask,
|
size_mask + 1, granularity,
|
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(unsigned long addr)
|
{
|
{
|
struct dev_memarea *ptmp;
|
struct dev_memarea *ptmp;
|
|
|
/* Check cached value first */
|
/* Check memory controller space first */
|
|
if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
|
|
return cur_area = mc_area;
|
|
|
|
/* Check cached value */
|
if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
|
if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
|
return cur_area;
|
return cur_area;
|
|
|
/* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
|
/* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
|
IFF (config.mc.enabled) {
|
IFF (config.mc.enabled) {
|
Line 654... |
Line 668... |
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, "%08X %08X (%i 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, &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;
|
Line 671... |
Line 685... |
}
|
}
|
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, &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;
|