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.
@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. */
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
@ -28,6 +29,13 @@ uint32_t mmu_translate(uint32_t page);
platform-dependent. */
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
//---
@ -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);
/* 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
@ -84,6 +92,6 @@ utlb_data_t const *utlb_data(uint E);
void utlb_mapped_memory(uint32_t *rom, uint32_t *ram);
/* 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 */

View file

@ -11,16 +11,30 @@
//---
/* 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 */
void *mmu_uram(void)
{
/* 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 */
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 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);
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;
}
@ -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 */
uint32_t utlb_translate(uint32_t page)
uint32_t utlb_translate(uint32_t page, uint32_t *size)
{
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);
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;
}