[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller.
From: |
takasi-y |
Subject: |
[Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller. |
Date: |
Mon, 27 Oct 2008 00:17:41 +0900 (JST) |
This adds IRQ controller in FPGA on r2d, and use it for CF.
Signed-off-by: Takashi YOSHII <address@hidden>
---
hw/r2d.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/hw/r2d.c b/hw/r2d.c
index 078f6a4..e5750cb 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -31,6 +31,7 @@
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
+#define PA_IRLMSK 0x00
#define PA_POWOFF 0x30
#define PA_VERREG 0x32
#define PA_OUTPORT 0x36
@@ -38,6 +39,8 @@
typedef struct {
target_phys_addr_t base;
+/* register */
+ uint16_t irlmsk;
uint16_t bcr;
uint16_t irlmon;
uint16_t cfctl;
@@ -59,8 +62,52 @@ typedef struct {
uint16_t inport;
uint16_t outport;
uint16_t bverreg;
+
+/* output pin */
+ wire 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 = 0xf;
+ for(i = 0; i < NR_IRQS; i++)
+ if(fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
+ if(irqtab[i].irl < irl)
+ irl = irqtab[i].irl;
+ wire_drive(fpga->irl, irl);
+}
+
+static void r2d_fpga_irq_set(r2d_fpga_t *fpga, int n, int level)
+{
+ 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;
@@ -87,6 +134,10 @@ r2d_fpga_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
addr -= s->base;
switch (addr) {
+ case PA_IRLMSK:
+ s->irlmsk = value;
+ update_irl(s);
+ break;
case PA_OUTPORT:
s->outport = value;
break;
@@ -111,19 +162,22 @@ static CPUWriteMemoryFunc *r2d_fpga_writefn[] = {
NULL,
};
-static void r2d_fpga_init(target_phys_addr_t base)
+static qemu_irq *r2d_fpga_init(target_phys_addr_t base, wire 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_init(ram_addr_t ram_size, int vga_ram_size,
@@ -135,6 +189,8 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
struct SH7750State *s;
BlockDriverState *cf;
int mmio[2];
+ qemu_irq *irq;
+ extern wire sh7750_irl(struct SH7750State *s);
extern void mmio_ide_init (int*, BlockDriverState*, BlockDriverState*,
qemu_irq, int);
@@ -150,12 +206,12 @@ static void r2d_init(ram_addr_t ram_size, int
vga_ram_size,
/* Allocate memory space */
cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, 0);
/* Register peripherals */
- r2d_fpga_init(0x04000000);
s = sh7750_init(env);
+ irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
/* onboard CF (True IDE mode, Primary only). */
cf = drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv;
- mmio_ide_init(mmio, cf, NULL, 0, 1);
+ mmio_ide_init(mmio, cf, NULL, irq[CF_IDE], 1);
cpu_register_physical_memory(0x14001000, 0x20, mmio[0]);
cpu_register_physical_memory(0x1400080c, 4, mmio[1]);
--
1.5.4.3
- [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller.,
takasi-y <=