Commit Graph

80 Commits

Author SHA1 Message Date
Mihai Parparita
cf4913deb0 bandit: Fix regression in non-Aspen PCI bridge
Refactor from e7da98b6bd accidentally
made the non-Aspen PCI code path for CONFIG_ADDR writes by a no-op.
2024-04-08 15:41:19 -05:00
Maxim Poliakovski
e7da98b6bd bandit: implement Aspen style PCI bridge. 2024-04-08 00:44:24 +02:00
Maxim Poliakovski
19dcb43658 pcibase.h: remove superfluous spaces. 2024-04-07 18:48:52 +02:00
joevt
60a4738694 Add stub for pci_unregister_device. 2024-03-27 18:23:27 -07:00
joevt
a26628ed50 bandit: Add delayed aack register. 2024-03-26 07:34:08 -07:00
joevt
fafbd9a04f mmiodevice: Move SIZE_ARG macro from pcibase. 2024-03-24 13:03:31 -07:00
joevt
78020c4794 Add Bandit2 and properties for Chaos. 2024-03-20 07:38:39 -07:00
joevt
a11770961e Add pci_find_device for pci type 0 requests. 2024-03-09 17:49:51 -07:00
joevt
777a02cbe9 pci: Use SIZE_ARG for logging arg size.
The SIZE_ARG macro defined in pcibase can be used outside pcibase with a small modification.
2024-03-04 21:16:46 -07:00
joevt
61b1940397 pci: Add command register mask.
The mask represents the list of bits that are allowed to change in the command register of PCI config space.
2024-03-04 21:16:38 -07:00
joevt
6503a300cc Add PCI interrupt method.
A PCI device passes an interrupt to its host. The host will determine from the PCI device which interrupt to trigger.
2024-03-04 07:47:20 -07:00
joevt
be80595834 Remove obsolete pci config type 1 methods.
pci_find_device is the method used to pass pci config type 1 methods to child PCI devices.
2024-03-04 07:47:08 -07:00
joevt
54bda0ea95 pci: Change pci_conv_rd_data unaligned.
pci_conv_rd_data can be used to handle unaligned or 64-bit accesses in mmio regions if it's modified to include the next 32-bit value.
For pci config accesses, grackle repeats the 32-bit value. bandit uses a seemingly random number for the next 32-bit value, but we'll make it work like grackle.
2024-03-03 20:06:13 -07:00
joevt
6d23e18c11 pci: Add PCI CardBus bridge.
PCCard is used by PowerBook G3 Wallstreet in Open Firmware 2.0.1.
CardBus is probed in New World Macs starting from at least Open Firmware 4.1.9f1 sometime after Open Firmware 3.1.1.

- Create PCIBase from common stuff in PCIDevice.
- Add PCIBridgeBase. These have a primary bus number, secondary bus number, and subordinate bus number which are used to determine if PCI type 1 config cycle should be passed.
- Change PCIBridge to use PCIBridgeBase instead of PCIDevice.
- Add PCICardBusBridge which uses PCIBridgeBase.
2024-03-03 16:00:55 -07:00
joevt
5f8e7fcb73 pci: Log invalid BAR values.
For example, Old World Macs have versions of Open Firmware that don't support 512 MB BARs correctly. They may attempt to set such a BAR to 0x90000000 (a 256 MB boundary) instead of 0xA0000000 (the next available 512 MB boundary).
2024-03-03 15:49:59 -07:00
joevt
d426d0faeb Add settings when adding pci device. 2024-03-03 15:01:39 -07:00
joevt
5876cc7e17 bandit: Fix indent. 2024-03-02 08:09:42 -07:00
joevt
2998796c2c pci: Fix log message for PCI rom exceptions.
It should log device name, not just "PCIDevice".
2024-03-01 08:02:01 -07:00
Mihai Parparita
35c86ad6bf Clean up #includes
Result of running IWYU (https://include-what-you-use.org/) and
applying most of the suggestions about unncessary includes and
forward declarations.

Was motivated by observing that <thread> was being included in
ppcopcodes.cpp even though it was unused (found while researching
the use of threads), but seems generally good to help with build
times and correctness.
2023-11-03 00:33:47 -07:00
Maxim Poliakovski
0b2fd60308 Fix Gazelle crash by adding PCI slot properties. 2023-05-30 19:48:40 +02:00
Maxim Poliakovski
03595c3940 Merge remote-tracking branch 'origin/machine-yosemite' 2023-04-21 12:49:58 +02:00
Maxim Poliakovski
49f47c5f3f bandit: attach devices from the CLI. 2023-04-02 03:01:13 +02:00
Maxim Poliakovski
ad2fc290ec Initial DEC 21154 P2P bridge emulation. 2023-02-15 02:36:40 +01:00
Maxim Poliakovski
7e5451a97d Cosmetics: break long lines, fix indentation. 2023-02-08 11:41:37 +01:00
joevt
bee24b166d Add method to attach PCI device with new name.
- Added an overloaded version of attach_pci_device which takes a suffix string that can be used to make a device name unique so that multiple devices of the same class can be added to a machine. The method returns a PCIDevice which can be easily used to attach more PCI devices if it is a PCIHost.
2023-02-05 07:17:29 -08:00
joevt
f61854a0ae Add has_io_space flag.
PCIDevice
- supports_io_space method now uses a flag has_io_space which is automatically set for PCI bridges or PCI devices that have an I/O BAR.

atirage
- Devices that have I/O BARs don't need a supports_io_space method.

mpc106
- Devices that don't have I/O methods don't need a supports_io_space method.
2023-02-05 07:17:28 -08:00
joevt
99eb93f9e1 Add set_irq_pin method.
A multi-function device may have functions of the same class (e.g. a USB device with two OHCI functions) but each function should be initialized with a different interrupt pin.
2023-02-05 07:17:28 -08:00
joevt
be45a6a020 Add PCI bridge and multi-function device support.
Add PCI bridge and multi-function device support.
Overview:
- A multi-function device is two or more PCIDevices with the same device number but one device is function zero (as with currently implemented PCIDevices) and the other functions have function numbers between 1 and 7. The device number and function number are properties of the PCIDevice's parent PCIHost connection.
- A PCIBridge is a PCIHost (it can connect child PCI devices) and a PCIDevice (it has config space, BARs, and expansion ROM).
- A PCIDevice has Type 0 header. It has 6 BARs.
- A PCIBridge has Type 1 header. It has 2 BARs. The config space registers beginning from offset 0x18 differ from those of a PCIDevice.

Possible future modifications:
- Add a PCICardBus class. It is a PCIHost. It has Type 2 header. It has one BAR. The first 20 bytes match Type 0 and Type 1 headers. These exist in New World Macs. They allow hot-plug of PCI devices.
- Split base PCI registers (first 16 bytes) into a PCIBase class. Type 1 and 2 have two or one BAR but I think all 6 BARs belong in PCIBase class anyway.
- Split PCIHost into two classes: Currently existing PCIHosts (Bandit, Grackle) are PCIHost and PCIRoot (they have the broadcast I/O requests functionality) while PCIBridge is PCIHost only - it can propagate I/O requests but does not originate the broadcast.
- pci_register_mmio_region should maybe return a pointer to a region struct so that it can be used for unregistering or modifying the region's range. This may be useful for PCI bridges which have ranges that may constrain memory BARs of their downstream devices.

PCIDevice
- Moved expansion ROM BAR handling to a separate function pci_wr_exp_rom_bar so that it can be used by both PCI devices and PCI bridges which have the ROM BAR in different locations. It now supports unmapping expansion ROM. Also made exp_rom_bar not writable if there's no ROM.
- Added num_bars field which specifies the number of valid BARs since Type 0, 1, and 2 headers have different number of BARs.
- map_exp_rom_mem now properly unmaps expansion ROM (using new function unmap_exp_rom_mem) before mapping it again.
- Added function set_multi_function which modifies hdr_type to indicate if a device has other functions. This is to be applied only to devices with function number 0.

PCIHost
- When attaching a PCI device, it will check if it's a multi-function device (there exists an attached function that is not zero) and adjust hdr_type of function 0 of the device accordingly.
- Attached PCI bridges are added to a list of PCI bridges attached to the host.
- Added pci_io_read_loop and pci_io_write_loop which loop through attached PCI devices to find one that will perform the action for the given I/O address without logging an error (since some other device might perform the action).
- Added pci_io_read_broadcast and pci_io_write_broadcast which are used by a PCI root (bandit/grackle). They will log an error if the action is not performed. They should probably do a machine check exception to match real Power Macs.
- pci_find_device (used by PCI root) will recursively find a PCIDevice for type 1 config register accesses.
- Logging from PCIHost now includes the name of the PCIHost instead of just "PCIHost" because there can be multiple PCI hosts.

PCIBridge
- Sets num_bars to 2 and hdr_type to 1.
- I/O ranges set in the config registers are handled correctly by pci_io_read and pci_io_write.
- Memory ranges set in the config registers do not currently affect memory mmio regions. It is assumed that Open Firmware and the OS will set the ranges and BARs correctly to allow all BARs to be accessed fully.

bandit, mpc106
- Bandit and Grackle now call pci_io_read_broadcast and pci_io_read_broadcast to pass I/O accesses to downstream PCI devices.
- Chaos is modified to work like Bandit even though it will never have PCI bridges attached or devices that support I/O accesses. It's simpler this way.
2023-02-05 07:17:28 -08:00
joevt
b472123746 Standardize PCIDevice slot_id for PCIHost.
PCIHost
- PCIHosts (bandit and grackle) now use device number and function number for identifying attached PCIDevices. A macro DEV_FUN is added to calculate this new slot_id. Bandit no longer uses IDSEL. Grackle no longer uses only device number.

machinecatalyst, machinegossamer, machinetnt
- Use DEV_FUN to attach PCI devices by device number and function number.
2023-02-05 06:57:04 -08:00
joevt
f7280c316b Fix 64 bit BAR.
A 64 bit BAR has least significant 32 bits first as in the original pull request.
2023-02-05 01:22:01 -08:00
Maxim Poliakovski
cc17035e67 pcidevice: improve BAR configuration. 2023-02-04 17:57:46 +01:00
joevt
2a64f547cc Add 64-bit BAR support.
While dingusppc only emulates 32-bit Macs (for now), it is possible for a 32-bit Power Mac to use a PCIe card that has 64-bit BARs.

finish_config_bars is added to scan the cfg values of the BARs and determine their type. The type is stored separately so that it does not need to be determined again.
The type can be I/O (16 or 32 bit) or Mem (20 or 32 or 64 bit). A 64 bit bar is two BARs, the second contains the most significant 32 bits.

set_bar_value uses the stored type instead of trying to determine the type itself. It is always called even when the firmware is doing sizing. For sizing, It does the job of setting the bar value so do_bar_sizing is now just a stub.

Every PCIDevice that has a BAR needs to call finish_config_bars after setting up the cfg values just as they need to setup the cfg values. Since they need to do both, maybe the cfg values should be arguments of finish_config_bars, then finish_config_bars() should be renamed config_bars().
2023-02-02 02:47:34 -08:00
joevt
fba2ff4231 Corrections for refactors.
- Macros need parenthesis to enforce operation order when expanded.
- Fix device and register numbers in log messages.
- Unmapped I/O space reads don't necessarily return 0xffffffff. That's only for config space reads. Just return 0. Unhandled I/O space read should probably cause a memory check (TEA - Transfer Error Acknowledge) exception as it does on a Power Mac 8600.
2023-02-02 02:47:34 -08:00
Maxim Poliakovski
e64aab1577 Rename data conversion helpers for PCI config.
Reword some descriptions for better understanding.
2023-02-02 02:22:47 +01:00
Maxim Poliakovski
ec97a671d8 bandit: refactor host read and write methods. 2023-02-01 16:21:49 +01:00
Maxim Poliakovski
31db015105 pcihost: refactor data access helpers. 2023-01-31 23:20:31 +01:00
Maxim Poliakovski
289ddf10b7 bandit: clean up PCI device connection. 2023-01-23 14:06:39 +01:00
joevt
4100a80f96 Fix PCI config r/w of byte and word and unaligned.
dingusppc could not read bytes from offset 1,2,3 or words from offset 2.
dingusppc did not read words from offset 1,3 and longs from offset 1,2,3 in the same way as a real Power Mac 8600 or B&W G3.
This commit fixes those issues.

- Added pci_cfg_rev_read. It takes a 32 bit value from offset 0 and returns a value of the specified size using bytes starting from the specified offset. Offsets 4,5, & 6 wrap around to 0,1, & 2 respectively. The result bytes are in flipped order as required by the read method (so a value of 0x12345678 is returned as 0x78563412)
A real Power Mac 8600 might return a random byte for offset 4, 5, 6 for vci0 but usually not for pci1. A B&W G3 seems to always wrap around correctly. We won't read random bytes, and we won't read a default such as 00 or FF. We'll do the wrap around which makes the most sense because writing 0x12345678 to any offset and reading from the same offset should produce the value that was written.

- Added pci_cfg_rev_write. It takes a 32 bit value from offset 0, and modifies a specified number of bytes starting at a specified offset with the offset wrapping around to 0 if it exceeds 3. The modified bytes take their new values from the flipped bytes passed to pci_cfg_write. When size is 4, the original value is not used since all bytes will be modified.

Basically, those two functions handle all the sizes and all the offsets and replace calls to BYTESWAP_32, read_mem or read_mem_rev, and write_mem or write_mem_rev.
read_mem_rev, as it was used by pcidevice and some other places, could read beyond offset 3 if it were ever passed a reg_offs value that did not have offset as 0. Since the offset was always zero, it would always read the wrong byte or word if they were not at offset 0. Same for read_mem as used by mpc106.
write_mem_rev, as it was used by pcidevice and some other places, could write beyond offset 3 if it were ever passed a reg_offs value that did not have offset as 0. Since the offset was always zero, it would always write the wrong byte or word if they were not at offset 0. Same for write_mem as used by mpc106.

pcidevice:
- The logging macros should be used to handle all config register access logging.
- Unaligned PCI config register accesses will be output as ERROR instead of WARNING.
- The logging macros include the offset and size. They also include the value for named registers or for writes.
- Added MMIODevice read and write methods so that PCIDevice is not abstract if a PCIDevice doesn't override the read and write method since some PCIDevices don't have MMIO.

pcihost:
- Added pci_find_device stub for handling PCI bridges in future commit.

bandit and mpc106:
- PCI host controllers will handle all PCI config access alignment and sizing. A PCIDevice will always access config registers as 32 bits on a 4 byte boundary. The AccessDetails passed to a PCIDevice config read or write method is there only for logging purposes.

bandit:
- Common MMIO code is moved to new BanditHost class so both Bandit and Chaos can use it. PCI related code is moved to new BanditPCI class.
- Simplify IDSEL to/from PCI device number conversion by removing the shift or subtract.
- Remove BANDIT_ID_SEL check. The IDSEL conversion to PCI device number can find the bandit PCI device.
- For logging, make best guess of PCI device number from invalid IDSEL - the result is always reasonable for device 0x00 to 0x0A when accessing config register 0x00 (as one would do when scanning for PCI devices like lspci does).

mpc106:
- Common config space code is put in cfg_setup. It handles extracting the offset.
- Added code to log access to unimplemented config registers of grackle.
- Don't call setup_ram when writing to config registers that setup_ram doesn't use.
- pci_cfg_read calls READ_DWORD_LE_A and pci_cfg_write calls WRITE_DWORD_LE_A. When reading or writing memory that is organized as little endian dwords, such as my_pci_cfg_hdr of mpc106, the function should explicitly state that it's little endian so that the emulator may be ported one day to a CPU architecture that is not little endian.

atirage:
- The changes correctly place user_cfg at byte 0x40 instead of 0x43 and writes the correct byte depending on size and offset.
2023-01-16 00:09:44 -08:00
joevt
f2db6bd066 Add missing header. 2023-01-11 01:17:13 -08:00
joevt
64fec88436 Fix compiler warnings: cast loses precision.
Use explicit cast when converting large integer types to smaller integer types when it is known that the most significant bytes are not required.
For pcidevice, check the ROM file size before casting to int. We'll allow expansion ROM sizes up to 4MB but usually they are 64K, sometimes 128K, rarely 256K.
for machinefactory, change the type to size_t so that it can correctly get the size of files that are larger than 4GB; it already checks the file size is 4MB before we need to cast to uint32_t.
For floppyimg, check the image size before casting to int. For raw images, only allow files up to 2MB. For DiskCopy42 images, it already checks the file size, so do the cast after that.
2023-01-11 01:17:12 -08:00
joevt
52fa30b71d Add ability to unregister mmio region.
mmio regions are registered when a PCI BAR is set. Add the ability to reverse that - for when a PCI BAR is changed.
2023-01-11 00:05:23 -08:00
joevt
0bd9d0e973 Fix HWComponent name initialization.
First, remove name override for subclasses of HWComponent (Chaos and ScsiBus) because HWComponent has its own name field.

HWComponent name should be set as early as possible in the constructor so it can be used in log messages.
PCIDevice should set name of HWComponent (through MMIODevice) in its constructor, using the name that is given to its constructor.
For Bandit and Grackle, they don't need to set the HWComponent name since its PCIDevice constructor will now do it.
Chaos is not a PCIDevice so it should set the MMIODevice name itself.
Why does PCIDevice have a name that is separate from the HWComponent name?
2023-01-11 00:05:23 -08:00
joevt
5aaae40d94 Add Nvidia vendor ID.
In case you want to emulate an Nvidia GPU in the future (for Core Image, etc.)
2023-01-11 00:05:23 -08:00
joevt
37c352955c Allow bit 1 of I/O BARs to be set.
Usually bit 1 of I/O BARs is 0 since it is reserved, but control has an I/O BAR where this bit is set.
bar_cfg is used to determine the default values of the least significant bits (2 bits for I/O BARs and 4 bits for Memory BARs).
The upper bits of bar_cfg determine which bits can be set and also determines the size of the BAR.
2023-01-11 00:05:23 -08:00
Maxim Poliakovski
f6e208267e bandit: more config space registers. 2022-12-19 01:28:16 +01:00
Maxim Poliakovski
24ccdabedc bandit: add PSX style PCI bridge. 2022-12-18 23:40:56 +01:00
Maxim Poliakovski
14bcb6c08a Clean up previous commit. 2022-11-23 20:28:09 +01:00
joevt
09d374f626 Log PCI config write values MSB first
Writes to config registers of invalid or non-existent PCI devices are logged. They should be logged with most significant byte first.
The values enter the methods in reverse byte order so they need to be byte swapped (except when size is 1) for logging.
The result is that this command in Open Firmware:
`12345678 16800 config-l!`
will log this:
`VCI0 err: write attempt to non-existing VCI device ??:0d.0 @00.l = 12345678`
2022-11-23 19:55:05 +01:00
joevt
072d5ae330 Fix Expansion ROM BAR writes
The bits that can be set are the enable bit (bit 0) plus the bits represented by exp_bar_cfg which is determined by the size of the ROM which is calculated to be a power of 2 and a minimum of 2K.
2022-11-23 12:25:28 +01:00
joevt
9f1d613a2d Fix PCI struct offset size
The Pointer to PCI Data Structure is supposed to be two bytes. It is described in the PCI Firmware Specification Revision 3.0, section 5.1.1. PCI Expansion ROM Header Format.
The pointer is two bytes at 0x18. The pointer is supposed to be a multiple of 4 which means there's always at least two bytes of padding after the pointer. Some BIOS firmware images may use the 2 bytes following the pointer for other purposes (plus additional bytes before the PCI Data Structure) so we cannot assume the bytes will be zero.
Some PCI expansion ROMs may include both BIOS and Open Firmware images.
2022-10-23 00:26:32 -07:00