URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1239 to Rev 1240
- ↔ Reverse comparison
Rev 1239 → Rev 1240
/trunk/or1ksim/cpu/common/abstract.c
322,6 → 322,36
return temp; |
} |
|
unsigned long eval_direct32(unsigned long memaddr, int *breakpoint, |
int through_mmu, int through_dc) |
{ |
unsigned long temp; |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return 0; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) |
memaddr = peek_into_dtlb(memaddr, 0, through_dc); |
|
if (through_dc) |
temp = dc_simulate_read(memaddr, 4); |
else { |
temp = evalsim_mem32(memaddr); |
if (!cur_area) { |
PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx) in eval_direct32()\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
} |
|
return temp; |
} |
|
|
/* Returns 32-bit values from mem array. Big endian version. */ |
unsigned long eval_insn(unsigned long memaddr,int* breakpoint) |
{ |
389,6 → 419,36
return temp; |
} |
|
unsigned short eval_direct16(unsigned long memaddr, int *breakpoint, |
int through_mmu, int through_dc) |
{ |
unsigned long temp; |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return 0; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) |
memaddr = peek_into_dtlb(memaddr, 0, through_dc); |
|
if (through_dc) |
temp = dc_simulate_read(memaddr, 2); |
else { |
temp = evalsim_mem16(memaddr); |
if (!cur_area) { |
PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx) in eval_direct16()\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
} |
|
return temp; |
} |
|
|
/* Returns 8-bit values from mem array. */ |
|
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint) |
423,6 → 483,34
return temp; |
} |
|
unsigned char eval_direct8(unsigned long memaddr, int *breakpoint, |
int through_mmu, int through_dc) |
{ |
unsigned char temp; |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return 0; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) |
memaddr = peek_into_dtlb(memaddr, 0, through_dc); |
|
if (through_dc) |
temp = (unsigned char)dc_simulate_read(memaddr, 1); |
else { |
temp = evalsim_mem8(memaddr); |
if (!cur_area) { |
PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx) in eval_direct8()\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
} |
} |
|
|
void setsim_mem32(unsigned long memaddr, unsigned long value) |
{ |
struct dev_memarea *dev; |
536,9 → 624,38
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
void set_direct32(unsigned long memaddr, unsigned long value,int* breakpoint, |
int through_mmu, int through_dc) |
{ |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) { |
/* 0 - no write access, we do not want a DPF exception do we ;) |
*/ |
memaddr = peek_into_dtlb(memaddr, 1, through_dc); |
} |
|
|
/* __PHX__ fixme: in principle we should write around the cache if |
* through_dc is set, but i believe we this will work |
* just fine anyway |
*/ |
dc_simulate_write(memaddr, value, 4); |
|
if (cur_area && cur_area->log) |
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
|
/* Set mem, 16-bit. Big endian version. */ |
|
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint) |
void set_mem16(unsigned long memaddr, unsigned short value, int* breakpoint) |
{ |
if (config.sim.mprofile) |
mprofile (memaddr, MPROF_16 | MPROF_WRITE); |
565,9 → 682,36
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
void set_direct16(unsigned long memaddr, unsigned short value, int* breakpoint, |
int through_mmu, int through_dc) |
{ |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) { |
/* 0 - no write access, we do not want a DPF exception do we ;) |
*/ |
memaddr = peek_into_dtlb(memaddr, 0, through_dc); |
} |
|
/* __PHX__ fixme: in principle we should write around the cache if |
* through_dc is set, but i believe we this will work |
* just fine anyway |
*/ |
dc_simulate_write(memaddr, value, 2); |
|
if (cur_area && cur_area->log) |
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
/* Set mem, 8-bit. */ |
|
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint) |
void set_mem8(unsigned long memaddr, unsigned char value, int* breakpoint) |
{ |
if (config.sim.mprofile) |
mprofile (memaddr, MPROF_8 | MPROF_WRITE); |
588,6 → 732,35
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
void set_direct8(unsigned long memaddr, unsigned char value, int* breakpoint, |
int through_mmu, int through_dc) |
{ |
|
if (memaddr & 3) { |
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__); |
return; |
} |
|
cur_vadd = memaddr; |
|
if (through_mmu) { |
/* 0 - no write access, we do not want a DPF exception do we ;) |
*/ |
memaddr = peek_into_dtlb(memaddr, 0, through_dc); |
} |
|
/* __PHX__ fixme: in principle we should write around the cache if |
* through_dc is set, but i believe we this will work |
* just fine anyway |
*/ |
dc_simulate_write(memaddr, value, 1); |
|
if (cur_area && cur_area->log) |
fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value); |
} |
|
|
|
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl) |
{ |
unsigned int i, j; |
/trunk/or1ksim/mmu/dmmu.c
108,6 → 108,85
} |
} |
|
/* DESC: try to find EA -> PA transaltion without changing |
* any of precessor states. if this is not passible gives up |
* (without triggering exceptions) |
* |
* PRMS: virtaddr - EA for which to find translation |
* |
* write_access - 0 ignore testing for write access |
* 1 test for write access, if fails |
* do not return translation |
* |
* through_dc - 1 go through data cache |
* 0 ignore data cache |
* |
* RTRN: 0 - no DMMU, DMMU disabled or ITLB miss |
* else - appropriate PA (note it DMMU is not present |
* PA === EA) |
*/ |
unsigned long peek_into_dtlb(unsigned long virtaddr, int write_access, |
int through_dc) |
{ |
int set, way = -1; |
int i; |
unsigned long tagaddr; |
unsigned long vpn, ppn; |
|
if (!(mfspr(SPR_SR) & SPR_SR_DME) || !testsprbits(SPR_UPR, SPR_UPR_DMP)) { |
if (through_dc) |
data_ci = (virtaddr >= 0x80000000); |
return virtaddr; |
} |
|
/* Which set to check out? */ |
set = (virtaddr / config.dmmu.pagesize) % config.dmmu.nsets; |
tagaddr = (virtaddr / config.dmmu.pagesize) / config.dmmu.nsets; |
vpn = virtaddr / (config.dmmu.pagesize * config.dmmu.nsets); |
|
/* Scan all ways and try to find a matching way. */ |
for (i = 0; i < config.dmmu.nways; i++) |
if (((mfspr(SPR_DTLBMR_BASE(i) + set) / (config.dmmu.pagesize * config.dmmu.nsets)) == vpn) && |
testsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_V)) |
way = i; |
|
/* Did we find our tlb entry? */ |
if (way >= 0) { /* Yes, we did. */ |
dmmu_stats.loads_tlbhit++; |
debug(5, "DTLB hit (virtaddr=%x).\n", virtaddr); |
|
/* Test for page fault */ |
if (mfspr (SPR_SR) & SPR_SR_SM) { |
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SWE) |
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SRE)) |
|
/* otherwise exception DPF would be raised */ |
return(0); |
} else { |
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_UWE) |
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_URE)) |
|
/* otherwise exception DPF would be raised */ |
return(0); |
} |
|
if (through_dc) { |
/* Check if page is cache inhibited */ |
data_ci = (mfspr(SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_CI) == SPR_DTLBTR_CI; |
} |
|
ppn = mfspr(SPR_DTLBTR_BASE(way) + set) / config.dmmu.pagesize; |
return (ppn * config.dmmu.pagesize) + (virtaddr % config.dmmu.pagesize); |
} |
else { /* No, we didn't. */ |
return(0); |
} |
|
PRINTF("ERR, should never have happened\n"); |
return(0); |
} |
|
|
unsigned long dmmu_translate(unsigned long virtaddr, int write_access) |
{ |
unsigned long phyaddr = dmmu_simulate_tlb(virtaddr, write_access); |