All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework)
@ 2015-11-11 22:49 Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 01/13] PPC: Allow Rc bit to be set on mtspr Mark Cave-Ayland
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

This is a rework of Cormac O'Brien's GSoC project to try and boot MacOS 9 under
QEMU, the original version of which was posted to the qemu-devel list at the
end of August (https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02521.html).

The patchset consisted of some simple patches from Alex and then a large set of
CUDA changes supplied as a single patch which were the result of Cormac analysing
MOL with Alex's help to try and further the boot process.

In their previous form, the patches were unsuitable for applying upstream since
while they furthered MacOS 9 boot, they also caused a couple of major regressions
such as breaking the mouse and causing Darwin/OS X boot to panic on startup.

This reworked patchset fixes these regressions, includes some other clean-ups 
and more importantly now passes all of my OpenBIOS image boot tests with an 
OpenBIOS binary from SVN trunk (separate pull request to be sent shortly).
Whilst OpenBIOS still needs one additional patch to run the MacOS 9 bootloader,
I've uploaded a pre-compiled binary to 
https://www.ilande.co.uk/tmp/openbios-ppc for people interested in testing the 
new MacOS 9 functionality.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

v2:
- Rebase onto master
- Fix lswx subject typo
- Add RB tags from David and Thomas
- Update comments as suggested by David


Alexander Graf (3):
  PPC: Allow Rc bit to be set on mtspr
  PPC: Fix lswx bounds checks
  PPC: mac99: Always add USB controller

Mark Cave-Ayland (10):
  cuda.c: fix CUDA ADB error packet format
  cuda.c: fix CUDA_PACKET response packet format
  cuda.c: implement simple CUDA_GET_6805_ADDR command
  cuda.c: implement dummy IIC access commands
  cuda.c: fix CUDA SR interrupt clearing
  cuda.c: add defines for CUDA registers
  cuda.c: refactor get_tb() so that the time can be passed in
  cuda.c: rename get_counter() state variable from s to ti for
    consistency
  cuda.c: fix T2 timer and enable its interrupt
  cuda.c: add delay to setting of SR_INT bit

 hw/misc/macio/cuda.c    |  246 ++++++++++++++++++++++++++++++-----------------
 hw/ppc/mac.h            |    3 +
 hw/ppc/mac_newworld.c   |    3 +-
 target-ppc/mem_helper.c |    5 +-
 target-ppc/translate.c  |    2 +-
 5 files changed, 166 insertions(+), 93 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 01/13] PPC: Allow Rc bit to be set on mtspr
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 02/13] PPC: Fix lswx bounds checks Mark Cave-Ayland
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

From: Alexander Graf <agraf@suse.de>

According to the ISA setting the Rc bit on mtspr is undefined behavior.
Real 750 hardware simply ignores the bit and doesn't touch cr0 though.

Unfortunately, Mac OS 9 relies on this fact and executes a few mtspr
instructions (to set XER for example) with Rc set.

So let's handle the bit the same way hardware does and ignore it.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/translate.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 308ad68..41a7258 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9884,7 +9884,7 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
 #endif
 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
-GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
+GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 02/13] PPC: Fix lswx bounds checks
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 01/13] PPC: Allow Rc bit to be set on mtspr Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 03/13] PPC: mac99: Always add USB controller Mark Cave-Ayland
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

From: Alexander Graf <agraf@suse.de>

The lswx instruction checks whether the desired string actually fits
into all defined registers. Unfortunately it does the calculation wrong,
resulting in illegal instruction traps for loads that really should fit.

Fix it up, making Mac OS happier.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/mem_helper.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
index 6d37dae..7e1f234 100644
--- a/target-ppc/mem_helper.c
+++ b/target-ppc/mem_helper.c
@@ -100,8 +100,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
                  uint32_t ra, uint32_t rb)
 {
     if (likely(xer_bc != 0)) {
-        if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
-                     (reg < rb && (reg + xer_bc) > rb))) {
+        int num_used_regs = (xer_bc + 3) / 4;
+        if (unlikely((ra != 0 && reg < ra && (reg + num_used_regs) > ra) ||
+                     (reg < rb && (reg + num_used_regs) > rb))) {
             helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
                                        POWERPC_EXCP_INVAL |
                                        POWERPC_EXCP_INVAL_LSWX);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 03/13] PPC: mac99: Always add USB controller
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 01/13] PPC: Allow Rc bit to be set on mtspr Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 02/13] PPC: Fix lswx bounds checks Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 04/13] cuda.c: fix CUDA ADB error packet format Mark Cave-Ayland
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

From: Alexander Graf <agraf@suse.de>

The mac99 machines always have a USB controller. Usually not having one around
doesn't hurt quite as much, but Mac OS 9 really really wants one or it crashes
on bootup.

So always add OHCI to make it happy.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/mac_newworld.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 66d016c..1b9a573 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -371,12 +371,13 @@ static void ppc_core99_init(MachineState *machine)
         /* 970 gets a U3 bus */
         pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99_U3;
-        machine->usb |= defaults_enabled() && !machine->usb_disabled;
     } else {
         pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99;
     }
 
+    machine->usb |= defaults_enabled() && !machine->usb_disabled;
+
     /* Timebase Frequency */
     if (kvm_enabled()) {
         tbfreq = kvmppc_get_tbfreq();
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 04/13] cuda.c: fix CUDA ADB error packet format
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (2 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 03/13] PPC: mac99: Always add USB controller Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 05/13] cuda.c: fix CUDA_PACKET response " Mark Cave-Ayland
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

According to MOL, ADB error packets should be of the form (type, status, cmd)
rather than just (type, status). This fixes ADB device detection under MacOS 9.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/macio/cuda.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 0fd75b3..bfcdcae 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -560,19 +560,21 @@ static void cuda_receive_packet_from_host(CUDAState *s,
     switch(data[0]) {
     case ADB_PACKET:
         {
-            uint8_t obuf[ADB_MAX_OUT_LEN + 2];
+            uint8_t obuf[ADB_MAX_OUT_LEN + 3];
             int olen;
             olen = adb_request(&s->adb_bus, obuf + 2, data + 1, len - 1);
             if (olen > 0) {
                 obuf[0] = ADB_PACKET;
                 obuf[1] = 0x00;
+                cuda_send_packet_to_host(s, obuf, olen + 2);
             } else {
                 /* error */
                 obuf[0] = ADB_PACKET;
                 obuf[1] = -olen;
+                obuf[2] = data[1];
                 olen = 0;
+                cuda_send_packet_to_host(s, obuf, olen + 3);
             }
-            cuda_send_packet_to_host(s, obuf, olen + 2);
         }
         break;
     case CUDA_PACKET:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 05/13] cuda.c: fix CUDA_PACKET response packet format
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (3 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 04/13] cuda.c: fix CUDA ADB error packet format Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 06/13] cuda.c: implement simple CUDA_GET_6805_ADDR command Mark Cave-Ayland
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

According to comments in MOL, the response to a CUDA_PACKET should be one of
the following:

Reply: (CUDA_PACKET, status, cmd)
Error: (ERROR_PACKET, status, CUDA_PACKET, cmd)

Update cuda_receive_packet() accordingly to reflect this in order to make
MacOS 9 happy.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/macio/cuda.c |   24 +++++-------------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index bfcdcae..89ec51e 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -480,7 +480,7 @@ static void cuda_adb_poll(void *opaque)
 static void cuda_receive_packet(CUDAState *s,
                                 const uint8_t *data, int len)
 {
-    uint8_t obuf[16];
+    uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
     int autopoll;
     uint32_t ti;
 
@@ -497,23 +497,15 @@ static void cuda_receive_packet(CUDAState *s,
                 timer_del(s->adb_poll_timer);
             }
         }
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = data[1];
-        cuda_send_packet_to_host(s, obuf, 2);
+        cuda_send_packet_to_host(s, obuf, 3);
         break;
     case CUDA_SET_TIME:
         ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
         s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = 0;
-        obuf[2] = 0;
         cuda_send_packet_to_host(s, obuf, 3);
         break;
     case CUDA_GET_TIME:
         ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = 0;
-        obuf[2] = 0;
         obuf[3] = ti >> 24;
         obuf[4] = ti >> 16;
         obuf[5] = ti >> 8;
@@ -524,20 +516,14 @@ static void cuda_receive_packet(CUDAState *s,
     case CUDA_SET_DEVICE_LIST:
     case CUDA_SET_AUTO_RATE:
     case CUDA_SET_POWER_MESSAGES:
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = 0;
-        cuda_send_packet_to_host(s, obuf, 2);
+        cuda_send_packet_to_host(s, obuf, 3);
         break;
     case CUDA_POWERDOWN:
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = 0;
-        cuda_send_packet_to_host(s, obuf, 2);
+        cuda_send_packet_to_host(s, obuf, 3);
         qemu_system_shutdown_request();
         break;
     case CUDA_RESET_SYSTEM:
-        obuf[0] = CUDA_PACKET;
-        obuf[1] = 0;
-        cuda_send_packet_to_host(s, obuf, 2);
+        cuda_send_packet_to_host(s, obuf, 3);
         qemu_system_reset_request();
         break;
     default:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 06/13] cuda.c: implement simple CUDA_GET_6805_ADDR command
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (4 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 05/13] cuda.c: fix CUDA_PACKET response " Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 07/13] cuda.c: implement dummy IIC access commands Mark Cave-Ayland
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

This simply returns an empty response with no error status as implemented by
MOL to allow MacOS 9 boot to proceed further.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/misc/macio/cuda.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 89ec51e..1a2ab01 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -499,6 +499,9 @@ static void cuda_receive_packet(CUDAState *s,
         }
         cuda_send_packet_to_host(s, obuf, 3);
         break;
+    case CUDA_GET_6805_ADDR:
+        cuda_send_packet_to_host(s, obuf, 3);
+        break;
     case CUDA_SET_TIME:
         ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
         s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 07/13] cuda.c: implement dummy IIC access commands
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (5 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 06/13] cuda.c: implement simple CUDA_GET_6805_ADDR command Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 08/13] cuda.c: fix CUDA SR interrupt clearing Mark Cave-Ayland
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

These are used by MacOS 9 on boot. Here we return an error except for 4-byte
commands which write to the IIC bus in a similar manner to MOL.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/macio/cuda.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 1a2ab01..b7e9dee 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -529,6 +529,24 @@ static void cuda_receive_packet(CUDAState *s,
         cuda_send_packet_to_host(s, obuf, 3);
         qemu_system_reset_request();
         break;
+    case CUDA_COMBINED_FORMAT_IIC:
+        obuf[0] = ERROR_PACKET;
+        obuf[1] = 0x5;
+        obuf[2] = CUDA_PACKET;
+        obuf[3] = data[0];
+        cuda_send_packet_to_host(s, obuf, 4);
+        break;
+    case CUDA_GET_SET_IIC:
+        if (len == 4) {
+            cuda_send_packet_to_host(s, obuf, 3);
+        } else {
+            obuf[0] = ERROR_PACKET;
+            obuf[1] = 0x2;
+            obuf[2] = CUDA_PACKET;
+            obuf[3] = data[0];
+            cuda_send_packet_to_host(s, obuf, 4);
+        }
+        break;
     default:
         break;
     }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 08/13] cuda.c: fix CUDA SR interrupt clearing
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (6 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 07/13] cuda.c: implement dummy IIC access commands Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 09/13] cuda.c: add defines for CUDA registers Mark Cave-Ayland
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

Make sure that we also clear the data and clock interrupts at the same time.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/macio/cuda.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index b7e9dee..364473f 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -57,6 +57,8 @@
 #define IER_SET		0x80		/* set bits in IER */
 #define IER_CLR		0		/* clear bits in IER */
 #define SR_INT		0x04		/* Shift register full/empty */
+#define SR_DATA_INT	0x08
+#define SR_CLOCK_INT	0x10
 #define T1_INT          0x40            /* Timer 1 interrupt */
 #define T2_INT          0x20            /* Timer 2 interrupt */
 
@@ -261,7 +263,7 @@ static uint32_t cuda_readb(void *opaque, hwaddr addr)
         break;
     case 10:
         val = s->sr;
-        s->ifr &= ~SR_INT;
+        s->ifr &= ~(SR_INT | SR_CLOCK_INT | SR_DATA_INT);
         cuda_update_irq(s);
         break;
     case 11:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 09/13] cuda.c: add defines for CUDA registers
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (7 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 08/13] cuda.c: fix CUDA SR interrupt clearing Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 10/13] cuda.c: refactor get_tb() so that the time can be passed in Mark Cave-Ayland
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/misc/macio/cuda.c |   87 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 53 insertions(+), 34 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 364473f..c0a3a68 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -110,6 +110,24 @@
 /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
 #define RTC_OFFSET                      2082844800
 
+/* CUDA registers */
+#define CUDA_REG_B       0x00
+#define CUDA_REG_A       0x01
+#define CUDA_REG_DIRB    0x02
+#define CUDA_REG_DIRA    0x03
+#define CUDA_REG_T1CL    0x04
+#define CUDA_REG_T1CH    0x05
+#define CUDA_REG_T1LL    0x06
+#define CUDA_REG_T1LH    0x07
+#define CUDA_REG_T2CL    0x08
+#define CUDA_REG_T2CH    0x09
+#define CUDA_REG_SR      0x0a
+#define CUDA_REG_ACR     0x0b
+#define CUDA_REG_PCR     0x0c
+#define CUDA_REG_IFR     0x0d
+#define CUDA_REG_IER     0x0e
+#define CUDA_REG_ANH     0x0f
+
 static void cuda_update(CUDAState *s);
 static void cuda_receive_packet_from_host(CUDAState *s,
                                           const uint8_t *data, int len);
@@ -226,66 +244,67 @@ static uint32_t cuda_readb(void *opaque, hwaddr addr)
 
     addr = (addr >> 9) & 0xf;
     switch(addr) {
-    case 0:
+    case CUDA_REG_B:
         val = s->b;
         break;
-    case 1:
+    case CUDA_REG_A:
         val = s->a;
         break;
-    case 2:
+    case CUDA_REG_DIRB:
         val = s->dirb;
         break;
-    case 3:
+    case CUDA_REG_DIRA:
         val = s->dira;
         break;
-    case 4:
+    case CUDA_REG_T1CL:
         val = get_counter(&s->timers[0]) & 0xff;
         s->ifr &= ~T1_INT;
         cuda_update_irq(s);
         break;
-    case 5:
+    case CUDA_REG_T1CH:
         val = get_counter(&s->timers[0]) >> 8;
         cuda_update_irq(s);
         break;
-    case 6:
+    case CUDA_REG_T1LL:
         val = s->timers[0].latch & 0xff;
         break;
-    case 7:
+    case CUDA_REG_T1LH:
         /* XXX: check this */
         val = (s->timers[0].latch >> 8) & 0xff;
         break;
-    case 8:
+    case CUDA_REG_T2CL:
         val = get_counter(&s->timers[1]) & 0xff;
         s->ifr &= ~T2_INT;
         break;
-    case 9:
+    case CUDA_REG_T2CH:
         val = get_counter(&s->timers[1]) >> 8;
         break;
-    case 10:
+    case CUDA_REG_SR:
         val = s->sr;
         s->ifr &= ~(SR_INT | SR_CLOCK_INT | SR_DATA_INT);
         cuda_update_irq(s);
         break;
-    case 11:
+    case CUDA_REG_ACR:
         val = s->acr;
         break;
-    case 12:
+    case CUDA_REG_PCR:
         val = s->pcr;
         break;
-    case 13:
+    case CUDA_REG_IFR:
         val = s->ifr;
-        if (s->ifr & s->ier)
+        if (s->ifr & s->ier) {
             val |= 0x80;
+        }
         break;
-    case 14:
+    case CUDA_REG_IER:
         val = s->ier | 0x80;
         break;
     default:
-    case 15:
+    case CUDA_REG_ANH:
         val = s->anh;
         break;
     }
-    if (addr != 13 || val != 0) {
+    if (addr != CUDA_REG_IFR || val != 0) {
         CUDA_DPRINTF("read: reg=0x%x val=%02x\n", (int)addr, val);
     }
 
@@ -300,61 +319,61 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
     CUDA_DPRINTF("write: reg=0x%x val=%02x\n", (int)addr, val);
 
     switch(addr) {
-    case 0:
+    case CUDA_REG_B:
         s->b = val;
         cuda_update(s);
         break;
-    case 1:
+    case CUDA_REG_A:
         s->a = val;
         break;
-    case 2:
+    case CUDA_REG_DIRB:
         s->dirb = val;
         break;
-    case 3:
+    case CUDA_REG_DIRA:
         s->dira = val;
         break;
-    case 4:
+    case CUDA_REG_T1CL:
         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
-    case 5:
+    case CUDA_REG_T1CH:
         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
         s->ifr &= ~T1_INT;
         set_counter(s, &s->timers[0], s->timers[0].latch);
         break;
-    case 6:
+    case CUDA_REG_T1LL:
         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
-    case 7:
+    case CUDA_REG_T1LH:
         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
         s->ifr &= ~T1_INT;
         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
-    case 8:
+    case CUDA_REG_T2CL:
         s->timers[1].latch = val;
         set_counter(s, &s->timers[1], val);
         break;
-    case 9:
+    case CUDA_REG_T2CH:
         set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
         break;
-    case 10:
+    case CUDA_REG_SR:
         s->sr = val;
         break;
-    case 11:
+    case CUDA_REG_ACR:
         s->acr = val;
         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         cuda_update(s);
         break;
-    case 12:
+    case CUDA_REG_PCR:
         s->pcr = val;
         break;
-    case 13:
+    case CUDA_REG_IFR:
         /* reset bits */
         s->ifr &= ~val;
         cuda_update_irq(s);
         break;
-    case 14:
+    case CUDA_REG_IER:
         if (val & IER_SET) {
             /* set bits */
             s->ier |= val & 0x7f;
@@ -365,7 +384,7 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
         cuda_update_irq(s);
         break;
     default:
-    case 15:
+    case CUDA_REG_ANH:
         s->anh = val;
         break;
     }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 10/13] cuda.c: refactor get_tb() so that the time can be passed in
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (8 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 09/13] cuda.c: add defines for CUDA registers Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 11/13] cuda.c: rename get_counter() state variable from s to ti for consistency Mark Cave-Ayland
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

This is in preparation for sharing the code between timers.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/misc/macio/cuda.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index c0a3a68..e61a3c5 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -143,10 +143,9 @@ static void cuda_update_irq(CUDAState *s)
     }
 }
 
-static uint64_t get_tb(uint64_t freq)
+static uint64_t get_tb(uint64_t time, uint64_t freq)
 {
-    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-                    freq, get_ticks_per_sec());
+    return muldiv64(time, freq, get_ticks_per_sec());
 }
 
 static unsigned int get_counter(CUDATimer *s)
@@ -154,9 +153,10 @@ static unsigned int get_counter(CUDATimer *s)
     int64_t d;
     unsigned int counter;
     uint64_t tb_diff;
+    uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
-    tb_diff = get_tb(s->frequency) - s->load_time;
+    tb_diff = get_tb(current_time, s->frequency) - s->load_time;
     d = (tb_diff * 0xBF401675E5DULL) / (s->frequency << 24);
 
     if (s->index == 0) {
@@ -176,7 +176,8 @@ static unsigned int get_counter(CUDATimer *s)
 static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
 {
     CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
-    ti->load_time = get_tb(s->frequency);
+    ti->load_time = get_tb(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                           s->frequency);
     ti->counter_value = val;
     cuda_timer_update(s, ti, ti->load_time);
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 11/13] cuda.c: rename get_counter() state variable from s to ti for consistency
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (9 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 10/13] cuda.c: refactor get_tb() so that the time can be passed in Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 12/13] cuda.c: fix T2 timer and enable its interrupt Mark Cave-Ayland
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/misc/macio/cuda.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index e61a3c5..b6da434 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -148,7 +148,7 @@ static uint64_t get_tb(uint64_t time, uint64_t freq)
     return muldiv64(time, freq, get_ticks_per_sec());
 }
 
-static unsigned int get_counter(CUDATimer *s)
+static unsigned int get_counter(CUDATimer *ti)
 {
     int64_t d;
     unsigned int counter;
@@ -156,19 +156,19 @@ static unsigned int get_counter(CUDATimer *s)
     uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
-    tb_diff = get_tb(current_time, s->frequency) - s->load_time;
-    d = (tb_diff * 0xBF401675E5DULL) / (s->frequency << 24);
+    tb_diff = get_tb(current_time, ti->frequency) - ti->load_time;
+    d = (tb_diff * 0xBF401675E5DULL) / (ti->frequency << 24);
 
-    if (s->index == 0) {
+    if (ti->index == 0) {
         /* the timer goes down from latch to -1 (period of latch + 2) */
-        if (d <= (s->counter_value + 1)) {
-            counter = (s->counter_value - d) & 0xffff;
+        if (d <= (ti->counter_value + 1)) {
+            counter = (ti->counter_value - d) & 0xffff;
         } else {
-            counter = (d - (s->counter_value + 1)) % (s->latch + 2);
-            counter = (s->latch - counter) & 0xffff;
+            counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
+            counter = (ti->latch - counter) & 0xffff;
         }
     } else {
-        counter = (s->counter_value - d) & 0xffff;
+        counter = (ti->counter_value - d) & 0xffff;
     }
     return counter;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 12/13] cuda.c: fix T2 timer and enable its interrupt
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (10 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 11/13] cuda.c: rename get_counter() state variable from s to ti for consistency Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 13/13] cuda.c: add delay to setting of SR_INT bit Mark Cave-Ayland
  2015-11-12  3:20 ` [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) David Gibson
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

Fix the counter loading logic and enable the T2 interrupt when the timer
expires. Otherwise MacOS 9 hangs on boot.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/macio/cuda.c |   33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index b6da434..9045c3b 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -136,7 +136,7 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
 
 static void cuda_update_irq(CUDAState *s)
 {
-    if (s->ifr & s->ier & (SR_INT | T1_INT)) {
+    if (s->ifr & s->ier & (SR_INT | T1_INT | T2_INT)) {
         qemu_irq_raise(s->irq);
     } else {
         qemu_irq_lower(s->irq);
@@ -175,7 +175,7 @@ static unsigned int get_counter(CUDATimer *ti)
 
 static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
 {
-    CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
+    CUDA_DPRINTF("T%d.counter=%d\n", 1 + ti->index, val);
     ti->load_time = get_tb(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                            s->frequency);
     ti->counter_value = val;
@@ -220,7 +220,7 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
 {
     if (!ti->timer)
         return;
-    if ((s->acr & T1MODE) != T1MODE_CONT) {
+    if (ti->index == 0 && (s->acr & T1MODE) != T1MODE_CONT) {
         timer_del(ti->timer);
     } else {
         ti->next_irq_time = get_next_irq_time(ti, current_time);
@@ -238,6 +238,16 @@ static void cuda_timer1(void *opaque)
     cuda_update_irq(s);
 }
 
+static void cuda_timer2(void *opaque)
+{
+    CUDAState *s = opaque;
+    CUDATimer *ti = &s->timers[1];
+
+    cuda_timer_update(s, ti, ti->next_irq_time);
+    s->ifr |= T2_INT;
+    cuda_update_irq(s);
+}
+
 static uint32_t cuda_readb(void *opaque, hwaddr addr)
 {
     CUDAState *s = opaque;
@@ -276,6 +286,7 @@ static uint32_t cuda_readb(void *opaque, hwaddr addr)
     case CUDA_REG_T2CL:
         val = get_counter(&s->timers[1]) & 0xff;
         s->ifr &= ~T2_INT;
+        cuda_update_irq(s);
         break;
     case CUDA_REG_T2CH:
         val = get_counter(&s->timers[1]) >> 8;
@@ -352,11 +363,15 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
     case CUDA_REG_T2CL:
-        s->timers[1].latch = val;
-        set_counter(s, &s->timers[1], val);
+        s->timers[1].latch = (s->timers[1].latch & 0xff00) | val;
         break;
     case CUDA_REG_T2CH:
-        set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
+        /* To ensure T2 generates an interrupt on zero crossing with the
+           common timer code, write the value directly from the latch to
+           the counter */
+        s->timers[1].latch = (s->timers[1].latch & 0xff) | (val << 8);
+        s->ifr &= ~T2_INT;
+        set_counter(s, &s->timers[1], s->timers[1].latch);
         break;
     case CUDA_REG_SR:
         s->sr = val;
@@ -719,8 +734,7 @@ static void cuda_reset(DeviceState *dev)
     s->timers[0].latch = 0xffff;
     set_counter(s, &s->timers[0], 0xffff);
 
-    s->timers[1].latch = 0;
-    set_counter(s, &s->timers[1], 0xffff);
+    s->timers[1].latch = 0xffff;
 }
 
 static void cuda_realizefn(DeviceState *dev, Error **errp)
@@ -730,7 +744,8 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
 
     s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
     s->timers[0].frequency = s->frequency;
-    s->timers[1].frequency = s->frequency;
+    s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer2, s);
+    s->timers[1].frequency = (SCALE_US * 6000) / 4700;
 
     qemu_get_timedate(&tm, 0);
     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 13/13] cuda.c: add delay to setting of SR_INT bit
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (11 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 12/13] cuda.c: fix T2 timer and enable its interrupt Mark Cave-Ayland
@ 2015-11-11 22:49 ` Mark Cave-Ayland
  2015-11-12  3:20 ` [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) David Gibson
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Cave-Ayland @ 2015-11-11 22:49 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf, david, cormac

MacOS 9 is racy when it comes to accessing the shift register. Fix this by
introducing a small delay between data accesses and raising the SR_INT
interrupt bit.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/misc/macio/cuda.c |   44 +++++++++++++++++++++++++++++++++-----------
 hw/ppc/mac.h         |    3 +++
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 9045c3b..9db4c64 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -248,6 +248,31 @@ static void cuda_timer2(void *opaque)
     cuda_update_irq(s);
 }
 
+static void cuda_set_sr_int(void *opaque)
+{
+    CUDAState *s = opaque;
+
+    CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__);
+    s->ifr |= SR_INT;
+    cuda_update_irq(s);
+}
+
+static void cuda_delay_set_sr_int(CUDAState *s)
+{
+    int64_t expire;
+
+    if (s->dirb == 0xff) {
+        /* Not in Mac OS, fire the IRQ directly */
+        cuda_set_sr_int(s);
+        return;
+    }
+
+    CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__);
+
+    expire = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 300 * SCALE_US;
+    timer_mod(s->sr_delay_timer, expire);
+}
+
 static uint32_t cuda_readb(void *opaque, hwaddr addr)
 {
     CUDAState *s = opaque;
@@ -421,8 +446,7 @@ static void cuda_update(CUDAState *s)
                 if (s->data_out_index < sizeof(s->data_out)) {
                     CUDA_DPRINTF("send: %02x\n", s->sr);
                     s->data_out[s->data_out_index++] = s->sr;
-                    s->ifr |= SR_INT;
-                    cuda_update_irq(s);
+                    cuda_delay_set_sr_int(s);
                 }
             }
         } else {
@@ -435,8 +459,7 @@ static void cuda_update(CUDAState *s)
                     if (s->data_in_index >= s->data_in_size) {
                         s->b = (s->b | TREQ);
                     }
-                    s->ifr |= SR_INT;
-                    cuda_update_irq(s);
+                    cuda_delay_set_sr_int(s);
                 }
             }
         }
@@ -448,15 +471,13 @@ static void cuda_update(CUDAState *s)
                 s->b = (s->b | TREQ);
             else
                 s->b = (s->b & ~TREQ);
-            s->ifr |= SR_INT;
-            cuda_update_irq(s);
+            cuda_delay_set_sr_int(s);
         } else {
             if (!(s->last_b & TIP)) {
                 /* handle end of host to cuda transfer */
                 packet_received = (s->data_out_index > 0);
                 /* always an IRQ at the end of transfer */
-                s->ifr |= SR_INT;
-                cuda_update_irq(s);
+                cuda_delay_set_sr_int(s);
             }
             /* signal if there is data to read */
             if (s->data_in_index < s->data_in_size) {
@@ -493,8 +514,7 @@ static void cuda_send_packet_to_host(CUDAState *s,
     s->data_in_size = len;
     s->data_in_index = 0;
     cuda_update(s);
-    s->ifr |= SR_INT;
-    cuda_update_irq(s);
+    cuda_delay_set_sr_int(s);
 }
 
 static void cuda_adb_poll(void *opaque)
@@ -717,7 +737,7 @@ static void cuda_reset(DeviceState *dev)
 
     s->b = 0;
     s->a = 0;
-    s->dirb = 0;
+    s->dirb = 0xff;
     s->dira = 0;
     s->sr = 0;
     s->acr = 0;
@@ -735,6 +755,8 @@ static void cuda_reset(DeviceState *dev)
     set_counter(s, &s->timers[0], 0xffff);
 
     s->timers[1].latch = 0xffff;
+
+    s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s);
 }
 
 static void cuda_realizefn(DeviceState *dev, Error **errp)
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 8bdba30..e375ed2 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -103,6 +103,9 @@ typedef struct CUDAState {
     uint8_t last_b;
     uint8_t last_acr;
 
+    /* MacOS 9 is racy and requires a delay upon setting the SR_INT bit */
+    QEMUTimer *sr_delay_timer;
+
     int data_in_size;
     int data_in_index;
     int data_out_index;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework)
  2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
                   ` (12 preceding siblings ...)
  2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 13/13] cuda.c: add delay to setting of SR_INT bit Mark Cave-Ayland
@ 2015-11-12  3:20 ` David Gibson
  13 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2015-11-12  3:20 UTC (permalink / raw)
  To: Mark Cave-Ayland; +Cc: cormac, qemu-ppc, qemu-devel, agraf

[-- Attachment #1: Type: text/plain, Size: 1757 bytes --]

On Wed, Nov 11, 2015 at 10:49:38PM +0000, Mark Cave-Ayland wrote:
> This is a rework of Cormac O'Brien's GSoC project to try and boot MacOS 9 under
> QEMU, the original version of which was posted to the qemu-devel list at the
> end of August (https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02521.html).
> 
> The patchset consisted of some simple patches from Alex and then a large set of
> CUDA changes supplied as a single patch which were the result of Cormac analysing
> MOL with Alex's help to try and further the boot process.
> 
> In their previous form, the patches were unsuitable for applying upstream since
> while they furthered MacOS 9 boot, they also caused a couple of major regressions
> such as breaking the mouse and causing Darwin/OS X boot to panic on startup.
> 
> This reworked patchset fixes these regressions, includes some other clean-ups 
> and more importantly now passes all of my OpenBIOS image boot tests with an 
> OpenBIOS binary from SVN trunk (separate pull request to be sent shortly).
> Whilst OpenBIOS still needs one additional patch to run the MacOS 9 bootloader,
> I've uploaded a pre-compiled binary to 
> https://www.ilande.co.uk/tmp/openbios-ppc for people interested in testing the 
> new MacOS 9 functionality.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Applied to ppc-next.  There's a couple of other pending patches I want
to look at, do some sanity checks, then I hope I can send out one last
pull request today to squeeze in before the hard freeze.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-11-12  3:22 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-11 22:49 [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 01/13] PPC: Allow Rc bit to be set on mtspr Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 02/13] PPC: Fix lswx bounds checks Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 03/13] PPC: mac99: Always add USB controller Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 04/13] cuda.c: fix CUDA ADB error packet format Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 05/13] cuda.c: fix CUDA_PACKET response " Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 06/13] cuda.c: implement simple CUDA_GET_6805_ADDR command Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 07/13] cuda.c: implement dummy IIC access commands Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 08/13] cuda.c: fix CUDA SR interrupt clearing Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 09/13] cuda.c: add defines for CUDA registers Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 10/13] cuda.c: refactor get_tb() so that the time can be passed in Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 11/13] cuda.c: rename get_counter() state variable from s to ti for consistency Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 12/13] cuda.c: fix T2 timer and enable its interrupt Mark Cave-Ayland
2015-11-11 22:49 ` [Qemu-devel] [PATCH v2 13/13] cuda.c: add delay to setting of SR_INT bit Mark Cave-Ayland
2015-11-12  3:20 ` [Qemu-devel] [PATCH v2 00/13] Mac OS 9 compatibility improvements (upstream rework) David Gibson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.