mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 06:46:37 +08:00
powerpc/haleakala: Fix warnings
This commit is contained in:
@@ -14,51 +14,51 @@
|
||||
/* #define qLogTLBDetails */
|
||||
|
||||
|
||||
/*--------------------------------- TLB handling ------------------------------------- */
|
||||
/*----------------------------- TLB handling -------------------------------- */
|
||||
/* The following are in assembler in mmu_405asm.S */
|
||||
extern void MMU_GetTLBEntry(uint8_t index, uint32_t* tagword, uint32_t* dataword, uint8_t* pid);
|
||||
extern void MMU_SetTLBEntry(uint8_t index, uint32_t hiword, uint32_t loword, uint8_t pid);
|
||||
extern void MMU_ClearTLBs();
|
||||
extern void MMU_ClearTLBs(void);
|
||||
extern int16_t MMU_FindTLBEntry(uint32_t address);
|
||||
|
||||
|
||||
enum { kNTLBs = 64 }; /* for 403GCX and 405 */
|
||||
enum { kNTLBs = 64 }; /* for 403GCX and 405 */
|
||||
|
||||
static bool sFreeTLBs[kNTLBs];
|
||||
static uint8_t sLastIndex = 0;
|
||||
static int sNInUse = 0;
|
||||
static bool sFreeTLBs[kNTLBs];
|
||||
static uint8_t sLastIndex = 0;
|
||||
static int sNInUse = 0;
|
||||
|
||||
static void MMUFault(const char* what)
|
||||
/* Used for all setup faults; these can't really be ignored */
|
||||
{
|
||||
printk("\n>>>MMU fatal error %s\n",what);
|
||||
rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
|
||||
printk("\n>>>MMU fatal error %s\n",what);
|
||||
rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
static uint8_t AllocTLB()
|
||||
static uint8_t AllocTLB(void)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
index = sLastIndex;
|
||||
do {
|
||||
index++;
|
||||
if (index == kNTLBs)
|
||||
index = 0;
|
||||
if (index == sLastIndex)
|
||||
MMUFault("TLB table full");
|
||||
} while (! sFreeTLBs[index]);
|
||||
sFreeTLBs[index] = false;
|
||||
sLastIndex = index;
|
||||
sNInUse++;
|
||||
return index;
|
||||
uint8_t index;
|
||||
|
||||
index = sLastIndex;
|
||||
do {
|
||||
index++;
|
||||
if (index == kNTLBs)
|
||||
index = 0;
|
||||
if (index == sLastIndex)
|
||||
MMUFault("TLB table full");
|
||||
} while (! sFreeTLBs[index]);
|
||||
sFreeTLBs[index] = false;
|
||||
sLastIndex = index;
|
||||
sNInUse++;
|
||||
return index;
|
||||
}
|
||||
|
||||
static void FreeTLB(uint8_t index)
|
||||
{
|
||||
MMU_SetTLBEntry(index,0,0,0);
|
||||
sFreeTLBs[index] = true;
|
||||
sLastIndex = index-1;
|
||||
sNInUse--;
|
||||
MMU_SetTLBEntry(index,0,0,0);
|
||||
sFreeTLBs[index] = true;
|
||||
sLastIndex = index-1;
|
||||
sNInUse--;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,157 +67,161 @@ static void FreeTLB(uint8_t index)
|
||||
int DataMissException(BSP_Exception_frame *f, unsigned int vector);
|
||||
int InstructionMissException(BSP_Exception_frame *f, unsigned int vector);
|
||||
int InstructionFetchException(BSP_Exception_frame *f, unsigned int vector);
|
||||
void mmu_initialise(void);
|
||||
int mmu_get_tlb_count(void);
|
||||
uint8_t mmu_new_processID(void);
|
||||
uint8_t mmu_current_processID(void);
|
||||
|
||||
void
|
||||
mmu_initialise()
|
||||
mmu_initialise(void)
|
||||
/* Clear the TLBs and set up exception handlers for the MMU miss handlers */
|
||||
{
|
||||
int i;
|
||||
|
||||
MMU_ClearTLBs();
|
||||
for (i=0; i<kNTLBs; i++) {
|
||||
sFreeTLBs[i] = true;
|
||||
MMU_SetTLBEntry(i,0,0,0xFF);
|
||||
}
|
||||
ppc_exc_set_handler(ASM_ISI_VECTOR ,InstructionFetchException);
|
||||
ppc_exc_set_handler(ASM_BOOKE_ITLBMISS_VECTOR ,DataMissException);
|
||||
ppc_exc_set_handler(ASM_BOOKE_DTLBMISS_VECTOR ,InstructionMissException);
|
||||
int i;
|
||||
|
||||
MMU_ClearTLBs();
|
||||
for (i=0; i<kNTLBs; i++) {
|
||||
sFreeTLBs[i] = true;
|
||||
MMU_SetTLBEntry(i,0,0,0xFF);
|
||||
}
|
||||
ppc_exc_set_handler(ASM_ISI_VECTOR ,InstructionFetchException);
|
||||
ppc_exc_set_handler(ASM_BOOKE_ITLBMISS_VECTOR ,DataMissException);
|
||||
ppc_exc_set_handler(ASM_BOOKE_DTLBMISS_VECTOR ,InstructionMissException);
|
||||
}
|
||||
|
||||
static void
|
||||
MakeTLBEntries(uint32_t startAt, uint32_t nBytes, bool EX, bool WR, bool I, uint8_t PID)
|
||||
{
|
||||
uint32_t mask, options, tagWord, dataWord;
|
||||
uint8_t index, sizeCode, pid;
|
||||
|
||||
if ((startAt & 0x3FF) != 0)
|
||||
MMUFault("TLB entry not on 1K boundary");
|
||||
if ((nBytes & 0x3FF) != 0)
|
||||
MMUFault("TLB size not on 1K boundary");
|
||||
|
||||
options = 0;
|
||||
if (EX) options += 0x200;
|
||||
if (WR) options += 0x100;
|
||||
if (I) options += 5;
|
||||
|
||||
#ifdef qLogTLB
|
||||
printk("TLB: make entries for $%X bytes from $%X..$%X PID %d",nBytes, startAt, startAt+nBytes-1, PID);
|
||||
if (EX) printk(" EX");
|
||||
if (WR) printk(" WR");
|
||||
if (I) printk(" I");
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
while (nBytes > 0) {
|
||||
/* Find the largest block we can base on this address */
|
||||
mask = 0x3FF;
|
||||
sizeCode = 0;
|
||||
while (mask < nBytes && ((startAt & mask)==0) && sizeCode < 8) {
|
||||
mask = (mask<<2) + 3;
|
||||
sizeCode++;
|
||||
}
|
||||
mask >>= 2;
|
||||
sizeCode--;
|
||||
|
||||
/* Make a TLB entry describing this, ZSEL=0 */
|
||||
tagWord = startAt | (sizeCode<<7) | 0x40;
|
||||
dataWord = startAt | options;
|
||||
index = AllocTLB();
|
||||
MMU_SetTLBEntry( index , tagWord, dataWord, PID);
|
||||
|
||||
{
|
||||
/* Paranoia: check that we can read that back... */
|
||||
uint8_t tdex, oldpid;
|
||||
|
||||
oldpid = mmu_current_processID();
|
||||
mmu_set_processID(PID);
|
||||
tdex = MMU_FindTLBEntry(startAt);
|
||||
mmu_set_processID(oldpid);
|
||||
|
||||
if (tdex != index) {
|
||||
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X ",index, startAt, mask+1,sizeCode,tagWord);
|
||||
printk(" -- find failed, %d/%d!\n",tdex,index);
|
||||
MMU_GetTLBEntry(index, &tagWord, &dataWord, &pid);
|
||||
printk(" -- reads back $%X : $%X, PID %d\n",tagWord,dataWord,pid);
|
||||
} else {
|
||||
#ifdef qLogTLBDetails
|
||||
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X\n",index, startAt, mask+1,sizeCode,tagWord);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtract block from startAddr and nBytes */
|
||||
mask++; /* Convert to a byte count */
|
||||
startAt += mask;
|
||||
nBytes -= mask;
|
||||
}
|
||||
#ifdef qLogTLB
|
||||
printk(" %d in use\n",sNInUse);
|
||||
#endif
|
||||
uint32_t mask, options, tagWord, dataWord;
|
||||
uint8_t index, sizeCode, pid;
|
||||
|
||||
if ((startAt & 0x3FF) != 0)
|
||||
MMUFault("TLB entry not on 1K boundary");
|
||||
if ((nBytes & 0x3FF) != 0)
|
||||
MMUFault("TLB size not on 1K boundary");
|
||||
|
||||
options = 0;
|
||||
if (EX) options += 0x200;
|
||||
if (WR) options += 0x100;
|
||||
if (I) options += 5;
|
||||
|
||||
#ifdef qLogTLB
|
||||
printk("TLB: make entries for $%X bytes from $%X..$%X PID %d",nBytes, startAt, startAt+nBytes-1, PID);
|
||||
if (EX) printk(" EX");
|
||||
if (WR) printk(" WR");
|
||||
if (I) printk(" I");
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
while (nBytes > 0) {
|
||||
/* Find the largest block we can base on this address */
|
||||
mask = 0x3FF;
|
||||
sizeCode = 0;
|
||||
while (mask < nBytes && ((startAt & mask)==0) && sizeCode < 8) {
|
||||
mask = (mask<<2) + 3;
|
||||
sizeCode++;
|
||||
}
|
||||
mask >>= 2;
|
||||
sizeCode--;
|
||||
|
||||
/* Make a TLB entry describing this, ZSEL=0 */
|
||||
tagWord = startAt | (sizeCode<<7) | 0x40;
|
||||
dataWord = startAt | options;
|
||||
index = AllocTLB();
|
||||
MMU_SetTLBEntry( index , tagWord, dataWord, PID);
|
||||
|
||||
{
|
||||
/* Paranoia: check that we can read that back... */
|
||||
uint8_t tdex, oldpid;
|
||||
|
||||
oldpid = mmu_current_processID();
|
||||
mmu_set_processID(PID);
|
||||
tdex = MMU_FindTLBEntry(startAt);
|
||||
mmu_set_processID(oldpid);
|
||||
|
||||
if (tdex != index) {
|
||||
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X ",index, startAt, mask+1,sizeCode,tagWord);
|
||||
printk(" -- find failed, %d/%d!\n",tdex,index);
|
||||
MMU_GetTLBEntry(index, &tagWord, &dataWord, &pid);
|
||||
printk(" -- reads back $%X : $%X, PID %d\n",tagWord,dataWord,pid);
|
||||
} else {
|
||||
#ifdef qLogTLBDetails
|
||||
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X\n",index, startAt, mask+1,sizeCode,tagWord);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtract block from startAddr and nBytes */
|
||||
mask++; /* Convert to a byte count */
|
||||
startAt += mask;
|
||||
nBytes -= mask;
|
||||
}
|
||||
#ifdef qLogTLB
|
||||
printk(" %d in use\n",sNInUse);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mmu_remove_space(uint32_t startAt, uint32_t endAt)
|
||||
{
|
||||
int16_t index;
|
||||
int32_t size;
|
||||
uint32_t tagword, dataword, nBytes;
|
||||
uint8_t pid, sCode;
|
||||
|
||||
nBytes = endAt - startAt;
|
||||
|
||||
#ifdef qLogTLB
|
||||
printk("TLB: delete entries for $%X bytes from $%X\n",nBytes,startAt);
|
||||
#endif
|
||||
|
||||
while (nBytes > 0) {
|
||||
index = MMU_FindTLBEntry( (uint32_t)startAt );
|
||||
size = 1024;
|
||||
if (index >= 0) {
|
||||
MMU_GetTLBEntry(index, &tagword, &dataword, &pid);
|
||||
if ((tagword & 0x40) == 0)
|
||||
MMUFault("Undefine failed: redundant entries?");
|
||||
if ((tagword & 0xFFFFFC00) != (uint32_t)startAt)
|
||||
MMUFault("Undefine not on TLB boundary");
|
||||
FreeTLB(index);
|
||||
sCode = (tagword >> 7) & 7;
|
||||
while (sCode > 0) {
|
||||
size <<= 2;
|
||||
sCode--;
|
||||
}
|
||||
#ifdef qLogTLBDetails
|
||||
printk(" Free TLB %d: At %X for $%X\n",index, startAt, size);
|
||||
#endif
|
||||
}
|
||||
startAt += size;
|
||||
nBytes -= size;
|
||||
}
|
||||
int16_t index;
|
||||
int32_t size;
|
||||
uint32_t tagword, dataword, nBytes;
|
||||
uint8_t pid, sCode;
|
||||
|
||||
nBytes = endAt - startAt;
|
||||
|
||||
#ifdef qLogTLB
|
||||
printk("TLB: delete entries for $%X bytes from $%X\n",nBytes,startAt);
|
||||
#endif
|
||||
|
||||
while (nBytes > 0) {
|
||||
index = MMU_FindTLBEntry( (uint32_t)startAt );
|
||||
size = 1024;
|
||||
if (index >= 0) {
|
||||
MMU_GetTLBEntry(index, &tagword, &dataword, &pid);
|
||||
if ((tagword & 0x40) == 0)
|
||||
MMUFault("Undefine failed: redundant entries?");
|
||||
if ((tagword & 0xFFFFFC00) != (uint32_t)startAt)
|
||||
MMUFault("Undefine not on TLB boundary");
|
||||
FreeTLB(index);
|
||||
sCode = (tagword >> 7) & 7;
|
||||
while (sCode > 0) {
|
||||
size <<= 2;
|
||||
sCode--;
|
||||
}
|
||||
#ifdef qLogTLBDetails
|
||||
printk(" Free TLB %d: At %X for $%X\n",index, startAt, size);
|
||||
#endif
|
||||
}
|
||||
startAt += size;
|
||||
nBytes -= size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mmu_add_space(uint32_t startAddr, uint32_t endAddr, MMUAccessType permissions, uint8_t processID)
|
||||
/* Convert accesstype to write-enable, executable, and cache-inhibit bits */
|
||||
{
|
||||
bool EX, WR, I;
|
||||
|
||||
EX = false;
|
||||
WR = false;
|
||||
I = false;
|
||||
switch (permissions) {
|
||||
case executable : EX = true; break;
|
||||
case readOnlyData : break;
|
||||
case readOnlyNoCache : I = true; break;
|
||||
case readWriteData : WR = true; break;
|
||||
case readWriteNoCache : WR = true; I= true; break;
|
||||
case readWriteExecutable: WR = true; EX = true; break;
|
||||
}
|
||||
MakeTLBEntries( (uint32_t)startAddr, (uint32_t)(endAddr-startAddr+1), EX, WR, I, processID);
|
||||
bool EX, WR, I;
|
||||
|
||||
EX = false;
|
||||
WR = false;
|
||||
I = false;
|
||||
switch (permissions) {
|
||||
case executable : EX = true; break;
|
||||
case readOnlyData : break;
|
||||
case readOnlyNoCache : I = true; break;
|
||||
case readWriteData : WR = true; break;
|
||||
case readWriteNoCache : WR = true; I= true; break;
|
||||
case readWriteExecutable: WR = true; EX = true; break;
|
||||
}
|
||||
MakeTLBEntries( (uint32_t)startAddr, (uint32_t)(endAddr-startAddr+1), EX, WR, I, processID);
|
||||
}
|
||||
|
||||
int
|
||||
mmu_get_tlb_count()
|
||||
mmu_get_tlb_count(void)
|
||||
{
|
||||
return sNInUse;
|
||||
return sNInUse;
|
||||
}
|
||||
|
||||
/*---------------------------- CPU process ID handling ----------------------------------
|
||||
@@ -226,56 +230,56 @@ mmu_get_tlb_count()
|
||||
|
||||
static uint8_t sNextPID = 1;
|
||||
|
||||
#define SPR_PID 0x3B1
|
||||
#define SPR_PID 0x3B1
|
||||
|
||||
uint8_t mmu_new_processID()
|
||||
uint8_t mmu_new_processID(void)
|
||||
{
|
||||
return sNextPID++;
|
||||
return sNextPID++;
|
||||
}
|
||||
|
||||
void mmu_free_processID(uint8_t freeThis)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t mmu_current_processID()
|
||||
uint8_t mmu_current_processID(void)
|
||||
{
|
||||
return PPC_SPECIAL_PURPOSE_REGISTER(SPR_PID);
|
||||
return PPC_SPECIAL_PURPOSE_REGISTER(SPR_PID);
|
||||
}
|
||||
|
||||
uint8_t mmu_set_processID(uint8_t newID)
|
||||
{
|
||||
uint8_t prev = mmu_current_processID();
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(SPR_PID,newID);
|
||||
return prev;
|
||||
uint8_t prev = mmu_current_processID();
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(SPR_PID,newID);
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------ Fault handlers ------------------ */
|
||||
|
||||
#define SPR_ESR 0x3D4
|
||||
#define SPR_DEAR 0x3D5
|
||||
#define SPR_ESR 0x3D4
|
||||
#define SPR_DEAR 0x3D5
|
||||
|
||||
enum { kESR_DST = 0x00800000 };
|
||||
|
||||
int DataMissException(BSP_Exception_frame *f, unsigned int vector)
|
||||
{
|
||||
uint32_t addr, excSyn;
|
||||
|
||||
addr = PPC_SPECIAL_PURPOSE_REGISTER(SPR_DEAR);
|
||||
excSyn = PPC_SPECIAL_PURPOSE_REGISTER(SPR_ESR);
|
||||
if (excSyn & kESR_DST) printk("\n---Data write to $%X attempted at $%X\n",addr,f->EXC_SRR0);
|
||||
else printk("\n---Data read from $%X attempted at $%X\n",addr,f->EXC_SRR0);
|
||||
return -1;
|
||||
uint32_t addr, excSyn;
|
||||
|
||||
addr = PPC_SPECIAL_PURPOSE_REGISTER(SPR_DEAR);
|
||||
excSyn = PPC_SPECIAL_PURPOSE_REGISTER(SPR_ESR);
|
||||
if (excSyn & kESR_DST) printk("\n---Data write to $%X attempted at $%X\n",addr,f->EXC_SRR0);
|
||||
else printk("\n---Data read from $%X attempted at $%X\n",addr,f->EXC_SRR0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int InstructionMissException(BSP_Exception_frame *f, unsigned int vector)
|
||||
{
|
||||
printk("\n---Instruction fetch attempted from $%X, no TLB exists\n",f->EXC_SRR0);
|
||||
return -1;
|
||||
printk("\n---Instruction fetch attempted from $%X, no TLB exists\n",f->EXC_SRR0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int InstructionFetchException(BSP_Exception_frame *f, unsigned int vector)
|
||||
{
|
||||
printk("\n---Instruction fetch attempted from $%X, TLB is no-execute\n",f->EXC_SRR0);
|
||||
return -1;
|
||||
printk("\n---Instruction fetch attempted from $%X, TLB is no-execute\n",f->EXC_SRR0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user