@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
LOG_DEBUG ( HW_Memory , " Mapping %p onto %08X-%08X " , memory , base * PAGE_SIZE ,
( base + size ) * PAGE_SIZE ) ;
u32 end = base + size ;
RasterizerFlushVirtualRegion ( base < < PAGE_BITS , size * PAGE_SIZE ,
FlushMode : : FlushAndInvalidate ) ;
u32 end = base + size ;
while ( base ! = end ) {
ASSERT_MSG ( base < PAGE_TABLE_NUM_ENTRIES , " out of range mapping at %08X " , base ) ;
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
if ( current_page_table - > attributes [ base ] = = PageType : : RasterizerCachedMemory | |
current_page_table - > attributes [ base ] = = PageType : : RasterizerCachedSpecial ) {
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( base < < PAGE_BITS ) ,
PAGE_SIZE ) ;
}
current_page_table - > attributes [ base ] = type ;
current_page_table - > pointers [ base ] = memory ;
current_page_table - > cached_res_count [ base ] = 0 ;
@ -189,7 +183,7 @@ T Read(const VAddr vaddr) {
ASSERT_MSG ( false , " Mapped memory page without a pointer @ %08X " , vaddr ) ;
break ;
case PageType : : RasterizerCachedMemory : {
RasterizerFlush Region( VirtualToPhysicalAddress ( vaddr ) , sizeof ( T ) ) ;
RasterizerFlush VirtualRegion( vaddr , sizeof ( T ) , FlushMode : : Flush ) ;
T value ;
std : : memcpy ( & value , GetPointerFromVMA ( vaddr ) , sizeof ( T ) ) ;
@ -198,8 +192,7 @@ T Read(const VAddr vaddr) {
case PageType : : Special :
return ReadMMIO < T > ( GetMMIOHandler ( vaddr ) , vaddr ) ;
case PageType : : RasterizerCachedSpecial : {
RasterizerFlushRegion ( VirtualToPhysicalAddress ( vaddr ) , sizeof ( T ) ) ;
RasterizerFlushVirtualRegion ( vaddr , sizeof ( T ) , FlushMode : : Flush ) ;
return ReadMMIO < T > ( GetMMIOHandler ( vaddr ) , vaddr ) ;
}
default :
@ -229,8 +222,7 @@ void Write(const VAddr vaddr, const T data) {
ASSERT_MSG ( false , " Mapped memory page without a pointer @ %08X " , vaddr ) ;
break ;
case PageType : : RasterizerCachedMemory : {
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( vaddr ) , sizeof ( T ) ) ;
RasterizerFlushVirtualRegion ( vaddr , sizeof ( T ) , FlushMode : : FlushAndInvalidate ) ;
std : : memcpy ( GetPointerFromVMA ( vaddr ) , & data , sizeof ( T ) ) ;
break ;
}
@ -238,8 +230,7 @@ void Write(const VAddr vaddr, const T data) {
WriteMMIO < T > ( GetMMIOHandler ( vaddr ) , vaddr , data ) ;
break ;
case PageType : : RasterizerCachedSpecial : {
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( vaddr ) , sizeof ( T ) ) ;
RasterizerFlushVirtualRegion ( vaddr , sizeof ( T ) , FlushMode : : FlushAndInvalidate ) ;
WriteMMIO < T > ( GetMMIOHandler ( vaddr ) , vaddr , data ) ;
break ;
}
@ -369,11 +360,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
}
void RasterizerFlushAndInvalidateRegion ( PAddr start , u32 size ) {
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
if ( VideoCore : : g_renderer ! = nullptr ) {
VideoCore : : g_renderer - > Rasterizer ( ) - > FlushAndInvalidateRegion ( start , size ) ;
}
}
void RasterizerFlushVirtualRegion ( VAddr start , u32 size , FlushMode mode ) {
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
if ( VideoCore : : g_renderer ! = nullptr ) {
VAddr end = start + size ;
auto CheckRegion = [ & ] ( VAddr region_start , VAddr region_end ) {
if ( start > = region_end | | end < = region_start ) {
// No overlap with region
return ;
}
VAddr overlap_start = std : : max ( start , region_start ) ;
VAddr overlap_end = std : : min ( end , region_end ) ;
PAddr physical_start = TryVirtualToPhysicalAddress ( overlap_start ) . value ( ) ;
u32 overlap_size = overlap_end - overlap_start ;
auto * rasterizer = VideoCore : : g_renderer - > Rasterizer ( ) ;
switch ( mode ) {
case FlushMode : : Flush :
rasterizer - > FlushRegion ( physical_start , overlap_size ) ;
break ;
case FlushMode : : FlushAndInvalidate :
rasterizer - > FlushAndInvalidateRegion ( physical_start , overlap_size ) ;
break ;
}
} ;
CheckRegion ( LINEAR_HEAP_VADDR , LINEAR_HEAP_VADDR_END ) ;
CheckRegion ( NEW_LINEAR_HEAP_VADDR , NEW_LINEAR_HEAP_VADDR_END ) ;
CheckRegion ( VRAM_VADDR , VRAM_VADDR_END ) ;
}
}
u8 Read8 ( const VAddr addr ) {
return Read < u8 > ( addr ) ;
}
@ -420,16 +448,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
break ;
}
case PageType : : RasterizerCachedMemory : {
RasterizerFlushRegion ( VirtualToPhysicalAddress ( current_vaddr ) , copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : Flush ) ;
std : : memcpy ( dest_buffer , GetPointerFromVMA ( current_vaddr ) , copy_amount ) ;
break ;
}
case PageType : : RasterizerCachedSpecial : {
DEBUG_ASSERT ( GetMMIOHandler ( current_vaddr ) ) ;
RasterizerFlushRegion ( VirtualToPhysicalAddress ( current_vaddr ) , copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : Flush ) ;
GetMMIOHandler ( current_vaddr ) - > ReadBlock ( current_vaddr , dest_buffer , copy_amount ) ;
break ;
}
@ -490,18 +515,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
break ;
}
case PageType : : RasterizerCachedMemory : {
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( current_vaddr ) ,
copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : FlushAndInvalidate ) ;
std : : memcpy ( GetPointerFromVMA ( current_vaddr ) , src_buffer , copy_amount ) ;
break ;
}
case PageType : : RasterizerCachedSpecial : {
DEBUG_ASSERT ( GetMMIOHandler ( current_vaddr ) ) ;
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( current_vaddr ) ,
copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : FlushAndInvalidate ) ;
GetMMIOHandler ( current_vaddr ) - > WriteBlock ( current_vaddr , src_buffer , copy_amount ) ;
break ;
}
@ -547,18 +567,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
break ;
}
case PageType : : RasterizerCachedMemory : {
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( current_vaddr ) ,
copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : FlushAndInvalidate ) ;
std : : memset ( GetPointerFromVMA ( current_vaddr ) , 0 , copy_amount ) ;
break ;
}
case PageType : : RasterizerCachedSpecial : {
DEBUG_ASSERT ( GetMMIOHandler ( current_vaddr ) ) ;
RasterizerFlushAndInvalidateRegion ( VirtualToPhysicalAddress ( current_vaddr ) ,
copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : FlushAndInvalidate ) ;
GetMMIOHandler ( current_vaddr ) - > WriteBlock ( current_vaddr , zeros . data ( ) , copy_amount ) ;
break ;
}
@ -603,15 +618,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
break ;
}
case PageType : : RasterizerCachedMemory : {
RasterizerFlushRegion ( VirtualToPhysicalAddress ( current_vaddr ) , copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : Flush ) ;
WriteBlock ( dest_addr , GetPointerFromVMA ( current_vaddr ) , copy_amount ) ;
break ;
}
case PageType : : RasterizerCachedSpecial : {
DEBUG_ASSERT ( GetMMIOHandler ( current_vaddr ) ) ;
RasterizerFlushRegion ( VirtualToPhysicalAddress ( current_vaddr ) , copy_amount ) ;
RasterizerFlushVirtualRegion ( current_vaddr , copy_amount , FlushMode : : Flush ) ;
std : : vector < u8 > buffer ( copy_amount ) ;
GetMMIOHandler ( current_vaddr ) - > ReadBlock ( current_vaddr , buffer . data ( ) , buffer . size ( ) ) ;