OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [sim/] [mmu.c] - Diff between revs 166 and 168

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 166 Rev 168
Line 24... Line 24...
static TLB_Entry tlb[TLB_SIZE];
static TLB_Entry tlb[TLB_SIZE];
static Word tlbIndex;
static Word tlbIndex;
static Word tlbEntryHi;
static Word tlbEntryHi;
static Word tlbEntryLo;
static Word tlbEntryLo;
static Word mmuBadAddr;
static Word mmuBadAddr;
 
static Word mmuBadAccs;
 
 
 
 
static int assoc(Word page) {
static int assoc(Word page) {
  int n, i;
  int n, i;
 
 
Line 39... Line 40...
  }
  }
  return n;
  return n;
}
}
 
 
 
 
static Word v2p(Word vAddr, Bool userMode, Bool writing) {
static Word v2p(Word vAddr, Bool userMode, Bool writing, int accsWidth) {
  Word pAddr;
  Word pAddr;
  Word page, offset;
  Word page, offset;
  int index;
  int index;
 
 
  if (debugUse) {
  if (debugUse) {
    cPrintf("**** vAddr = 0x%08X", vAddr);
    cPrintf("**** vAddr = 0x%08X", vAddr);
  }
  }
  if ((vAddr & 0x80000000) != 0 && userMode) {
  if ((vAddr & 0x80000000) != 0 && userMode) {
    /* trying to access a privileged address from user mode */
    /* trying to access a privileged address from user mode */
 
    mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth;
    mmuBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_PRV_ADDRESS);
    throwException(EXC_PRV_ADDRESS);
  }
  }
  if ((vAddr & 0xC0000000) == 0xC0000000) {
  if ((vAddr & 0xC0000000) == 0xC0000000) {
    /* unmapped address space */
    /* unmapped address space */
Line 65... Line 67...
    page = vAddr & PAGE_MASK;
    page = vAddr & PAGE_MASK;
    offset = vAddr & OFFSET_MASK;
    offset = vAddr & OFFSET_MASK;
    index = assoc(page);
    index = assoc(page);
    if (index == -1) {
    if (index == -1) {
      /* TLB miss exception */
      /* TLB miss exception */
 
      mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth;
      mmuBadAddr = vAddr;
      mmuBadAddr = vAddr;
      tlbEntryHi = page;
      tlbEntryHi = page;
      throwException(EXC_TLB_MISS);
      throwException(EXC_TLB_MISS);
    }
    }
    if (!tlb[index].valid) {
    if (!tlb[index].valid) {
      /* TLB invalid exception */
      /* TLB invalid exception */
 
      mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth;
      mmuBadAddr = vAddr;
      mmuBadAddr = vAddr;
      tlbEntryHi = page;
      tlbEntryHi = page;
      throwException(EXC_TLB_INVALID);
      throwException(EXC_TLB_INVALID);
    }
    }
    if (!tlb[index].write && writing) {
    if (!tlb[index].write && writing) {
      /* TLB write exception */
      /* TLB write exception */
 
      mmuBadAccs = (writing ? MMU_ACCS_WRITE : MMU_ACCS_READ) | accsWidth;
      mmuBadAddr = vAddr;
      mmuBadAddr = vAddr;
      tlbEntryHi = page;
      tlbEntryHi = page;
      throwException(EXC_TLB_WRITE);
      throwException(EXC_TLB_WRITE);
    }
    }
    pAddr = tlb[index].frame | offset;
    pAddr = tlb[index].frame | offset;
Line 93... Line 98...
 
 
 
 
Word mmuReadWord(Word vAddr, Bool userMode) {
Word mmuReadWord(Word vAddr, Bool userMode) {
  if ((vAddr & 3) != 0) {
  if ((vAddr & 3) != 0) {
    /* throw illegal address exception */
    /* throw illegal address exception */
 
    mmuBadAccs = MMU_ACCS_READ | MMU_ACCS_WORD;
    mmuBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  return memoryReadWord(v2p(vAddr, userMode, false));
  return memoryReadWord(v2p(vAddr, userMode, false, MMU_ACCS_WORD));
}
}
 
 
 
 
Half mmuReadHalf(Word vAddr, Bool userMode) {
Half mmuReadHalf(Word vAddr, Bool userMode) {
  if ((vAddr & 1) != 0) {
  if ((vAddr & 1) != 0) {
    /* throw illegal address exception */
    /* throw illegal address exception */
 
    mmuBadAccs = MMU_ACCS_READ | MMU_ACCS_HALF;
    mmuBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    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) {
Byte mmuReadByte(Word vAddr, Bool userMode) {
  return memoryReadByte(v2p(vAddr, userMode, false));
  return memoryReadByte(v2p(vAddr, userMode, false, MMU_ACCS_BYTE));
}
}
 
 
 
 
void mmuWriteWord(Word vAddr, Word data, Bool userMode) {
void mmuWriteWord(Word vAddr, Word data, Bool userMode) {
  if ((vAddr & 3) != 0) {
  if ((vAddr & 3) != 0) {
    /* throw illegal address exception */
    /* throw illegal address exception */
 
    mmuBadAccs = MMU_ACCS_WRITE | MMU_ACCS_WORD;
    mmuBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  memoryWriteWord(v2p(vAddr, userMode, true), data);
  memoryWriteWord(v2p(vAddr, userMode, true, MMU_ACCS_WORD), data);
}
}
 
 
 
 
void mmuWriteHalf(Word vAddr, Half data, Bool userMode) {
void mmuWriteHalf(Word vAddr, Half data, Bool userMode) {
  if ((vAddr & 1) != 0) {
  if ((vAddr & 1) != 0) {
    /* throw illegal address exception */
    /* throw illegal address exception */
 
    mmuBadAccs = MMU_ACCS_WRITE | MMU_ACCS_HALF;
    mmuBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    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) {
void mmuWriteByte(Word vAddr, Byte data, Bool userMode) {
  memoryWriteByte(v2p(vAddr, userMode, true), data);
  memoryWriteByte(v2p(vAddr, userMode, true, MMU_ACCS_BYTE), data);
}
}
 
 
 
 
Word mmuGetIndex(void) {
Word mmuGetIndex(void) {
  return tlbIndex;
  return tlbIndex;
Line 180... Line 189...
void mmuSetBadAddr(Word value) {
void mmuSetBadAddr(Word value) {
  mmuBadAddr = value;
  mmuBadAddr = value;
}
}
 
 
 
 
 
Word mmuGetBadAccs(void) {
 
  return mmuBadAccs;
 
}
 
 
 
 
 
void mmuSetBadAccs(Word value) {
 
  mmuBadAccs = value;
 
}
 
 
 
 
void mmuTbs(void) {
void mmuTbs(void) {
  int index;
  int index;
 
 
  index = assoc(tlbEntryHi & PAGE_MASK);
  index = assoc(tlbEntryHi & PAGE_MASK);
  if (index == -1) {
  if (index == -1) {
Line 281... Line 300...
  }
  }
  tlbIndex = rand() & TLB_MASK;
  tlbIndex = rand() & TLB_MASK;
  tlbEntryHi = rand() & PAGE_MASK;
  tlbEntryHi = rand() & PAGE_MASK;
  tlbEntryLo = rand() & (PAGE_MASK | TLB_WRITE | TLB_VALID);
  tlbEntryLo = rand() & (PAGE_MASK | TLB_WRITE | TLB_VALID);
  mmuBadAddr = rand();
  mmuBadAddr = rand();
 
  mmuBadAccs = rand() & MMU_ACCS_MASK;
}
}
 
 
 
 
void mmuInit(void) {
void mmuInit(void) {
  mmuReset();
  mmuReset();

powered by: WebSVN 2.1.0

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