Recent Changes

2019-08-18
2019-06-08
2019-02-11
2019-02-09
2019-02-08
2019-02-07

Wiki Guide

Mac99 I2C emulation

This subproject is about implementing I2C emulation for the mac99 machine in QEMU

Why?

The QEMU mac99 emulation can boot MorphOS but it has a background task which expects to be able to read hardware sensor data which is not emulated by QEMU. This task not only wakes up frequently (like every 2 seconds) but also seems to busy wait for reply from I2C bus which does not exist on QEMU and this causes high CPU load and periodical freezes that can be seen for example when moving the mouse. A workaround currently is to issue ikill temperature.sensor from a shell window to prevent this periodical access to I2C but this has to be done after every reboot and is inconvenient, so implementing this I2C bus to avoid this problem is a nicer solution. Not sure if just a dummy implementation of the I2C bus without the actual sensor is enough to avoid the busy waiting and slowdown but once the I2C bus is there the sensor chip emulation might not be too difficult to add.

How?

The main problem here is that there is no available documentation of the Apple hardware whatsoever so the knowledge about what to emulate has to be gathered from checking how the available drivers access this hardware. The best source of information may be the various open source kernel drivers but then the first question is which I2C bus to emulate. The PowerMac3,1 machine the mac99 emulation in QEMU is trying to approximate has several I2C busses. MorphOS prints these log messages:

i2c_xfer_real: bus 1 ch 0 adr 0x92 sadr 2 read len 2
i2c_xfer_real: MODE 0x00 CTRL 0x00 STAT 0x00 ISR 0x00 REV 0x00 RISETIMECNT 0x00 BITTIMECNT 0x00
i2c_xfer_real: ISCL/ISDA is not HIGH!
timeout waiting for int 0x00000002 at libfunctions.c:226, ISR 0x00000000
timeout waiting for int 0x00000004 at libfunctions.c:439, ISR 0x00000000
timeout waiting for stop int

So it's looking for something on I2C bus 1 at address 0x92 (also similar lines are printed with address 0x9c so these are the sensors it's looking for, I think these are temperature and fan speed sensors) but which is bus 1? Enabling debug messages to print unassigned memory accesses in QEMU gives these logs:

Unassigned mem read 00000000f8001023
Unassigned mem read 00000000f8001003
Unassigned mem read 00000000f8001013
Unassigned mem read 00000000f8001023
Unassigned mem read 00000000f8001083
Unassigned mem read 00000000f8001093
Unassigned mem read 00000000f80010a3
Unassigned mem read 00000000f8001013
Unassigned mem write 00000000f8001003 = 0xc
Unassigned mem read 00000000f8001003
Unassigned mem write 00000000f8001023 = 0x0
Unassigned mem read 00000000f8001023
Unassigned mem write 00000000f8001053 = 0x93
Unassigned mem read 00000000f8001053
Unassigned mem write 00000000f8001063 = 0x2
Unassigned mem read 00000000f8001063
Unassigned mem write 00000000f8001013 = 0x2
Unassigned mem read 00000000f8001013
Unassigned mem read 00000000f8001023
Unassigned mem read 00000000f8001013
Unassigned mem write 00000000f8001023 = 0x0
Unassigned mem read 00000000f8001023

and a lot of Unassigned mem read 00000000f8001033 when busy waiting. So the I2C device registers are between f8001000 and up at least until f80010a3. Comparing this with a PowerMac3,1 device tree dump can be seen that this is /uni-n@f8000000/i2c@f8001000 that is the I2C bus of the uninorth chip, and another sysinfo dump shows this is compatible with keywest-i2c. So we have to look for keywest-i2c drivers. Here are a few I've found:

What's missing?

From here the next step would be for someone to read the above driver sources and devise how the uninorth I2C controller works and document that so a sufficient emulation of it can be implemented in QEMU based on that documentation to make MorphOS happy enough to not hang on busy waiting. Unless of course someone already has this info and can share to save us the work of finding it out from the above. (Make sure to keep this legal and don't share non-free docs or don't copy code from Darwin sources as APSL is incompatible with GPL. Taking code from Linux and FreeBSD is OK as those are under compatible licenses.)