Break up vl.h.
[qemu] / hw / cuda.c
index 98a2637..246c72d 100644 (file)
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -1,8 +1,9 @@
 /*
- * QEMU CUDA support
- * 
- * Copyright (c) 2004 Fabrice Bellard
- * 
+ * QEMU PowerMac CUDA device support
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "vl.h"
+#include "hw.h"
+#include "ppc_mac.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
 
 /* XXX: implement all timer modes */
 
@@ -94,7 +98,7 @@
 #define RTC_OFFSET                      2082844800
 
 typedef struct CUDATimer {
-    int index; 
+    int index;
     uint16_t latch;
     uint16_t counter_value; /* counter value at load time */
     int64_t load_time;
@@ -116,17 +120,15 @@ typedef struct CUDAState {
     uint8_t anh;    /* A-side data, no handshake */
 
     CUDATimer timers[2];
-    
+
     uint8_t last_b; /* last value of B register */
     uint8_t last_acr; /* last value of B register */
-    
+
     int data_in_size;
     int data_in_index;
     int data_out_index;
 
-    SetIRQFunc *set_irq;
-    int irq;
-    void *irq_opaque;
+    qemu_irq irq;
     uint8_t autopoll;
     uint8_t data_in[128];
     uint8_t data_out[16];
@@ -137,17 +139,17 @@ static CUDAState cuda_state;
 ADBBusState adb_bus;
 
 static void cuda_update(CUDAState *s);
-static void cuda_receive_packet_from_host(CUDAState *s, 
+static void cuda_receive_packet_from_host(CUDAState *s,
                                           const uint8_t *data, int len);
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
                               int64_t current_time);
 
 static void cuda_update_irq(CUDAState *s)
 {
     if (s->ifr & s->ier & (SR_INT | T1_INT)) {
-        s->set_irq(s->irq_opaque, s->irq, 1);
+        qemu_irq_raise(s->irq);
     } else {
-        s->set_irq(s->irq_opaque, s->irq, 0);
+        qemu_irq_lower(s->irq);
     }
 }
 
@@ -156,7 +158,7 @@ static unsigned int get_counter(CUDATimer *s)
     int64_t d;
     unsigned int counter;
 
-    d = muldiv64(qemu_get_clock(vm_clock) - s->load_time, 
+    d = muldiv64(qemu_get_clock(vm_clock) - s->load_time,
                  CUDA_TIMER_FREQ, ticks_per_sec);
     if (s->index == 0) {
         /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -164,7 +166,7 @@ static unsigned int get_counter(CUDATimer *s)
             counter = (s->counter_value - d) & 0xffff;
         } else {
             counter = (d - (s->counter_value + 1)) % (s->latch + 2);
-            counter = (s->latch - counter) & 0xffff; 
+            counter = (s->latch - counter) & 0xffff;
         }
     } else {
         counter = (s->counter_value - d) & 0xffff;
@@ -189,16 +191,16 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
     unsigned int counter;
 
     /* current counter value */
-    d = muldiv64(current_time - s->load_time, 
+    d = muldiv64(current_time - s->load_time,
                  CUDA_TIMER_FREQ, ticks_per_sec);
     /* the timer goes down from latch to -1 (period of latch + 2) */
     if (d <= (s->counter_value + 1)) {
         counter = (s->counter_value - d) & 0xffff;
     } else {
         counter = (d - (s->counter_value + 1)) % (s->latch + 2);
-        counter = (s->latch - counter) & 0xffff; 
+        counter = (s->latch - counter) & 0xffff;
     }
-    
+
     /* Note: we consider the irq is raised on 0 */
     if (counter == 0xffff) {
         next_time = d + s->latch + 1;
@@ -209,18 +211,18 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
     }
 #if 0
 #ifdef DEBUG_CUDA
-    printf("latch=%d counter=%lld delta_next=%lld\n", 
+    printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
            s->latch, d, next_time - d);
 #endif
 #endif
-    next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + 
+    next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) +
         s->load_time;
     if (next_time <= current_time)
         next_time = current_time + 1;
     return next_time;
 }
 
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
                               int64_t current_time)
 {
     if (!ti->timer)
@@ -298,9 +300,11 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
         break;
     case 13:
         val = s->ifr;
+        if (s->ifr & s->ier)
+            val |= 0x80;
         break;
     case 14:
-        val = s->ier;
+        val = s->ier | 0x80;
         break;
     default:
     case 15:
@@ -317,7 +321,7 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
 static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     CUDAState *s = opaque;
-    
+
     addr = (addr >> 9) & 0xf;
 #ifdef DEBUG_CUDA
     printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
@@ -379,7 +383,6 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
         cuda_update_irq(s);
         break;
     case 14:
-#if 0
         if (val & IER_SET) {
             /* set bits */
             s->ier |= val & 0x7f;
@@ -387,10 +390,6 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             /* reset bits */
             s->ier &= ~val;
         }
-#else
-        /* XXX: please explain me why the SPEC is not correct ! */
-        s->ier = val;
-#endif
         cuda_update_irq(s);
         break;
     default:
@@ -450,9 +449,9 @@ static void cuda_update(CUDAState *s)
             cuda_update_irq(s);
         } else {
             if (!(s->last_b & TIP)) {
-                /* handle end of host to cuda transfert */
+                /* handle end of host to cuda transfer */
                 packet_received = (s->data_out_index > 0);
-                /* always an IRQ at the end of transfert */
+                /* always an IRQ at the end of transfer */
                 s->ifr |= SR_INT;
                 cuda_update_irq(s);
             }
@@ -475,7 +474,7 @@ static void cuda_update(CUDAState *s)
     }
 }
 
-static void cuda_send_packet_to_host(CUDAState *s, 
+static void cuda_send_packet_to_host(CUDAState *s,
                                      const uint8_t *data, int len)
 {
 #ifdef DEBUG_CUDA_PACKET
@@ -507,12 +506,12 @@ static void cuda_adb_poll(void *opaque)
         obuf[1] = 0x40; /* polled data */
         cuda_send_packet_to_host(s, obuf, olen + 2);
     }
-    qemu_mod_timer(s->adb_poll_timer, 
-                   qemu_get_clock(vm_clock) + 
+    qemu_mod_timer(s->adb_poll_timer,
+                   qemu_get_clock(vm_clock) +
                    (ticks_per_sec / CUDA_ADB_POLL_FREQ));
 }
 
-static void cuda_receive_packet(CUDAState *s, 
+static void cuda_receive_packet(CUDAState *s,
                                 const uint8_t *data, int len)
 {
     uint8_t obuf[16];
@@ -524,8 +523,8 @@ static void cuda_receive_packet(CUDAState *s,
         if (autopoll != s->autopoll) {
             s->autopoll = autopoll;
             if (autopoll) {
-                qemu_mod_timer(s->adb_poll_timer, 
-                               qemu_get_clock(vm_clock) + 
+                qemu_mod_timer(s->adb_poll_timer,
+                               qemu_get_clock(vm_clock) +
                                (ticks_per_sec / CUDA_ADB_POLL_FREQ));
             } else {
                 qemu_del_timer(s->adb_poll_timer);
@@ -562,12 +561,18 @@ static void cuda_receive_packet(CUDAState *s,
         cuda_send_packet_to_host(s, obuf, 2);
        qemu_system_shutdown_request();
        break;
+    case CUDA_RESET_SYSTEM:
+        obuf[0] = CUDA_PACKET;
+        obuf[1] = 0;
+        cuda_send_packet_to_host(s, obuf, 2);
+        qemu_system_reset_request();
+        break;
     default:
         break;
     }
 }
 
-static void cuda_receive_packet_from_host(CUDAState *s, 
+static void cuda_receive_packet_from_host(CUDAState *s,
                                           const uint8_t *data, int len)
 {
 #ifdef DEBUG_CUDA_PACKET
@@ -633,13 +638,10 @@ static CPUReadMemoryFunc *cuda_read[] = {
     &cuda_readl,
 };
 
-int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq)
+void cuda_init (int *cuda_mem_index, qemu_irq irq)
 {
     CUDAState *s = &cuda_state;
-    int cuda_mem_index;
 
-    s->set_irq = set_irq;
-    s->irq_opaque = irq_opaque;
     s->irq = irq;
 
     s->timers[0].index = 0;
@@ -654,6 +656,5 @@ int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq)
     set_counter(s, &s->timers[1], 0xffff);
 
     s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
-    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
-    return cuda_mem_index;
+    *cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
 }