Merge pull request #2451 from RadWolfie/fix-hardware-model

Fix hardware model conversions + use respective hardware model based on console type
This commit is contained in:
RadWolfie 2024-02-08 12:48:46 -06:00 committed by GitHub
commit bfb10092c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 127 additions and 46 deletions

View File

@ -2081,6 +2081,11 @@ typedef enum _XC_VALUE_INDEX
} }
XC_VALUE_INDEX, *PXC_VALUE_INDEX; XC_VALUE_INDEX, *PXC_VALUE_INDEX;
#define XBOX_HW_FLAG_INTERNAL_USB_HUB 0x00000001
#define XBOX_HW_FLAG_DEVKIT_KERNEL 0x00000002
#define XBOX_480P_MACROVISION_ENABLED 0x00000004
#define XBOX_HW_FLAG_ARCADE 0x00000008
// ****************************************************************** // ******************************************************************
// * XBOX_HARDWARE_INFO // * XBOX_HARDWARE_INFO
// ****************************************************************** // ******************************************************************

View File

@ -41,13 +41,19 @@ XBSYSAPI EXPORTNUM(321) xbox::XBOX_KEY_DATA xbox::XboxEEPROMKey = { 0 };
// ****************************************************************** // ******************************************************************
// * 0x0142 - XboxHardwareInfo // * 0x0142 - XboxHardwareInfo
// ****************************************************************** // ******************************************************************
// TODO: The main goal is to completely unset custom init values and have
// them set from kernel's initialization end and device classes.
// Although, device classes does not really set this value but read
// from PCI space for Gpu rev, Mcp rev, and possibility INTERNAL_USB flag.
XBSYSAPI EXPORTNUM(322) xbox::XBOX_HARDWARE_INFO xbox::XboxHardwareInfo = XBSYSAPI EXPORTNUM(322) xbox::XBOX_HARDWARE_INFO xbox::XboxHardwareInfo =
{ {
0xC0000031, // Flags: 1=INTERNAL_USB, 2=DEVKIT, 4=MACROVISION, 8=CHIHIRO // TODO: What exactly 0xC0000030 flags are? Might need default to null then set them later properly.
0xA2, // GpuRevision, byte read from NV2A first register, at 0xFD0000000 - see NV_PMC_BOOT_0 // NOTE: Will be set by src/devices/Xbox.cpp and maybe other file(s)...
0xD3, // McpRevision, Retail 1.6 - see https://github.com/JayFoxRox/xqemu-jfr/wiki/MCPX-and-bootloader .Flags = 0xC0000030, // Flags: 1=INTERNAL_USB, 2=DEVKIT, 4=MACROVISION, 8=CHIHIRO
0, // unknown .GpuRevision = 0xD3, // GpuRevision, byte read from NV2A first register, at 0xFD0000000 - see NV_PMC_BOOT_0
0 // unknown .McpRevision = 0, // NOTE: Will be set by src/devices/Xbox.cpp file.
.Unknown3 = 0, // unknown
.Unknown4 = 0 // unknown
}; };
// ****************************************************************** // ******************************************************************

View File

@ -542,7 +542,10 @@ static void CxbxrKrnlSetupMemorySystem(int BootFlags, unsigned emulate_system, u
} }
} }
static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems, blocks_reserved_t blocks_reserved) static bool CxbxrKrnlXbeSystemSelector(int BootFlags,
unsigned& reserved_systems,
blocks_reserved_t blocks_reserved,
HardwareModel &hardwareModel)
{ {
unsigned int emulate_system = 0; unsigned int emulate_system = 0;
// Get title path : // Get title path :
@ -717,6 +720,17 @@ static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems
g_bIsChihiro = (emulate_system == SYSTEM_CHIHIRO); g_bIsChihiro = (emulate_system == SYSTEM_CHIHIRO);
g_bIsDevKit = (emulate_system == SYSTEM_DEVKIT); g_bIsDevKit = (emulate_system == SYSTEM_DEVKIT);
g_bIsRetail = (emulate_system == SYSTEM_XBOX); g_bIsRetail = (emulate_system == SYSTEM_XBOX);
if (g_bIsChihiro) {
hardwareModel = HardwareModel::Chihiro_Type1; // TODO: Make configurable to support Type-3 console.
}
else if (g_bIsDevKit) {
hardwareModel = HardwareModel::DebugKit_r1_2; // Unlikely need to make configurable.
}
// Retail (default)
else {
// Should not be configurable. Otherwise, titles compiled with newer XDK will patch older xbox kernel.
hardwareModel = HardwareModel::Revision1_6;
}
#ifdef CHIHIRO_WORK #ifdef CHIHIRO_WORK
// If this is a Chihiro title, we need to patch the init flags to disable HDD setup // If this is a Chihiro title, we need to patch the init flags to disable HDD setup
@ -934,7 +948,8 @@ static bool CxbxrKrnlPrepareXbeMap()
Xbe::Header* XbeHeader, Xbe::Header* XbeHeader,
uint32_t XbeHeaderSize, uint32_t XbeHeaderSize,
void (*Entry)(), void (*Entry)(),
int BootFlags int BootFlags,
HardwareModel hardwareModel
); );
void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_reserved) void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_reserved)
@ -1088,7 +1103,8 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
// using XeLoadImage from LaunchDataPage->Header.szLaunchPath // using XeLoadImage from LaunchDataPage->Header.szLaunchPath
// Now we can load the XBE : // Now we can load the XBE :
if (!CxbxrKrnlXbeSystemSelector(BootFlags, reserved_systems, blocks_reserved)) { HardwareModel hardwareModel = HardwareModel::Revision1_6; // It is configured by CxbxrKrnlXbeSystemSelector function according to console type.
if (!CxbxrKrnlXbeSystemSelector(BootFlags, reserved_systems, blocks_reserved, hardwareModel)) {
return; return;
} }
@ -1116,7 +1132,8 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
(Xbe::Header*)CxbxKrnl_Xbe->m_Header.dwBaseAddr, (Xbe::Header*)CxbxKrnl_Xbe->m_Header.dwBaseAddr,
CxbxKrnl_Xbe->m_Header.dwSizeofHeaders, CxbxKrnl_Xbe->m_Header.dwSizeofHeaders,
(void(*)())EntryPoint, (void(*)())EntryPoint,
BootFlags BootFlags,
hardwareModel
); );
} }
@ -1178,7 +1195,8 @@ static void CxbxrKrnlInitHacks()
Xbe::Header *pXbeHeader, Xbe::Header *pXbeHeader,
uint32_t dwXbeHeaderSize, uint32_t dwXbeHeaderSize,
void(*Entry)(), void(*Entry)(),
int BootFlags) int BootFlags,
HardwareModel hardwareModel)
{ {
unsigned Host2XbStackBaseReserved = 0; unsigned Host2XbStackBaseReserved = 0;
__asm mov Host2XbStackBaseReserved, esp; __asm mov Host2XbStackBaseReserved, esp;
@ -1383,7 +1401,7 @@ static void CxbxrKrnlInitHacks()
SetupXboxDeviceTypes(); SetupXboxDeviceTypes();
} }
InitXboxHardware(HardwareModel::Revision1_5); // TODO : Make configurable InitXboxHardware(hardwareModel);
// Read Xbox video mode from the SMC, store it in HalBootSMCVideoMode // Read Xbox video mode from the SMC, store it in HalBootSMCVideoMode
xbox::HalReadSMBusValue(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, SMC_COMMAND_AV_PACK, FALSE, (xbox::PULONG)&xbox::HalBootSMCVideoMode); xbox::HalReadSMBusValue(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, SMC_COMMAND_AV_PACK, FALSE, (xbox::PULONG)&xbox::HalBootSMCVideoMode);

View File

@ -91,10 +91,13 @@ uint8_t SMCDevice::ReadByte(uint8_t command)
// See https://xboxdevwiki.net/PIC#PIC_version_string // See https://xboxdevwiki.net/PIC#PIC_version_string
switch (m_revision) { switch (m_revision) {
case SCMRevision::P01: buffer[1] = "P01"[m_PICVersionStringIndex]; break; case SCMRevision::P01: buffer[1] = "P01"[m_PICVersionStringIndex]; break;
case SCMRevision::P2L: buffer[1] = "P05"[m_PICVersionStringIndex]; break; // ?? case SCMRevision::P05: buffer[1] = "P05"[m_PICVersionStringIndex]; break;
case SCMRevision::P11: buffer[1] = "P11"[m_PICVersionStringIndex]; break;
case SCMRevision::P2L: buffer[1] = "P2L"[m_PICVersionStringIndex]; break;
case SCMRevision::D01: buffer[1] = "DXB"[m_PICVersionStringIndex]; break; case SCMRevision::D01: buffer[1] = "DXB"[m_PICVersionStringIndex]; break;
case SCMRevision::D05: buffer[1] = "D05"[m_PICVersionStringIndex]; break; // ?? case SCMRevision::D05: buffer[1] = "D05"[m_PICVersionStringIndex]; break; // ??
// default: UNREACHABLE(m_revision); case SCMRevision::B11: buffer[1] = "B11"[m_PICVersionStringIndex]; break; // ??
default: CxbxrAbort("Unknown PIC revision: %d", m_revision);
} }
m_PICVersionStringIndex = (m_PICVersionStringIndex + 1) % 3; m_PICVersionStringIndex = (m_PICVersionStringIndex + 1) % 3;

View File

@ -93,10 +93,14 @@
typedef enum { typedef enum {
// https://xboxdevwiki.net/System_Management_Controller // https://xboxdevwiki.net/System_Management_Controller
// https://xboxdevwiki.net/Xboxen_Info
P01, P01,
P05,
P11,
P2L, P2L,
D01, // Seen in a debug kit D01, // Seen in a debug kit
D05, // Seen in a earlier model chihiro D05, // Seen in a earlier model chihiro
B11,
} SCMRevision; } SCMRevision;
class SMCDevice : public SMDevice { class SMCDevice : public SMDevice {

View File

@ -25,8 +25,12 @@
// * // *
// ****************************************************************** // ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::XBOX
#include "Xbox.h" // For HardwareModel #include "Xbox.h" // For HardwareModel
#include "common\xbe\Xbe.h" // Without this HLEIntercept complains about some undefined xbe variables #include "common\xbe\Xbe.h" // Without this HLEIntercept complains about some undefined xbe variables
#include "core\kernel\common\xbox.h"
#include "cxbxr.hpp"
#include "core\hle\Intercept.hpp" #include "core\hle\Intercept.hpp"
PCIBus* g_PCIBus; PCIBus* g_PCIBus;
@ -41,66 +45,82 @@ USBDevice* g_USB0;
MCPXRevision MCPXRevisionFromHardwareModel(HardwareModel hardwareModel) MCPXRevision MCPXRevisionFromHardwareModel(HardwareModel hardwareModel)
{ {
switch (hardwareModel) { // https://xboxdevwiki.net/Xboxen_Info
case Revision1_0: switch (GET_HW_CONSOLE(hardwareModel)) {
case Revision1_1: case Retail:
case Revision1_2:
case Revision1_3:
case Revision1_4:
case Revision1_5:
case Revision1_6:
return MCPXRevision::MCPX_X3; return MCPXRevision::MCPX_X3;
case DebugKit: case DebugKit:
// EmuLog(LOG_LEVEL::WARNING, "Guessing MCPXVersion"); case Chihiro:
return MCPXRevision::MCPX_X2; return MCPXRevision::MCPX_X2;
default: default:
// UNREACHABLE(hardwareModel); CxbxrAbort("MCPXRevisionFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
return MCPXRevision::MCPX_X3;
} }
} }
SCMRevision SCMRevisionFromHardwareModel(HardwareModel hardwareModel) SCMRevision SCMRevisionFromHardwareModel(HardwareModel hardwareModel)
{ {
// https://xboxdevwiki.net/Xboxen_Info
switch (hardwareModel) { switch (hardwareModel) {
case Revision1_0: case Revision1_0:
return SCMRevision::P01; // Our SCM returns PIC version string "P01" return SCMRevision::P01;
case Revision1_1: case Revision1_1:
return SCMRevision::P05;
case Revision1_2: case Revision1_2:
case Revision1_3: case Revision1_3:
case Revision1_4: case Revision1_4:
return SCMRevision::P11;
case Revision1_5: case Revision1_5:
case Revision1_6: case Revision1_6:
// EmuLog(LOG_LEVEL::WARNING, "Guessing SCMRevision");
return SCMRevision::P2L; // Assumption; Our SCM returns PIC version string "P05"
case DebugKit:
return SCMRevision::D01; // Our SCM returns PIC version string "DXB"
default:
// UNREACHABLE(hardwareModel);
return SCMRevision::P2L; return SCMRevision::P2L;
case DebugKit:
return SCMRevision::D01;
case Chihiro_Type1:
return SCMRevision::D05;
case DebugKit_r1_2:
case Chihiro_Type3:
return SCMRevision::B11;
default:
CxbxrAbort("SCMRevisionFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
} }
} }
TVEncoder TVEncoderFromHardwareModel(HardwareModel hardwareModel) TVEncoder TVEncoderFromHardwareModel(HardwareModel hardwareModel)
{ {
switch (hardwareModel) { // https://xboxdevwiki.net/Xboxen_Info
// LukeUsher : My debug kit and at least most of them (maybe all?)
// are equivalent to v1.0 and have Conexant encoders.
switch (GET_HW_REVISION(hardwareModel)) {
case Revision1_0: case Revision1_0:
case Revision1_1: case Revision1_1:
case Revision1_2: case Revision1_2:
case Revision1_3: case Revision1_3:
return TVEncoder::Conexant; return TVEncoder::Conexant;
case Revision1_4: case Revision1_4:
case Revision1_5: // Assumption
return TVEncoder::Focus; return TVEncoder::Focus;
case Revision1_5:
return TVEncoder::Focus; // Assumption
case Revision1_6: case Revision1_6:
return TVEncoder::XCalibur; return TVEncoder::XCalibur;
case DebugKit: default:
// LukeUsher : My debug kit and at least most of them (maybe all?) CxbxrAbort("TVEncoderFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
// are equivalent to v1.0 and have Conexant encoders. }
return TVEncoder::Conexant; }
default:
// UNREACHABLE(hardwareModel); xbox::uchar_xt MCP_PCIRevisionFromHardwareModel(HardwareModel hardwareModel)
return TVEncoder::Focus; {
// https://xboxdevwiki.net/Xboxen_Info
switch (GET_HW_REVISION(hardwareModel)) {
case Revision1_0:
return 0xB2;
case Revision1_1:
case Revision1_2:
case Revision1_3:
case Revision1_4:
case Revision1_5: // Assumption
return 0xD4;
case Revision1_6:
return 0xD5;
default:
CxbxrAbort("MCP_PCIRevisionFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
} }
} }
@ -111,16 +131,29 @@ void InitXboxHardware(HardwareModel hardwareModel)
SCMRevision smc_revision = SCMRevisionFromHardwareModel(hardwareModel); SCMRevision smc_revision = SCMRevisionFromHardwareModel(hardwareModel);
TVEncoder tv_encoder = TVEncoderFromHardwareModel(hardwareModel); TVEncoder tv_encoder = TVEncoderFromHardwareModel(hardwareModel);
// Only Xbox 1.0 has usb daughterboard supplied, later revisions are integrated onto motherboard.
if (GET_HW_REVISION(hardwareModel) == HardwareModel::Revision1_0) {
xbox::XboxHardwareInfo.Flags |= XBOX_HW_FLAG_INTERNAL_USB_HUB;
}
// Set the special type of consoles according to xbox kernel designed respectively.
if (IS_DEVKIT(hardwareModel)) {
xbox::XboxHardwareInfo.Flags |= XBOX_HW_FLAG_DEVKIT_KERNEL;
}
else if (IS_CHIHIRO(hardwareModel)) {
xbox::XboxHardwareInfo.Flags |= XBOX_HW_FLAG_ARCADE;
}
xbox::XboxHardwareInfo.McpRevision = MCP_PCIRevisionFromHardwareModel(hardwareModel);
// Create busses // Create busses
g_PCIBus = new PCIBus(); g_PCIBus = new PCIBus();
g_SMBus = new SMBus(); g_SMBus = new SMBus();
// Create devices // Create devices
g_MCPX = new MCPXDevice(mcpx_revision); g_MCPX = new MCPXDevice(mcpx_revision);
g_SMC = new SMCDevice(smc_revision, IS_CHIHIRO(hardwareModel) ? 6 : 1); // 6 = AV_PACK_STANDARD, 1 = AV_PACK_HDTV. Chihiro doesn't support HDTV!
g_SMC = new SMCDevice(smc_revision, g_bIsChihiro ? 6 : 1); // 6 = AV_PACK_STANDARD, 1 = AV_PACK_HDTV. Chihiro doesn't support HDTV! // SMC uses different AV_PACK values than the Kernel
// SMC uses different AV_PACK values than the Kernel // See https://xboxdevwiki.net/PIC#The_AV_Pack
// See https://xboxdevwiki.net/PIC#The_AV_Pack
g_EEPROM = new EEPROMDevice(); g_EEPROM = new EEPROMDevice();
g_NVNet = new NVNetDevice(); g_NVNet = new NVNetDevice();
g_NV2A = new NV2ADevice(); g_NV2A = new NV2ADevice();

View File

@ -53,9 +53,21 @@ typedef enum {
Revision1_4, Revision1_4,
Revision1_5, Revision1_5,
Revision1_6, Revision1_6,
DebugKit Retail = 0x00,
// We don't need include revison 1.0 to 1.6 here, use above revision range instead.
DebugKit = 0x10, // TODO: Since there are 1.0/1.1/1.2 revisions. For now, let's go with 1.2 by default.
DebugKit_r1_2 = DebugKit | Revision1_2,
Chihiro = 0x20,
Chihiro_Type1 = Chihiro | Revision1_1,
Chihiro_Type3 = Chihiro | Revision1_2, // TODO: Need verify on Chihiro hw, it is currently base on (B11) Debug Kit list.
} HardwareModel; } HardwareModel;
#define GET_HW_REVISION(hardwareModel) (hardwareModel & 0x0F)
#define GET_HW_CONSOLE(hardwareModel) (hardwareModel & 0xF0)
#define IS_RETAIL(hardwareModel) (GET_HW_CONSOLE(hardwareModel) == Retail)
#define IS_DEVKIT(hardwareModel) (GET_HW_CONSOLE(hardwareModel) == DebugKit)
#define IS_CHIHIRO(hardwareModel) (GET_HW_CONSOLE(hardwareModel) == Chihiro)
typedef enum { // TODO : Move to it's own file typedef enum { // TODO : Move to it's own file
// https://xboxdevwiki.net/Hardware_Revisions#Video_encoder // https://xboxdevwiki.net/Hardware_Revisions#Video_encoder
Conexant, Conexant,