Uint64 __udivdi3(Uint64 Num, Uint64 Den)
{
return DivMod64U(Num, Den, NULL);
+ #if 0
// if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0
if( Den == 16 ) return Num >> 4;
if( Den == 256 ) return Num >> 8;
Uint64 ret = 0;
for( ret = 0; Num > Den; ret ++, Num -= Den );
return ret;
+ #endif
}
// Unsigned Modulus 64-bit Integer
Uint64 __umoddi3(Uint64 Num, Uint64 Den)
{
+ Uint64 ret = 0;
+ DivMod64U(Num, Den, &ret);
+ return ret;
+ #if 0
if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0
if( Num < Den ) return Num;
if( Den == 1 ) return 0;
#endif
for( ; Num > Den; Num -= Den );
return Num;
+ #endif
}
#define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \
* ARM7 Virtual Memory Manager
* - arch/arm7/mm_virt.c
*/
+#define DEBUG 0
#include <acess.h>
#include <mm_virt.h>
#include <hal_proc.h>
#define AP_RW_BOTH 0x3
#define AP_RO_BOTH 0x6
+// === IMPORTS ===
+extern Uint32 kernel_table0[];
+
// === TYPES ===
typedef struct
{
void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1)
{
if(VAddr & 0x80000000) {
- *Table0 = (void*)MM_TABLE0KERN; // Level 0
+ *Table0 = (void*)&kernel_table0; // Level 0
*Table1 = (void*)MM_TABLE1KERN; // Level 1
}
else {
Uint32 *table0, *table1;
Uint32 *desc;
tPAddr paddr;
+
+ ENTER("xVAddr iDomain", VAddr, Domain);
MM_int_GetTables(VAddr, &table0, &table1);
VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page
- desc = &table0[VAddr>>20];
+ desc = &table0[ VAddr>>20];
+ LOG("desc = %p", desc);
+
+ // table0: 4 bytes = 1 MiB
+
+ LOG("desc[0] = %x", desc[0]);
+ LOG("desc[1] = %x", desc[1]);
+ LOG("desc[2] = %x", desc[2]);
+ LOG("desc[3] = %x", desc[3]);
if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0
|| (desc[2] & 3) != 0 || (desc[3] & 3) != 0 )
{
// Error?
+ LEAVE('i', 1);
return 1;
}
if( !paddr )
{
// Error
+ LEAVE('i', 2);
return 2;
}
// TLBIALL
TLBIALL();
+ LEAVE('i', 0);
return 0;
}
Uint32 *table0, *table1;
Uint32 *desc;
+ ENTER("pVADdr ppi", VAddr, pi);
+
MM_int_GetTables(VAddr, &table0, &table1);
desc = &table0[ VAddr >> 20 ];
+ LOG("desc = %p", desc);
switch(pi->Size)
{
case 12: // Small Page
case 16: // Large Page
+ LOG("Page");
if( (*desc & 3) == 0 ) {
MM_int_AllocateCoarse( VAddr, pi->Domain );
}
desc = &table1[ VAddr >> 12 ];
+ LOG("desc (2) = %p", desc);
if( pi->Size == 12 )
{
// Small page
// - Error if overwriting a large page
- if( (*desc & 3) == 1 ) return 1;
+ if( (*desc & 3) == 1 ) LEAVE_RET('i', 1);
if( pi->PhysAddr == 0 ) {
*desc = 0;
+ LEAVE('i', 0);
return 0;
}
case 24: // Supersection
// Error if not aligned
if( VAddr & 0xFFFFFF ) {
+ LEAVE('i', 1);
return 1;
}
if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18))) )
if( pi->PhysAddr == 0 ) {
*desc = 0;
// TODO: Apply to all entries
+ LEAVE('i', 0);
return 0;
}
// Apply
// *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5;
*desc |= 2 | (1 << 18);
// TODO: Apply to all entries
+ LEAVE('i', 0);
return 0;
}
+ LEAVE('i', 1);
return 1;
}
+ LEAVE('i', 1);
return 1;
}
tPAddr MM_Allocate(tVAddr VAddr)
{
tMM_PageInfo pi = {0};
+
+ ENTER("pVAddr", VAddr);
pi.PhysAddr = MM_AllocPhys();
- if( pi.PhysAddr == 0 ) return 0;
+ if( pi.PhysAddr == 0 ) LEAVE_RET('i', 0);
pi.Size = 12;
pi.AP = AP_KRW_ONLY; // Kernel Read/Write
pi.bExecutable = 1;
if( MM_int_SetPageInfo(VAddr, &pi) ) {
MM_DerefPhys(pi.PhysAddr);
+ LEAVE('i', 0);
return 0;
}
+ LEAVE('x', pi.PhysAddr);
return pi.PhysAddr;
}