mmu: add an mmu_uram_size() function detecting static RAM size

This function performs a more rigorous analysis of the mapped region by
checking continuity. So far all pages mapped in userpsace have been
contiguous, so the results are identical to gint[HWURAM].

Page size is now optionnaly provided in mmu_translate() and its
subfunctions; programs that use this function need to add a second NULL
parameter.
This commit is contained in:
Lephe 2021-02-05 18:19:53 +01:00
parent bbf6401213
commit 2c9ff901d1
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
2 changed files with 43 additions and 10 deletions

View file

@ -17,8 +17,9 @@
page-aligned. page-aligned.
@virtual Virtual page address @virtual Virtual page address
@size If provided, set to the size of the page
Returns the page's physical address, or -1 if not mapped. */ Returns the page's physical address, or -1 if not mapped. */
uint32_t mmu_translate(uint32_t page); uint32_t mmu_translate(uint32_t page, uint32_t *size);
/* mmu_uram(): Get pointer to physical start of user RAM /* mmu_uram(): Get pointer to physical start of user RAM
@ -28,6 +29,13 @@ uint32_t mmu_translate(uint32_t page);
platform-dependent. */ platform-dependent. */
void *mmu_uram(void); void *mmu_uram(void);
/* mmu_uram_size(): Get size of user RAM area
Returns the size of the static memory at 0x08100000, whose address is
returned by mmu_uram(). This is typically 8k on SH3 fx-9860G, 32k on SH4
fx-9860G, and 512k on fx-CG 50. */
uint32_t mmu_uram_size(void);
//--- //---
// SH7705 TLB // SH7705 TLB
//--- //---
@ -56,7 +64,7 @@ tlb_data_t const *tlb_data(uint way, uint E);
void tlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram); void tlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram);
/* tlb_translate(): Get the physical address for a virtual page */ /* tlb_translate(): Get the physical address for a virtual page */
uint32_t tlb_translate(uint32_t page); uint32_t tlb_translate(uint32_t page, uint32_t *size);
//--- //---
// SH7305 Unified TLB // SH7305 Unified TLB
@ -84,6 +92,6 @@ utlb_data_t const *utlb_data(uint E);
void utlb_mapped_memory(uint32_t *rom, uint32_t *ram); void utlb_mapped_memory(uint32_t *rom, uint32_t *ram);
/* utlb_translate(): Get the physical address for a virtual page */ /* utlb_translate(): Get the physical address for a virtual page */
uint32_t utlb_translate(uint32_t page); uint32_t utlb_translate(uint32_t page, uint32_t *size);
#endif /* GINT_MMU */ #endif /* GINT_MMU */

View file

@ -11,16 +11,30 @@
//--- //---
/* mmu_translate(): Get the physical address for a virtual page */ /* mmu_translate(): Get the physical address for a virtual page */
uint32_t mmu_translate(uint32_t page) uint32_t mmu_translate(uint32_t page, uint32_t *size)
{ {
return isSH3() ? tlb_translate(page) : utlb_translate(page); return isSH3() ? tlb_translate(page,size) : utlb_translate(page,size);
} }
/* mmu_uram(): Get pointer to physical start of user RAM */ /* mmu_uram(): Get pointer to physical start of user RAM */
void *mmu_uram(void) void *mmu_uram(void)
{ {
/* Use P1 access */ /* Use P1 access */
return (void *)(mmu_translate(0x08100000) | 0x80000000); return (void *)(mmu_translate(0x08100000, NULL) | 0x80000000);
}
/* mmu_uram_size(): Get size of user RAM area */
uint32_t mmu_uram_size(void)
{
uint32_t size = 0;
uint32_t pagesize;
while(mmu_translate(0x08100000 + size, &pagesize) != (uint32_t)-1)
{
size += pagesize;
}
return size;
} }
//--- //---
@ -72,7 +86,7 @@ void tlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram)
} }
/* tlb_translate(): Get the physical address for a virtual page */ /* tlb_translate(): Get the physical address for a virtual page */
uint32_t tlb_translate(uint32_t page) uint32_t tlb_translate(uint32_t page, uint32_t *size)
{ {
for(int way = 0; way < 4; way++) for(int way = 0; way < 4; way++)
for(int E = 0; E < 32; E++) for(int E = 0; E < 32; E++)
@ -85,7 +99,11 @@ uint32_t tlb_translate(uint32_t page)
if(data->SZ) src = (((addr->VPN >> 2) | E) << 12); if(data->SZ) src = (((addr->VPN >> 2) | E) << 12);
else src = (addr->VPN | (E << 2)) << 10; else src = (addr->VPN | (E << 2)) << 10;
if(src == page) return data->PPN << 10; if(src == page)
{
if(size) *size = (data->SZ ? 4096 : 1024);
return data->PPN << 10;
}
} }
return -1; return -1;
} }
@ -137,7 +155,7 @@ void utlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram)
} }
/* utlb_translate(): Get the physical address for a virtual page */ /* utlb_translate(): Get the physical address for a virtual page */
uint32_t utlb_translate(uint32_t page) uint32_t utlb_translate(uint32_t page, uint32_t *size)
{ {
for(int E = 0; E < 64; E++) for(int E = 0; E < 64; E++)
{ {
@ -145,7 +163,14 @@ uint32_t utlb_translate(uint32_t page)
const utlb_data_t *data = utlb_data(E); const utlb_data_t *data = utlb_data(E);
if(!addr->V || !data->V) continue; if(!addr->V || !data->V) continue;
if((uint32_t)addr->VPN << 10 == page) return data->PPN << 10; if((uint32_t)addr->VPN << 10 == page)
{
/* Same magic formula as utlb_mapped_memory() */
int sz = ((data->SZ1 << 1) | data->SZ2) << 3;
if(size) *size = 1 << ((0x14100c0a >> sz) & 0xff);
return data->PPN << 10;
}
} }
return -1; return -1;
} }