diff --git a/build/libraries/fs/ARM7/src/fs_loader.c b/build/libraries/fs/ARM7/src/fs_loader.c index 3ba74a87..803384c3 100644 --- a/build/libraries/fs/ARM7/src/fs_loader.c +++ b/build/libraries/fs/ARM7/src/fs_loader.c @@ -124,8 +124,10 @@ BOOL FS_LoadBuffer( int fd, u32 offset, u32 size ) u8* dest = aesFlag ? aesBuffer : (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE; u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE; - while ( MI_GetWramBankMaster_B( count ) != MI_WRAM_ARM7 ) // wait to be ready + PXI_AcquireLoadBufferSemaphore(); // wait to be ready + if ( MI_GetWramBankMaster_B( count ) != MI_WRAM_ARM7 ) { + OS_TPanic("PROGRAM ERROR!"); } #ifdef WORKAROUND_NAND_2KB_BUG { @@ -152,7 +154,7 @@ BOOL FS_LoadBuffer( int fd, u32 offset, u32 size ) { CopyWithAes( dest, (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE, unit ); } - PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD ); + PXI_ReleaseLoadBufferSemaphore(); count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS; size -= unit; } diff --git a/build/libraries/fs/ARM9/src/fs_loader.c b/build/libraries/fs/ARM9/src/fs_loader.c index 335e8311..f5d623bc 100644 --- a/build/libraries/fs/ARM9/src/fs_loader.c +++ b/build/libraries/fs/ARM9/src/fs_loader.c @@ -179,10 +179,7 @@ BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx ) { u8* src = (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE; u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE; - if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD ) - { - return FALSE; - } + PXI_AcquireLoadBufferSemaphore(); // wait to be ready MIi_SetWramBankMaster_B( count, MI_WRAM_ARM9 ); if (ctx) { @@ -204,6 +201,7 @@ BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx ) size -= unit; dest += unit; MIi_SetWramBankMaster_B( count, MI_WRAM_ARM7 ); + PXI_ReleaseLoadBufferSemaphore(); count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS; } return TRUE; diff --git a/build/libraries/pxi/common/pxi_firm.c b/build/libraries/pxi/common/pxi_firm.c index 74f51a65..c7913ee1 100644 --- a/build/libraries/pxi/common/pxi_firm.c +++ b/build/libraries/pxi/common/pxi_firm.c @@ -24,8 +24,11 @@ typedef struct { u32 wp; u32 rp; + u8 id[PXI_FIRM_ID_MAX]; + u32 semaphore; // for fs_loader.c + u32 length; u32 current; u8 data[PXI_FIRM_STREAM_MAX]; @@ -66,6 +69,18 @@ static void PxiFirmIDCallback( PXIFifoTag tag, u32 data, BOOL err ) u32 next_wp = ( work.wp + 1 ) % PXI_FIRM_ID_MAX; (void)tag; (void)err; + + // special ID + if ( data == FIRM_PXI_ID_LOAD_BUFFER_SEMAPHORE ) + { + work.semaphore++; + if ( work.semaphore > HW_FIRM_LOAD_BUFFER_UNIT_NUMS ) + { + OS_TPanic("PROGRAM ERROR: Semaphore counter was overlow."); + } + return; + } + if ( next_wp != work.rp ) { work.wp = next_wp; @@ -93,6 +108,7 @@ void PXI_InitFIRM(void) while (!PXI_IsCallbackReady(PXI_FIFO_TAG_USER_0, PXI_PROC_ARM7)) { } + work.semaphore = 0; #endif work.rp = work.wp = work.length = 0; PXI_SetFifoRecvCallback( PXI_FIFO_TAG_USER_0, PxiFirmStreamCallback ); @@ -101,6 +117,7 @@ void PXI_InitFIRM(void) while (!PXI_IsCallbackReady(PXI_FIFO_TAG_USER_1, PXI_PROC_ARM9)) { } + work.semaphore = HW_FIRM_LOAD_BUFFER_UNIT_NUMS; #endif } @@ -220,6 +237,44 @@ FIRMPxiID PXI_RecvID( void ) } } +/*---------------------------------------------------------------------------* + Name: PXI_ReleaseLoadBufferSemaphore + + Description: Release semaphore for *_LoadBuffer + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_ReleaseLoadBufferSemaphore( void ) +{ + PXI_NotifyID( FIRM_PXI_ID_LOAD_BUFFER_SEMAPHORE ); +} + +/*---------------------------------------------------------------------------* + Name: PXI_AcquireLoadBufferSemaphore + + Description: Acquire semaphore for *_LoadBuffer + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_AcquireLoadBufferSemaphore( void ) +{ + while ( 1 ) + { + OSIntrMode enabled = OS_DisableInterrupts(); + if ( work.semaphore > 0 ) + { + work.semaphore--; + OS_RestoreInterrupts( enabled ); + return; + } + OS_RestoreInterrupts( enabled ); + } +} + /*---------------------------------------------------------------------------* Name: PXIi_SendIDByIntf diff --git a/include/firm/pxi/common/pxi_firm.h b/include/firm/pxi/common/pxi_firm.h index b6eb7687..2abcda25 100644 --- a/include/firm/pxi/common/pxi_firm.h +++ b/include/firm/pxi/common/pxi_firm.h @@ -36,7 +36,7 @@ typedef enum FIRM_PXI_ID_LOAD_HEADER = 6, // FATFS_LoadHeader FIRM_PXI_ID_LOAD_STATIC = 5, // FATFS_LoadStatic - FIRM_PXI_ID_LOAD_PIRIOD = 1, // *_LoadBuffer + FIRM_PXI_ID_LOAD_BUFFER_SEMAPHORE = 1, // *_LoadBuffer // from ARM9 FIRM_PXI_ID_INIT_MMEM = 3, // _start @@ -114,6 +114,28 @@ void PXI_NotifyID( FIRMPxiID id ); *---------------------------------------------------------------------------*/ FIRMPxiID PXI_RecvID( void ); +/*---------------------------------------------------------------------------* + Name: PXI_ReleaseLoadBufferSemaphore + + Description: Release semaphore for *_LoadBuffer + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_ReleaseLoadBufferSemaphore( void ); + +/*---------------------------------------------------------------------------* + Name: PXI_AcquireLoadBufferSemaphore + + Description: Acquire semaphore for *_LoadBuffer + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_AcquireLoadBufferSemaphore( void ); + /*---------------------------------------------------------------------------* Name: PXIi_SendIDByIntf