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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [sim/] [mmu.c] - Diff between revs 8 and 78

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

Rev 8 Rev 78
Line 23... Line 23...
 
 
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 tlbBadAddr;
static Word mmuBadAddr;
 
 
 
 
static int assoc(Word page) {
static int assoc(Word page) {
  int n, i;
  int n, i;
 
 
Line 63... Line 63...
  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 */
    tlbBadAddr = 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 */
    assocDelay();
    assocDelay();
Line 77... Line 77...
    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 */
      tlbBadAddr = 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 */
      tlbBadAddr = 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 */
      tlbBadAddr = 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 105... Line 105...
 
 
 
 
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 */
    tlbBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  return memoryReadWord(v2p(vAddr, userMode, false));
  return memoryReadWord(v2p(vAddr, userMode, false));
}
}
 
 
 
 
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 */
    tlbBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  return memoryReadHalf(v2p(vAddr, userMode, false));
  return memoryReadHalf(v2p(vAddr, userMode, false));
}
}
 
 
Line 130... Line 130...
 
 
 
 
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 */
    tlbBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  memoryWriteWord(v2p(vAddr, userMode, true), data);
  memoryWriteWord(v2p(vAddr, userMode, true), 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 */
    tlbBadAddr = vAddr;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
    throwException(EXC_ILL_ADDRESS);
  }
  }
  memoryWriteHalf(v2p(vAddr, userMode, true), data);
  memoryWriteHalf(v2p(vAddr, userMode, true), data);
}
}
 
 
Line 183... Line 183...
  tlbEntryLo = value & (PAGE_MASK | TLB_WRITE | TLB_VALID);
  tlbEntryLo = value & (PAGE_MASK | TLB_WRITE | TLB_VALID);
}
}
 
 
 
 
Word mmuGetBadAddr(void) {
Word mmuGetBadAddr(void) {
  return tlbBadAddr;
  return mmuBadAddr;
}
}
 
 
 
 
void mmuSetBadAddr(Word value) {
void mmuSetBadAddr(Word value) {
  tlbBadAddr = value;
  mmuBadAddr = value;
}
}
 
 
 
 
void mmuTbs(void) {
void mmuTbs(void) {
  int index;
  int index;
Line 292... Line 292...
    }
    }
  }
  }
  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);
  tlbBadAddr = rand();
  mmuBadAddr = rand();
}
}
 
 
 
 
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.