Sparc32/64 CPU selection
[qemu] / hw / ppc.c
index c460fec..c910cb9 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -1,7 +1,7 @@
 /*
  * QEMU generic PPC hardware System Emulator
  * 
- * Copyright (c) 2003-2004 Jocelyn Mayer
+ * Copyright (c) 2003-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
@@ -41,7 +41,7 @@ static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
 {
     /* TB time in tb periods */
     return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
-                   tb_env->tb_freq, ticks_per_sec);
+                    tb_env->tb_freq, ticks_per_sec);
 }
 
 uint32_t cpu_ppc_load_tbl (CPUState *env)
@@ -52,14 +52,14 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
     tb = cpu_ppc_get_tb(tb_env);
 #ifdef DEBUG_TB
     {
-         static int last_time;
-        int now;
-        now = time(NULL);
-        if (last_time != now) {
-            last_time = now;
-            printf("%s: tb=0x%016lx %d %08lx\n",
-                    __func__, tb, now, tb_env->tb_offset);
-        }
+        static int last_time;
+        int now;
+        now = time(NULL);
+        if (last_time != now) {
+            last_time = now;
+            printf("%s: tb=0x%016lx %d %08lx\n",
+                   __func__, tb, now, tb_env->tb_offset);
+        }
     }
 #endif
 
@@ -75,6 +75,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
 #ifdef DEBUG_TB
     printf("%s: tb=0x%016lx\n", __func__, tb);
 #endif
+
     return tb >> 32;
 }
 
@@ -117,6 +118,7 @@ uint32_t cpu_ppc_load_decr (CPUState *env)
 #if defined(DEBUG_TB)
     printf("%s: 0x%08x\n", __func__, decr);
 #endif
+
     return decr;
 }
 
@@ -146,7 +148,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
     if (is_excp)
         next += tb_env->decr_next - now;
     if (next == now)
-       next++;
+        next++;
     tb_env->decr_next = next;
     /* Adjust timer */
     qemu_mod_timer(tb_env->decr_timer, next);
@@ -154,7 +156,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
      * raise an exception.
      */
     if ((value & 0x80000000) && !(decr & 0x80000000))
-       cpu_ppc_decr_excp(env);
+        cpu_ppc_decr_excp(env);
 }
 
 void cpu_ppc_store_decr (CPUState *env, uint32_t value)
@@ -177,87 +179,73 @@ ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
         return NULL;
     env->tb_env = tb_env;
     if (tb_env->tb_freq == 0 || 1) {
-       tb_env->tb_freq = freq;
-       /* Create new timer */
-       tb_env->decr_timer =
+        tb_env->tb_freq = freq;
+        /* Create new timer */
+        tb_env->decr_timer =
             qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
-       /* There is a bug in  2.4 kernels:
-        * if a decrementer exception is pending when it enables msr_ee,
-        * it's not ready to handle it...
-        */
-       _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
+        /* There is a bug in Linux 2.4 kernels:
+         * if a decrementer exception is pending when it enables msr_ee,
+         * it's not ready to handle it...
+         */
+        _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
     }
 
     return tb_env;
 }
 
-#if 0
-/*****************************************************************************/
-/* Handle system reset (for now, just stop emulation) */
-void cpu_ppc_reset (CPUState *env)
+/* Specific helpers for POWER & PowerPC 601 RTC */
+ppc_tb_t *cpu_ppc601_rtc_init (CPUState *env)
 {
-    printf("Reset asked... Stop emulation\n");
-    abort();
+    return cpu_ppc_tb_init(env, 7812500);
 }
-#endif
 
-static void PPC_io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
+__attribute__ (( alias ("cpu_ppc_store_tbu") ));
+
+uint32_t cpu_ppc601_load_rtcu (CPUState *env)
+__attribute__ (( alias ("cpu_ppc_load_tbu") ));
+
+void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
 {
-    cpu_outb(NULL, addr & 0xffff, value);
+    cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
 }
 
-static uint32_t PPC_io_readb (void *opaque, target_phys_addr_t addr)
+uint32_t cpu_ppc601_load_rtcl (CPUState *env)
 {
-    uint32_t ret = cpu_inb(NULL, addr & 0xffff);
-    return ret;
+    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
 }
 
-static void PPC_io_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+/* Embedded PowerPC timers */
+target_ulong load_40x_pit (CPUState *env)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap16(value);
-#endif
-    cpu_outw(NULL, addr & 0xffff, value);
+    /* XXX: TODO */
+    return 0;
 }
 
-static uint32_t PPC_io_readw (void *opaque, target_phys_addr_t addr)
+void store_40x_pit (CPUState *env, target_ulong val)
 {
-    uint32_t ret = cpu_inw(NULL, addr & 0xffff);
-#ifdef TARGET_WORDS_BIGENDIAN
-    ret = bswap16(ret);
-#endif
-    return ret;
+    /* XXX: TODO */
 }
 
-static void PPC_io_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+void store_booke_tcr (CPUState *env, target_ulong val)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-    value = bswap32(value);
-#endif
-    cpu_outl(NULL, addr & 0xffff, value);
+    /* XXX: TODO */
 }
 
-static uint32_t PPC_io_readl (void *opaque, target_phys_addr_t addr)
+void store_booke_tsr (CPUState *env, target_ulong val)
 {
-    uint32_t ret = cpu_inl(NULL, addr & 0xffff);
-
-#ifdef TARGET_WORDS_BIGENDIAN
-    ret = bswap32(ret);
-#endif
-    return ret;
+    /* XXX: TODO */
 }
 
-CPUWriteMemoryFunc *PPC_io_write[] = {
-    &PPC_io_writeb,
-    &PPC_io_writew,
-    &PPC_io_writel,
-};
-
-CPUReadMemoryFunc *PPC_io_read[] = {
-    &PPC_io_readb,
-    &PPC_io_readw,
-    &PPC_io_readl,
-};
+#if 0
+/*****************************************************************************/
+/* Handle system reset (for now, just stop emulation) */
+void cpu_ppc_reset (CPUState *env)
+{
+    printf("Reset asked... Stop emulation\n");
+    abort();
+}
+#endif
 
 /*****************************************************************************/
 /* Debug port */
@@ -283,60 +271,45 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
 /* NVRAM helpers */
 void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
 {
-    m48t59_set_addr(nvram, addr);
-    m48t59_write(nvram, value);
+    m48t59_write(nvram, addr, value);
 }
 
 uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
 {
-    m48t59_set_addr(nvram, addr);
-    return m48t59_read(nvram);
+    return m48t59_read(nvram, addr);
 }
 
 void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
 {
-    m48t59_set_addr(nvram, addr);
-    m48t59_write(nvram, value >> 8);
-    m48t59_set_addr(nvram, addr + 1);
-    m48t59_write(nvram, value & 0xFF);
+    m48t59_write(nvram, addr, value >> 8);
+    m48t59_write(nvram, addr + 1, value & 0xFF);
 }
 
 uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
 {
     uint16_t tmp;
 
-    m48t59_set_addr(nvram, addr);
-    tmp = m48t59_read(nvram) << 8;
-    m48t59_set_addr(nvram, addr + 1);
-    tmp |= m48t59_read(nvram);
-
+    tmp = m48t59_read(nvram, addr) << 8;
+    tmp |= m48t59_read(nvram, addr + 1);
     return tmp;
 }
 
 void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
 {
-    m48t59_set_addr(nvram, addr);
-    m48t59_write(nvram, value >> 24);
-    m48t59_set_addr(nvram, addr + 1);
-    m48t59_write(nvram, (value >> 16) & 0xFF);
-    m48t59_set_addr(nvram, addr + 2);
-    m48t59_write(nvram, (value >> 8) & 0xFF);
-    m48t59_set_addr(nvram, addr + 3);
-    m48t59_write(nvram, value & 0xFF);
+    m48t59_write(nvram, addr, value >> 24);
+    m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
+    m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
+    m48t59_write(nvram, addr + 3, value & 0xFF);
 }
 
 uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
 {
     uint32_t tmp;
 
-    m48t59_set_addr(nvram, addr);
-    tmp = m48t59_read(nvram) << 24;
-    m48t59_set_addr(nvram, addr + 1);
-    tmp |= m48t59_read(nvram) << 16;
-    m48t59_set_addr(nvram, addr + 2);
-    tmp |= m48t59_read(nvram) << 8;
-    m48t59_set_addr(nvram, addr + 3);
-    tmp |= m48t59_read(nvram);
+    tmp = m48t59_read(nvram, addr) << 24;
+    tmp |= m48t59_read(nvram, addr + 1) << 16;
+    tmp |= m48t59_read(nvram, addr + 2) << 8;
+    tmp |= m48t59_read(nvram, addr + 3);
 
     return tmp;
 }
@@ -347,11 +320,9 @@ void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
     int i;
 
     for (i = 0; i < max && str[i] != '\0'; i++) {
-        m48t59_set_addr(nvram, addr + i);
-        m48t59_write(nvram, str[i]);
+        m48t59_write(nvram, addr + i, str[i]);
     }
-    m48t59_set_addr(nvram, addr + max - 1);
-    m48t59_write(nvram, '\0');
+    m48t59_write(nvram, addr + max - 1, '\0');
 }
 
 int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
@@ -392,10 +363,10 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
     odd = count & 1;
     count &= ~1;
     for (i = 0; i != count; i++) {
-       crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
+        crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
     }
     if (odd) {
-       crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
+        crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
     }
 
     return crc;