qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5926] sh4: Add r2d onboard FPGA IRQ controller (Takashi YO


From: Andrzej Zaborowski
Subject: [Qemu-devel] [5926] sh4: Add r2d onboard FPGA IRQ controller (Takashi YOSHII).
Date: Sun, 07 Dec 2008 18:59:57 +0000

Revision: 5926
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5926
Author:   balrog
Date:     2008-12-07 18:59:57 +0000 (Sun, 07 Dec 2008)

Log Message:
-----------
sh4: Add r2d onboard FPGA IRQ controller (Takashi YOSHII).

This adds IRQ controller in FPGA on r2d, and use it for CF.

Signed-off-by: Takashi YOSHII <address@hidden>
Signed-off-by: Andrzej Zaborowski <address@hidden>

Modified Paths:
--------------
    trunk/hw/r2d.c

Modified: trunk/hw/r2d.c
===================================================================
--- trunk/hw/r2d.c      2008-12-07 18:49:57 UTC (rev 5925)
+++ trunk/hw/r2d.c      2008-12-07 18:59:57 UTC (rev 5926)
@@ -34,12 +34,14 @@
 
 #define SM501_VRAM_SIZE 0x800000
 
+#define PA_IRLMSK      0x00
 #define PA_POWOFF      0x30
 #define PA_VERREG      0x32
 #define PA_OUTPORT     0x36
 
 typedef struct {
     uint16_t bcr;
+    uint16_t irlmsk;
     uint16_t irlmon;
     uint16_t cfctl;
     uint16_t cfpow;
@@ -60,13 +62,60 @@
     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;
 
     switch (addr) {
+    case PA_IRLMSK:
+        return s->irlmsk;
     case PA_OUTPORT:
        return s->outport;
     case PA_POWOFF:
@@ -84,6 +133,10 @@
     r2d_fpga_t *s = opaque;
 
     switch (addr) {
+    case PA_IRLMSK:
+        s->irlmsk = value;
+        update_irl(s);
+       break;
     case PA_OUTPORT:
        s->outport = value;
        break;
@@ -108,18 +161,21 @@
     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;
+
     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_init(ram_addr_t ram_size, int vga_ram_size,
@@ -130,6 +186,7 @@
     CPUState *env;
     struct SH7750State *s;
     ram_addr_t sdram_addr, sm501_vga_ram_addr;
+    qemu_irq *irq;
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -144,15 +201,16 @@
     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). */
-    mmio_ide_init(0x14001000, 0x1400080c, NULL, 1,
-                  drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
+    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+        drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
 
     /* Todo: register on board registers */
     {






reply via email to

[Prev in Thread] Current Thread [Next in Thread]