2020-02-28 16:04:28 +00:00
|
|
|
/*
|
|
|
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
2022-03-11 07:47:11 +00:00
|
|
|
Copyright (C) 2018-22 divingkatae and maximum
|
2020-02-28 16:04:28 +00:00
|
|
|
(theweirdo) spatium
|
|
|
|
|
|
|
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 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 received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2019-08-23 21:30:33 +00:00
|
|
|
#ifndef PCI_DEVICE_H
|
|
|
|
#define PCI_DEVICE_H
|
|
|
|
|
2021-10-23 18:17:47 +00:00
|
|
|
#include <devices/common/mmiodevice.h>
|
|
|
|
#include <devices/common/pci/pcihost.h>
|
|
|
|
|
2020-05-12 18:55:45 +00:00
|
|
|
#include <cinttypes>
|
2022-03-11 07:47:11 +00:00
|
|
|
#include <functional>
|
2022-04-13 21:01:27 +00:00
|
|
|
#include <memory>
|
2020-05-12 18:55:45 +00:00
|
|
|
#include <string>
|
2019-08-23 21:30:33 +00:00
|
|
|
|
2020-03-31 19:12:06 +00:00
|
|
|
/** PCI configuration space registers offsets */
|
2019-08-23 21:30:33 +00:00
|
|
|
enum {
|
2022-03-11 07:47:11 +00:00
|
|
|
PCI_CFG_DEV_ID = 0x00, // device and vendor IDs
|
|
|
|
PCI_CFG_STAT_CMD = 0x04, // command/status register
|
|
|
|
PCI_CFG_CLASS_REV = 0x08, // class code and revision ID
|
|
|
|
PCI_CFG_DWORD_3 = 0x0C, // BIST, HeaderType, Lat_Timer and Cache_Line_Size
|
|
|
|
PCI_CFG_BAR0 = 0x10, // base address register 0
|
|
|
|
PCI_CFG_BAR1 = 0x14, // base address register 1
|
|
|
|
PCI_CFG_BAR2 = 0x18, // base address register 2
|
|
|
|
PCI_CFG_BAR3 = 0x1C, // base address register 3
|
|
|
|
PCI_CFG_BAR4 = 0x20, // base address register 4
|
|
|
|
PCI_CFG_BAR5 = 0x24, // base address register 5
|
|
|
|
PCI_CFG_CIS_PTR = 0x28, // Cardbus CIS Pointer
|
|
|
|
PCI_CFG_SUBSYS_ID = 0x2C, // Subsysten IDs
|
|
|
|
PCI_CFG_ROM_BAR = 0x30, // expansion ROM base address
|
2022-08-22 09:39:07 +00:00
|
|
|
PCI_CFG_CAP_PTR = 0x34, // capabilities pointer
|
|
|
|
PCI_CFG_DWORD_14 = 0x38, // reserved
|
2022-03-11 07:47:11 +00:00
|
|
|
PCI_CFG_DWORD_15 = 0x3C, // Max_Lat, Min_Gnt, Int_Pin and Int_Line registers
|
|
|
|
};
|
|
|
|
|
|
|
|
/** PCI Vendor IDs for devices used in Power Macintosh computers. */
|
|
|
|
enum {
|
|
|
|
PCI_VENDOR_ATI = 0x1002,
|
|
|
|
PCI_VENDOR_MOTOROLA = 0x1057,
|
|
|
|
PCI_VENDOR_APPLE = 0x106B,
|
2022-10-26 06:06:59 +00:00
|
|
|
PCI_VENDOR_NVIDIA = 0x10DE,
|
2019-08-23 21:30:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class PCIDevice : public MMIODevice {
|
|
|
|
public:
|
2022-03-11 07:47:11 +00:00
|
|
|
PCIDevice(std::string name);
|
2019-08-23 21:30:33 +00:00
|
|
|
virtual ~PCIDevice() = default;
|
|
|
|
|
2022-03-11 07:47:11 +00:00
|
|
|
virtual bool supports_io_space() {
|
|
|
|
return false;
|
|
|
|
};
|
2020-03-31 19:12:06 +00:00
|
|
|
|
|
|
|
/* I/O space access methods */
|
2020-05-12 18:55:45 +00:00
|
|
|
virtual bool pci_io_read(uint32_t offset, uint32_t size, uint32_t* res) {
|
|
|
|
return false;
|
|
|
|
};
|
2020-03-31 19:12:06 +00:00
|
|
|
|
2020-05-12 18:55:45 +00:00
|
|
|
virtual bool pci_io_write(uint32_t offset, uint32_t value, uint32_t size) {
|
|
|
|
return false;
|
|
|
|
};
|
2020-03-31 19:12:06 +00:00
|
|
|
|
2022-03-11 07:47:11 +00:00
|
|
|
// configuration space access methods
|
|
|
|
virtual uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size);
|
|
|
|
virtual void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
|
|
|
|
|
|
|
|
// plugin interface for using in the derived classes
|
|
|
|
std::function<uint16_t()> pci_rd_stat;
|
|
|
|
std::function<void(uint16_t)> pci_wr_stat;
|
|
|
|
std::function<uint16_t()> pci_rd_cmd;
|
|
|
|
std::function<void(uint16_t)> pci_wr_cmd;
|
|
|
|
std::function<uint8_t()> pci_rd_bist;
|
|
|
|
std::function<void(uint8_t)> pci_wr_bist;
|
|
|
|
std::function<uint8_t()> pci_rd_lat_timer;
|
|
|
|
std::function<void(uint8_t)> pci_wr_lat_timer;
|
|
|
|
std::function<uint8_t()> pci_rd_cache_lnsz;
|
|
|
|
std::function<void(uint8_t)> pci_wr_cache_lnsz;
|
|
|
|
|
|
|
|
std::function<void(int)> pci_notify_bar_change;
|
2019-08-23 21:30:33 +00:00
|
|
|
|
2022-04-13 21:01:27 +00:00
|
|
|
int attach_exp_rom_image(const std::string img_path);
|
|
|
|
|
2020-05-12 18:55:45 +00:00
|
|
|
virtual void set_host(PCIHost* host_instance) {
|
|
|
|
this->host_instance = host_instance;
|
|
|
|
};
|
2019-08-23 21:30:33 +00:00
|
|
|
|
|
|
|
protected:
|
2022-03-11 07:47:11 +00:00
|
|
|
void do_bar_sizing(int bar_num);
|
|
|
|
void set_bar_value(int bar_num, uint32_t value);
|
2022-08-20 10:51:08 +00:00
|
|
|
void map_exp_rom_mem();
|
2022-03-11 07:47:11 +00:00
|
|
|
|
2020-05-12 18:55:45 +00:00
|
|
|
std::string pci_name; // human-readable device name
|
|
|
|
PCIHost* host_instance; // host bridge instance to call back
|
2022-03-11 07:47:11 +00:00
|
|
|
|
|
|
|
// PCI configuration space state
|
|
|
|
uint16_t vendor_id;
|
|
|
|
uint16_t device_id;
|
|
|
|
uint32_t class_rev; // class code and revision id
|
|
|
|
uint16_t status = 0;
|
|
|
|
uint16_t command = 0;
|
|
|
|
uint8_t hdr_type = 0; // header type
|
|
|
|
uint8_t lat_timer = 0; // latency timer
|
|
|
|
uint8_t cache_ln_sz = 0; // cache line size
|
|
|
|
uint16_t subsys_id = 0;
|
|
|
|
uint16_t subsys_vndr = 0;
|
2022-08-22 09:39:07 +00:00
|
|
|
uint8_t cap_ptr = 0;
|
2022-03-11 07:47:11 +00:00
|
|
|
uint8_t max_lat = 0;
|
|
|
|
uint8_t min_gnt = 0;
|
|
|
|
uint8_t irq_pin = 0;
|
|
|
|
uint8_t irq_line = 0;
|
|
|
|
|
|
|
|
uint32_t bars[6] = { 0 }; // base address registers
|
|
|
|
uint32_t bars_cfg[6] = { 0 }; // configuration values for base address registers
|
2022-04-13 21:01:27 +00:00
|
|
|
|
|
|
|
uint32_t exp_bar_cfg = 0; // expansion ROM configuration
|
|
|
|
uint32_t exp_rom_bar = 0; // expansion ROM base address register
|
|
|
|
uint32_t exp_rom_addr = 0; // expansion ROM base address
|
|
|
|
uint32_t exp_rom_size = 0; // expansion ROM size in bytes
|
|
|
|
|
|
|
|
std::unique_ptr<uint8_t[]> exp_rom_data;
|
2019-08-23 21:30:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* PCI_DEVICE_H */
|