OpenCores
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);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.