2020-12-05 13:08:24 +01:00
# include "stdafx.h"
2016-03-21 20:43:03 +01:00
# include "Emu/IdManager.h"
# include "Emu/Cell/PPUModule.h"
2014-08-23 22:40:04 +02:00
2018-07-27 21:07:34 +02:00
# include "Emu/Memory/vm.h"
2018-10-27 21:02:10 +02:00
# include "Emu/Cell/lv2/sys_ppu_thread.h"
2019-02-21 12:14:00 +01:00
# include "Emu/Cell/lv2/sys_rsx.h"
2020-10-30 21:26:22 +01:00
# include "Emu/RSX/RSXThread.h"
2019-02-21 12:14:00 +01:00
2014-08-01 01:52:43 +02:00
# include "cellGcmSys.h"
2018-10-11 00:17:19 +02:00
# include "sysPrxForUser.h"
2013-06-30 10:46:29 +02:00
2020-12-18 07:47:08 +01:00
# include "util/asm.hpp"
2016-05-13 15:55:34 +02:00
2018-08-25 14:39:00 +02:00
LOG_CHANNEL ( cellGcmSys ) ;
2016-03-21 20:43:03 +01:00
2020-01-16 22:31:58 +01:00
template < >
void fmt_class_string < CellGcmError > : : format ( std : : string & out , u64 arg )
{
format_enum ( out , arg , [ ] ( auto error )
{
switch ( error )
{
STR_CASE ( CELL_GCM_ERROR_FAILURE ) ;
STR_CASE ( CELL_GCM_ERROR_NO_IO_PAGE_TABLE ) ;
STR_CASE ( CELL_GCM_ERROR_INVALID_ENUM ) ;
STR_CASE ( CELL_GCM_ERROR_INVALID_VALUE ) ;
STR_CASE ( CELL_GCM_ERROR_INVALID_ALIGNMENT ) ;
STR_CASE ( CELL_GCM_ERROR_ADDRESS_OVERWRAP ) ;
}
return unknown ;
} ) ;
}
2020-12-12 11:12:39 +01:00
namespace rsx
{
u32 make_command ( vm : : bptr < u32 > & dst , u32 start_register , std : : initializer_list < any32 > values )
{
* dst + + = start_register < < 2 | static_cast < u32 > ( values . size ( ) ) < < 18 ;
for ( const any32 & cmd : values )
{
* dst + + = cmd . as < u32 > ( ) ;
}
return u32 { sizeof ( u32 ) } * ( static_cast < u32 > ( values . size ( ) ) + 1 ) ;
}
u32 make_jump ( vm : : bptr < u32 > & dst , u32 offset )
{
* dst + + = RSX_METHOD_OLD_JUMP_CMD | offset ;
return sizeof ( u32 ) ;
}
}
2017-02-22 11:10:55 +01:00
extern s32 cellGcmCallback ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > context , u32 count ) ;
2013-06-30 10:46:29 +02:00
2014-08-01 01:52:43 +02:00
const u32 tiled_pitches [ ] = {
0x00000000 , 0x00000200 , 0x00000300 , 0x00000400 ,
0x00000500 , 0x00000600 , 0x00000700 , 0x00000800 ,
0x00000A00 , 0x00000C00 , 0x00000D00 , 0x00000E00 ,
0x00001000 , 0x00001400 , 0x00001800 , 0x00001A00 ,
0x00001C00 , 0x00002000 , 0x00002800 , 0x00003000 ,
0x00003400 , 0x00003800 , 0x00004000 , 0x00005000 ,
0x00006000 , 0x00006800 , 0x00007000 , 0x00008000 ,
0x0000A000 , 0x0000C000 , 0x0000D000 , 0x0000E000 ,
0x00010000
} ;
2014-08-17 11:22:36 +02:00
// Auxiliary functions
/*
* Get usable local memory size for a specific game SDK version
* Example : For 0x00446000 ( FW 4.46 ) we get a localSize of 0x0F900000 ( 249 MB )
2018-08-13 18:15:56 +02:00
*/
2014-08-17 11:22:36 +02:00
u32 gcmGetLocalMemorySize ( u32 sdk_version )
{
2015-09-10 16:13:31 +02:00
if ( sdk_version > = 0x00220000 )
{
2014-11-15 15:45:02 +01:00
return 0x0F900000 ; // 249MB
2014-08-17 11:22:36 +02:00
}
2015-09-10 16:13:31 +02:00
if ( sdk_version > = 0x00200000 )
{
2014-11-15 15:45:02 +01:00
return 0x0F200000 ; // 242MB
2014-08-17 11:22:36 +02:00
}
2015-09-10 16:13:31 +02:00
if ( sdk_version > = 0x00190000 )
{
2014-11-15 15:45:02 +01:00
return 0x0EA00000 ; // 234MB
2014-08-17 11:22:36 +02:00
}
2015-09-10 16:13:31 +02:00
if ( sdk_version > = 0x00180000 )
{
2014-11-15 15:45:02 +01:00
return 0x0E800000 ; // 232MB
2014-08-17 11:22:36 +02:00
}
2014-11-15 15:45:02 +01:00
return 0x0E000000 ; // 224MB
2014-08-17 11:22:36 +02:00
}
2020-10-30 16:00:25 +01:00
error_code gcmMapEaIoAddress ( ppu_thread & ppu , u32 ea , u32 io , u32 size , bool is_strict ) ;
2020-01-16 22:31:58 +01:00
2020-01-16 21:40:47 +01:00
u32 gcmIoOffsetToAddress ( u32 ioOffset )
{
2021-03-02 12:59:19 +01:00
const u32 upper12Bits = g_fxo - > get < gcm_config > ( ) . offsetTable . eaAddress [ ioOffset > > 20 ] ;
2020-01-16 21:40:47 +01:00
2020-02-11 22:31:17 +01:00
if ( upper12Bits > 0xBFF )
2020-01-16 21:40:47 +01:00
{
return 0 ;
}
return ( upper12Bits < < 20 ) | ( ioOffset & 0xFFFFF ) ;
}
2014-08-25 23:17:51 +02:00
void InitOffsetTable ( )
{
2021-03-02 12:59:19 +01:00
auto & cfg = g_fxo - > get < gcm_config > ( ) ;
2014-08-25 23:17:51 +02:00
2020-02-15 17:11:16 +01:00
const u32 addr = vm : : alloc ( ( 3072 + 512 ) * sizeof ( u16 ) , vm : : main ) ;
2018-07-27 21:07:34 +02:00
2021-03-02 12:59:19 +01:00
cfg . offsetTable . ioAddress . set ( addr ) ;
cfg . offsetTable . eaAddress . set ( addr + ( 3072 * sizeof ( u16 ) ) ) ;
2020-01-16 21:40:47 +01:00
2020-02-15 17:11:16 +01:00
std : : memset ( vm : : base ( addr ) , 0xFF , ( 3072 + 512 ) * sizeof ( u16 ) ) ;
2014-08-25 23:17:51 +02:00
}
2014-03-31 02:02:27 +02:00
//----------------------------------------------------------------------------
// Data Retrieval
//----------------------------------------------------------------------------
u32 cellGcmGetLabelAddress ( u8 index )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetLabelAddress(index=%d) " , index ) ;
2022-05-11 00:00:03 +02:00
return rsx : : get_current_renderer ( ) - > label_addr + 0x10 * index ;
2014-03-31 02:02:27 +02:00
}
2014-09-02 03:05:13 +02:00
vm : : ptr < CellGcmReportData > cellGcmGetReportDataAddressLocation ( u32 index , u32 location )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetReportDataAddressLocation(index=%d, location=%d) " , index , location ) ;
2014-06-05 00:04:11 +02:00
2018-12-29 12:15:43 +01:00
if ( location = = CELL_GCM_LOCATION_MAIN )
{
if ( index > = 1024 * 1024 )
{
cellGcmSys . error ( " cellGcmGetReportDataAddressLocation: Wrong main index (%d) " , index ) ;
2014-06-05 00:04:11 +02:00
}
2018-12-29 12:15:43 +01:00
2020-01-16 21:40:47 +01:00
return vm : : cast ( gcmIoOffsetToAddress ( 0x0e000000 + index * 0x10 ) ) ;
2014-06-05 00:04:11 +02:00
}
2018-12-29 12:15:43 +01:00
// Anything else is Local
if ( index > = 2048 )
{
cellGcmSys . error ( " cellGcmGetReportDataAddressLocation: Wrong local index (%d) " , index ) ;
2014-06-05 00:04:11 +02:00
}
2022-05-11 00:00:03 +02:00
return vm : : cast ( rsx : : get_current_renderer ( ) - > label_addr + : : offset32 ( & RsxReports : : report ) + index * 0x10 ) ;
2014-03-31 02:02:27 +02:00
}
u64 cellGcmGetTimeStamp ( u32 index )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetTimeStamp(index=%d) " , index ) ;
2014-06-05 00:04:11 +02:00
2018-12-29 12:15:43 +01:00
if ( index > = 2048 )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmGetTimeStamp: Wrong local index (%d) " , index ) ;
2014-06-05 00:04:11 +02:00
}
2018-12-29 12:15:43 +01:00
2022-05-11 00:00:03 +02:00
const u32 address = rsx : : get_current_renderer ( ) - > label_addr + : : offset32 ( & RsxReports : : report ) + index * 0x10 ;
return * vm : : get_super_ptr < u64 > ( address ) ;
2014-03-31 02:02:27 +02:00
}
2017-05-15 13:30:14 +02:00
u32 cellGcmGetCurrentField ( )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmGetCurrentField() " ) ;
return 0 ;
2014-06-04 22:05:04 +02:00
}
2014-08-25 23:17:51 +02:00
u32 cellGcmGetNotifyDataAddress ( u32 index )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetNotifyDataAddress(index=%d) " , index ) ;
2014-08-25 23:17:51 +02:00
// If entry not in use, return NULL
2021-03-02 12:59:19 +01:00
u16 entry = g_fxo - > get < gcm_config > ( ) . offsetTable . eaAddress [ 241 ] ;
2014-08-25 23:17:51 +02:00
if ( entry = = 0xFFFF ) {
return 0 ;
}
2018-12-06 13:09:17 +01:00
return ( entry < < 20 ) + ( index * 0x40 ) ;
2014-08-25 23:17:51 +02:00
}
/*
* Get base address of local report data area
*/
2014-09-02 03:05:13 +02:00
vm : : ptr < CellGcmReportData > _cellGcmFunc12 ( )
2014-08-25 23:17:51 +02:00
{
2022-05-11 00:00:03 +02:00
return vm : : ptr < CellGcmReportData > : : make ( rsx : : get_current_renderer ( ) - > label_addr + : : offset32 ( & RsxReports : : report ) ) ; // TODO
2014-06-04 22:05:04 +02:00
}
2014-06-05 00:04:11 +02:00
u32 cellGcmGetReport ( u32 type , u32 index )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetReport(type=%d, index=%d) " , type , index ) ;
2014-06-05 00:04:11 +02:00
2018-12-29 12:15:43 +01:00
if ( index > = 2048 )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmGetReport: Wrong local index (%d) " , index ) ;
2014-06-05 00:04:11 +02:00
}
2014-08-25 23:17:51 +02:00
if ( type < 1 | | type > 5 ) {
return - 1 ;
2014-06-05 00:04:11 +02:00
}
2014-08-25 23:17:51 +02:00
2014-09-02 03:05:13 +02:00
vm : : ptr < CellGcmReportData > local_reports = _cellGcmFunc12 ( ) ;
2014-08-25 23:17:51 +02:00
return local_reports [ index ] . value ;
2014-06-04 22:05:04 +02:00
}
2014-06-05 00:04:11 +02:00
u32 cellGcmGetReportDataAddress ( u32 index )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . warning ( " cellGcmGetReportDataAddress(index=%d) " , index ) ;
2014-06-05 00:04:11 +02:00
2018-12-29 12:15:43 +01:00
if ( index > = 2048 )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmGetReportDataAddress: Wrong local index (%d) " , index ) ;
2014-06-05 00:04:11 +02:00
}
2018-12-29 12:15:43 +01:00
2022-05-11 00:00:03 +02:00
return rsx : : get_current_renderer ( ) - > label_addr + : : offset32 ( & RsxReports : : report ) + index * 0x10 ;
2014-06-04 22:05:04 +02:00
}
2014-06-05 00:04:11 +02:00
u32 cellGcmGetReportDataLocation ( u32 index , u32 location )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetReportDataLocation(index=%d, location=%d) " , index , location ) ;
2014-06-05 00:04:11 +02:00
2014-09-02 03:05:13 +02:00
vm : : ptr < CellGcmReportData > report = cellGcmGetReportDataAddressLocation ( index , location ) ;
2014-08-25 23:17:51 +02:00
return report - > value ;
2014-06-04 22:05:04 +02:00
}
2014-06-05 00:04:11 +02:00
u64 cellGcmGetTimeStampLocation ( u32 index , u32 location )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetTimeStampLocation(index=%d, location=%d) " , index , location ) ;
2014-06-05 00:04:11 +02:00
2020-01-16 21:40:47 +01:00
// NOTE: No error checkings
return cellGcmGetReportDataAddressLocation ( index , location ) - > timer ;
2014-06-04 22:05:04 +02:00
}
2014-03-31 02:02:27 +02:00
//----------------------------------------------------------------------------
// Command Buffer Control
//----------------------------------------------------------------------------
u32 cellGcmGetControlRegister ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetControlRegister() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . gcm_info . control_addr ;
2014-03-31 02:02:27 +02:00
}
u32 cellGcmGetDefaultCommandWordSize ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetDefaultCommandWordSize() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . gcm_info . command_size ;
2014-03-31 02:02:27 +02:00
}
u32 cellGcmGetDefaultSegmentWordSize ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetDefaultSegmentWordSize() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . gcm_info . segment_size ;
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmInitDefaultFifoMode ( s32 mode )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmInitDefaultFifoMode(mode=%d) " , mode ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetDefaultFifoSize ( u32 bufferSize , u32 segmentSize )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x) " , bufferSize , segmentSize ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
//----------------------------------------------------------------------------
// Hardware Resource Management
//----------------------------------------------------------------------------
2020-01-16 22:31:58 +01:00
error_code cellGcmBindTile ( u8 index )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmBindTile(index=%d) " , index ) ;
2014-03-31 02:02:27 +02:00
2015-10-04 00:45:26 +02:00
if ( index > = rsx : : limits : : tiles_count )
2014-03-31 02:02:27 +02:00
{
return CELL_GCM_ERROR_INVALID_VALUE ;
}
2020-04-10 22:09:13 +02:00
rsx : : get_current_renderer ( ) - > tiles [ index ] . bound = true ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmBindZcull ( u8 index , u32 offset , u32 width , u32 height , u32 cullStart , u32 zFormat , u32 aaFormat , u32 zCullDir , u32 zCullFormat , u32 sFunc , u32 sRef , u32 sMask )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . warning ( " cellGcmBindZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x) " ,
index , offset , width , height , cullStart , zFormat , aaFormat , zCullDir , zCullFormat , sFunc , sRef , sMask ) ;
2014-06-05 18:47:01 +02:00
2015-10-04 00:45:26 +02:00
if ( index > = rsx : : limits : : zculls_count )
2014-06-05 18:47:01 +02:00
{
return CELL_GCM_ERROR_INVALID_VALUE ;
}
2020-04-10 22:09:13 +02:00
rsx : : get_current_renderer ( ) - > zculls [ index ] . bound = true ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmGetConfiguration ( vm : : ptr < CellGcmConfig > config )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetConfiguration(config=*0x%x) " , config ) ;
2021-03-02 12:59:19 +01:00
* config = g_fxo - > get < gcm_config > ( ) . current_config ;
2014-03-31 02:02:27 +02:00
}
2017-05-15 13:30:14 +02:00
u32 cellGcmGetFlipStatus ( )
2014-03-31 02:02:27 +02:00
{
2018-05-10 13:50:32 +02:00
u32 status = rsx : : get_current_renderer ( ) - > flip_status ;
2014-06-05 18:47:01 +02:00
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetFlipStatus() -> %d " , status ) ;
2014-11-10 01:21:50 +01:00
return status ;
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGetFlipStatus2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2014-03-31 02:02:27 +02:00
u32 cellGcmGetTiledPitchSize ( u32 size )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetTiledPitchSize(size=%d) " , size ) ;
2014-06-05 18:47:01 +02:00
2020-12-18 08:39:54 +01:00
for ( usz i = 0 ; i < std : : size ( tiled_pitches ) - 1 ; i + + ) {
2017-07-26 04:33:32 +02:00
if ( tiled_pitches [ i ] < size & & size < = tiled_pitches [ i + 1 ] ) {
return tiled_pitches [ i + 1 ] ;
2014-08-01 01:52:43 +02:00
}
}
return 0 ;
2014-03-31 02:02:27 +02:00
}
2014-08-17 11:22:36 +02:00
void _cellGcmFunc1 ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . todo ( " _cellGcmFunc1() " ) ;
2014-08-17 11:22:36 +02:00
return ;
}
2014-09-02 03:05:13 +02:00
void _cellGcmFunc15 ( vm : : ptr < CellGcmContextData > context )
2014-08-17 11:22:36 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . todo ( " _cellGcmFunc15(context=*0x%x) " , context ) ;
2014-08-17 11:22:36 +02:00
return ;
}
2015-06-24 13:53:47 +02:00
u32 g_defaultCommandBufferBegin , g_defaultCommandBufferFragmentCount ;
2015-06-18 14:58:28 +02:00
2014-08-17 11:22:36 +02:00
// Called by cellGcmInit
2020-01-16 22:31:58 +01:00
error_code _cellGcmInitBody ( ppu_thread & ppu , vm : : pptr < CellGcmContextData > context , u32 cmdSize , u32 ioSize , u32 ioAddress )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " _cellGcmInitBody(context=**0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x) " , context , cmdSize , ioSize , ioAddress ) ;
2014-01-23 18:03:43 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2017-07-26 04:33:32 +02:00
2021-03-02 12:59:19 +01:00
gcm_cfg . current_config . ioAddress = 0 ;
gcm_cfg . current_config . localAddress = 0 ;
gcm_cfg . local_size = 0 ;
gcm_cfg . local_addr = 0 ;
2016-03-21 20:43:03 +01:00
2021-03-02 12:59:19 +01:00
//if (!gcm_cfg.local_size && !gcm_cfg.local_addr)
2014-01-17 17:56:03 +01:00
{
2021-03-02 12:59:19 +01:00
gcm_cfg . local_size = 0xf900000 ; // TODO: Get sdk_version in _cellGcmFunc15 and pass it to gcmGetLocalMemorySize
gcm_cfg . local_addr = rsx : : constants : : local_mem_base ;
vm : : falloc ( gcm_cfg . local_addr , gcm_cfg . local_size , vm : : video ) ;
2014-01-17 17:56:03 +01:00
}
2013-08-26 16:18:59 +02:00
2021-03-02 12:59:19 +01:00
cellGcmSys . warning ( " *** local memory(addr=0x%x, size=0x%x) " , gcm_cfg . local_addr , gcm_cfg . local_size ) ;
2013-12-08 01:09:16 +01:00
2014-03-03 21:45:27 +01:00
InitOffsetTable ( ) ;
2018-07-27 21:07:34 +02:00
const auto render = rsx : : get_current_renderer ( ) ;
2021-03-02 12:59:19 +01:00
if ( gcm_cfg . system_mode = = CELL_GCM_SYSTEM_MODE_IOMAP_512MB )
2014-07-05 18:02:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmInit(): 512MB io address space used " ) ;
2018-07-27 21:07:34 +02:00
render - > main_mem_size = 0x20000000 ;
2014-07-05 18:02:59 +02:00
}
else
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmInit(): 256MB io address space used " ) ;
2018-07-27 21:07:34 +02:00
render - > main_mem_size = 0x10000000 ;
2014-07-05 18:02:59 +02:00
}
2020-10-30 16:00:25 +01:00
if ( gcmMapEaIoAddress ( ppu , ioAddress , 0 , ioSize , false ) ! = CELL_OK )
2014-03-03 21:45:27 +01:00
{
return CELL_GCM_ERROR_FAILURE ;
}
2021-03-02 12:59:19 +01:00
gcm_cfg . current_config . ioSize = ioSize ;
gcm_cfg . current_config . ioAddress = ioAddress ;
gcm_cfg . current_config . localSize = gcm_cfg . local_size ;
gcm_cfg . current_config . localAddress = gcm_cfg . local_addr ;
gcm_cfg . current_config . memoryFrequency = 650000000 ;
gcm_cfg . current_config . coreFrequency = 500000000 ;
2013-08-26 16:18:59 +02:00
2015-06-18 14:58:28 +02:00
// Create contexts
2018-10-31 03:40:04 +01:00
const auto area = vm : : reserve_map ( vm : : rsx_context , 0 , 0x10000000 , 0x403 ) ;
const u32 rsx_ctxaddr = area ? area - > alloc ( 0x400000 ) : 0 ;
2020-12-09 08:47:45 +01:00
ensure ( rsx_ctxaddr ) ;
2017-07-26 04:33:32 +02:00
2015-06-18 14:58:28 +02:00
g_defaultCommandBufferBegin = ioAddress ;
g_defaultCommandBufferFragmentCount = cmdSize / ( 32 * 1024 ) ;
2021-03-02 12:59:19 +01:00
gcm_cfg . gcm_info . context_addr = rsx_ctxaddr ;
gcm_cfg . gcm_info . control_addr = rsx_ctxaddr + 0x100000 ;
gcm_cfg . gcm_info . label_addr = rsx_ctxaddr + 0x300000 ;
2016-03-21 20:43:03 +01:00
2021-03-02 12:59:19 +01:00
gcm_cfg . current_context . begin . set ( g_defaultCommandBufferBegin + 4096 ) ; // 4 kb reserved at the beginning
gcm_cfg . current_context . end . set ( g_defaultCommandBufferBegin + 32 * 1024 - 4 ) ; // 4b at the end for jump
gcm_cfg . current_context . current = gcm_cfg . current_context . begin ;
2021-05-17 13:22:27 +02:00
gcm_cfg . current_context . callback . set ( g_fxo - > get < ppu_function_manager > ( ) . func_addr ( FIND_FUNC ( cellGcmCallback ) ) ) ;
2015-02-13 15:04:03 +01:00
2021-03-02 12:59:19 +01:00
gcm_cfg . ctxt_addr = context . addr ( ) ;
gcm_cfg . gcm_buffers . set ( vm : : alloc ( sizeof ( CellGcmDisplayInfo ) * 8 , vm : : main ) ) ;
gcm_cfg . zculls_addr = vm : : alloc ( sizeof ( CellGcmZcullInfo ) * 8 , vm : : main ) ;
gcm_cfg . tiles_addr = vm : : alloc ( sizeof ( CellGcmTileInfo ) * 15 , vm : : main ) ;
2013-08-26 16:18:59 +02:00
2021-03-02 12:59:19 +01:00
vm : : _ref < CellGcmContextData > ( gcm_cfg . gcm_info . context_addr ) = gcm_cfg . current_context ;
context - > set ( gcm_cfg . gcm_info . context_addr ) ;
2017-07-26 04:33:32 +02:00
// 0x40 is to offset CellGcmControl from RsxDmaControl
2021-03-02 12:59:19 +01:00
gcm_cfg . gcm_info . control_addr + = 0x40 ;
auto & ctrl = vm : : _ref < CellGcmControl > ( gcm_cfg . gcm_info . control_addr ) ;
2015-09-18 00:41:14 +02:00
ctrl . put = 0 ;
ctrl . get = 0 ;
2018-09-19 07:32:08 +02:00
ctrl . ref = 0 ; // Set later to -1 at RSX initialization
2013-08-26 16:18:59 +02:00
2018-10-11 00:17:19 +02:00
vm : : var < u64 > _tid ;
vm : : var < char [ ] > _name = vm : : make_str ( " _gcm_intr_thread " ) ;
2019-04-11 20:03:46 +02:00
ppu_execute < & sys_ppu_thread_create > ( ppu , + _tid , 0x10000 , 0 , 1 , 0x4000 , SYS_PPU_THREAD_CREATE_INTERRUPT , + _name ) ;
2019-10-25 12:32:21 +02:00
render - > intr_thread = idm : : get < named_thread < ppu_thread > > ( static_cast < u32 > ( * _tid ) ) ;
2018-10-27 21:02:10 +02:00
render - > intr_thread - > state - = cpu_flag : : stop ;
2017-07-26 04:57:43 +02:00
render - > isHLE = true ;
2021-03-02 12:59:19 +01:00
render - > label_addr = gcm_cfg . gcm_info . label_addr ;
render - > device_addr = gcm_cfg . gcm_info . context_addr ;
render - > local_mem_size = gcm_cfg . local_size ;
render - > init ( gcm_cfg . gcm_info . control_addr - 0x40 ) ;
2013-08-26 16:18:59 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmResetFlipStatus ( )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmResetFlipStatus() " ) ;
2014-06-05 18:47:01 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_WAITING ;
2014-03-31 02:02:27 +02:00
}
2013-08-26 16:18:59 +02:00
2020-01-16 22:31:58 +01:00
error_code cellGcmResetFlipStatus2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmSetDebugOutputLevel ( s32 level )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetDebugOutputLevel(level=%d) " , level ) ;
2014-03-31 02:02:27 +02:00
switch ( level )
{
case CELL_GCM_DEBUG_LEVEL0 :
case CELL_GCM_DEBUG_LEVEL1 :
case CELL_GCM_DEBUG_LEVEL2 :
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > debug_level = level ;
2014-03-31 02:02:27 +02:00
break ;
2017-05-15 13:30:14 +02:00
default :
break ;
2014-03-31 02:02:27 +02:00
}
2013-08-26 16:18:59 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetDisplayBuffer ( u8 id , u32 offset , u32 pitch , u32 width , u32 height )
2013-08-26 16:18:59 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . trace ( " cellGcmSetDisplayBuffer(id=0x%x, offset=0x%x, pitch=%d, width=%d, height=%d) " , id , offset , width ? pitch / width : pitch , width , height ) ;
2014-06-05 18:47:01 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2017-07-26 04:33:32 +02:00
2015-09-10 16:30:14 +02:00
if ( id > 7 )
{
2017-05-15 13:30:14 +02:00
return CELL_GCM_ERROR_FAILURE ;
2014-06-04 22:05:04 +02:00
}
2013-08-26 16:18:59 +02:00
2018-05-10 13:50:32 +02:00
const auto render = rsx : : get_current_renderer ( ) ;
2016-03-21 20:43:03 +01:00
2017-07-26 04:33:32 +02:00
auto buffers = render - > display_buffers ;
2013-08-26 16:18:59 +02:00
2014-08-17 11:22:36 +02:00
buffers [ id ] . offset = offset ;
buffers [ id ] . pitch = pitch ;
buffers [ id ] . width = width ;
buffers [ id ] . height = height ;
2013-08-26 16:18:59 +02:00
2021-03-02 12:59:19 +01:00
gcm_cfg . gcm_buffers [ id ] . offset = offset ;
gcm_cfg . gcm_buffers [ id ] . pitch = pitch ;
gcm_cfg . gcm_buffers [ id ] . width = width ;
gcm_cfg . gcm_buffers [ id ] . height = height ;
2017-07-26 04:33:32 +02:00
2017-07-27 18:04:55 +02:00
if ( id + 1u > render - > display_buffers_count )
2015-09-10 16:30:14 +02:00
{
2017-07-26 04:33:32 +02:00
render - > display_buffers_count = id + 1 ;
2013-08-26 16:18:59 +02:00
}
return CELL_OK ;
}
2015-01-28 13:59:16 +01:00
void cellGcmSetFlipHandler ( vm : : ptr < void ( u32 ) > handler )
2013-08-19 01:06:11 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetFlipHandler(handler=*0x%x) " , handler ) ;
2014-06-04 22:05:04 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > flip_handler = handler ;
2013-08-19 01:06:11 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlipHandler2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmSetFlipMode ( u32 mode )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetFlipMode(mode=%d) " , mode ) ;
2014-03-31 02:02:27 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > requested_vsync . store ( mode = = CELL_GCM_DISPLAY_VSYNC ) ;
2013-08-26 16:18:59 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlipMode2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2013-08-26 16:18:59 +02:00
void cellGcmSetFlipStatus ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetFlipStatus() " ) ;
2014-03-31 02:02:27 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE ;
2013-08-26 16:18:59 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlipStatus2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
template < bool old_api = false , typename ret_type = std : : conditional_t < old_api , s32 , error_code > >
ret_type gcmSetPrepareFlip ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > ctxt , u32 id )
2014-01-14 20:03:48 +01:00
{
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2014-02-24 17:03:47 +01:00
2015-07-27 03:27:33 +02:00
if ( id > 7 )
2014-01-14 20:03:48 +01:00
{
2014-03-31 02:02:27 +02:00
return CELL_GCM_ERROR_FAILURE ;
2014-01-14 20:03:48 +01:00
}
2020-01-16 22:31:58 +01:00
if ( ! old_api & & ctxt - > current + 2 > = ctxt - > end )
2014-11-10 01:21:50 +01:00
{
2015-07-27 03:27:33 +02:00
if ( s32 res = ctxt - > callback ( ppu , ctxt , 8 /* ??? */ ) )
2014-11-08 17:58:51 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmSetPrepareFlip: callback failed (0x%08x) " , res ) ;
2020-01-16 22:31:58 +01:00
return static_cast < ret_type > ( not_an_error ( res ) ) ;
2014-11-08 17:58:51 +01:00
}
2014-01-14 20:03:48 +01:00
}
2016-04-25 12:49:12 +02:00
const u32 cmd_size = rsx : : make_command ( ctxt - > current , GCM_FLIP_COMMAND , { id } ) ;
2014-03-31 02:02:27 +02:00
2021-03-02 12:59:19 +01:00
if ( ! old_api & & ctxt . addr ( ) = = gcm_cfg . gcm_info . context_addr )
2014-01-14 20:03:48 +01:00
{
2021-03-02 12:59:19 +01:00
vm : : _ref < CellGcmControl > ( gcm_cfg . gcm_info . control_addr ) . put + = cmd_size ;
2014-01-14 20:03:48 +01:00
}
2020-01-16 22:31:58 +01:00
return static_cast < ret_type > ( not_an_error ( id ) ) ;
}
error_code cellGcmSetPrepareFlip ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > ctxt , u32 id )
{
cellGcmSys . trace ( " cellGcmSetPrepareFlip(ctxt=*0x%x, id=0x%x) " , ctxt , id ) ;
return gcmSetPrepareFlip ( ppu , ctxt , id ) ;
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlip ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > ctxt , u32 id )
2015-02-13 22:45:36 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmSetFlip(ctxt=*0x%x, id=0x%x) " , ctxt , id ) ;
2015-02-13 22:45:36 +01:00
2020-01-16 22:31:58 +01:00
if ( auto res = gcmSetPrepareFlip ( ppu , ctxt , id ) ; res < 0 )
2015-07-27 03:27:33 +02:00
{
2020-01-16 22:31:58 +01:00
return CELL_GCM_ERROR_FAILURE ;
2015-07-27 03:27:33 +02:00
}
return CELL_OK ;
2015-02-13 22:45:36 +01:00
}
2017-05-15 13:30:14 +02:00
void cellGcmSetSecondVFrequency ( u32 freq )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetSecondVFrequency(level=%d) " , freq ) ;
2014-03-31 02:02:27 +02:00
switch ( freq )
2014-01-14 20:03:48 +01:00
{
2014-03-31 02:02:27 +02:00
case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ :
2016-03-21 20:43:03 +01:00
break ;
2014-03-31 02:02:27 +02:00
case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT :
2016-03-21 20:43:03 +01:00
cellGcmSys . todo ( " Unimplemented display frequency: Scanout " ) ;
break ;
2014-03-31 02:02:27 +02:00
case CELL_GCM_DISPLAY_FREQUENCY_DISABLE :
2016-03-21 20:43:03 +01:00
cellGcmSys . todo ( " Unimplemented display frequency: Disabled " ) ;
break ;
2017-05-15 13:30:14 +02:00
default :
cellGcmSys . error ( " Improper display frequency specified! " ) ;
break ;
2014-03-31 02:02:27 +02:00
}
2014-01-14 20:03:48 +01:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetTileInfo ( u8 index , u8 location , u32 offset , u32 size , u32 pitch , u8 comp , u16 base , u8 bank )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d) " ,
2013-08-26 16:18:59 +02:00
index , location , offset , size , pitch , comp , base , bank ) ;
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2017-07-26 04:33:32 +02:00
2015-10-25 15:27:04 +01:00
if ( index > = rsx : : limits : : tiles_count | | base > = 2048 | | bank > = 4 )
2013-08-26 16:18:59 +02:00
{
return CELL_GCM_ERROR_INVALID_VALUE ;
}
2017-09-02 13:43:44 +02:00
if ( offset & 0xffff | | size & 0xffff | | pitch & 0xff )
2013-08-26 16:18:59 +02:00
{
return CELL_GCM_ERROR_INVALID_ALIGNMENT ;
}
2014-03-31 02:02:27 +02:00
if ( location > = 2 | | ( comp ! = 0 & & ( comp < 7 | | comp > 12 ) ) )
2013-08-26 16:18:59 +02:00
{
return CELL_GCM_ERROR_INVALID_ENUM ;
}
2014-03-31 02:02:27 +02:00
if ( comp )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmSetTileInfo: bad compression mode! (%d) " , comp ) ;
2013-08-26 16:18:59 +02:00
}
2018-05-10 13:50:32 +02:00
const auto render = rsx : : get_current_renderer ( ) ;
2016-03-21 20:43:03 +01:00
auto & tile = render - > tiles [ index ] ;
2015-10-04 00:45:26 +02:00
tile . location = location ;
tile . offset = offset ;
tile . size = size ;
tile . pitch = pitch ;
tile . comp = comp ;
tile . base = base ;
tile . bank = bank ;
2013-08-26 16:18:59 +02:00
2021-03-02 12:59:19 +01:00
vm : : _ptr < CellGcmTileInfo > ( gcm_cfg . tiles_addr ) [ index ] = tile . pack ( ) ;
2013-08-26 16:18:59 +02:00
return CELL_OK ;
}
2015-01-28 13:59:16 +01:00
void cellGcmSetUserHandler ( vm : : ptr < void ( u32 ) > handler )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetUserHandler(handler=*0x%x) " , handler ) ;
2014-06-28 03:19:44 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > user_handler = handler ;
2014-03-31 02:02:27 +02:00
}
2013-08-26 16:18:59 +02:00
2017-05-15 13:30:14 +02:00
void cellGcmSetUserCommand ( vm : : ptr < CellGcmContextData > ctxt , u32 cause )
2015-08-03 00:00:00 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetUserCommand(ctxt=*0x%x, cause=0x%x) " , ctxt , cause ) ;
2015-08-03 00:00:00 +02:00
}
2015-01-28 13:59:16 +01:00
void cellGcmSetVBlankHandler ( vm : : ptr < void ( u32 ) > handler )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetVBlankHandler(handler=*0x%x) " , handler ) ;
2014-06-28 03:19:44 +02:00
2018-05-10 13:50:32 +02:00
rsx : : get_current_renderer ( ) - > vblank_handler = handler ;
2014-03-31 02:02:27 +02:00
}
2013-08-26 16:18:59 +02:00
2017-05-15 13:30:14 +02:00
void cellGcmSetWaitFlip ( vm : : ptr < CellGcmContextData > ctxt )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . warning ( " cellGcmSetWaitFlip(ctxt=*0x%x) " , ctxt ) ;
2015-07-27 03:27:33 +02:00
// TODO: emit RSX command for "wait flip" operation
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetWaitFlipUnsafe ( )
2015-08-03 00:00:00 +02:00
{
2017-05-16 01:33:37 +02:00
cellGcmSys . todo ( " cellGcmSetWaitFlipUnsafe() " ) ;
2017-07-26 04:33:32 +02:00
2017-05-16 01:33:37 +02:00
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2017-05-15 13:30:14 +02:00
void cellGcmSetZcull ( u8 index , u32 offset , u32 width , u32 height , u32 cullStart , u32 zFormat , u32 aaFormat , u32 zCullDir , u32 zCullFormat , u32 sFunc , u32 sRef , u32 sMask )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . todo ( " cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x) " ,
2014-03-31 02:02:27 +02:00
index , offset , width , height , cullStart , zFormat , aaFormat , zCullDir , zCullFormat , sFunc , sRef , sMask ) ;
2013-08-26 16:18:59 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2017-07-26 04:33:32 +02:00
2015-10-04 00:45:26 +02:00
if ( index > = rsx : : limits : : zculls_count )
2014-06-05 18:47:01 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmSetZcull: CELL_GCM_ERROR_INVALID_VALUE " ) ;
2017-05-15 13:30:14 +02:00
return ;
2014-06-05 18:47:01 +02:00
}
2018-05-10 13:50:32 +02:00
const auto render = rsx : : get_current_renderer ( ) ;
2016-03-21 20:43:03 +01:00
auto & zcull = render - > zculls [ index ] ;
2015-10-04 00:45:26 +02:00
zcull . offset = offset ;
2017-07-26 04:33:32 +02:00
zcull . width = width ;
2015-10-04 00:45:26 +02:00
zcull . height = height ;
zcull . cullStart = cullStart ;
zcull . zFormat = zFormat ;
zcull . aaFormat = aaFormat ;
zcull . zcullDir = zCullDir ;
zcull . zcullFormat = zCullFormat ;
zcull . sFunc = sFunc ;
zcull . sRef = sRef ;
zcull . sMask = sMask ;
2020-04-10 22:09:13 +02:00
zcull . bound = ( zCullFormat > 0 ) ;
2015-10-04 00:45:26 +02:00
2021-03-02 12:59:19 +01:00
vm : : _ptr < CellGcmZcullInfo > ( gcm_cfg . zculls_addr ) [ index ] = zcull . pack ( ) ;
2013-08-26 16:18:59 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmUnbindTile ( u8 index )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmUnbindTile(index=%d) " , index ) ;
2013-08-26 16:18:59 +02:00
2015-10-04 00:45:26 +02:00
if ( index > = rsx : : limits : : tiles_count )
2013-08-26 16:18:59 +02:00
{
return CELL_GCM_ERROR_INVALID_VALUE ;
}
2020-04-10 22:09:13 +02:00
rsx : : get_current_renderer ( ) - > tiles [ index ] . bound = false ;
2013-08-26 16:18:59 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmUnbindZcull ( u8 index )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmUnbindZcull(index=%d) " , index ) ;
2014-06-04 22:05:04 +02:00
2014-03-31 02:02:27 +02:00
if ( index > = 8 )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
return CELL_GCM_ERROR_INVALID_VALUE ;
2014-06-04 22:05:04 +02:00
}
2014-03-31 02:02:27 +02:00
2020-04-10 22:09:13 +02:00
rsx : : get_current_renderer ( ) - > zculls [ index ] . bound = false ;
2014-06-05 18:47:01 +02:00
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2013-08-26 16:18:59 +02:00
u32 cellGcmGetTileInfo ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetTileInfo() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . tiles_addr ;
2013-08-26 16:18:59 +02:00
}
2014-03-31 02:02:27 +02:00
u32 cellGcmGetZcullInfo ( )
2013-08-26 16:18:59 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetZcullInfo() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . zculls_addr ;
2013-08-26 16:18:59 +02:00
}
2014-03-31 02:02:27 +02:00
u32 cellGcmGetDisplayInfo ( )
2013-08-26 16:18:59 +02:00
{
2016-03-21 20:43:03 +01:00
cellGcmSys . warning ( " cellGcmGetDisplayInfo() " ) ;
2021-03-02 12:59:19 +01:00
return g_fxo - > get < gcm_config > ( ) . gcm_buffers . addr ( ) ;
2013-08-26 16:18:59 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGetCurrentDisplayBufferId ( vm : : ptr < u8 > id )
2013-11-25 12:49:55 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmGetCurrentDisplayBufferId(id=*0x%x) " , id ) ;
2013-11-25 12:49:55 +01:00
2021-05-22 20:46:10 +02:00
* id = : : narrow < u8 > ( rsx : : get_current_renderer ( ) - > current_display_buffer ) ;
2015-07-11 01:38:40 +02:00
2013-12-07 23:52:41 +01:00
return CELL_OK ;
2013-11-25 12:49:55 +01:00
}
2017-05-15 13:30:14 +02:00
void cellGcmSetInvalidateTile ( u8 index )
2014-06-05 18:47:01 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetInvalidateTile(index=%d) " , index ) ;
2014-06-05 18:47:01 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmTerminate ( )
2015-08-03 00:00:00 +02:00
{
2018-05-25 05:52:10 +02:00
// The firmware just return CELL_OK as well
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmDumpGraphicsError ( )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmDumpGraphicsError() " ) ;
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
s32 cellGcmGetDisplayBufferByFlipIndex ( u32 qid )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmGetDisplayBufferByFlipIndex(qid=%d) " , qid ) ;
2020-01-16 22:31:58 +01:00
return - 1 ; // Invalid id, todo
2014-06-04 22:05:04 +02:00
}
2014-06-29 05:21:57 +02:00
u64 cellGcmGetLastFlipTime ( )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetLastFlipTime() " ) ;
2014-06-29 05:21:57 +02:00
2022-04-13 21:29:26 +02:00
return rsx : : get_current_renderer ( ) - > last_guest_flip_timestamp ;
2014-06-04 22:05:04 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGetLastFlipTime2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2015-09-13 09:26:01 +02:00
u64 cellGcmGetLastSecondVTime ( )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . todo ( " cellGcmGetLastSecondVTime() " ) ;
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2014-06-28 03:19:44 +02:00
u64 cellGcmGetVBlankCount ( )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetVBlankCount() " ) ;
2014-06-28 03:19:44 +02:00
2018-05-10 13:50:32 +02:00
return rsx : : get_current_renderer ( ) - > vblank_count ;
2014-06-04 22:05:04 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGetVBlankCount2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSysGetLastVBlankTime ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " cellGcmSysGetLastVBlankTime() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmInitSystemMode ( u64 mode )
2014-06-04 22:05:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmInitSystemMode(mode=0x%x) " , mode ) ;
2014-07-05 18:02:59 +02:00
2021-03-02 12:59:19 +01:00
g_fxo - > get < gcm_config > ( ) . system_mode = mode ;
2014-07-05 18:02:59 +02:00
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlipImmediate ( u8 id )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetFlipImmediate(id=0x%x) " , id ) ;
2014-08-13 16:00:37 +02:00
if ( id > 7 )
{
return CELL_GCM_ERROR_FAILURE ;
}
cellGcmSetFlipMode ( id ) ;
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetFlipImmediate2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmSetGraphicsHandler ( vm : : ptr < void ( u32 ) > handler )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetGraphicsHandler(handler=*0x%x) " , handler ) ;
2014-06-04 22:05:04 +02:00
}
2017-05-15 13:30:14 +02:00
void cellGcmSetQueueHandler ( vm : : ptr < void ( u32 ) > handler )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetQueueHandler(handler=*0x%x) " , handler ) ;
2014-06-04 22:05:04 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetSecondVHandler ( vm : : ptr < void ( u32 ) > handler )
2014-06-04 22:05:04 +02:00
{
2017-03-22 11:09:10 +01:00
cellGcmSys . todo ( " cellGcmSetSecondVHandler(handler=0x%x) " , handler ) ;
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
void cellGcmSetVBlankFrequency ( u32 freq )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetVBlankFrequency(freq=%d) " , freq ) ;
2014-06-04 22:05:04 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSortRemapEaIoAddress ( )
2014-06-04 22:05:04 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSortRemapEaIoAddress() " ) ;
2014-06-04 22:05:04 +02:00
return CELL_OK ;
}
2014-03-31 02:02:27 +02:00
//----------------------------------------------------------------------------
// Memory Mapping
//----------------------------------------------------------------------------
2020-01-16 22:31:58 +01:00
error_code cellGcmAddressToOffset ( u32 address , vm : : ptr < u32 > offset )
2014-01-17 17:56:03 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmAddressToOffset(address=0x%x, offset=*0x%x) " , address , offset ) ;
2014-01-17 17:56:03 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2014-01-17 17:56:03 +01:00
2014-01-21 19:08:33 +01:00
u32 result ;
2020-02-15 07:56:57 +01:00
// Test if address is within local memory
2021-03-02 12:59:19 +01:00
if ( const u32 offs = address - gcm_cfg . local_addr ; offs < gcm_cfg . local_size )
2015-02-13 22:45:36 +01:00
{
2020-02-15 07:56:57 +01:00
result = offs ;
2014-01-17 17:56:03 +01:00
}
2018-08-13 18:15:56 +02:00
// Address in main memory else check
2014-01-17 17:56:03 +01:00
else
{
2021-03-02 12:59:19 +01:00
const u32 upper12Bits = gcm_cfg . offsetTable . ioAddress [ address > > 20 ] ;
2014-01-17 17:56:03 +01:00
2014-08-26 01:45:15 +02:00
// If the address is mapped in IO
2020-02-15 07:56:57 +01:00
if ( upper12Bits < < 20 < rsx : : get_current_renderer ( ) - > main_mem_size )
2015-02-13 22:45:36 +01:00
{
result = ( upper12Bits < < 20 ) | ( address & 0xFFFFF ) ;
2014-01-21 19:08:33 +01:00
}
2015-02-13 22:45:36 +01:00
else
{
2014-01-21 19:08:33 +01:00
return CELL_GCM_ERROR_FAILURE ;
}
}
2014-01-17 17:56:03 +01:00
2014-09-01 02:51:48 +02:00
* offset = result ;
2014-01-17 17:56:03 +01:00
return CELL_OK ;
}
2014-08-01 01:52:43 +02:00
u32 cellGcmGetMaxIoMapSize ( )
2014-01-17 17:56:03 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetMaxIoMapSize() " ) ;
2014-08-06 00:19:33 +02:00
2021-03-02 12:59:19 +01:00
return rsx : : get_current_renderer ( ) - > main_mem_size - g_fxo - > get < gcm_config > ( ) . reserved_size ;
2014-01-17 17:56:03 +01:00
}
2014-09-02 03:05:13 +02:00
void cellGcmGetOffsetTable ( vm : : ptr < CellGcmOffsetTable > table )
2014-01-17 17:56:03 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmGetOffsetTable(table=*0x%x) " , table ) ;
2014-08-06 00:19:33 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2020-01-16 21:40:47 +01:00
2021-03-02 12:59:19 +01:00
table - > ioAddress = gcm_cfg . offsetTable . ioAddress ;
table - > eaAddress = gcm_cfg . offsetTable . eaAddress ;
2014-01-17 17:56:03 +01:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmIoOffsetToAddress ( u32 ioOffset , vm : : ptr < u32 > address )
2014-01-17 17:56:03 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmIoOffsetToAddress(ioOffset=0x%x, address=*0x%x) " , ioOffset , address ) ;
2014-08-06 00:19:33 +02:00
2020-01-16 21:40:47 +01:00
const u32 addr = gcmIoOffsetToAddress ( ioOffset ) ;
2014-01-17 17:56:03 +01:00
2020-01-16 21:40:47 +01:00
if ( ! addr )
2018-05-22 20:16:22 +02:00
{
2014-01-17 17:56:03 +01:00
return CELL_GCM_ERROR_FAILURE ;
2018-05-22 20:16:22 +02:00
}
2014-01-17 17:56:03 +01:00
2020-01-16 21:40:47 +01:00
* address = addr ;
2014-01-17 17:56:03 +01:00
return CELL_OK ;
}
2020-10-30 16:00:25 +01:00
error_code gcmMapEaIoAddress ( ppu_thread & ppu , u32 ea , u32 io , u32 size , bool is_strict )
2014-01-18 22:36:22 +01:00
{
2019-02-21 12:14:00 +01:00
if ( ! size | | ( ea & 0xFFFFF ) | | ( io & 0xFFFFF ) | | ( size & 0xFFFFF ) )
{
return CELL_GCM_ERROR_FAILURE ;
}
2020-10-30 16:00:25 +01:00
if ( auto error = sys_rsx_context_iomap ( ppu , 0x55555555 , io , ea , size , 0xe000000000000800ull | ( u64 { is_strict } < < 60 ) ) )
2014-01-18 22:36:22 +01:00
{
2019-02-21 12:14:00 +01:00
return error ;
2014-01-18 22:36:22 +01:00
}
2018-07-27 21:07:34 +02:00
2020-01-16 21:40:47 +01:00
// Assume lock is acquired
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2019-02-21 12:14:00 +01:00
ea > > = 20 , io > > = 20 , size > > = 20 ;
2018-07-27 21:07:34 +02:00
2019-02-21 12:14:00 +01:00
// Fill the offset table
2018-07-27 21:07:34 +02:00
for ( u32 i = 0 ; i < size ; i + + )
2014-01-18 22:36:22 +01:00
{
2021-03-02 12:59:19 +01:00
gcm_cfg . offsetTable . ioAddress [ ea + i ] = io + i ;
gcm_cfg . offsetTable . eaAddress [ io + i ] = ea + i ;
2014-01-18 22:36:22 +01:00
}
2021-03-02 12:59:19 +01:00
gcm_cfg . IoMapTable [ ea ] = size ;
2014-01-18 22:36:22 +01:00
return CELL_OK ;
}
2020-10-30 16:00:25 +01:00
error_code cellGcmMapEaIoAddress ( ppu_thread & ppu , u32 ea , u32 io , u32 size )
2014-10-09 23:26:04 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x) " , ea , io , size ) ;
2014-10-09 23:26:04 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2020-10-30 16:00:25 +01:00
return gcmMapEaIoAddress ( ppu , ea , io , size , false ) ;
2014-10-09 23:26:04 +02:00
}
2020-10-30 16:00:25 +01:00
error_code cellGcmMapEaIoAddressWithFlags ( ppu_thread & ppu , u32 ea , u32 io , u32 size , u32 flags )
2014-03-03 21:45:27 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x) " , ea , io , size , flags ) ;
2014-10-09 23:26:04 +02:00
2020-12-09 08:47:45 +01:00
ensure ( flags = = 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/ ) ;
2014-10-09 23:26:04 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2020-10-30 16:00:25 +01:00
return gcmMapEaIoAddress ( ppu , ea , io , size , true ) ;
2014-03-03 21:45:27 +01:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmMapLocalMemory ( vm : : ptr < u32 > address , vm : : ptr < u32 > size )
2014-01-17 17:56:03 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmMapLocalMemory(address=*0x%x, size=*0x%x) " , address , size ) ;
2014-08-06 00:19:33 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2021-03-02 12:59:19 +01:00
if ( ! gcm_cfg . local_addr & & ! gcm_cfg . local_size & & vm : : falloc ( gcm_cfg . local_addr = rsx : : constants : : local_mem_base , gcm_cfg . local_size = 0xf900000 /* TODO */ , vm : : video ) )
2014-01-17 17:56:03 +01:00
{
2021-03-02 12:59:19 +01:00
* address = gcm_cfg . local_addr ;
* size = gcm_cfg . local_size ;
2020-01-16 21:40:47 +01:00
return CELL_OK ;
2014-01-17 17:56:03 +01:00
}
2020-01-16 21:40:47 +01:00
return CELL_GCM_ERROR_FAILURE ;
2014-01-17 17:56:03 +01:00
}
2020-10-30 16:00:25 +01:00
error_code cellGcmMapMainMemory ( ppu_thread & ppu , u32 ea , u32 size , vm : : ptr < u32 > offset )
2014-01-21 19:08:33 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmMapMainMemory(ea=0x%x, size=0x%x, offset=*0x%x) " , ea , size , offset ) ;
2014-01-21 19:08:33 +01:00
2018-05-19 14:46:29 +02:00
if ( ! size | | ( ea & 0xFFFFF ) | | ( size & 0xFFFFF ) ) return CELL_GCM_ERROR_FAILURE ;
2014-01-21 19:08:33 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2018-05-27 12:48:21 +02:00
// Use the offset table to find the next free io address
2021-03-02 12:59:19 +01:00
for ( u32 io = 0 , end = ( rsx : : get_current_renderer ( ) - > main_mem_size - gcm_cfg . reserved_size ) > > 20 , unmap_count = 1 ; io < end ; unmap_count + + )
2018-05-27 12:48:21 +02:00
{
2021-03-02 12:59:19 +01:00
if ( gcm_cfg . offsetTable . eaAddress [ io + unmap_count - 1 ] > 0xBFF )
2018-05-27 12:48:21 +02:00
{
if ( unmap_count > = ( size > > 20 ) )
{
2020-01-31 14:59:44 +01:00
io < < = 20 ;
2020-10-30 16:00:25 +01:00
if ( auto error = gcmMapEaIoAddress ( ppu , ea , io , size , false ) )
2019-02-21 12:14:00 +01:00
{
return error ;
}
2014-10-04 16:43:46 +02:00
2020-01-31 14:59:44 +01:00
* offset = io ;
2018-05-27 12:48:21 +02:00
return CELL_OK ;
}
}
else
2014-01-21 19:08:33 +01:00
{
2018-05-27 12:48:21 +02:00
io + = unmap_count ;
unmap_count = 0 ;
2014-01-21 19:08:33 +01:00
}
}
2018-05-27 12:48:21 +02:00
return CELL_GCM_ERROR_NO_IO_PAGE_TABLE ;
2014-01-21 19:08:33 +01:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmReserveIoMapSize ( u32 size )
2014-01-21 20:10:44 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmReserveIoMapSize(size=0x%x) " , size ) ;
2014-08-06 00:19:33 +02:00
2014-03-31 02:02:27 +02:00
if ( size & 0xFFFFF )
2014-06-04 22:05:04 +02:00
{
2014-01-21 20:10:44 +01:00
return CELL_GCM_ERROR_INVALID_ALIGNMENT ;
2014-06-04 22:05:04 +02:00
}
2014-01-21 20:10:44 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2014-03-31 02:02:27 +02:00
if ( size > cellGcmGetMaxIoMapSize ( ) )
2014-06-04 22:05:04 +02:00
{
2014-01-21 20:10:44 +01:00
return CELL_GCM_ERROR_INVALID_VALUE ;
2014-06-04 22:05:04 +02:00
}
2014-01-21 20:10:44 +01:00
2021-03-02 12:59:19 +01:00
gcm_cfg . reserved_size + = size ;
2014-01-21 20:10:44 +01:00
return CELL_OK ;
}
2021-03-02 12:59:19 +01:00
error_code GcmUnmapIoAddress ( ppu_thread & ppu , gcm_config & gcm_cfg , u32 io )
2014-01-21 20:10:44 +01:00
{
2021-03-02 12:59:19 +01:00
if ( u32 ea = gcm_cfg . offsetTable . eaAddress [ io > > = 20 ] , size = gcm_cfg . IoMapTable [ ea ] ; size )
2014-01-21 20:10:44 +01:00
{
2020-12-07 18:10:34 +01:00
if ( auto error = sys_rsx_context_iounmap ( ppu , 0x55555555 , io < < 20 , size < < 20 ) )
2020-01-16 21:40:47 +01:00
{
return error ;
}
2018-07-27 21:07:34 +02:00
for ( u32 i = 0 ; i < size ; i + + )
2014-01-21 20:10:44 +01:00
{
2021-03-02 12:59:19 +01:00
gcm_cfg . offsetTable . ioAddress [ ea + i ] = 0xFFFF ;
gcm_cfg . offsetTable . eaAddress [ io + i ] = 0xFFFF ;
2014-01-21 20:10:44 +01:00
}
2019-06-29 17:48:42 +02:00
2021-03-02 12:59:19 +01:00
gcm_cfg . IoMapTable [ ea ] = 0 ;
2020-01-16 21:40:47 +01:00
return CELL_OK ;
2014-01-21 20:10:44 +01:00
}
2020-01-16 21:40:47 +01:00
return CELL_GCM_ERROR_FAILURE ;
2014-01-21 20:10:44 +01:00
}
2020-10-30 16:00:25 +01:00
error_code cellGcmUnmapEaIoAddress ( ppu_thread & ppu , u32 ea )
2014-01-21 20:10:44 +01:00
{
2020-02-15 13:25:57 +01:00
cellGcmSys . warning ( " cellGcmUnmapEaIoAddress(ea=0x%x) " , ea ) ;
2014-08-06 00:19:33 +02:00
2020-02-15 13:25:57 +01:00
// Ignores lower bits
ea > > = 20 ;
2020-01-16 21:40:47 +01:00
2020-02-15 13:25:57 +01:00
if ( ea > 0xBFF )
2014-01-21 20:10:44 +01:00
{
2020-02-15 13:25:57 +01:00
return CELL_GCM_ERROR_FAILURE ;
}
2014-01-21 20:10:44 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2019-06-29 17:48:42 +02:00
2021-03-02 12:59:19 +01:00
if ( const u32 io = gcm_cfg . offsetTable . ioAddress [ ea ] < < 20 ;
2020-02-15 13:25:57 +01:00
io < rsx : : get_current_renderer ( ) - > main_mem_size )
{
2021-03-02 12:59:19 +01:00
return GcmUnmapIoAddress ( ppu , gcm_cfg , io ) ;
2014-01-21 20:10:44 +01:00
}
2020-01-16 21:40:47 +01:00
return CELL_GCM_ERROR_FAILURE ;
2014-01-21 20:10:44 +01:00
}
2020-10-30 16:00:25 +01:00
error_code cellGcmUnmapIoAddress ( ppu_thread & ppu , u32 io )
2020-02-15 13:25:57 +01:00
{
cellGcmSys . warning ( " cellGcmUnmapIoAddress(io=0x%x) " , io ) ;
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-02-15 13:25:57 +01:00
2021-03-02 12:59:19 +01:00
return GcmUnmapIoAddress ( ppu , gcm_cfg , io ) ;
2020-02-15 13:25:57 +01:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmUnreserveIoMapSize ( u32 size )
2014-01-21 20:10:44 +01:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmUnreserveIoMapSize(size=0x%x) " , size ) ;
2014-06-04 22:05:04 +02:00
2014-03-31 02:02:27 +02:00
if ( size & 0xFFFFF )
2014-06-04 22:05:04 +02:00
{
2014-01-21 20:10:44 +01:00
return CELL_GCM_ERROR_INVALID_ALIGNMENT ;
2014-06-04 22:05:04 +02:00
}
2014-01-21 20:10:44 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
std : : lock_guard lock ( gcm_cfg . gcmio_mutex ) ;
2020-01-16 21:40:47 +01:00
2021-03-02 12:59:19 +01:00
if ( size > gcm_cfg . reserved_size )
2014-06-04 22:05:04 +02:00
{
2014-01-21 20:10:44 +01:00
return CELL_GCM_ERROR_INVALID_VALUE ;
2014-06-04 22:05:04 +02:00
}
2014-01-21 20:10:44 +01:00
2021-03-02 12:59:19 +01:00
gcm_cfg . reserved_size - = size ;
2014-01-21 20:10:44 +01:00
return CELL_OK ;
}
2014-03-31 02:25:55 +02:00
//----------------------------------------------------------------------------
2017-05-15 13:30:14 +02:00
// Cursor Functions
2014-03-31 02:25:55 +02:00
//----------------------------------------------------------------------------
2014-03-31 02:02:27 +02:00
2020-01-16 22:31:58 +01:00
error_code cellGcmInitCursor ( )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmInitCursor() " ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetCursorPosition ( s32 x , s32 y )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetCursorPosition(x=%d, y=%d) " , x , y ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetCursorDisable ( )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetCursorDisable() " ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmUpdateCursor ( )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmUpdateCursor() " ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetCursorEnable ( )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetCursorEnable() " ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetCursorImageOffset ( u32 offset )
2014-03-31 02:02:27 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmSetCursorImageOffset(offset=0x%x) " , offset ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
//------------------------------------------------------------------------
// Functions for Maintaining Compatibility
//------------------------------------------------------------------------
void cellGcmSetDefaultCommandBuffer ( )
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetDefaultCommandBuffer() " ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
vm : : write32 ( gcm_cfg . ctxt_addr , gcm_cfg . gcm_info . context_addr ) ;
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetDefaultCommandBufferAndSegmentWordSize ( u32 bufferSize , u32 segmentSize )
2015-08-03 00:00:00 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . warning ( " cellGcmSetDefaultCommandBufferAndSegmentWordSize(bufferSize=0x%x, segmentSize=0x%x) " , bufferSize , segmentSize ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
const auto & put = vm : : _ref < CellGcmControl > ( gcm_cfg . gcm_info . control_addr ) . put ;
const auto & get = vm : : _ref < CellGcmControl > ( gcm_cfg . gcm_info . control_addr ) . get ;
2017-02-04 15:18:37 +01:00
2017-09-02 13:43:44 +02:00
if ( put ! = 0x1000 | | get ! = 0x1000 | | bufferSize < segmentSize * 2 | | segmentSize > = 0x80000000 )
2017-02-04 15:18:37 +01:00
{
return CELL_GCM_ERROR_FAILURE ;
}
2021-03-02 12:59:19 +01:00
gcm_cfg . gcm_info . command_size = bufferSize ;
gcm_cfg . gcm_info . segment_size = segmentSize ;
2017-02-04 15:18:37 +01:00
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2014-03-31 02:02:27 +02:00
//------------------------------------------------------------------------
// Other
//------------------------------------------------------------------------
2020-01-16 22:31:58 +01:00
void _cellGcmSetFlipCommand ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > ctx , u32 id )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmSetFlipCommand(ctx=*0x%x, id=0x%x) " , ctx , id ) ;
2014-08-06 00:19:33 +02:00
2020-01-16 22:31:58 +01:00
if ( auto error = gcmSetPrepareFlip < true > ( ppu , ctx , id ) ; error < 0 )
{
// TODO: On actual fw this function doesn't have error checks at all
cellGcmSys . error ( " cellGcmSetFlipCommand(): gcmSetPrepareFlip failed with %s " , CellGcmError { error + 0u } ) ;
}
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmSetFlipCommand2 ( )
2019-04-05 20:14:01 +02:00
{
UNIMPLEMENTED_FUNC ( cellGcmSys ) ;
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
void _cellGcmSetFlipCommandWithWaitLabel ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > ctx , u32 id , u32 label_index , u32 label_value )
2014-03-31 02:02:27 +02:00
{
2020-01-16 22:31:58 +01:00
cellGcmSys . todo ( " cellGcmSetFlipCommandWithWaitLabel(ctx=*0x%x, id=0x%x, label_index=0x%x, label_value=0x%x) " , ctx , id , label_index , label_value ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2019-08-25 02:44:08 +02:00
2020-01-16 22:31:58 +01:00
if ( auto error = gcmSetPrepareFlip < true > ( ppu , ctx , id ) ; error < 0 )
{
// TODO: On actual fw this function doesn't have error checks at all
cellGcmSys . error ( " cellGcmSetFlipCommandWithWaitLabel(): gcmSetPrepareFlip failed with %s " , CellGcmError { error + 0u } ) ;
}
// TODO: Fix this (must enqueue WaitLabel command instead)
2021-03-02 12:59:19 +01:00
vm : : write32 ( gcm_cfg . gcm_info . label_addr + 0x10 * label_index , label_value ) ;
2014-03-31 02:02:27 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmSetTile ( u8 index , u8 location , u32 offset , u32 size , u32 pitch , u8 comp , u16 base , u8 bank )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . warning ( " cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d) " ,
2014-03-31 02:02:27 +02:00
index , location , offset , size , pitch , comp , base , bank ) ;
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2017-07-26 04:33:32 +02:00
2014-03-31 02:02:27 +02:00
// Copied form cellGcmSetTileInfo
2015-10-25 15:27:04 +01:00
if ( index > = rsx : : limits : : tiles_count | | base > = 2048 | | bank > = 4 )
2014-03-31 02:02:27 +02:00
{
return CELL_GCM_ERROR_INVALID_VALUE ;
}
2017-09-02 13:43:44 +02:00
if ( offset & 0xffff | | size & 0xffff | | pitch & 0xff )
2014-03-31 02:02:27 +02:00
{
return CELL_GCM_ERROR_INVALID_ALIGNMENT ;
}
2015-09-10 16:30:14 +02:00
if ( location > = 2 | | ( comp ! = 0 & & ( comp < 7 | | comp > 12 ) ) )
2014-03-31 02:02:27 +02:00
{
return CELL_GCM_ERROR_INVALID_ENUM ;
}
2015-09-10 16:30:14 +02:00
if ( comp )
2014-03-31 02:02:27 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . error ( " cellGcmSetTile: bad compression mode! (%d) " , comp ) ;
2014-03-31 02:02:27 +02:00
}
2018-05-10 13:50:32 +02:00
const auto render = rsx : : get_current_renderer ( ) ;
2016-03-21 20:43:03 +01:00
auto & tile = render - > tiles [ index ] ;
2015-10-04 00:45:26 +02:00
tile . location = location ;
tile . offset = offset ;
tile . size = size ;
tile . pitch = pitch ;
tile . comp = comp ;
tile . base = base ;
tile . bank = bank ;
2020-04-10 22:09:13 +02:00
tile . bound = ( pitch > 0 ) ;
2014-03-31 02:02:27 +02:00
2021-03-02 12:59:19 +01:00
vm : : _ptr < CellGcmTileInfo > ( gcm_cfg . tiles_addr ) [ index ] = tile . pack ( ) ;
2014-03-31 02:02:27 +02:00
return CELL_OK ;
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmFunc2 ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " _cellGcmFunc2() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmFunc3 ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " _cellGcmFunc3() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmFunc4 ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " _cellGcmFunc4() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmFunc13 ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " _cellGcmFunc13() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code _cellGcmFunc38 ( )
2015-08-03 00:00:00 +02:00
{
2019-09-02 13:41:57 +02:00
cellGcmSys . todo ( " _cellGcmFunc38() " ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGpadGetStatus ( vm : : ptr < u32 > status )
2015-08-03 00:00:00 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmGpadGetStatus(status=*0x%x) " , status ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGpadNotifyCaptureSurface ( vm : : ptr < CellGcmSurface > surface )
2015-08-03 00:00:00 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmGpadNotifyCaptureSurface(surface=*0x%x) " , surface ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2020-01-16 22:31:58 +01:00
error_code cellGcmGpadCaptureSnapshot ( u32 num )
2015-08-03 00:00:00 +02:00
{
2017-05-15 13:30:14 +02:00
cellGcmSys . todo ( " cellGcmGpadCaptureSnapshot(num=%d) " , num ) ;
return CELL_OK ;
2015-08-03 00:00:00 +02:00
}
2014-03-31 02:02:27 +02:00
//----------------------------------------------------------------------------
2014-01-21 20:10:44 +01:00
2015-06-18 14:58:28 +02:00
/**
* Using current to determine what is the next useable command buffer .
* Caller may wait for RSX not to use the command buffer .
*/
static std : : pair < u32 , u32 > getNextCommandBufferBeginEnd ( u32 current )
{
2015-06-24 13:53:47 +02:00
u32 currentRange = ( current - g_defaultCommandBufferBegin ) / ( 32 * 1024 ) ;
2015-06-22 00:48:15 +02:00
if ( currentRange > = g_defaultCommandBufferFragmentCount - 1 )
2015-06-18 14:58:28 +02:00
return std : : make_pair ( g_defaultCommandBufferBegin + 4096 , g_defaultCommandBufferBegin + 32 * 1024 - 4 ) ;
return std : : make_pair ( g_defaultCommandBufferBegin + ( currentRange + 1 ) * 32 * 1024 ,
g_defaultCommandBufferBegin + ( currentRange + 2 ) * 32 * 1024 - 4 ) ;
}
static u32 getOffsetFromAddress ( u32 address )
{
2021-03-02 12:59:19 +01:00
const u32 upper = g_fxo - > get < gcm_config > ( ) . offsetTable . ioAddress [ address > > 20 ] ; // 12 bits
2020-12-09 08:47:45 +01:00
ensure ( upper ! = 0xFFFF ) ;
2015-06-18 14:58:28 +02:00
return ( upper < < 20 ) | ( address & 0xFFFFF ) ;
}
/**
* Returns true if getPos is a valid position in command buffer and not between
* bufferBegin and bufferEnd which are absolute memory address
*/
static bool isInCommandBufferExcept ( u32 getPos , u32 bufferBegin , u32 bufferEnd )
{
// Is outside of default command buffer :
// It's in a call/return statement
// Conservatively return false here
if ( getPos < getOffsetFromAddress ( g_defaultCommandBufferBegin + 4096 ) & &
getPos > getOffsetFromAddress ( g_defaultCommandBufferBegin + g_defaultCommandBufferFragmentCount * 32 * 1024 ) )
return false ;
if ( getPos > = getOffsetFromAddress ( bufferBegin ) & &
getPos < = getOffsetFromAddress ( bufferEnd ) )
return false ;
return true ;
}
2017-02-22 11:10:55 +01:00
s32 cellGcmCallback ( ppu_thread & ppu , vm : : ptr < CellGcmContextData > context , u32 count )
2014-06-25 00:38:34 +02:00
{
2016-01-12 22:57:16 +01:00
cellGcmSys . trace ( " cellGcmCallback(context=*0x%x, count=0x%x) " , context , count ) ;
2014-11-30 20:23:51 +01:00
2021-03-02 12:59:19 +01:00
auto & gcm_cfg = g_fxo - > get < gcm_config > ( ) ;
2019-08-25 02:44:08 +02:00
2021-03-02 12:59:19 +01:00
auto & ctrl = vm : : _ref < CellGcmControl > ( gcm_cfg . gcm_info . control_addr ) ;
2017-02-22 11:10:55 +01:00
2015-06-18 14:58:28 +02:00
// Flush command buffer (ie allow RSX to read up to context->current)
2015-07-27 03:27:33 +02:00
ctrl . put . exchange ( getOffsetFromAddress ( context - > current . addr ( ) ) ) ;
2015-06-18 14:58:28 +02:00
2015-07-27 03:27:33 +02:00
std : : pair < u32 , u32 > newCommandBuffer = getNextCommandBufferBeginEnd ( context - > current . addr ( ) ) ;
2015-06-18 14:58:28 +02:00
u32 offset = getOffsetFromAddress ( newCommandBuffer . first ) ;
// Write jump instruction
2016-10-01 21:13:15 +02:00
* context - > current = RSX_METHOD_OLD_JUMP_CMD | offset ;
2015-06-18 14:58:28 +02:00
// Update current command buffer
2015-07-27 03:27:33 +02:00
context - > begin . set ( newCommandBuffer . first ) ;
context - > current . set ( newCommandBuffer . first ) ;
context - > end . set ( newCommandBuffer . second ) ;
2015-06-18 14:58:28 +02:00
// Wait for rsx to "release" the new command buffer
2017-02-22 11:10:55 +01:00
while ( true )
2015-06-18 14:58:28 +02:00
{
2015-09-26 22:46:04 +02:00
u32 getPos = ctrl . get . load ( ) ;
2015-06-18 14:58:28 +02:00
if ( isInCommandBufferExcept ( getPos , newCommandBuffer . first , newCommandBuffer . second ) )
break ;
2017-02-22 11:10:55 +01:00
2018-10-11 00:17:19 +02:00
if ( ppu . test_stopped ( ) )
{
return 0 ;
}
2017-02-22 11:10:55 +01:00
busy_wait ( ) ;
2015-06-18 14:58:28 +02:00
}
return CELL_OK ;
2014-06-25 00:38:34 +02:00
}
//----------------------------------------------------------------------------
2016-03-21 20:43:03 +01:00
DECLARE ( ppu_module_manager : : cellGcmSys ) ( " cellGcmSys " , [ ] ( )
2013-06-30 10:46:29 +02:00
{
2014-03-31 00:58:51 +02:00
// Data Retrieval
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmGetCurrentField ) ;
REG_FUNC ( cellGcmSys , cellGcmGetLabelAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmGetNotifyDataAddress ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc12 ) ;
REG_FUNC ( cellGcmSys , cellGcmGetReport ) ;
REG_FUNC ( cellGcmSys , cellGcmGetReportDataAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmGetReportDataAddressLocation ) ;
REG_FUNC ( cellGcmSys , cellGcmGetReportDataLocation ) ;
2022-05-11 00:00:03 +02:00
REG_FUNC ( cellGcmSys , cellGcmGetTimeStamp ) . flag ( MFF_FORCED_HLE ) ; // HLE-ing this allows for optimizations around reports
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmGetTimeStampLocation ) ;
2014-03-31 00:58:51 +02:00
// Command Buffer Control
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmGetControlRegister ) ;
REG_FUNC ( cellGcmSys , cellGcmGetDefaultCommandWordSize ) ;
REG_FUNC ( cellGcmSys , cellGcmGetDefaultSegmentWordSize ) ;
REG_FUNC ( cellGcmSys , cellGcmInitDefaultFifoMode ) ;
REG_FUNC ( cellGcmSys , cellGcmSetDefaultFifoSize ) ;
2014-03-31 20:30:07 +02:00
2014-03-31 00:58:51 +02:00
// Hardware Resource Management
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmBindTile ) ;
REG_FUNC ( cellGcmSys , cellGcmBindZcull ) ;
REG_FUNC ( cellGcmSys , cellGcmDumpGraphicsError ) ;
REG_FUNC ( cellGcmSys , cellGcmGetConfiguration ) ;
REG_FUNC ( cellGcmSys , cellGcmGetDisplayBufferByFlipIndex ) ;
REG_FUNC ( cellGcmSys , cellGcmGetFlipStatus ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmGetFlipStatus2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmGetLastFlipTime ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmGetLastFlipTime2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmGetLastSecondVTime ) ;
REG_FUNC ( cellGcmSys , cellGcmGetTiledPitchSize ) ;
REG_FUNC ( cellGcmSys , cellGcmGetVBlankCount ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmGetVBlankCount2 ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmSysGetLastVBlankTime ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , _cellGcmFunc1 ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc15 ) ;
REG_FUNC ( cellGcmSys , _cellGcmInitBody ) ;
REG_FUNC ( cellGcmSys , cellGcmInitSystemMode ) ;
REG_FUNC ( cellGcmSys , cellGcmResetFlipStatus ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmResetFlipStatus2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetDebugOutputLevel ) ;
REG_FUNC ( cellGcmSys , cellGcmSetDisplayBuffer ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetFlip ) ; //
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipHandler ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipHandler2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipImmediate ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipImmediate2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipMode ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipMode2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipStatus ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetFlipStatus2 ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetGraphicsHandler ) ;
REG_FUNC ( cellGcmSys , cellGcmSetPrepareFlip ) ;
REG_FUNC ( cellGcmSys , cellGcmSetQueueHandler ) ;
REG_FUNC ( cellGcmSys , cellGcmSetSecondVFrequency ) ;
REG_FUNC ( cellGcmSys , cellGcmSetSecondVHandler ) ;
REG_FUNC ( cellGcmSys , cellGcmSetTileInfo ) ;
REG_FUNC ( cellGcmSys , cellGcmSetUserHandler ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetUserCommand ) ; //
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetVBlankFrequency ) ;
REG_FUNC ( cellGcmSys , cellGcmSetVBlankHandler ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetWaitFlip ) ; //
REG_FUNC ( cellGcmSys , cellGcmSetWaitFlipUnsafe ) ; //
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetZcull ) ;
REG_FUNC ( cellGcmSys , cellGcmSortRemapEaIoAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmUnbindTile ) ;
REG_FUNC ( cellGcmSys , cellGcmUnbindZcull ) ;
REG_FUNC ( cellGcmSys , cellGcmGetTileInfo ) ;
REG_FUNC ( cellGcmSys , cellGcmGetZcullInfo ) ;
REG_FUNC ( cellGcmSys , cellGcmGetDisplayInfo ) ;
REG_FUNC ( cellGcmSys , cellGcmGetCurrentDisplayBufferId ) ;
REG_FUNC ( cellGcmSys , cellGcmSetInvalidateTile ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmTerminate ) ;
2014-01-17 17:56:03 +01:00
2014-03-31 20:30:07 +02:00
// Memory Mapping
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmAddressToOffset ) ;
REG_FUNC ( cellGcmSys , cellGcmGetMaxIoMapSize ) ;
REG_FUNC ( cellGcmSys , cellGcmGetOffsetTable ) ;
REG_FUNC ( cellGcmSys , cellGcmIoOffsetToAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmMapEaIoAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmMapEaIoAddressWithFlags ) ;
REG_FUNC ( cellGcmSys , cellGcmMapLocalMemory ) ;
REG_FUNC ( cellGcmSys , cellGcmMapMainMemory ) ;
REG_FUNC ( cellGcmSys , cellGcmReserveIoMapSize ) ;
REG_FUNC ( cellGcmSys , cellGcmUnmapEaIoAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmUnmapIoAddress ) ;
REG_FUNC ( cellGcmSys , cellGcmUnreserveIoMapSize ) ;
2014-03-31 00:58:51 +02:00
// Cursor
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmInitCursor ) ;
REG_FUNC ( cellGcmSys , cellGcmSetCursorEnable ) ;
REG_FUNC ( cellGcmSys , cellGcmSetCursorDisable ) ;
REG_FUNC ( cellGcmSys , cellGcmSetCursorImageOffset ) ;
REG_FUNC ( cellGcmSys , cellGcmSetCursorPosition ) ;
REG_FUNC ( cellGcmSys , cellGcmUpdateCursor ) ;
2014-03-31 00:58:51 +02:00
// Functions for Maintaining Compatibility
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetDefaultCommandBuffer ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , cellGcmSetDefaultCommandBufferAndSegmentWordSize ) ;
2014-03-31 00:58:51 +02:00
// Other
2015-02-20 22:21:52 +01:00
REG_FUNC ( cellGcmSys , _cellGcmSetFlipCommand ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellGcmSys , _cellGcmSetFlipCommand2 ) ;
2015-02-20 22:21:52 +01:00
REG_FUNC ( cellGcmSys , _cellGcmSetFlipCommandWithWaitLabel ) ;
2015-02-20 14:58:40 +01:00
REG_FUNC ( cellGcmSys , cellGcmSetTile ) ;
2015-08-03 00:00:00 +02:00
REG_FUNC ( cellGcmSys , _cellGcmFunc2 ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc3 ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc4 ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc13 ) ;
REG_FUNC ( cellGcmSys , _cellGcmFunc38 ) ;
// GPAD
REG_FUNC ( cellGcmSys , cellGcmGpadGetStatus ) ;
REG_FUNC ( cellGcmSys , cellGcmGpadNotifyCaptureSurface ) ;
REG_FUNC ( cellGcmSys , cellGcmGpadCaptureSnapshot ) ;
2016-03-21 20:43:03 +01:00
// Special
2021-09-06 09:33:44 +02:00
REG_HIDDEN_FUNC ( cellGcmCallback ) ;
2017-09-02 13:43:44 +02:00
} ) ;