qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: yoshii.takashi@gmail.com
To: Kristoffer Ericson <kristoffer.ericson@gmail.com>
Cc: qemu-devel@nongnu.org, takasi-y@ops.dti.ne.jp,
	"linux-sh@vger.kernel.org" <linux-sh@vger.kernel.org>
Subject: [Qemu-devel] Re: Qemu SH4 status #2
Date: Wed, 12 Nov 2008 13:33:13 +0900	[thread overview]
Message-ID: <20081112133313.967c82e2.yoshii.takashi@gmail.com> (raw)
In-Reply-To: <20081111122700.79906a33.kristoffer.ericson@gmail.com>

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

Hi,

> I'm still getting segmentation fault at exact same
> location. Have you made additional patches?
Please find attached file "qemu081111.diff".
Basically, this is an aggregate of patches found on qemu-devel ML,
 with some conflicts against current svn source being resolved,
 and some small fix are added, which are scheduled to be posted after
 I finished with my pending patches.

I post this to share information between qemu and linux/sh people,
 and hopefully accelerate debugging with linux people's help.

Another file "linuxconfig_r2d_qemu.diff" is diff for linux kernel
 configuretion. It changes following parameters from r2d+'s defconfig.
- Cache -> off (qemu has no cache)
- commandline change (for debugging)
- 8139too -> 8139cp (qemu's default is c+, still thinking how to switch)
- SH SPI -> off (sci emulation is not mature enough to handle it)

Build procedure is as follows,
Configure kernel:
 make ARCH=sh rts7751r2dplus_defconfig
 patch .config < linuxconfig_r2d_qemu.diff
 (and build)

Configure Qemu:
 ./configure --disable-system --target-list=sh4-softmmu \
  --disable-linux-user --disable-kqemu

Execute:
 sh4-softmmu/qemu-system-sh4 -M r2d --serial vc --serial /dev/tty \
  --kernel zImage --append "console=tty0 root=/dev/sda" \
  -usb --usbdevice keyboard --usbdevice mouse disk.img

I've tested it on qemu svn head this morning.
You will see penguin logo, and fbcon input/output working.
For debugging purpose, console=ttySC0,115200 might help.
/yoshii

[-- Attachment #2: qemu081111.diff --]
[-- Type: text/x-patch, Size: 22795 bytes --]

--- svn/target-sh4/helper.c	(revision 5703)
+++ svn/target-sh4/helper.c	(working copy)
@@ -359,14 +359,12 @@
 			   int *prot, target_ulong address,
 			   int rw, int access_type)
 {
-    int use_asid, is_code, n;
+    int use_asid, n;
     tlb_t *matching = NULL;
 
-    use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
-    is_code = env->pc == address;	/* Hack */
+    use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;    
 
-    /* Use a hack to find if this is an instruction or data access */
-    if (env->pc == address && !(rw & PAGE_WRITE)) {
+    if (rw == 2) {
 	n = find_itlb_entry(env, address, use_asid, 1);
 	if (n >= 0) {
 	    matching = &env->itlb[n];
@@ -382,13 +380,13 @@
 	    switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
 	    case 0:		/* 000 */
 	    case 2:		/* 010 */
-		n = (rw & PAGE_WRITE) ? MMU_DTLB_VIOLATION_WRITE :
+	      n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
 		    MMU_DTLB_VIOLATION_READ;
 		break;
 	    case 1:		/* 001 */
 	    case 4:		/* 100 */
 	    case 5:		/* 101 */
-		if (rw & PAGE_WRITE)
+		if (rw == 1)
 		    n = MMU_DTLB_VIOLATION_WRITE;
 		else
 		    *prot = PAGE_READ;
@@ -396,11 +394,11 @@
 	    case 3:		/* 011 */
 	    case 6:		/* 110 */
 	    case 7:		/* 111 */
-		*prot = rw & (PAGE_READ | PAGE_WRITE);
+	        *prot = (rw == 1)? PAGE_WRITE : PAGE_READ;
 		break;
 	    }
 	} else if (n == MMU_DTLB_MISS) {
-	    n = (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
+	    n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
 		MMU_DTLB_MISS_READ;
 	}
     }
@@ -426,12 +424,19 @@
 	    && (address < 0xe0000000 || address > 0xe4000000)) {
 	    /* Unauthorized access in user mode (only store queues are available) */
 	    fprintf(stderr, "Unauthorized access\n");
-	    return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
-		MMU_DTLB_MISS_READ;
+	    if (rw == 0)
+	        return MMU_DTLB_MISS_READ;
+	    else if (rw == 1)
+	        return MMU_DTLB_MISS_WRITE;
+	    else
+	        return MMU_ITLB_MISS;
 	}
 	if (address >= 0x80000000 && address < 0xc0000000) {
 	    /* Mask upper 3 bits for P1 and P2 areas */
 	    *physical = address & 0x1fffffff;
+	} else if (address >= 0xfd000000 && address < 0xfe000000) {
+	    /* PCI memory space */
+	    *physical = address;
 	} else if (address >= 0xfc000000) {
 	    /*
 	     * Mask upper 3 bits for control registers in P4 area,
@@ -465,27 +470,6 @@
     target_ulong physical, page_offset, page_size;
     int prot, ret, access_type;
 
-    switch (rw) {
-    case 0:
-        rw = PAGE_READ;
-        break;
-    case 1:
-        rw = PAGE_WRITE;
-        break;
-    case 2: /* READ_ACCESS_TYPE == 2 defined in softmmu_template.h */
-        rw = PAGE_READ;
-        break;
-    default:
-        /* fatal error */
-        assert(0);
-    }
-
-    /* XXXXX */
-#if 0
-    fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
-	    __func__, env->pc, address, rw, mmu_idx, is_softmmu);
-#endif
-
     access_type = ACCESS_INT;
     ret =
 	get_physical_address(env, &physical, &prot, address, rw,
@@ -537,7 +521,7 @@
     target_ulong physical;
     int prot;
 
-    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
+    get_physical_address(env, &physical, &prot, addr, 0, 0);
     return physical;
 }
 
--- svn/Makefile.target	(revision 5703)
+++ svn/Makefile.target	(working copy)
@@ -736,7 +736,8 @@
 endif
 ifeq ($(TARGET_BASE_ARCH), sh4)
 OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
-OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sm501.o serial.o
+OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sh_pci.o sm501.o serial.o
+OBJS+= ide.o
 endif
 ifeq ($(TARGET_BASE_ARCH), m68k)
 OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
--- svn/hw/r2d.c	(revision 5703)
+++ svn/hw/r2d.c	(working copy)
@@ -28,12 +28,16 @@
 #include "devices.h"
 #include "sysemu.h"
 #include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sh7750_regs.h"
 
 #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
 #define SDRAM_SIZE 0x04000000
 
 #define SM501_VRAM_SIZE 0x800000
 
+#define PA_IRLMSK	0x00
 #define PA_POWOFF	0x30
 #define PA_VERREG	0x32
 #define PA_OUTPORT	0x36
@@ -41,6 +45,8 @@
 typedef struct {
     target_phys_addr_t base;
 
+/* register */
+    uint16_t irlmsk;
     uint16_t bcr;
     uint16_t irlmon;
     uint16_t cfctl;
@@ -62,8 +68,53 @@
     uint16_t inport;
     uint16_t outport;
     uint16_t bverreg;
+
+/* output pin */
+    qemu_irq irl;
 } r2d_fpga_t;
 
+enum r2d_fpga_irq {
+    PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
+    SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
+    NR_IRQS
+};
+
+static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
+    [CF_IDE]	= {  1, 1<<9 },
+    [CF_CD]	= {  2, 1<<8 },
+    [PCI_INTA]	= {  9, 1<<14 },
+    [PCI_INTB]	= { 10, 1<<13 },
+    [PCI_INTC]	= {  3, 1<<12 },
+    [PCI_INTD]	= {  0, 1<<11 },
+    [SM501]	= {  4, 1<<10 },
+    [KEY]	= {  5, 1<<6 },
+    [RTC_A]	= {  6, 1<<5 },
+    [RTC_T]	= {  7, 1<<4 },
+    [SDCARD]	= {  8, 1<<7 },
+    [EXT]	= { 11, 1<<0 },
+    [TP]	= { 12, 1<<15 },
+};
+
+static void update_irl(r2d_fpga_t *fpga)
+{
+    int i, irl = 15;
+    for (i = 0; i < NR_IRQS; i++)
+        if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
+            if (irqtab[i].irl < irl)
+                irl = irqtab[i].irl;
+    qemu_set_irq(fpga->irl, irl ^ 15);
+}
+
+static void r2d_fpga_irq_set(void *opaque, int n, int level)
+{
+    r2d_fpga_t *fpga = opaque;
+    if (level)
+        fpga->irlmon |= irqtab[n].msk;
+    else
+        fpga->irlmon &= ~irqtab[n].msk;
+    update_irl(fpga);
+}
+
 static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
 {
     r2d_fpga_t *s = opaque;
@@ -71,6 +122,8 @@
     addr -= s->base;
 
     switch (addr) {
+    case PA_IRLMSK:
+        return s->irlmsk;
     case PA_OUTPORT:
 	return s->outport;
     case PA_POWOFF:
@@ -90,6 +143,10 @@
     addr -= s->base;
 
     switch (addr) {
+    case PA_IRLMSK:
+        s->irlmsk = value;
+        update_irl(s);
+	break;
     case PA_OUTPORT:
 	s->outport = value;
 	break;
@@ -114,21 +171,35 @@
     NULL,
 };
 
-static void r2d_fpga_init(target_phys_addr_t base)
+static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
 {
     int iomemtype;
     r2d_fpga_t *s;
 
     s = qemu_mallocz(sizeof(r2d_fpga_t));
     if (!s)
-	return;
+	return NULL;
 
+    s->irl = irl;
+
     s->base = base;
     iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
 				       r2d_fpga_writefn, s);
     cpu_register_physical_memory(base, 0x40, iomemtype);
+    return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
 }
 
+static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
+{
+    qemu_set_irq(p[n], l);
+}
+
+static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
+{
+    const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD };
+    return intx[d->devfn>>3];
+}
+
 static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
               const char *boot_device, DisplayState * ds,
 	      const char *kernel_filename, const char *kernel_cmdline,
@@ -137,6 +208,9 @@
     CPUState *env;
     struct SH7750State *s;
     ram_addr_t sdram_addr, sm501_vga_ram_addr;
+    qemu_irq *irq;
+    PCIBus *pci;
+    int i;
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -151,23 +225,50 @@
     sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
     cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
     /* Register peripherals */
-    r2d_fpga_init(0x04000000);
     s = sh7750_init(env);
+    irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
+
     sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
     sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
 	       serial_hds[2]);
+
+    /* onboard CF (True IDE mode, Master only). */
+    if ((i = drive_get_index(IF_IDE, 0, 0)) != -1)
+        mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+                      drives_table[i].bdrv, NULL);
+
+    /* PCI host and peripherals */
+    pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
+
+    /* NIC: rtl8139 on-board, and 2 slots. */
+    if (nb_nics)
+        pci_rtl8139_init(pci, &nd_table[0], 2<<3);
+    for (i = 1; i < nb_nics; i++)
+        pci_nic_init(pci, &nd_table[i], -1);
+    /* USB OHCI for keyboard & mouse */
+    if (usb_enabled)
+        usb_ohci_init_pci(pci, 4, -1);
     /* Todo: register on board registers */
-    {
+    if (kernel_filename) {
       int kernel_size;
+      /* initialization which should be done by firmware */
+      uint32_t bcr1 = 1<<3; // cs3 SDRAM
+      uint16_t bcr2 = 3<<(3*2); // cs3 32bit
+      cpu_physical_memory_write(SH7750_BCR1_A7,&bcr1,4);
+      cpu_physical_memory_write(SH7750_BCR2_A7,&bcr2,2);
 
-      kernel_size = load_image(kernel_filename, phys_ram_base);
-
+      if (kernel_cmdline) {
+          kernel_size = load_image(kernel_filename, phys_ram_base + 0x80000);
+          env->pc = (SDRAM_BASE + 0x80000) | 0xa0000000;
+          pstrcpy(phys_ram_base + 0x10100, 256, kernel_cmdline);
+      } else {
+          kernel_size = load_image(kernel_filename, phys_ram_base);
+          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
+      }
       if (kernel_size < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
         exit(1);
       }
-
-      env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
     }
 }
 
--- svn/hw/sh_pci.c	(revision 0)
+++ svn/hw/sh_pci.c	(revision 0)
@@ -0,0 +1,207 @@
+/*
+ * SuperH on-chip PCIC emulation.	
+ *
+ * Copyright (c) 2008 Takashi YOSHII
+ *
+ * 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
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "hw.h"
+#include "sh.h"
+#include "pci.h"
+#include "bswap.h"
+
+typedef struct {
+    PCIBus *bus;
+    PCIDevice *dev;
+    uint32_t regbase;
+    uint32_t iopbase;
+    uint32_t membase;
+    uint32_t par;
+    uint32_t mbr;
+    uint32_t iobr;
+} SHPCIC;
+
+static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    SHPCIC *pcic = p;
+    addr -= pcic->regbase;
+    switch(addr) {
+      case 0 ... 0xfc:
+        cpu_to_le32w((uint32_t*)(pcic->dev->config + addr), val);
+        break;
+      case 0x1c0:
+        pcic->par = val;
+        break;
+      case 0x1c4:
+        pcic->mbr = val;
+        break;
+      case 0x1c8:
+        pcic->iobr = val;
+        break;
+      case 0x220:
+        pci_data_write(pcic->bus, pcic->par, val, 4);
+        break;
+    }
+}
+
+static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
+{
+    SHPCIC *pcic = p;
+    addr -= pcic->regbase;
+    switch(addr) {
+      case 0 ... 0xfc:
+        return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
+      case 0x1c0:
+        return pcic->par;
+      case 0x220:
+        return pci_data_read(pcic->bus, pcic->par, 4);
+    }
+    return 0;
+}
+
+static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
+                               uint32_t val, int size)
+{
+    pci_data_write(pcic->bus, addr - pcic->membase + pcic->mbr, val, size);
+}
+
+static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
+                                 int size)
+{
+    return pci_data_read(pcic->bus, addr - pcic->membase + pcic->mbr, size);
+}
+
+static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    sh_pci_data_write(p, addr, val, 1);
+}
+
+static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    sh_pci_data_write(p, addr, val, 2);
+}
+
+static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    sh_pci_data_write(p, addr, val, 4);
+}
+
+static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
+{
+    return sh_pci_mem_read(p, addr, 1);
+}
+
+static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
+{
+    return sh_pci_mem_read(p, addr, 2);
+}
+
+static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
+{
+    return sh_pci_mem_read(p, addr, 4);
+}
+
+static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
+{
+    return addr - pcic->iopbase + pcic->iobr;
+}
+
+static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outb(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outw(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outl(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
+{
+    return cpu_inb(NULL, sh_pci_addr2port(p, addr));
+}
+
+static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
+{
+    return cpu_inw(NULL, sh_pci_addr2port(p, addr));
+}
+
+static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
+{
+    return cpu_inl(NULL, sh_pci_addr2port(p, addr));
+}
+
+typedef struct {
+    CPUReadMemoryFunc *r[3];
+    CPUWriteMemoryFunc *w[3];
+} MemOp;
+
+static MemOp sh_pci_reg = {
+    { NULL, NULL, sh_pci_reg_read },
+    { NULL, NULL, sh_pci_reg_write },
+};
+
+static MemOp sh_pci_mem = {
+    { sh_pci_readb, sh_pci_readw, sh_pci_readl },
+    { sh_pci_writeb, sh_pci_writew, sh_pci_writel },
+};
+
+static MemOp sh_pci_iop = {
+    { sh_pci_inb, sh_pci_inw, sh_pci_inl },
+    { sh_pci_outb, sh_pci_outw, sh_pci_outl },
+};
+
+PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                            qemu_irq *pic, int devfn_min, int nirq)
+{
+    SHPCIC *p;
+    int mem, reg, iop;
+
+    p = qemu_mallocz(sizeof(SHPCIC));
+    p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
+
+    p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
+                                 -1, NULL, NULL);
+    p->regbase = 0x1e200000;
+    p->iopbase = 0x1e240000;
+    p->membase = 0xfd000000;
+    reg = cpu_register_io_memory(0, sh_pci_reg.r, sh_pci_reg.w, p);
+    mem = cpu_register_io_memory(0, sh_pci_mem.r, sh_pci_mem.w, p);
+    iop = cpu_register_io_memory(0, sh_pci_iop.r, sh_pci_iop.w, p);
+    cpu_register_physical_memory(p->regbase, 0x224, reg);
+    cpu_register_physical_memory(p->iopbase, 0x40000, iop);
+    cpu_register_physical_memory(p->membase, 0x1000000, mem);
+
+    p->dev->config[0x00] = 0x54; // HITACHI
+    p->dev->config[0x01] = 0x10; //
+    p->dev->config[0x02] = 0x0e; // SH7751R
+    p->dev->config[0x03] = 0x35; //
+    p->dev->config[0x04] = 0x80;
+    p->dev->config[0x05] = 0x00;
+    p->dev->config[0x06] = 0x90;
+    p->dev->config[0x07] = 0x02;
+
+    return p->bus;
+}
+
--- svn/hw/sh.h	(revision 5703)
+++ svn/hw/sh.h	(working copy)
@@ -42,7 +42,14 @@
 		     struct intc_source *tei_source,
 		     struct intc_source *bri_source);
 
+/* sh7750.c */
+qemu_irq sh7750_irl(struct SH7750State *s);
+
 /* tc58128.c */
 int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
 
+/* ide.c */
+void mmio_ide_init(target_phys_addr_t membase, target_phys_addr_t membase2,
+                   qemu_irq irq, int shift,
+                   BlockDriverState *hd0, BlockDriverState *hd1);
 #endif
--- svn/hw/sh7750.c	(revision 5703)
+++ svn/hw/sh7750.c	(working copy)
@@ -41,6 +41,8 @@
     /* Peripheral frequency in Hz */
     uint32_t periph_freq;
     /* SDRAM controller */
+    uint32_t bcr1;
+    uint32_t bcr2;
     uint16_t rfcr;
     /* IO ports */
     uint16_t gpioic;
@@ -208,6 +210,8 @@
     SH7750State *s = opaque;
 
     switch (addr) {
+    case SH7750_BCR2_A7:
+	return s->bcr2;
     case SH7750_FRQCR_A7:
 	return 0;
     case SH7750_RFCR_A7:
@@ -231,6 +235,15 @@
     SH7750State *s = opaque;
 
     switch (addr) {
+    case SH7750_BCR1_A7:
+	return s->bcr1;
+    case SH7750_BCR4_A7:
+    case SH7750_WCR1_A7:
+    case SH7750_WCR2_A7:
+    case SH7750_WCR3_A7:
+    case SH7750_MCR_A7:
+	ignore_access("long read", addr);
+	return 0;
     case SH7750_MMUCR_A7:
 	return s->cpu->mmucr;
     case SH7750_PTEH_A7:
@@ -285,6 +298,8 @@
     switch (addr) {
 	/* SDRAM controller */
     case SH7750_BCR2_A7:
+	s->bcr2 = mem_value;
+	return;
     case SH7750_BCR3_A7:
     case SH7750_RTCOR_A7:
     case SH7750_RTCNT_A7:
@@ -331,6 +346,8 @@
     switch (addr) {
 	/* SDRAM controller */
     case SH7750_BCR1_A7:
+	s->bcr1 = mem_value;
+        return;
     case SH7750_BCR4_A7:
     case SH7750_WCR1_A7:
     case SH7750_WCR2_A7:
@@ -412,7 +429,9 @@
 	UNUSED = 0,
 
 	/* interrupt sources */
-	IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
+	IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
+	IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
+	IRL0, IRL1, IRL2, IRL3,
 	HUDI, GPIOI,
 	DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
 	DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
@@ -428,6 +447,8 @@
 
 	/* interrupt groups */
 	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+	/* irl bundle */
+	IRL,
 
 	NR_SOURCES,
 };
@@ -529,6 +550,29 @@
 		   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
 };
 
+static struct intc_vect vectors_irl[] = {
+	INTC_VECT(IRL_0, 0x200),
+	INTC_VECT(IRL_1, 0x220),
+	INTC_VECT(IRL_2, 0x240),
+	INTC_VECT(IRL_3, 0x260),
+	INTC_VECT(IRL_4, 0x280),
+	INTC_VECT(IRL_5, 0x2a0),
+	INTC_VECT(IRL_6, 0x2c0),
+	INTC_VECT(IRL_7, 0x2e0),
+	INTC_VECT(IRL_8, 0x300),
+	INTC_VECT(IRL_9, 0x320),
+	INTC_VECT(IRL_A, 0x340),
+	INTC_VECT(IRL_B, 0x360),
+	INTC_VECT(IRL_C, 0x380),
+	INTC_VECT(IRL_D, 0x3a0),
+	INTC_VECT(IRL_E, 0x3c0),
+};
+
+static struct intc_group groups_irl[] = {
+	INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6,
+		IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E),
+};
+
 /**********************************************************************
  Memory mapped cache and TLB
 **********************************************************************/
@@ -717,5 +761,16 @@
 				 NULL, 0);
     }
 
+    sh_intc_register_sources(&s->intc,
+				_INTC_ARRAY(vectors_irl),
+				_INTC_ARRAY(groups_irl));
     return s;
 }
+
+qemu_irq sh7750_irl(SH7750State *s)
+{
+    sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
+    return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
+                               1)[0];
+}
+
--- svn/hw/ide.c	(revision 5703)
+++ svn/hw/ide.c	(working copy)
@@ -3512,6 +3512,98 @@
 }
 
 /***********************************************************/
+/* MMIO based ide port
+ * This emulates IDE device connected directly to the CPU bus without
+ * dedicated ide controller, which is often seen on embedded boards.
+ */
+
+typedef struct {
+    void *dev;
+    int shift;
+} MMIOState;
+
+static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
+{
+    MMIOState *s = (MMIOState*)opaque;
+    IDEState *ide = (IDEState*)s->dev;
+    addr >>= s->shift;
+    if (addr & 7)
+        return ide_ioport_read(ide, addr);
+    else
+        return ide_data_readw(ide, 0);
+}
+
+static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
+	uint32_t val)
+{
+    MMIOState *s = (MMIOState*)opaque;
+    IDEState *ide = (IDEState*)s->dev;
+    addr >>= s->shift;
+    if (addr & 7)
+        ide_ioport_write(ide, addr, val);
+    else
+        ide_data_writew(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_reads[] = {
+    mmio_ide_read,
+    mmio_ide_read,
+    mmio_ide_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_writes[] = {
+    mmio_ide_write,
+    mmio_ide_write,
+    mmio_ide_write,
+};
+
+static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
+{
+    MMIOState *s= (MMIOState*)opaque;
+    IDEState *ide = (IDEState*)s->dev;
+    return ide_status_read(ide, 0);
+}
+
+static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
+	uint32_t val)
+{
+    MMIOState *s = (MMIOState*)opaque;
+    IDEState *ide = (IDEState*)s->dev;
+    ide_cmd_write(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_status[] = {
+    mmio_ide_status_read,
+    mmio_ide_status_read,
+    mmio_ide_status_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_cmd[] = {
+    mmio_ide_cmd_write,
+    mmio_ide_cmd_write,
+    mmio_ide_cmd_write,
+};
+
+void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, 
+	            qemu_irq irq, int shift,
+                    BlockDriverState *hd0, BlockDriverState *hd1)
+{
+    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+    IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+    int mem1, mem2;
+
+    ide_init2(ide, hd0, hd1, irq);
+
+    s->dev = ide;
+    s->shift = shift;
+
+    mem1 = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+    mem2 = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+    cpu_register_physical_memory(membase, 16<<shift, mem1);
+    cpu_register_physical_memory(membase2, 2<<shift, mem2);
+}
+
+/***********************************************************/
 /* CF-ATA Microdrive */
 
 #define METADATA_SIZE	0x20
--- svn/hw/sh_intc.c	(revision 5703)
+++ svn/hw/sh_intc.c	(working copy)
@@ -451,3 +451,18 @@
 
     return 0;
 }
+
+/* Assert level <n> IRL interrupt. 
+   0:deassert. 1:lowest priority,... 15:highest priority. */
+void sh_intc_set_irl(void *opaque, int n, int level)
+{
+    struct intc_source *s = opaque;
+    int i, irl = level ^ 15;
+    for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) {
+	if (i == irl)
+	    sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1);
+	else
+	    if (s->asserted)
+	        sh_intc_toggle_source(s, 0, -1);
+    }
+}
--- svn/hw/sh_intc.h	(revision 5703)
+++ svn/hw/sh_intc.h	(working copy)
@@ -72,4 +72,6 @@
 		 struct intc_prio_reg *prio_regs,
 		 int nr_prio_regs);
 
+void sh_intc_set_irl(void *opaque, int n, int level);
+
 #endif /* __SH_INTC_H__ */

[-- Attachment #3: linuxconfig_r2d_qemu.diff --]
[-- Type: text/x-patch, Size: 1150 bytes --]

--- arch/sh/configs/rts7751r2dplus_defconfig	2008-11-11 16:18:39.000000000 +0900
+++ .config	2008-11-12 13:09:59.000000000 +0900
@@ -197,9 +197,9 @@
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITEBACK is not set
 # CONFIG_CACHE_WRITETHROUGH is not set
-# CONFIG_CACHE_OFF is not set
+CONFIG_CACHE_OFF=y
 
 #
 # Processor features
@@ -283,8 +283,7 @@
 CONFIG_ZERO_PAGE_OFFSET=0x00010000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Bus options
@@ -613,8 +612,8 @@
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
+CONFIG_8139CP=y
+# CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
@@ -772,7 +772,7 @@
 # SPI Master Controller Drivers
 #
 CONFIG_SPI_BITBANG=y
-CONFIG_SPI_SH_SCI=y
+# CONFIG_SPI_SH_SCI is not set
 
 #
 # SPI Protocol Masters

  reply	other threads:[~2008-11-12  4:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20081110233926.3d8c7fd1.kristoffer.ericson@gmail.com>
     [not found] ` <20081111141335.3c869c26.yoshii.takashi@gmail.com>
2008-11-11 11:27   ` [Qemu-devel] Re: Qemu SH4 status #2 Kristoffer Ericson
2008-11-12  4:33     ` yoshii.takashi [this message]
2008-11-12  4:58       ` Paul Mundt
2008-11-12 10:56       ` Kristoffer Ericson
2008-11-12 16:52       ` Kristoffer Ericson
2008-11-24  7:10       ` Shin-ichiro KAWASAKI
2008-11-25 16:37         ` Jean-Christophe PLAGNIOL-VILLARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081112133313.967c82e2.yoshii.takashi@gmail.com \
    --to=yoshii.takashi@gmail.com \
    --cc=kristoffer.ericson@gmail.com \
    --cc=linux-sh@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    --cc=takasi-y@ops.dti.ne.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).