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;
#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
// ******************************************************************

View file

@ -41,13 +41,19 @@ XBSYSAPI EXPORTNUM(321) xbox::XBOX_KEY_DATA xbox::XboxEEPROMKey = { 0 };
// ******************************************************************
// * 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 =
{
0xC0000031, // Flags: 1=INTERNAL_USB, 2=DEVKIT, 4=MACROVISION, 8=CHIHIRO
0xA2, // GpuRevision, byte read from NV2A first register, at 0xFD0000000 - see NV_PMC_BOOT_0
0xD3, // McpRevision, Retail 1.6 - see https://github.com/JayFoxRox/xqemu-jfr/wiki/MCPX-and-bootloader
0, // unknown
0 // unknown
// TODO: What exactly 0xC0000030 flags are? Might need default to null then set them later properly.
// NOTE: Will be set by src/devices/Xbox.cpp and maybe other file(s)...
.Flags = 0xC0000030, // Flags: 1=INTERNAL_USB, 2=DEVKIT, 4=MACROVISION, 8=CHIHIRO
.GpuRevision = 0xD3, // GpuRevision, byte read from NV2A first register, at 0xFD0000000 - see NV_PMC_BOOT_0
.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;
// Get title path :
@ -717,6 +720,17 @@ static bool CxbxrKrnlXbeSystemSelector(int BootFlags, unsigned& reserved_systems
g_bIsChihiro = (emulate_system == SYSTEM_CHIHIRO);
g_bIsDevKit = (emulate_system == SYSTEM_DEVKIT);
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
// 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,
uint32_t XbeHeaderSize,
void (*Entry)(),
int BootFlags
int BootFlags,
HardwareModel hardwareModel
);
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
// 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;
}
@ -1116,7 +1132,8 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
(Xbe::Header*)CxbxKrnl_Xbe->m_Header.dwBaseAddr,
CxbxKrnl_Xbe->m_Header.dwSizeofHeaders,
(void(*)())EntryPoint,
BootFlags
BootFlags,
hardwareModel
);
}
@ -1178,7 +1195,8 @@ static void CxbxrKrnlInitHacks()
Xbe::Header *pXbeHeader,
uint32_t dwXbeHeaderSize,
void(*Entry)(),
int BootFlags)
int BootFlags,
HardwareModel hardwareModel)
{
unsigned Host2XbStackBaseReserved = 0;
__asm mov Host2XbStackBaseReserved, esp;
@ -1383,7 +1401,7 @@ static void CxbxrKrnlInitHacks()
SetupXboxDeviceTypes();
}
InitXboxHardware(HardwareModel::Revision1_5); // TODO : Make configurable
InitXboxHardware(hardwareModel);
// 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);

View file

@ -91,10 +91,13 @@ uint8_t SMCDevice::ReadByte(uint8_t command)
// See https://xboxdevwiki.net/PIC#PIC_version_string
switch (m_revision) {
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::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;

View file

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

View file

@ -25,8 +25,12 @@
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::XBOX
#include "Xbox.h" // For HardwareModel
#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"
PCIBus* g_PCIBus;
@ -41,66 +45,82 @@ USBDevice* g_USB0;
MCPXRevision MCPXRevisionFromHardwareModel(HardwareModel hardwareModel)
{
switch (hardwareModel) {
case Revision1_0:
case Revision1_1:
case Revision1_2:
case Revision1_3:
case Revision1_4:
case Revision1_5:
case Revision1_6:
// https://xboxdevwiki.net/Xboxen_Info
switch (GET_HW_CONSOLE(hardwareModel)) {
case Retail:
return MCPXRevision::MCPX_X3;
case DebugKit:
// EmuLog(LOG_LEVEL::WARNING, "Guessing MCPXVersion");
case Chihiro:
return MCPXRevision::MCPX_X2;
default:
// UNREACHABLE(hardwareModel);
return MCPXRevision::MCPX_X3;
CxbxrAbort("MCPXRevisionFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
}
}
SCMRevision SCMRevisionFromHardwareModel(HardwareModel hardwareModel)
{
// https://xboxdevwiki.net/Xboxen_Info
switch (hardwareModel) {
case Revision1_0:
return SCMRevision::P01; // Our SCM returns PIC version string "P01"
return SCMRevision::P01;
case Revision1_1:
return SCMRevision::P05;
case Revision1_2:
case Revision1_3:
case Revision1_4:
return SCMRevision::P11;
case Revision1_5:
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;
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)
{
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_1:
case Revision1_2:
case Revision1_3:
return TVEncoder::Conexant;
case Revision1_4:
case Revision1_5: // Assumption
return TVEncoder::Focus;
case Revision1_5:
return TVEncoder::Focus; // Assumption
case Revision1_6:
return TVEncoder::XCalibur;
case DebugKit:
// LukeUsher : My debug kit and at least most of them (maybe all?)
// are equivalent to v1.0 and have Conexant encoders.
return TVEncoder::Conexant;
default:
// UNREACHABLE(hardwareModel);
return TVEncoder::Focus;
default:
CxbxrAbort("TVEncoderFromHardwareModel: Unknown conversion for hardware model (0x%02X)", hardwareModel);
}
}
xbox::uchar_xt MCP_PCIRevisionFromHardwareModel(HardwareModel hardwareModel)
{
// 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);
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
g_PCIBus = new PCIBus();
g_SMBus = new SMBus();
// Create devices
g_MCPX = new MCPXDevice(mcpx_revision);
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
// See https://xboxdevwiki.net/PIC#The_AV_Pack
g_SMC = new SMCDevice(smc_revision, IS_CHIHIRO(hardwareModel) ? 6 : 1); // 6 = AV_PACK_STANDARD, 1 = AV_PACK_HDTV. Chihiro doesn't support HDTV!
// SMC uses different AV_PACK values than the Kernel
// See https://xboxdevwiki.net/PIC#The_AV_Pack
g_EEPROM = new EEPROMDevice();
g_NVNet = new NVNetDevice();
g_NV2A = new NV2ADevice();

View file

@ -53,9 +53,21 @@ typedef enum {
Revision1_4,
Revision1_5,
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;
#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
// https://xboxdevwiki.net/Hardware_Revisions#Video_encoder
Conexant,