mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-09-06 05:54:32 +00:00
276 lines
14 KiB
Markdown
276 lines
14 KiB
Markdown
# Heathrow ASIC
|
||
|
||
The Heathrow ASIC is an intergrated I/O controller designed for use in Power
|
||
Macintosh G3 computers.
|
||
|
||
Its predecessors are Grand Central and O'Hare ASICs used in other Power Macintosh
|
||
computers. As those names suggest, Apple engineers liked to name their I/O controllers
|
||
after airports and train stations.
|
||
|
||
Heathrow and its siblings are collectively referred to as __mac-io__ devices in the
|
||
Open Firmware device tree.
|
||
|
||
## Mac I/O family
|
||
|
||
The purpose of a Mac I/O (MIO) controller is to bring support for Apple legacy
|
||
I/O hardware to the 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 that controls ADB, parameter RAM, realtime clock and power management
|
||
- serial communication controller (SCC)
|
||
- Macintosh Enhanced SCSI Hardware (MESH)
|
||
|
||
In the 68k Macintosh era, all this hardware was implemented in separate ICs.
|
||
In a PCI-compatible Power Macintosh, the above devices are part
|
||
of the MIO chip itself. MIO's functional blocks implementing the above 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 the 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.
|
||
|
||
## Heathrow I/O modules
|
||
|
||
Being a Mac I/O compatible device, the Heathrow ASIC contains the following modules/cells:
|
||
|
||
* VIA cell for establishing communication with the Cuda MCU (separate IC)
|
||
* ATA/IDE cell for controlling ATA-3 compatible drives
|
||
* enhanced serial communication controller (ESCC cell)
|
||
* Ethernet controller cell funnily called __bmac__
|
||
* floppy disk controller (SWIM3 cell)
|
||
* SCSI controller (MESH cell)
|
||
* integrated DBDMA controller
|
||
* interrupt controller
|
||
* logic for controlling built-in audio HW
|
||
* logic for accessing NVRAM (separate IC)
|
||
* logic for controlling a media bay on portables
|
||
|
||
## PCI configuration space registers
|
||
|
||
| Register name | Default value |
|
||
|:-------------:|:--------------:|
|
||
| VendorID | 0x106B (Apple) |
|
||
| DeviceID | 0x0010 |
|
||
| RevisionID | 0x01 |
|
||
| Class code | 0xFF0000 |
|
||
|
||
It looks like Heathrow supports only one Base Address Register - __BAR0__.
|
||
It contains base address of the memory-mapped registers programmed by system software
|
||
during system initialization.
|
||
|
||
## Memory-mapped registers
|
||
|
||
Software communicates with the Heathrow ASIC via memory-mapped registers that
|
||
occupy 512 Kb starting from the base address located in the BAR0 register
|
||
in the PCI configuration space.
|
||
|
||
Macintosh firmware configures the Heathrow ASIC to live at address `0xF3000000`.
|
||
|
||
### General chip control registers
|
||
|
||
| Offset | Register name | Description |
|
||
|:------:|:-----------------:|:----------------------------------------------:|
|
||
| 0x10 | InterruptEvents2 | each "1" bit indicates a pending int |
|
||
| 0x14 | InterruptMask2 | enabling (1) / disabling(0) of specific ints |
|
||
| 0x18 | InterruptClear2 | bit value "1" clears the corresponding int |
|
||
| 0x1C | InterruptLevels2 | interrupt status for devices 32...63 |
|
||
| 0x20 | InterruptEvents1 | each "1" bit indicates a pending int |
|
||
| 0x24 | InterruptMask1 | enabling (1) / disabling(0) of specific ints |
|
||
| 0x28 | InterruptClear1 | bit value "1" clears the corresponding int |
|
||
| 0x2C | InterruptLevels1 | interrupt status for devices 0...31 |
|
||
| 0x30 | UnknownReg30 | Not much is known about this register |
|
||
| 0x34 | HeathrowIDs | bits for identifying media bay features? |
|
||
| 0x38 | FeatureControl | bits for controlling Heathrow operation |
|
||
| 0x3C | AuxControl | auxilary control bits |
|
||
|
||
### Device DMA spaces
|
||
|
||
| Offset | Size in bytes | Space name |
|
||
|:------:|:-------------:|:-----------------------------:|
|
||
| 0x8000 | 256 | MESH SCSI DMA |
|
||
| 0x8100 | 256 | Floppy controller DMA |
|
||
| 0x8200 | 256 | Ethernet transmit DMA |
|
||
| 0x8300 | 256 | Ethernet receive DMA |
|
||
| 0x8400 | 256 | Serial channel A transmit DMA |
|
||
| 0x8500 | 256 | Serial channel A receive DMA |
|
||
| 0x8600 | 256 | Serial channel B transmit DMA |
|
||
| 0x8700 | 256 | Serial channel B receive DMA |
|
||
| 0x8800 | 256 | Audio output DMA |
|
||
| 0x8900 | 256 | Audio input DMA |
|
||
| 0x8A00 | 256 | unassigned DMA ? |
|
||
| 0x8B00 | 256 | internal ATA (IDE0) DMA |
|
||
| 0x8C00 | 256 | media bay (?) ATA (IDE1) DMA |
|
||
| 0x8D00 | 256 | unassigned DMA ? |
|
||
| 0x8E00 | 256 | unassigned DMA ? |
|
||
| 0x8F00 | 256 | unassigned DMA ? |
|
||
|
||
### Device register spaces
|
||
|
||
| Offset | Size | Space name |
|
||
|:-------:|:-------------:|:----------------------------------------:|
|
||
| 0x10000 | 4 KB | MESH SCSI controller registers |
|
||
| 0x11000 | 4 KB | Ethernet (bmac) controller registers |
|
||
| 0x12000 | 4 KB | Legacy serial (SCC) controller registers |
|
||
| 0x13000 | 4 KB | Serial (ESCC) controller registers |
|
||
| 0x14000 | 4 KB | Audio codec registers |
|
||
| 0x15000 | 4 KB | Floppy (SWIM3) controller registers |
|
||
| 0x16000 | 8 KB | VIA registers |
|
||
| 0x20000 | 4 KB | IDE0 registers |
|
||
| 0x21000 | 4 KB | IDE1 registers |
|
||
| 0x60000 | 128 KB | NVRAM access |
|
||
|
||
## Registers description
|
||
|
||
### General chip control
|
||
|
||
#### Feature control register
|
||
|
||
Bit names in the table below were pulled from Open Firmware v2.4.
|
||
The field "Description" represents my personal attempt to describe the function
|
||
of those bits based on publicly available Apple and Linux sources.
|
||
|
||
| Bit # | Active | Name | Description |
|
||
|:-----:|:------:|:-------------:|:---------------------------------------:|
|
||
| 0 | high | in_use_led | "1" enables monitor sense on G3 desktop |
|
||
| 1 | low | -mb_pwr | media bay power on/off |
|
||
| 2 | high | pci_mb_en | enable media bay PCI (?) |
|
||
| 3 | high | ide_mb_en | enable media bay ATA (IDE1) |
|
||
| 4 | high | floppy_en | enable floppy disk controller cell |
|
||
| 5 | high | ide_int_en | enable internal ATA (IDE0) |
|
||
| 6 | low | -ide0_reset | reset internal ATA |
|
||
| 7 | low | -mb_reset | reset media bay |
|
||
| 8 | high | iobus_enable | *not available* |
|
||
| 9 | high | scc_enable | enable SCC controller cell |
|
||
| 10 | high | scsi_cell_en | enable MESH SCSI controller cell |
|
||
| 11 | high | swim_cell_en | enable SWIM3 floppy controller cell |
|
||
| 12 | high | snd_pwr | *not available* |
|
||
| 13 | high | snd_clk_en | enable sound chip clock (?) |
|
||
| 14 | high | scc_a_enable | enable SCC channel A |
|
||
| 15 | high | scc_b_enable | enable SCC channel B |
|
||
| 16 | low | -port_via | switch VIA cell to portable mode (?) |
|
||
| 16 | high | desktop_via | switch VIA cell to desktop mode (?) |
|
||
| 17 | low | -pwm | *not available* |
|
||
| 17 | high | mon_id | *not available* |
|
||
| 18 | low | -hookpb | *not available* |
|
||
| 18 | high | mb_cnt | *not available* |
|
||
| 19 | low | -swimiii | floppy controller in SWIM3 mode (?) |
|
||
| 19 | high | clonefloppy | floppy controller in PC-compat mode (?) |
|
||
| 20 | high | aud22run | *not available* |
|
||
| 21 | high | scsi_linkmode | *not available* |
|
||
| 22 | high | arb_bypass | disable internal PCI arbiter (?) |
|
||
| 23 | low | -ide1_reset | reset media bay ATA |
|
||
| 24 | high | slow_scc_pclk | *not available* |
|
||
| 25 | high | reset_scc | reset serial (SCC) controller cell |
|
||
| 26 | high | mfdc_cell_en | enable PC-compat floppy controller (?) |
|
||
| 27 | high | use_mfdc | use PC floppy ctrl instead of SWIM3 ? |
|
||
| 29 | high | enet_ctrl_en | enable Ethernet controller cell (?) |
|
||
| 30 | high | enet_xcvr_en | enable Ethernet Transceiver (?) |
|
||
| 31 | high | enet_reset | reset Ethernet cell |
|
||
|
||
|
||
### Cell-specific registers
|
||
|
||
#### ATA cell registers
|
||
|
||
##### Internal ATA (IDE0)
|
||
|
||
| Offset from I/O base | Width in bits | Function on read | Function on write |
|
||
|:--------------------:|:-------------:|:-----------------:|:-----------------:|
|
||
| 0x20000 | 16 | Data | Data |
|
||
| 0x20010 | 8 | Error | Features |
|
||
| 0x20020 | 8 | Sector Count | Sector Count |
|
||
| 0x20030 | 8 | Sector Number | Sector Number |
|
||
| 0x20040 | 8 | Cylinder Low | Cylinder Low |
|
||
| 0x20050 | 8 | Cylinder High | Cylinder High |
|
||
| 0x20060 | 8 | Drive/Head | Drive/Head |
|
||
| 0x20070 | 8 | Status | Command |
|
||
| 0x20160 | 8 | Alternate Status | Device Control |
|
||
| 0x20200 | 32 | Timing Config | Timing Config |
|
||
|
||
##### Media Bay ATA (IDE1)
|
||
|
||
| Offset from I/O base | Width in bits | Function on read | Function on write |
|
||
|:--------------------:|:-------------:|:-----------------:|:-----------------:|
|
||
| 0x21000 | 16 | Data | Data |
|
||
| 0x21010 | 8 | Error | Features |
|
||
| 0x21020 | 8 | Sector Count | Sector Count |
|
||
| 0x21030 | 8 | Sector Number | Sector Number |
|
||
| 0x21040 | 8 | Cylinder Low | Cylinder Low |
|
||
| 0x21050 | 8 | Cylinder High | Cylinder High |
|
||
| 0x21060 | 8 | Drive/Head | Drive/Head |
|
||
| 0x21070 | 8 | Status | Command |
|
||
| 0x21160 | 8 | Alternate Status | Device Control |
|
||
| 0x21200 | 32 | Timing Config | Timing Config |
|
||
|
||
##### Timing Config Register
|
||
|
||
The timing config register is specific to Apple's ATA implementation. According
|
||
with
|
||
[this source](https://android.googlesource.com/kernel/msm/+/android-wear-5.0.2_r0.1/drivers/ata/pata_macio.c),
|
||
this register is used to control timings for Multiword DMA (MDMA) and Programmed I/O (PIO) modes.
|
||
|
||
This register has the following format:
|
||
|
||
| 31 ... 22 | 21 | 20 ... 16 | 15 ... 11 | 10 | 9 ... 5 | 4 ... 0 |
|
||
|------------|----|---------------|-------------|----|--------------|------------|
|
||
| Unused (?) | HT | MDMA Recovery | MDMA Access | E | PIO Recovery | PIO Access |
|
||
|
||
I don't know what Recovery and Access values mean. It seems that all values are
|
||
in 30 ns units. It corresponds to one PCI cycle when running at a 33 MHz clock speed.
|
||
|
||
Both PIO and MDMA recovery values are specified in `x / 30` units after subtracting
|
||
a constant offset. This offset is 120 ns for PIO transfers and 30 ns for MDMA transfers.
|
||
|
||
- The "HT" stands for _HalfTick_. When set, 15 ns will be added to both MDMA access
|
||
and recovery times. Otherwise, 30 ns are added to the MDMA recovery time.
|
||
- The "E" bit, when set, adds 30 ns to the final PIO timing.
|
||
|
||
The [official Apple source](https://opensource.apple.com/source/HeathrowATA/HeathrowATA-108.3.1/HeathrowATA.cpp.auto.html)
|
||
specifies the following default values for each PIO mode:
|
||
|
||
| Mode # | Cycle time | Transfer rate | Recovery | Access |
|
||
|:------:|:----------:|:-------------:|:--------:|:------:|
|
||
| 0 | 600 ns | 3,33 MB/s | 420 ns | 180 ns |
|
||
| 1 | 390 ns | 5,13 MB/s | 240 ns | 150 ns |
|
||
| 2 | 360 ns | 5,56 MB/s | 180 ns | 180 ns |
|
||
| 3 | 330 ns | 6,1 MB/s | 180 ns | 150 ns |
|
||
| 4 | 300 ns | 6,67 MB/s | 150 ns | 150 ns |
|
||
|
||
Timing values for the PIO modes 2...4 deviate from the corresponding values given
|
||
in the ATA-3 specification.
|
||
|
||
PIO cycle time can be calculated using the following equation:
|
||
```
|
||
PIO_Cycle_ns = PIO_Recovery * 30 + 120 + PIO_Access * 30 + E * 30
|
||
```
|
||
|
||
Multiword DMA modes are specified as follows:
|
||
|
||
| Mode # | Cycle time | Transfer rate | Recovery | Access |
|
||
|:------:|:----------:|:-------------:|:--------:|:------:|
|
||
| 0 | 480 ns | 4,17 MB/s | 240 ns | 240 ns |
|
||
| 1 | 360 ns | 5,56 MB/s | 180 ns | 180 ns |
|
||
| 2 | 270 ns | 7,4 MB/s | 135 ns | 135 ns |
|
||
| 3 | 240 ns | 8,33 MB/s | 120 ns | 120 ns |
|
||
| 4 | 210 ns | 9,52 MB/s | 105 ns | 105 ns |
|
||
| 5 | 180 ns | 11,11 MB/s | 90 ns | 90 ns |
|
||
| 6 | 150 ns | 13,33 MB/s | 75 ns | 75 ns |
|
||
| 7 | 120 ns | 16,67 MB/s | 45 ns | 75 ns |
|
||
|
||
Modes 0, 6 and 7 from the table above correspond to the MDMA modes 0...2 specified
|
||
in the ATA-2 standard.
|
||
|
||
MDMA cycle time can be calculated using the following equation:
|
||
```
|
||
MDMA_Cycle_ns = MDMA_Recovery * 30 + MDMA_Access * 30 + 30
|
||
```
|