/*
|
/*
|
* mmu.c -- memory and TLB access
|
* mmu.c -- memory and TLB access
|
*/
|
*/
|
|
|
|
|
#include "common.h"
|
#include "common.h"
|
#include "stdarg.h"
|
#include "stdarg.h"
|
#include "romlib.h"
|
#include "romlib.h"
|
#include "mmu.h"
|
#include "mmu.h"
|
#include "start.h"
|
#include "start.h"
|
|
|
|
|
static Word tlbIndex;
|
static Word tlbIndex;
|
static Word tlbEntryHi;
|
static Word tlbEntryHi;
|
static Word tlbEntryLo;
|
static Word tlbEntryLo;
|
|
static Word badAddress;
|
|
|
|
|
Word mmuReadWord(Word vAddr) {
|
Word mmuReadWord(Word vAddr) {
|
return *(Word *)vAddr;
|
return *(Word *)vAddr;
|
}
|
}
|
|
|
|
|
Half mmuReadHalf(Word vAddr) {
|
Half mmuReadHalf(Word vAddr) {
|
return *(Half *)vAddr;
|
return *(Half *)vAddr;
|
}
|
}
|
|
|
|
|
Byte mmuReadByte(Word vAddr) {
|
Byte mmuReadByte(Word vAddr) {
|
return *(Byte *)vAddr;
|
return *(Byte *)vAddr;
|
}
|
}
|
|
|
|
|
void mmuWriteWord(Word vAddr, Word data) {
|
void mmuWriteWord(Word vAddr, Word data) {
|
*(Word *)vAddr = data;
|
*(Word *)vAddr = data;
|
}
|
}
|
|
|
|
|
void mmuWriteHalf(Word vAddr, Half data) {
|
void mmuWriteHalf(Word vAddr, Half data) {
|
*(Half *)vAddr = data;
|
*(Half *)vAddr = data;
|
}
|
}
|
|
|
|
|
void mmuWriteByte(Word vAddr, Byte data) {
|
void mmuWriteByte(Word vAddr, Byte data) {
|
*(Byte *)vAddr = data;
|
*(Byte *)vAddr = data;
|
}
|
}
|
|
|
|
|
Word mmuGetIndex(void) {
|
Word mmuGetIndex(void) {
|
return tlbIndex;
|
return tlbIndex;
|
}
|
}
|
|
|
|
|
void mmuSetIndex(Word value) {
|
void mmuSetIndex(Word value) {
|
tlbIndex = value;
|
tlbIndex = value;
|
}
|
}
|
|
|
|
|
Word mmuGetEntryHi(void) {
|
Word mmuGetEntryHi(void) {
|
return tlbEntryHi;
|
return tlbEntryHi;
|
}
|
}
|
|
|
|
|
void mmuSetEntryHi(Word value) {
|
void mmuSetEntryHi(Word value) {
|
tlbEntryHi = value;
|
tlbEntryHi = value;
|
}
|
}
|
|
|
|
|
Word mmuGetEntryLo(void) {
|
Word mmuGetEntryLo(void) {
|
return tlbEntryLo;
|
return tlbEntryLo;
|
}
|
}
|
|
|
|
|
void mmuSetEntryLo(Word value) {
|
void mmuSetEntryLo(Word value) {
|
tlbEntryLo = value;
|
tlbEntryLo = value;
|
}
|
}
|
|
|
|
|
|
Word mmuGetBadAddr(void) {
|
|
return badAddress;
|
|
}
|
|
|
|
|
|
void mmuSetBadAddr(Word value) {
|
|
badAddress = value;
|
|
}
|
|
|
|
|
TLB_Entry mmuGetTLB(int index) {
|
TLB_Entry mmuGetTLB(int index) {
|
Word hi;
|
Word hi;
|
Word lo;
|
Word lo;
|
TLB_Entry result;
|
TLB_Entry result;
|
|
|
hi = getTLB_HI(index);
|
hi = getTLB_HI(index);
|
lo = getTLB_LO(index);
|
lo = getTLB_LO(index);
|
result.page = hi & PAGE_MASK;
|
result.page = hi & PAGE_MASK;
|
result.frame = lo & PAGE_MASK;
|
result.frame = lo & PAGE_MASK;
|
result.write = (lo & TLB_WRITE) ? true : false;
|
result.write = (lo & TLB_WRITE) ? true : false;
|
result.valid = (lo & TLB_VALID) ? true : false;
|
result.valid = (lo & TLB_VALID) ? true : false;
|
return result;
|
return result;
|
}
|
}
|
|
|
|
|
void mmuSetTLB(int index, TLB_Entry tlbEntry) {
|
void mmuSetTLB(int index, TLB_Entry tlbEntry) {
|
Word flags;
|
Word flags;
|
|
|
flags = 0;
|
flags = 0;
|
if (tlbEntry.write) {
|
if (tlbEntry.write) {
|
flags |= TLB_WRITE;
|
flags |= TLB_WRITE;
|
}
|
}
|
if (tlbEntry.valid) {
|
if (tlbEntry.valid) {
|
flags |= TLB_VALID;
|
flags |= TLB_VALID;
|
}
|
}
|
setTLB(index, tlbEntry.page, tlbEntry.frame | flags);
|
setTLB(index, tlbEntry.page, tlbEntry.frame | flags);
|
}
|
}
|
|
|