Initial implementation for Heathrow/Mac-io.

This commit is contained in:
Maxim Poliakovski 2019-08-23 23:34:19 +02:00
parent af5a096532
commit 3131325bff
3 changed files with 160 additions and 11 deletions

44
devices/heathrow.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <cinttypes>
#include <iostream>
#include "macio.h"
using namespace std;
uint32_t HeathrowIC::pci_cfg_read(uint32_t reg_offs, uint32_t size)
{
return this->pci_cfg_hdr[reg_offs & 0xFF];
}
void HeathrowIC::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size)
{
switch(reg_offs) {
case CFG_REG_BAR0: // base address register
value = LE2BE(value);
if (value == 0xFFFFFFFF) {
cout << this->name << " err: BAR0 block size determination not "
<< "implemented yet" << endl;
} else if (value & 1) {
cout << this->name << " err: BAR0 I/O space not supported!" << endl;
} else if (value & 0x06) {
cout << this->name << " err: BAR0 64-bit I/O space not supported!"
<< endl;
} else {
this->base_addr = value & 0xFFFFFFF0;
this->host_instance->pci_register_mmio_region(this->base_addr, 0x80000, this);
cout << this->name << " base address set to " << hex << this->base_addr
<< endl;
}
break;
}
}
uint32_t HeathrowIC::read(uint32_t offset, int size)
{
cout << this->name << ": reading from offset " << hex << offset << endl;
return 0;
}
void HeathrowIC::write(uint32_t offset, uint32_t value, int size)
{
cout << this->name << ": writing to offset " << hex << offset << endl;
}

97
devices/macio.h Normal file
View File

@ -0,0 +1,97 @@
/** MacIO device family emulation
Mac I/O (MIO) is a family of ASICs to bring support for Apple legacy
I/O hardware to PCI-based Power Macintosh. That legacy hardware has
existed long before Power Macintosh was introduced. It includes:
- versatile interface adapter (VIA)
- Sander-Woz integrated machine (SWIM) that is a floppy disk controller
- CUDA MCU for ADB, parameter RAM, realtime clock and power management support
- serial communication controller (SCC)
- Macintosh Enhanced SCSI Hardware (MESH)
In the 68k Macintosh era, all this hardware was implemented using several
custom chips. In PCI-compatible Power Macintosh, the above devices are part
of the MIO chip itself. MIO's functional blocks implementing virtual devices
are called "cells", i.e. "VIA cell", "SWIM cell" etc.
MIO itself is PCI compliant while the legacy hardware it emulates isn't.
MIO occupies 512Kb of PCI memory space divided into registers space and DMA
space. Access to emulated legacy devices is accomplished by reading from/
writing to MIO's PCI address space at predefined offsets.
MIO includes a DMA controller that offers 15 DMA channels implementing
Apple's own DMA protocol called descriptor-based DMA (DBDMA).
Official documentation (that is somewhat incomplete and erroneous) can be
found in the second chapter of the book "Macintosh Technology in the Common
Hardware Reference Platform" by Apple Computer, Inc.
*/
#ifndef MACIO_H
#define MACIO_H
#include <cinttypes>
#include "pcidevice.h"
#include "memctrlbase.h"
#include "mmiodevice.h"
#include "pcihost.h"
/**
Heathrow ASIC emulation
Author: Max Poliakovski
Heathrow is a MIO-compliant ASIC used in the Gossamer architecture. It's
hard-wired to PCI device number 16. Its I/O memory (512Kb) will be configured
by the Macintosh firmware to live at 0xF3000000.
Emulated subdevices and their offsets within Heathrow I/O space:
----------------------------------------------------------------
mesh(SCSI) register space: 0x00010000, DMA space: 0x00008000
bmac(ethernet) register space: 0x00011000, DMA space: 0x00008200, 0x00008300
escc(serial) register space: 0x00013000, size: 0x00001000
DMA space: 0x00008400, size: 0x00000400
escc:ch-a register space: 0x00013020, DMA space: 0x00008400, 0x00008500
escc:ch-b register space: 0x00013000, DMA space: 0x00008600, 0x00008700
davbus(sound) register space: 0x00014000, DMA space: 0x00008800, 0x00008900
SWIM3(floppy) register space: 0x00015000, DMA space: 0x00008100
NVRAM register space: 0x00060000, size: 0x00020000
IDE register space: 0x00020000, DMA space: 0x00008b00
VIA-CUDA register space: 0x00016000, size: 0x00002000
*/
class HeathrowIC : public PCIDevice
{
public:
using PCIDevice::name;
HeathrowIC() : PCIDevice("mac-io/heathrow") {};
~HeathrowIC() = default;
void set_host(PCIHost *host_instance) {this->host_instance = host_instance;};
/* PCI device methods */
uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size);
void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
/* MMIO device methods */
uint32_t read(uint32_t offset, int size);
void write(uint32_t offset, uint32_t value, int size);
private:
uint8_t pci_cfg_hdr[256] = {
0x6B, 0x10, // vendor ID: Apple Computer Inc.
0x10, 0x00, // device ID: Heathrow Mac I/O
0x00, 0x00, // PCI command (set to 0 at power-up?)
0x00, 0x00, // PCI status (set to 0 at power-up?)
0x01, // revision ID
// class code is reported in OF property "class-code" as 0xff0000
0x00, // standard programming
0x00, // subclass code
0xFF, // class code: unassigned
0x00, 0x00, // unknown defaults
0x00, 0x00 // unknown defaults
};
};
#endif /* MACIO_H */

View File

@ -26,7 +26,8 @@
#include "devices/mpc106.h"
#include "openpic.h"
#include "debugger.h"
//#include <vector>
#include "devices/macio.h"
#include "devices/mpc106.h"
#define max_16b_int 65535
#define max_32b_int 4294967295
@ -83,6 +84,7 @@ uint32_t ppc_next_instruction_address; //Used for branching, setting up the NIA
uint32_t return_value;
MemCtrlBase *mem_ctrl_instance = 0;
HeathrowIC *heathrow = 0;
//A pointer to a pointer, used for quick movement to one of the following
//memory areas. These are listed right below.
@ -546,17 +548,22 @@ int main(int argc, char **argv)
}
switch(rom_id) {
case 0x476F7373:
cout << "Initialize Gossamer hardware...";
mem_ctrl_instance = new MPC106();
if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000) ||
!mem_ctrl_instance->add_ram_region(0x00000000, 0x800000)) {
cout << "failure!\n" << endl;
delete(mem_ctrl_instance);
romFile.close();
return 1;
case 0x476F7373: {
cout << "Initialize Gossamer hardware...";
MPC106 *mpc106 = new MPC106();
mem_ctrl_instance = mpc106;
if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000) ||
!mem_ctrl_instance->add_ram_region(0x00000000, 0x800000)) {
cout << "failure!\n" << endl;
delete(mem_ctrl_instance);
romFile.close();
return 1;
}
heathrow = new HeathrowIC();
assert(heathrow != 0);
mpc106->pci_register_device(16, heathrow);
cout << "done" << endl;
}
cout << "done" << endl;
break;
default:
cout << "This machine not supported yet." << endl;
@ -785,6 +792,7 @@ int main(int argc, char **argv)
std::cout << "playground - Mess around with and opcodes. " << endl;
}
delete(heathrow);
delete(mem_ctrl_instance);
//Free memory after the emulation is completed.