]> git.proxmox.com Git - qemu.git/blobdiff - hw/sh7750.c
usb: Add a usb_fill_port helper function
[qemu.git] / hw / sh7750.c
index afdb9f5bcbd0830af057d2b3e6c90a1d230b7197..4f279e7e516d7ebef36e191cf2e8b9ebaf2be632 100644 (file)
  * THE SOFTWARE.
  */
 #include <stdio.h>
-#include <assert.h>
 #include "hw.h"
 #include "sh.h"
 #include "sysemu.h"
 #include "sh7750_regs.h"
 #include "sh7750_regnames.h"
 #include "sh_intc.h"
-#include "exec-all.h"
 #include "cpu.h"
 
 #define NB_DEVICES 4
@@ -42,8 +40,12 @@ typedef struct SH7750State {
     uint32_t periph_freq;
     /* SDRAM controller */
     uint32_t bcr1;
-    uint32_t bcr2;
+    uint16_t bcr2;
+    uint16_t bcr3;
+    uint32_t bcr4;
     uint16_t rfcr;
+    /* PCMCIA controller */
+    uint16_t pcr;
     /* IO ports */
     uint16_t gpioic;
     uint32_t pctra;
@@ -66,7 +68,10 @@ typedef struct SH7750State {
     struct intc_desc intc;
 } SH7750State;
 
-
+static inline int has_bcr3_and_bcr4(SH7750State * s)
+{
+       return (s->cpu->features & SH_FEATURE_BCR3_AND_BCR4);
+}
 /**********************************************************************
  I/O ports
 **********************************************************************/
@@ -200,7 +205,7 @@ static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
     switch (addr) {
     default:
        error_access("byte read", addr);
-       assert(0);
+        abort();
     }
 }
 
@@ -211,8 +216,14 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
     switch (addr) {
     case SH7750_BCR2_A7:
        return s->bcr2;
+    case SH7750_BCR3_A7:
+       if(!has_bcr3_and_bcr4(s))
+           error_access("word read", addr);
+       return s->bcr3;
     case SH7750_FRQCR_A7:
        return 0;
+    case SH7750_PCR_A7:
+       return s->pcr;
     case SH7750_RFCR_A7:
        fprintf(stderr,
                "Read access to refresh count register, incrementing\n");
@@ -221,9 +232,14 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
        return porta_lines(s);
     case SH7750_PDTRB_A7:
        return portb_lines(s);
+    case SH7750_RTCOR_A7:
+    case SH7750_RTCNT_A7:
+    case SH7750_RTCSR_A7:
+       ignore_access("word read", addr);
+       return 0;
     default:
        error_access("word read", addr);
-       assert(0);
+        abort();
     }
 }
 
@@ -235,6 +251,9 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
     case SH7750_BCR1_A7:
        return s->bcr1;
     case SH7750_BCR4_A7:
+       if(!has_bcr3_and_bcr4(s))
+           error_access("long read", addr);
+       return s->bcr4;
     case SH7750_WCR1_A7:
     case SH7750_WCR2_A7:
     case SH7750_WCR3_A7:
@@ -267,23 +286,23 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
        return s->cpu->prr;
     default:
        error_access("long read", addr);
-       assert(0);
+        abort();
     }
 }
 
+#define is_in_sdrmx(a, x) (a >= SH7750_SDMR ## x ## _A7 \
+                       && a <= (SH7750_SDMR ## x ## _A7 + SH7750_SDMR ## x ## _REGNB))
 static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
                              uint32_t mem_value)
 {
-    switch (addr) {
-       /* PRECHARGE ? XXXXX */
-    case SH7750_PRECHARGE0_A7:
-    case SH7750_PRECHARGE1_A7:
+
+    if (is_in_sdrmx(addr, 2) || is_in_sdrmx(addr, 3)) {
        ignore_access("byte write", addr);
        return;
-    default:
-       error_access("byte write", addr);
-       assert(0);
     }
+
+    error_access("byte write", addr);
+    abort();
 }
 
 static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
@@ -298,8 +317,15 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
         s->bcr2 = mem_value;
         return;
     case SH7750_BCR3_A7:
-    case SH7750_RTCOR_A7:
+       if(!has_bcr3_and_bcr4(s))
+           error_access("word write", addr);
+       s->bcr3 = mem_value;
+       return;
+    case SH7750_PCR_A7:
+       s->pcr = mem_value;
+       return;
     case SH7750_RTCNT_A7:
+    case SH7750_RTCOR_A7:
     case SH7750_RTCSR_A7:
        ignore_access("word write", addr);
        return;
@@ -322,12 +348,12 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
        s->gpioic = mem_value;
        if (mem_value != 0) {
            fprintf(stderr, "I/O interrupts not implemented\n");
-           assert(0);
+            abort();
        }
        return;
     default:
        error_access("word write", addr);
-       assert(0);
+        abort();
     }
 }
 
@@ -343,6 +369,10 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
         s->bcr1 = mem_value;
         return;
     case SH7750_BCR4_A7:
+       if(!has_bcr3_and_bcr4(s))
+           error_access("long write", addr);
+       s->bcr4 = mem_value;
+       return;
     case SH7750_WCR1_A7:
     case SH7750_WCR2_A7:
     case SH7750_WCR3_A7:
@@ -365,8 +395,11 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
        portb_changed(s, temp);
        return;
     case SH7750_MMUCR_A7:
-       s->cpu->mmucr = mem_value;
-       return;
+        if (mem_value & MMUCR_TI) {
+            cpu_sh4_invalidate_tlb(s->cpu);
+        }
+        s->cpu->mmucr = mem_value & ~MMUCR_TI;
+        return;
     case SH7750_PTEH_A7:
         /* If asid changes, clear all registered tlb entries. */
        if ((s->cpu->pteh & 0xff) != (mem_value & 0xff))
@@ -399,17 +432,17 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
        return;
     default:
        error_access("long write", addr);
-       assert(0);
+        abort();
     }
 }
 
-static CPUReadMemoryFunc *sh7750_mem_read[] = {
+static CPUReadMemoryFunc * const sh7750_mem_read[] = {
     sh7750_mem_readb,
     sh7750_mem_readw,
     sh7750_mem_readl
 };
 
-static CPUWriteMemoryFunc *sh7750_mem_write[] = {
+static CPUWriteMemoryFunc * const sh7750_mem_write[] = {
     sh7750_mem_writeb,
     sh7750_mem_writew,
     sh7750_mem_writel
@@ -584,13 +617,14 @@ static struct intc_group groups_irl[] = {
 
 static uint32_t invalid_read(void *opaque, target_phys_addr_t addr)
 {
-    assert(0);
+    abort();
 
     return 0;
 }
 
 static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
 {
+    SH7750State *s = opaque;
     uint32_t ret = 0;
 
     switch (MM_REGION_TYPE(addr)) {
@@ -599,21 +633,23 @@ static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
         /* do nothing */
        break;
     case MM_ITLB_ADDR:
+        ret = cpu_sh4_read_mmaped_itlb_addr(s->cpu, addr);
+        break;
     case MM_ITLB_DATA:
-        /* XXXXX */
-        assert(0);
-       break;
+        ret = cpu_sh4_read_mmaped_itlb_data(s->cpu, addr);
+        break;
     case MM_OCACHE_ADDR:
     case MM_OCACHE_DATA:
         /* do nothing */
        break;
     case MM_UTLB_ADDR:
+        ret = cpu_sh4_read_mmaped_utlb_addr(s->cpu, addr);
+        break;
     case MM_UTLB_DATA:
-        /* XXXXX */
-        assert(0);
-       break;
+        ret = cpu_sh4_read_mmaped_utlb_data(s->cpu, addr);
+        break;
     default:
-        assert(0);
+        abort();
     }
 
     return ret;
@@ -622,7 +658,7 @@ static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
 static void invalid_write(void *opaque, target_phys_addr_t addr,
                          uint32_t mem_value)
 {
-    assert(0);
+    abort();
 }
 
 static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr,
@@ -636,9 +672,11 @@ static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr,
         /* do nothing */
        break;
     case MM_ITLB_ADDR:
+        cpu_sh4_write_mmaped_itlb_addr(s->cpu, addr, mem_value);
+        break;
     case MM_ITLB_DATA:
-        /* XXXXX */
-        assert(0);
+        cpu_sh4_write_mmaped_itlb_data(s->cpu, addr, mem_value);
+        abort();
        break;
     case MM_OCACHE_ADDR:
     case MM_OCACHE_DATA:
@@ -648,22 +686,21 @@ static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr,
         cpu_sh4_write_mmaped_utlb_addr(s->cpu, addr, mem_value);
        break;
     case MM_UTLB_DATA:
-        /* XXXXX */
-        assert(0);
+        cpu_sh4_write_mmaped_utlb_data(s->cpu, addr, mem_value);
        break;
     default:
-        assert(0);
+        abort();
        break;
     }
 }
 
-static CPUReadMemoryFunc *sh7750_mmct_read[] = {
+static CPUReadMemoryFunc * const sh7750_mmct_read[] = {
     invalid_read,
     invalid_read,
     sh7750_mmct_readl
 };
 
-static CPUWriteMemoryFunc *sh7750_mmct_write[] = {
+static CPUWriteMemoryFunc * const sh7750_mmct_write[] = {
     invalid_write,
     invalid_write,
     sh7750_mmct_writel
@@ -678,19 +715,25 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
     s = qemu_mallocz(sizeof(SH7750State));
     s->cpu = cpu;
     s->periph_freq = 60000000; /* 60MHz */
-    sh7750_io_memory = cpu_register_io_memory(0,
-                                             sh7750_mem_read,
-                                             sh7750_mem_write, s);
+    sh7750_io_memory = cpu_register_io_memory(sh7750_mem_read,
+                                             sh7750_mem_write, s,
+                                              DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory_offset(0x1f000000, 0x1000,
                                         sh7750_io_memory, 0x1f000000);
+    cpu_register_physical_memory_offset(0xff000000, 0x1000,
+                                        sh7750_io_memory, 0x1f000000);
     cpu_register_physical_memory_offset(0x1f800000, 0x1000,
                                         sh7750_io_memory, 0x1f800000);
+    cpu_register_physical_memory_offset(0xff800000, 0x1000,
+                                        sh7750_io_memory, 0x1f800000);
     cpu_register_physical_memory_offset(0x1fc00000, 0x1000,
                                         sh7750_io_memory, 0x1fc00000);
+    cpu_register_physical_memory_offset(0xffc00000, 0x1000,
+                                        sh7750_io_memory, 0x1fc00000);
 
-    sh7750_mm_cache_and_tlb = cpu_register_io_memory(0,
-                                                    sh7750_mmct_read,
-                                                    sh7750_mmct_write, s);
+    sh7750_mm_cache_and_tlb = cpu_register_io_memory(sh7750_mmct_read,
+                                                    sh7750_mmct_write, s,
+                                                     DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(0xf0000000, 0x08000000,
                                 sh7750_mm_cache_and_tlb);
 
@@ -772,4 +815,3 @@ qemu_irq sh7750_irl(SH7750State *s)
     return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
                                1)[0];
 }
-