Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

447 lines
11 KiB

#ifndef __PS3_HELPERS__
#define __PS3_HELPERS__
#ifndef SN_TARGET_PS3
#error
#endif
#include <cellstatus.h>
#include <sys/paths.h>
#include <sys/prx.h>
#include <sys/synchronization.h>
#include <sys/ppu_thread.h>
#include <sys/timer.h>
#include "ppu_intrinsics.h"
#include <np.h>
#include <np/drm.h>
// Forward declarations
#ifndef _CERT
#define PS3PRXLOADDIAGNOSTIC printf
#else
#define PS3PRXLOADDIAGNOSTIC( ... ) ((void)0)
#endif
struct TLSGlobals;
// PS3 PRX load parameters structures
struct PS3_PrxLoadParametersBase_t
{
int32_t cbSize;
sys_prx_id_t sysPrxId;
uint64_t uiFlags;
uint64_t reserved[7];
};
struct PS3_PrxModuleEntry_t
{
PS3_PrxModuleEntry_t *pNextModule;
char chName[256];
uint32_t uiRefCount;
PS3_PrxLoadParametersBase_t prxParams[0];
};
extern "C" PS3_PrxModuleEntry_t ** PS3_PrxGetModulesList();
struct PS3_GcmSharedData;
// exported from tier0
extern "C" PS3_GcmSharedData *g_pGcmSharedData;
struct PS3_GcmSharedData
{
void *m_pIoMemory;
uint32_t m_nIoMemorySize;
PS3_GcmSharedData()
{
memset(this, 0, sizeof(PS3_GcmSharedData));
}
// Thread for the QMS and Server (when host_thread_mode)
// Thread wakes up on a semaphore and when it does so it checks for
// sv_runflag and then qms runFlag and does the right thing
// This is hand coded because the PS3 scheduler sometimes (regardless of priorities)
// pushes out the main thread to run the server if the server is it's own job.
// So we create a single thread, one which we have the ability to explicitly
// run the server and the qms
// The semaphore is there so that we can sleep instead of exiting the job
// Otherwise the run flags actually control if we run locklessly
// CheckForServerRequest() is called eregularly on the QMS and so allows the
// server to interrupt the QMS and run pretty much where we need to to.
//
sys_ppu_thread_t m_thread;
sys_semaphore_t m_semaphore;
// Server
volatile int m_svRunFlag;
volatile int m_svDoneFlag;
volatile int m_numTicks;
void (*m_pfnAsyncServer)(int numTicks);
// QMS
volatile int m_qmsRunFlag;
volatile int m_qmsDoneFlag;
volatile void* m_cmat;
volatile void* m_ptr;
void (*m_func)(void*, void*);
// Audio
volatile int m_audioRunFlag;
volatile int m_audioDoneFlag;
void (*m_AudioFunc)(void);
// Endframe Defrag
volatile int m_bDeFrag;
// Create semaphore & thread
void Init()
{
// Create Semaphore
sys_semaphore_attribute_t attr;
sys_semaphore_attribute_initialize(attr);
int ret = sys_semaphore_create(&m_semaphore, &attr, 0, 2); // No point in allowing > 2 posts
if(ret != CELL_OK)
{
printf("Unable to create QMS sem\n");
}
}
void RunServer(void (*pfn)(int), int numticks)
{
// Set global data
m_pfnAsyncServer = pfn;
m_numTicks = numticks;
__lwsync();
m_svRunFlag = 1;
// Post semaphore incase trhead sleeps
sys_semaphore_post(m_semaphore, 1);
}
void RunQMS(void (*func)(void* cmat, void* ptr), void* cmat, void* ptr )
{
m_func = func;
m_cmat = cmat;
m_ptr = ptr;
__lwsync();
m_qmsRunFlag = 1;
// Post semaphore incase trhead sleeps
sys_semaphore_post(m_semaphore, 1);
}
void WaitForServer()
{
while (!m_svDoneFlag) sys_timer_usleep(60);
m_svDoneFlag = 0;
}
void WaitForQMS()
{
while (!m_qmsDoneFlag) sys_timer_usleep(60);
m_qmsDoneFlag = 0;
}
void CheckForServerRequest()
{
if (m_svRunFlag)
{
m_svRunFlag = 0;
m_pfnAsyncServer(m_numTicks);
m_svDoneFlag = 1;
}
}
// Audio
void RunAudio(void (*pfn)(void))
{
// Set global data
m_AudioFunc = pfn;
__lwsync();
m_audioRunFlag = 1;
// Post semaphore incase trhead sleeps
sys_semaphore_post(m_semaphore, 1);
}
void WaitForAudio()
{
while (!m_audioDoneFlag) sys_timer_usleep(60);
m_audioDoneFlag = 0;
}
void CheckForAudioRequest()
{
if (g_pGcmSharedData->m_audioRunFlag)
{
g_pGcmSharedData->m_audioRunFlag = 0;
g_pGcmSharedData->m_AudioFunc();
g_pGcmSharedData->m_audioDoneFlag = 1;
}
}
};
class CPs3ContentPathInfo;
struct PS3_LoadTier0_Parameters_t : public PS3_PrxLoadParametersBase_t
{
typedef TLSGlobals * ( *PFNGETTLSGLOBALS )();
PFNGETTLSGLOBALS pfnGetTlsGlobals; // [IN] [ from launcher_main to tier0 ]
PS3_PrxModuleEntry_t **ppPrxModulesList; // [IN] [ from launcher_main: head of the list of loaded PRX modules ]
CPs3ContentPathInfo *pPS3PathInfo; // [IN] [ from launcher_main to tier0 ]
uint64_t fiosLaunchTime; // [IN] [ from launcher_main: the time when the launcher was launched, the baseline time ]
uint32_t nCLNumber; // [IN] [ from launcher_main to tier0: the changelist number for this image (0 if unknown) ]
void(*pfnPushMarker)( const char * pName );
void(*pfnPopMarker)();
void(*pfnSwapBufferMarker)();
// Raw SPU libSN functions
void (*snRawSPULockHandler) (void);
void (*snRawSPUUnlockHandler) (void);
void (*snRawSPUNotifyCreation) (unsigned int uID);
void (*snRawSPUNotifyDestruction) (unsigned int uID);
void (*snRawSPUNotifyElfLoad) (unsigned int uID, unsigned int uEntry, const char *pFileName);
void (*snRawSPUNotifyElfLoadNoWait) (unsigned int uID, unsigned int uEntry, const char *pFileName);
void (*snRawSPUNotifyElfLoadAbs) (unsigned int uID, unsigned int uEntry, const char *pFileName);
void (*snRawSPUNotifyElfLoadAbsNoWait) (unsigned int uID, unsigned int uEntry, const char *pFileName);
void (*snRawSPUNotifySPUStopped) (unsigned int uID);
void (*snRawSPUNotifySPUStarted) (unsigned int uID);
struct PS3_GcmSharedData *m_pGcmSharedData;
typedef void ( *PFNSHUTDOWN )();
PFNSHUTDOWN pfnTier0Shutdown; // [OUT] [ tier0 shutdown procedure to be invoked ]
};
struct PS3_LoadLauncher_Parameters_t : public PS3_PrxLoadParametersBase_t
{
typedef int ( *PFNLAUNCHERMAIN )( int argc, char **argv );
PFNLAUNCHERMAIN pfnLauncherMain; // [OUT] [ launcher entry point ]
typedef void ( *PFNSHUTDOWN )();
PFNSHUTDOWN pfnLauncherShutdown; // [OUT] [ launcher shutdown procedure to be invoked ]
};
struct PS3_LoadAppSystemInterface_Parameters_t : public PS3_PrxLoadParametersBase_t
{
typedef void* ( *PFNCREATEINTERFACE )( const char *pName, int *pReturnCode );
PFNCREATEINTERFACE pfnCreateInterface; // [OUT] [ app system module create interface entry point ]
uint64_t reserved[8];
};
inline int PS3_PrxLoad( const char *path, PS3_PrxLoadParametersBase_t *params )
{
#define NP_POOL_SIZE (128*1024)
static uint8_t np_pool[NP_POOL_SIZE];
int res;
int modres;
sys_prx_id_t id;
if ( !params )
return -1;
PS3_PrxModuleEntry_t ** ppPrxModulesList = PS3_PrxGetModulesList();
//
// Walk the loaded list
//
for ( PS3_PrxModuleEntry_t *pEntry = *ppPrxModulesList; pEntry; pEntry = pEntry->pNextModule )
{
if ( strcmp( pEntry->chName, path ) )
continue;
++ pEntry->uiRefCount;
memcpy( params, pEntry->prxParams, ( pEntry->prxParams->cbSize <= params->cbSize ) ? pEntry->prxParams->cbSize : params->cbSize );
PS3PRXLOADDIAGNOSTIC("PRX MODULE ADDREF: %s [0x%08X] (refs=%u)\n", path, params->sysPrxId, pEntry->uiRefCount);
return 0;
}
//
// Load a new instance of PRX
//
params->sysPrxId = -1;
// If sceNp wasn't already initalised then we need to un-init it after we're done here. If Steam is loaded
// after this and it finds NP is already intialised it won't like it
int npInit = sceNpInit( NP_POOL_SIZE, np_pool );
SceNpDrmKey key = { 0x2B, 0x8E, 0xD3, 0xE4, 0xDF, 0xF1, 0x43, 0xA2, 0xA5, 0xD7, 0x4D, 0x8D, 0x89, 0x29, 0xC5, 0xF4 };
sceNpDrmIsAvailable( &key, path );
id = sys_prx_load_module(path, 0, NULL);
if (id < CELL_OK)
{
PS3PRXLOADDIAGNOSTIC("sys_prx_load_module failed: %s [0x%08x]\n", path, id);
return id;
}
PS3PRXLOADDIAGNOSTIC("PRX MODULE LOADED: %s [0x%08X]\n", path, id);
if ( npInit != SCE_NP_ERROR_ALREADY_INITIALIZED )
{
sceNpTerm();
}
params->sysPrxId = id;
res = sys_prx_start_module(id, params->cbSize, params, &modres, 0, NULL);
if (res < CELL_OK)
{
PS3PRXLOADDIAGNOSTIC("sys_prx_start_module failed: %s [0x%08x]\n", path, res);
return res;
}
PS3PRXLOADDIAGNOSTIC("PRX MODULE STARTED: %s [0x%08X 0x%08X]\n", path, id, res);
//
// Add to the loaded list
//
if ( void *pvEntry = malloc( sizeof( PS3_PrxModuleEntry_t ) + params->cbSize ) )
{
PS3_PrxModuleEntry_t *pPrxEntry = ( PS3_PrxModuleEntry_t * ) pvEntry;
pPrxEntry->pNextModule = *ppPrxModulesList;
*ppPrxModulesList = pPrxEntry;
strncpy( pPrxEntry->chName, path, sizeof( pPrxEntry->chName ) );
pPrxEntry->uiRefCount = 1;
memcpy( pPrxEntry->prxParams, params, params->cbSize );
}
return modres;
}
inline int PS3_PrxUnload( sys_prx_id_t id )
{
PS3_PrxModuleEntry_t ** ppPrxModulesList = PS3_PrxGetModulesList();
//
// Walk the loaded list
//
for ( PS3_PrxModuleEntry_t *pEntry = *ppPrxModulesList, **ppFromPrevEntry = ppPrxModulesList;
pEntry; ppFromPrevEntry = &pEntry->pNextModule, pEntry = pEntry->pNextModule )
{
if ( pEntry->prxParams->sysPrxId != id )
continue;
if ( -- pEntry->uiRefCount )
{
PS3PRXLOADDIAGNOSTIC("PRX MODULE RELREF: %s [0x%08X] (refs=%u)\n", pEntry->chName, pEntry->prxParams->sysPrxId, pEntry->uiRefCount);
return 0;
}
else
{
PS3PRXLOADDIAGNOSTIC("PRX MODULE UNLOAD: %s [0x%08X]\n", pEntry->chName, pEntry->prxParams->sysPrxId, pEntry->uiRefCount);
*ppFromPrevEntry = pEntry->pNextModule;
free( pEntry );
break;
}
}
//
// Perform the system unload process
//
int modres;
int res;
res = sys_prx_stop_module(id, 0, NULL, &modres, 0, NULL);
if (res < CELL_OK)
{
PS3PRXLOADDIAGNOSTIC("sys_prx_stop_module failed: id=0x%08x, 0x%08x\n", id, res);
return res;
}
PS3PRXLOADDIAGNOSTIC("PRX MODULE STOPPED: id=0x%08x, 0x%08x\n", id, res);
res = sys_prx_unload_module(id, 0, NULL);
if (res < CELL_OK)
{
PS3PRXLOADDIAGNOSTIC("sys_prx_unload_module failed: id=0x%08X, 0x%08x\n", id, res);
return res;
}
PS3PRXLOADDIAGNOSTIC("PRX MODULE UNLOADED: id=0x%08x, 0x%08x\n", id, res);
return modres;
}
//////////////////////////////////////////////////////////////////////////
//
// DEFINITION OF BASIC APPSYSTEM PRX IMPLEMENTATION
//
//
#include "ps3_changelistver.h"
#ifndef PS3CLVERMAJOR
#define PS3CLVERMAJOR ((APPCHANGELISTVERSION / 256) % 256)
#define PS3CLVERMINOR (APPCHANGELISTVERSION % 256)
#endif
#ifdef _DEBUG
#define PS3_PRX_SYS_MODULE_INFO_FULLMACROREPLACEMENTHELPER(ps3modulename) SYS_MODULE_INFO( ps3modulename##_dbg, 0, PS3CLVERMAJOR, PS3CLVERMINOR)
#else
#define PS3_PRX_SYS_MODULE_INFO_FULLMACROREPLACEMENTHELPER(ps3modulename) SYS_MODULE_INFO( ps3modulename##_rel, 0, PS3CLVERMAJOR, PS3CLVERMINOR)
#endif
#define PS3_PRX_SYS_MODULE_START_NAME_FULLMACROREPLACEMENTHELPER(ps3modulename) _##ps3modulename##_ps3_prx_entry
#define PS3_PRX_APPSYSTEM_MODULE( ps3modulename ) \
\
PS3_PRX_SYS_MODULE_INFO_FULLMACROREPLACEMENTHELPER( ps3modulename ); \
SYS_MODULE_START( PS3_PRX_SYS_MODULE_START_NAME_FULLMACROREPLACEMENTHELPER( ps3modulename ) ); \
\
extern "C" int PS3_PRX_SYS_MODULE_START_NAME_FULLMACROREPLACEMENTHELPER( ps3modulename )( unsigned int args, void *pArg ) \
{ \
Assert( args >= sizeof( PS3_LoadAppSystemInterface_Parameters_t ) ); \
PS3_LoadAppSystemInterface_Parameters_t *pParams = reinterpret_cast< PS3_LoadAppSystemInterface_Parameters_t * >( pArg ); \
Assert( pParams->cbSize >= sizeof( PS3_LoadAppSystemInterface_Parameters_t ) ); \
pParams->pfnCreateInterface = CreateInterface; \
return SYS_PRX_RESIDENT; \
} \
//
//
// END DEFINITION OF BASIC APPSYSTEM PRX IMPLEMENTATION
//
//
//////////////////////////////////////////////////////////////////////////
#endif // __PS3_HELPERS__