URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 167 to Rev 168
- ↔ Reverse comparison
Rev 167 → Rev 168
/eco32/trunk/sim/mmu.c
26,6 → 26,7
static Word tlbEntryHi; |
static Word tlbEntryLo; |
static Word mmuBadAddr; |
static Word mmuBadAccs; |
|
|
static int assoc(Word page) { |
41,7 → 42,7
} |
|
|
static Word v2p(Word vAddr, Bool userMode, Bool writing) { |
static Word v2p(Word vAddr, Bool userMode, Bool writing, int accsWidth) { |
Word pAddr; |
Word page, offset; |
int index; |
51,6 → 52,7
} |
if ((vAddr & 0x80000000) != 0 && userMode) { |
/* trying to access a privileged address from user mode */ |
mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth; |
mmuBadAddr = vAddr; |
throwException(EXC_PRV_ADDRESS); |
} |
67,6 → 69,7
index = assoc(page); |
if (index == -1) { |
/* TLB miss exception */ |
mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth; |
mmuBadAddr = vAddr; |
tlbEntryHi = page; |
throwException(EXC_TLB_MISS); |
73,6 → 76,7
} |
if (!tlb[index].valid) { |
/* TLB invalid exception */ |
mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth; |
mmuBadAddr = vAddr; |
tlbEntryHi = page; |
throwException(EXC_TLB_INVALID); |
79,6 → 83,7
} |
if (!tlb[index].write && writing) { |
/* TLB write exception */ |
mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth; |
mmuBadAddr = vAddr; |
tlbEntryHi = page; |
throwException(EXC_TLB_WRITE); |
95,10 → 100,11
Word mmuReadWord(Word vAddr, Bool userMode) { |
if ((vAddr & 3) != 0) { |
/* throw illegal address exception */ |
mmuBadAccs = MMU_ACCS_READ | MMU_ACCS_WORD; |
mmuBadAddr = vAddr; |
throwException(EXC_ILL_ADDRESS); |
} |
return memoryReadWord(v2p(vAddr, userMode, false)); |
return memoryReadWord(v2p(vAddr, userMode, false, MMU_ACCS_WORD)); |
} |
|
|
105,15 → 111,16
Half mmuReadHalf(Word vAddr, Bool userMode) { |
if ((vAddr & 1) != 0) { |
/* throw illegal address exception */ |
mmuBadAccs = MMU_ACCS_READ | MMU_ACCS_HALF; |
mmuBadAddr = vAddr; |
throwException(EXC_ILL_ADDRESS); |
} |
return memoryReadHalf(v2p(vAddr, userMode, false)); |
return memoryReadHalf(v2p(vAddr, userMode, false, MMU_ACCS_HALF)); |
} |
|
|
Byte mmuReadByte(Word vAddr, Bool userMode) { |
return memoryReadByte(v2p(vAddr, userMode, false)); |
return memoryReadByte(v2p(vAddr, userMode, false, MMU_ACCS_BYTE)); |
} |
|
|
120,10 → 127,11
void mmuWriteWord(Word vAddr, Word data, Bool userMode) { |
if ((vAddr & 3) != 0) { |
/* throw illegal address exception */ |
mmuBadAccs = MMU_ACCS_WRITE | MMU_ACCS_WORD; |
mmuBadAddr = vAddr; |
throwException(EXC_ILL_ADDRESS); |
} |
memoryWriteWord(v2p(vAddr, userMode, true), data); |
memoryWriteWord(v2p(vAddr, userMode, true, MMU_ACCS_WORD), data); |
} |
|
|
130,15 → 138,16
void mmuWriteHalf(Word vAddr, Half data, Bool userMode) { |
if ((vAddr & 1) != 0) { |
/* throw illegal address exception */ |
mmuBadAccs = MMU_ACCS_WRITE | MMU_ACCS_HALF; |
mmuBadAddr = vAddr; |
throwException(EXC_ILL_ADDRESS); |
} |
memoryWriteHalf(v2p(vAddr, userMode, true), data); |
memoryWriteHalf(v2p(vAddr, userMode, true, MMU_ACCS_HALF), data); |
} |
|
|
void mmuWriteByte(Word vAddr, Byte data, Bool userMode) { |
memoryWriteByte(v2p(vAddr, userMode, true), data); |
memoryWriteByte(v2p(vAddr, userMode, true, MMU_ACCS_BYTE), data); |
} |
|
|
182,6 → 191,16
} |
|
|
Word mmuGetBadAccs(void) { |
return mmuBadAccs; |
} |
|
|
void mmuSetBadAccs(Word value) { |
mmuBadAccs = value; |
} |
|
|
void mmuTbs(void) { |
int index; |
|
283,6 → 302,7
tlbEntryHi = rand() & PAGE_MASK; |
tlbEntryLo = rand() & (PAGE_MASK | TLB_WRITE | TLB_VALID); |
mmuBadAddr = rand(); |
mmuBadAccs = rand() & MMU_ACCS_MASK; |
} |
|
|
/eco32/trunk/sim/mmu.h
15,7 → 15,14
#define TLB_WRITE (1 << 1) /* write bit in EntryLo */ |
#define TLB_VALID (1 << 0) /* valid bit in EntryLo */ |
|
#define MMU_ACCS_MASK 0x07 /* bits used in BadAccs */ |
#define MMU_ACCS_READ 0x00 /* access type = read */ |
#define MMU_ACCS_WRITE 0x04 /* access type = write */ |
#define MMU_ACCS_BYTE 0x00 /* access width = byte */ |
#define MMU_ACCS_HALF 0x01 /* access width = half */ |
#define MMU_ACCS_WORD 0x02 /* access width = word */ |
|
|
typedef struct { |
Word page; /* 20 high-order bits of virtual address */ |
Word frame; /* 20 high-order bits of physical address */ |
39,6 → 46,8
void mmuSetEntryLo(Word value); |
Word mmuGetBadAddr(void); |
void mmuSetBadAddr(Word value); |
Word mmuGetBadAccs(void); |
void mmuSetBadAccs(Word value); |
|
void mmuTbs(void); |
void mmuTbwr(void); |
/eco32/trunk/sim/cpu.c
427,6 → 427,9
case 4: |
WR(reg2, mmuGetBadAddr()); |
break; |
case 5: |
WR(reg2, mmuGetBadAccs()); |
break; |
default: |
throwException(EXC_ILL_INSTRCT); |
break; |
452,6 → 455,9
case 4: |
mmuSetBadAddr(RR(reg2)); |
break; |
case 5: |
mmuSetBadAccs(RR(reg2)); |
break; |
default: |
throwException(EXC_ILL_INSTRCT); |
break; |
/eco32/trunk/sim/command.c
783,8 → 783,10
|
|
static void doTLB(char *tokens[], int n) { |
static char *mmuAccsWidth[4] = { "byte", "half", "word", "????" }; |
int index; |
TLB_Entry tlbEntry; |
Word mmuAccs; |
Word data; |
|
if (n == 1) { |
795,10 → 797,15
tlbEntry.write ? 'w' : '-', |
tlbEntry.valid ? 'v' : '-'); |
} |
cPrintf("Index(1) %08X\n", mmuGetIndex()); |
cPrintf("EntryHi(2) %08X\n", mmuGetEntryHi()); |
cPrintf("EntryLo(3) %08X\n", mmuGetEntryLo()); |
cPrintf("BadAddr(4) %08X\n", mmuGetBadAddr()); |
cPrintf("Index (1) %08X\n", mmuGetIndex()); |
cPrintf("EntryHi (2) %08X\n", mmuGetEntryHi()); |
cPrintf("EntryLo (3) %08X\n", mmuGetEntryLo()); |
cPrintf("BadAddr (4) %08X\n", mmuGetBadAddr()); |
mmuAccs = mmuGetBadAccs(); |
cPrintf("BadAccs (5) %08X (%s %s)\n", |
mmuAccs, |
(mmuAccs & MMU_ACCS_WRITE) ? "write" : "read", |
mmuAccsWidth[mmuAccs & 0x03]); |
} else if (n == 2) { |
if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) { |
cPrintf("illegal TLB index\n"); |