From 46a03cb4420c4d4594484ec20a6c745a4fdeacef Mon Sep 17 00:00:00 2001 From: ergo720 Date: Wed, 2 May 2018 12:41:05 +0200 Subject: [PATCH] Created USB devices --- build/win32/Cxbx.vcxproj | 2 + build/win32/Cxbx.vcxproj.filters | 7 ++- src/CxbxKrnl/CxbxKrnl.h | 21 --------- src/devices/EmuNVNet.cpp | 6 +-- src/devices/EmuNVNet.h | 4 +- src/devices/MCPXDevice.cpp | 2 +- src/devices/MCPXDevice.h | 2 +- src/devices/PCIBus.cpp | 4 +- src/devices/PCIBus.h | 2 +- src/devices/PCIDevice.h | 24 +++++++++- src/devices/SMBus.cpp | 4 +- src/devices/SMBus.h | 2 +- src/devices/USBController/USBDevice.cpp | 52 +++++++++++++++++++++ src/devices/USBController/USBDevice.h | 60 +++++++++++++++++++++++++ src/devices/Xbox.cpp | 13 ++++-- src/devices/Xbox.h | 3 ++ src/devices/video/nv2a.cpp | 4 +- src/devices/video/nv2a.h | 7 +-- 18 files changed, 172 insertions(+), 47 deletions(-) create mode 100644 src/devices/USBController/USBDevice.cpp create mode 100644 src/devices/USBController/USBDevice.h diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj index 322a89925..f4f72cdf9 100644 --- a/build/win32/Cxbx.vcxproj +++ b/build/win32/Cxbx.vcxproj @@ -361,6 +361,7 @@ + @@ -729,6 +730,7 @@ + diff --git a/build/win32/Cxbx.vcxproj.filters b/build/win32/Cxbx.vcxproj.filters index 7c335b606..bce4f2b5a 100644 --- a/build/win32/Cxbx.vcxproj.filters +++ b/build/win32/Cxbx.vcxproj.filters @@ -281,6 +281,9 @@ Emulator + + Hardware + GUI @@ -565,7 +568,9 @@ Emulator - + + Hardware + GUI diff --git a/src/CxbxKrnl/CxbxKrnl.h b/src/CxbxKrnl/CxbxKrnl.h index 1b7604026..9bf123098 100644 --- a/src/CxbxKrnl/CxbxKrnl.h +++ b/src/CxbxKrnl/CxbxKrnl.h @@ -104,27 +104,6 @@ extern "C" { #define CONTIGUOUS_MEMORY_CHIHIRO_SIZE (128 * ONE_MB) #define XBOX_PFN_ADDRESS ((XBOX_PFN_DATABASE_PHYSICAL_PAGE << PAGE_SHIFT) + (PCHAR)KSEG0_BASE) #define CHIHIRO_PFN_ADDRESS ((CHIHIRO_PFN_DATABASE_PHYSICAL_PAGE << PAGE_SHIFT) + (PCHAR)KSEG0_BASE) -#define NV2A_MEMORY_BASE 0xFD000000 // See NV2A_ADDR -#define NV2A_MEMORY_SIZE 0x01000000 // See NV2A_SIZE -#define NV2A_PRAMIN_ADDR 0xFD700000 -#define NV2A_PRAMIN_SIZE 0x100000 -#define NV2A_USER_ADDR 0xFD800000 -#define NV2A_USER_SIZE 0x800000 -#define APU_BASE 0xFE800000 -#define APU_SIZE 0x80000 -#define AC97_BASE 0xFEC00000 -#define AC97_SIZE 0x1000 -#define USB0_BASE 0xFED00000 -#define USB0_SIZE 0x1000 -#define USB1_BASE 0xFED08000 -#define USB1_SIZE 0x1000 -#define NVNet_BASE 0xFEF00000 -#define NVNet_SIZE 0x400 -#define BIOS_BASE 0xFF000000 // this takes into account that the bios covers the top 16 MiB of memory -#define BIOS_XBOX_SIZE 0xFFFE00 -#define BIOS_CHIHIRO_SIZE 0x1000000 -#define MCPX_BASE 0xFFFFFE00 -#define MCPX_SIZE 0x200 #define MAX_VIRTUAL_ADDRESS 0xFFFFFFFF /*! base addresses of various components */ diff --git a/src/devices/EmuNVNet.cpp b/src/devices/EmuNVNet.cpp index 2dff00f47..f63ee5d90 100644 --- a/src/devices/EmuNVNet.cpp +++ b/src/devices/EmuNVNet.cpp @@ -514,14 +514,14 @@ void EmuNVNet_Write(xbaddr addr, uint32_t value, int size) // PCI Device functions -void NVNetDevice::Init() +void NVNetDevice::Init(unsigned int address) { PCIBarRegister r; // Register Memory bar : r.Raw.type = PCI_BAR_TYPE_MEMORY; - r.Memory.address = NVNET_ADDR >> 4; - RegisterBAR(0, NVNET_SIZE, r.value); + r.Memory.address = address >> 4; + RegisterBAR(0, NVNet_SIZE, r.value); // Register IO bar : r.Raw.type = PCI_BAR_TYPE_IO; diff --git a/src/devices/EmuNVNet.h b/src/devices/EmuNVNet.h index be80a8473..e669665fd 100644 --- a/src/devices/EmuNVNet.h +++ b/src/devices/EmuNVNet.h @@ -35,13 +35,11 @@ #include "PCIDevice.h" // For PCIDevice -#define NVNET_ADDR 0xFEF00000 -#define NVNET_SIZE 0x00000400 class NVNetDevice : public PCIDevice { public: // PCI Device functions - void Init(); + void Init(unsigned int address); void Reset(); uint32_t IORead(int barIndex, uint32_t port, unsigned size); void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size); diff --git a/src/devices/MCPXDevice.cpp b/src/devices/MCPXDevice.cpp index ec0ff9264..e2a7c4381 100644 --- a/src/devices/MCPXDevice.cpp +++ b/src/devices/MCPXDevice.cpp @@ -49,7 +49,7 @@ MCPXDevice::MCPXDevice(MCPXRevision revision) // PCI Device functions -void MCPXDevice::Init() +void MCPXDevice::Init(unsigned int address) { // m_DeviceId = ?; // m_VendorId = PCI_VENDOR_ID_NVIDIA; diff --git a/src/devices/MCPXDevice.h b/src/devices/MCPXDevice.h index 73a42c375..5141be11c 100644 --- a/src/devices/MCPXDevice.h +++ b/src/devices/MCPXDevice.h @@ -51,7 +51,7 @@ public: MCPXDevice(MCPXRevision revision); // PCI Device functions - void Init(); + void Init(unsigned int address); void Reset(); uint32_t IORead(int barIndex, uint32_t port, unsigned size); diff --git a/src/devices/PCIBus.cpp b/src/devices/PCIBus.cpp index da222ac4f..230a9a73d 100644 --- a/src/devices/PCIBus.cpp +++ b/src/devices/PCIBus.cpp @@ -1,7 +1,7 @@ #include "PCIBus.h" #include -void PCIBus::ConnectDevice(uint32_t deviceId, PCIDevice *pDevice) +void PCIBus::ConnectDevice(uint32_t deviceId, PCIDevice *pDevice, unsigned int address) { if (m_Devices.find(deviceId) != m_Devices.end()) { printf("PCIBus: Attempting to connect two devices to the same device address\n"); @@ -9,7 +9,7 @@ void PCIBus::ConnectDevice(uint32_t deviceId, PCIDevice *pDevice) } m_Devices[deviceId] = pDevice; - pDevice->Init(); + pDevice->Init(address); } void PCIBus::IOWriteConfigAddress(uint32_t pData) diff --git a/src/devices/PCIBus.h b/src/devices/PCIBus.h index 29dc9b6cf..8e84d6b13 100644 --- a/src/devices/PCIBus.h +++ b/src/devices/PCIBus.h @@ -30,7 +30,7 @@ typedef struct { class PCIBus { public: - void ConnectDevice(uint32_t deviceId, PCIDevice *pDevice); + void ConnectDevice(uint32_t deviceId, PCIDevice *pDevice, unsigned int address); bool IORead(uint32_t addr, uint32_t* value, unsigned size); bool IOWrite(uint32_t addr, uint32_t value, unsigned size); diff --git a/src/devices/PCIDevice.h b/src/devices/PCIDevice.h index 270338d05..5a137e089 100644 --- a/src/devices/PCIDevice.h +++ b/src/devices/PCIDevice.h @@ -18,6 +18,28 @@ #define PCI_VENDOR_ID_NVIDIA 0x10DE +// MMIO addresses and sizes for the various xbox devices +#define NV2A_ADDR 0xFD000000 +#define NV2A_SIZE 0x01000000 +#define NV2A_PRAMIN_ADDR 0xFD700000 +#define NV2A_PRAMIN_SIZE 0x100000 +#define NV2A_USER_ADDR 0xFD800000 +#define NV2A_USER_SIZE 0x800000 +#define APU_BASE 0xFE800000 +#define APU_SIZE 0x80000 +#define AC97_BASE 0xFEC00000 +#define AC97_SIZE 0x1000 +#define USB0_BASE 0xFED00000 +#define USB1_BASE 0xFED08000 +#define USB_SIZE 0x1000 +#define NVNet_BASE 0xFEF00000 +#define NVNet_SIZE 0x400 +#define BIOS_BASE 0xFF000000 // this takes into account that the bios covers the top 16 MiB of memory +#define BIOS_XBOX_SIZE 0xFFFE00 +#define BIOS_CHIHIRO_SIZE 0x1000000 +#define MCPX_BASE 0xFFFFFE00 +#define MCPX_SIZE 0x200 + class PCIDevice; typedef struct @@ -65,7 +87,7 @@ typedef struct { class PCIDevice { // PCI Device Interface public: - virtual void Init() = 0; + virtual void Init(unsigned int address) = 0; virtual void Reset() = 0; virtual uint32_t IORead(int barIndex, uint32_t port, unsigned size) = 0; virtual void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) = 0; diff --git a/src/devices/SMBus.cpp b/src/devices/SMBus.cpp index 90b13a268..eaff032e9 100644 --- a/src/devices/SMBus.cpp +++ b/src/devices/SMBus.cpp @@ -2,11 +2,11 @@ #include "SMBus.h" -void SMBus::Init() +void SMBus::Init(unsigned int address) { PCIBarRegister r; r.Raw.type = PCI_BAR_TYPE_IO; - r.IO.address = 0xC000; + r.IO.address = address; RegisterBAR(1, 32, r.value); m_DeviceId = 0x01B4; diff --git a/src/devices/SMBus.h b/src/devices/SMBus.h index e78995de1..f3ac3dda9 100644 --- a/src/devices/SMBus.h +++ b/src/devices/SMBus.h @@ -51,7 +51,7 @@ class SMBus : public PCIDevice { using PCIDevice::PCIDevice; // PCI Functions - void Init(); + void Init(unsigned int address); void Reset(); uint32_t IORead(int barIndex, uint32_t addr, unsigned size = sizeof(uint8_t)); diff --git a/src/devices/USBController/USBDevice.cpp b/src/devices/USBController/USBDevice.cpp new file mode 100644 index 000000000..10ba9c3bc --- /dev/null +++ b/src/devices/USBController/USBDevice.cpp @@ -0,0 +1,52 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->devices->USBController->USBDevice.cpp +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2018 ergo720 +// * +// * All rights reserved +// * +// ****************************************************************** + +#include "USBDevice.h" + + +void USBDevice::Init(unsigned int address) +{ + PCIBarRegister r; + + // Register Memory bar : + r.Raw.type = PCI_BAR_TYPE_MEMORY; + r.Memory.address = address >> 4; + RegisterBAR(0, USB_SIZE, r.value); + + // Taken from https://github.com/docbrown/vxb/wiki/Xbox-Hardware-Information + m_DeviceId = 0x01C2; + m_VendorId = PCI_VENDOR_ID_NVIDIA; +} \ No newline at end of file diff --git a/src/devices/USBController/USBDevice.h b/src/devices/USBController/USBDevice.h new file mode 100644 index 000000000..ba5f1c2fd --- /dev/null +++ b/src/devices/USBController/USBDevice.h @@ -0,0 +1,60 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->devices->USBController->USBDevice.h +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2018 ergo720 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef USBDEVICE_H_ +#define USBDEVICE_H_ + +#include "..\PCIDevice.h" + +class USBDevice : public PCIDevice { + public: + // constructor + USBDevice() {} + // destructor + ~USBDevice() {} + + // PCI Device functions + void Init(unsigned int address); + void Reset() {} + + uint32_t IORead(int barIndex, uint32_t port, unsigned size); + void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size); + uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size); + void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size); + + +}; + +#endif \ No newline at end of file diff --git a/src/devices/Xbox.cpp b/src/devices/Xbox.cpp index 8f1688def..10a43de32 100644 --- a/src/devices/Xbox.cpp +++ b/src/devices/Xbox.cpp @@ -33,6 +33,7 @@ // * All rights reserved // * // ****************************************************************** + #include "Xbox.h" // For HardwareModel PCIBus* g_PCIBus; @@ -43,6 +44,8 @@ EEPROMDevice* g_EEPROM; NVNetDevice* g_NVNet; NV2ADevice* g_NV2A; ADM1032Device* g_ADM1032; +USBDevice* g_USB0; +USBDevice* g_USB1; MCPXRevision MCPXRevisionFromHardwareModel(HardwareModel hardwareModel) { @@ -127,6 +130,8 @@ void InitXboxHardware(HardwareModel hardwareModel) g_NVNet = new NVNetDevice(); g_NV2A = new NV2ADevice(); g_ADM1032 = new ADM1032Device(); + g_USB0 = new USBDevice(); + g_USB1 = new USBDevice(); // Connect devices to SM bus g_SMBus->ConnectDevice(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, g_SMC); // W 0x20 R 0x21 @@ -149,12 +154,14 @@ void InitXboxHardware(HardwareModel hardwareModel) } // Connect devices to PCI bus - g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(1, 1)), g_SMBus); - g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(4, 0)), g_NVNet); + g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(1, 1)), g_SMBus, 0xC000); + g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(4, 0)), g_NVNet, NVNet_BASE); //g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(4, 1)), g_MCPX); // MCPX device ID = 0x0808 ? //g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(5, 0)), g_NVAPU); //g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(6, 0)), g_AC97); - g_PCIBus->ConnectDevice(PCI_DEVID(1, PCI_DEVFN(0, 0)), g_NV2A); + g_PCIBus->ConnectDevice(PCI_DEVID(1, PCI_DEVFN(0, 0)), g_NV2A, NV2A_ADDR); + g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(2, 0)), g_USB0, USB0_BASE); + g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(3, 0)), g_USB1, USB1_BASE); // TODO : Handle other SMBUS Addresses, like PIC_ADDRESS, XCALIBUR_ADDRESS // Resources : http://pablot.com/misc/fancontroller.cpp diff --git a/src/devices/Xbox.h b/src/devices/Xbox.h index 634f1ace9..0be572227 100644 --- a/src/devices/Xbox.h +++ b/src/devices/Xbox.h @@ -43,6 +43,7 @@ #include "EmuNVNet.h" // For NVNetDevice #include "ADM1032Device.h" // For ADM1032 #include "devices\video\nv2a.h" // For NV2ADevice +#include "USBController\USBDevice.h" // For USBDevice #define SMBUS_ADDRESS_MCPX 0x10 // = Write; Read = 0x11 #define SMBUS_ADDRESS_TV_ENCODER 0x88 // = Write; Read = 0x89 @@ -78,5 +79,7 @@ extern SMCDevice* g_SMC; extern EEPROMDevice* g_EEPROM; extern NVNetDevice* g_NVNet; extern NV2ADevice* g_NV2A; +extern USBDevice* g_USB0; +extern USBDevice* g_USB1; extern void InitXboxHardware(HardwareModel hardwareModel); \ No newline at end of file diff --git a/src/devices/video/nv2a.cpp b/src/devices/video/nv2a.cpp index 501ca33b9..aede3c54e 100644 --- a/src/devices/video/nv2a.cpp +++ b/src/devices/video/nv2a.cpp @@ -846,13 +846,13 @@ NV2ADevice::~NV2ADevice() // PCI Device functions -void NV2ADevice::Init() +void NV2ADevice::Init(unsigned int address) { PCIBarRegister r; // Register Memory bar : r.Raw.type = PCI_BAR_TYPE_MEMORY; - r.Memory.address = NV2A_ADDR >> 4; + r.Memory.address = address >> 4; RegisterBAR(0, NV2A_SIZE, r.value); // Register physical memory on bar 1 diff --git a/src/devices/video/nv2a.h b/src/devices/video/nv2a.h index 52c3009c5..62d54f60d 100644 --- a/src/devices/video/nv2a.h +++ b/src/devices/video/nv2a.h @@ -55,11 +55,8 @@ #include "qemu-thread.h" // For qemu_mutex, etc #include "nv2a_shaders.h" // For ShaderBinding -#define NV2A_ADDR 0xFD000000 -#define NV2A_SIZE 0x01000000 - #define NV_PMC_SIZE 0x001000 -#define _NV_PFIFO_SIZE 0x002000 // Underscore prefix to prevent clash with NV_PFIFO_SIZE +#define _NV_PFIFO_SIZE 0x002000 // Underscore prefix to prevent clash with NV_PFIFO_SIZE #define NV_PVIDEO_SIZE 0x001000 #define NV_PTIMER_SIZE 0x001000 #define NV_PFB_SIZE 0x001000 @@ -640,7 +637,7 @@ public: ~NV2ADevice(); // PCI Device functions - void Init(); + void Init(unsigned int address); void Reset(); uint32_t IORead(int barIndex, uint32_t port, unsigned size);