qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.
@ 2008-09-22 16:31 yoshii.takashi
  2008-09-22 19:00 ` takasi-y
                   ` (5 more replies)
  0 siblings, 6 replies; 22+ messages in thread
From: yoshii.takashi @ 2008-09-22 16:31 UTC (permalink / raw)
  To: qemu-devel

Hi,

This patch adds emulation for a CompactFlash on sh4/r2d board. 
I can mount/umount and some read/writes with r2d-1 kernel (no irq mode).
No heavy/formal test has not be done, though.

The device is CF, but wired to be worked as True-IDE mode, and connected
 directly to SH bus. So, this code is to supports generally mmio based IDEs
 which are supported by "pata_platform" driver in linux kernel.

I wonder where to put function prototype for mmio_ide_init().
Currently, it is in r2d.c, but I believe it can be in more common place.

Any suggestions?

Cheers,
/yoshii

diff --git a/Makefile.target b/Makefile.target
index 88e877f..3844a04 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -620,6 +620,7 @@ 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
+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
diff --git a/hw/ide.c b/hw/ide.c
index 1e60591..f0e1607 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -3439,6 +3439,95 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
 }
 
 /***********************************************************/
+/* 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 (int *mmio, BlockDriverState *hd0, BlockDriverState *hd1,
+	qemu_irq irq, int shift)
+{
+    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+    IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+    int *io;
+
+    ide_init2(ide, hd0, hd1, irq);
+
+    s->dev = ide;
+    s->shift = shift;
+
+    mmio[0] = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+    mmio[1] = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+}
+
+/***********************************************************/
 /* CF-ATA Microdrive */
 
 #define METADATA_SIZE	0x20
diff --git a/hw/r2d.c b/hw/r2d.c
index a7607d1..d9d43a6 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -133,6 +133,10 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
 {
     CPUState *env;
     struct SH7750State *s;
+    BlockDriverState *cf;
+    int mmio[2];
+    extern void mmio_ide_init (int*, BlockDriverState*, BlockDriverState*,
+        qemu_irq, int);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -148,6 +152,13 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
     /* Register peripherals */
     r2d_fpga_init(0x04000000);
     s = sh7750_init(env);
+
+    /* 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);
+    cpu_register_physical_memory(0x14001000, 0x20, mmio[0]);
+    cpu_register_physical_memory(0x1400080c, 4, mmio[1]);
+
     /* Todo: register on board registers */
     {
       int kernel_size;

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
@ 2008-09-22 19:00 ` takasi-y
  2008-09-23  8:55 ` Paul Mundt
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: takasi-y @ 2008-09-22 19:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: yoshii.takashi

> yoshii.takashi@gmail.com
Sorry. Wrong address. 
I've re-sent same message from another address. Sorry for making noise...
/yoshii

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
  2008-09-22 19:00 ` takasi-y
@ 2008-09-23  8:55 ` Paul Mundt
  2008-10-08 15:20   ` pmac kernel & disk image wanted (was Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.) Shin-ichiro KAWASAKI
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board takasi-y
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 22+ messages in thread
From: Paul Mundt @ 2008-09-23  8:55 UTC (permalink / raw)
  To: qemu-devel

On Tue, Sep 23, 2008 at 01:31:36AM +0900, yoshii.takashi@gmail.com wrote:
> This patch adds emulation for a CompactFlash on sh4/r2d board. 
> I can mount/umount and some read/writes with r2d-1 kernel (no irq mode).
> No heavy/formal test has not be done, though.
> 
> The device is CF, but wired to be worked as True-IDE mode, and connected
>  directly to SH bus. So, this code is to supports generally mmio based IDEs
>  which are supported by "pata_platform" driver in linux kernel.
> 
> I wonder where to put function prototype for mmio_ide_init().
> Currently, it is in r2d.c, but I believe it can be in more common place.
> 
> Any suggestions?
> 
ide.c is likely the best place for it. It looks like there is a bit of
overlap with pmac_ide though. ARM and others that use pata_platform will
want to use this as well.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* pmac kernel & disk image wanted (was Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.)
  2008-09-23  8:55 ` Paul Mundt
@ 2008-10-08 15:20   ` Shin-ichiro KAWASAKI
  2008-10-26 15:35     ` Andreas Färber
  0 siblings, 1 reply; 22+ messages in thread
From: Shin-ichiro KAWASAKI @ 2008-10-08 15:20 UTC (permalink / raw)
  To: qemu-devel

Paul Mundt wrote:
> On Tue, Sep 23, 2008 at 01:31:36AM +0900, yoshii.takashi@gmail.com wrote:
>> This patch adds emulation for a CompactFlash on sh4/r2d board. 
>> I can mount/umount and some read/writes with r2d-1 kernel (no irq mode).
>> No heavy/formal test has not be done, though.
>>
>> The device is CF, but wired to be worked as True-IDE mode, and connected
>>  directly to SH bus. So, this code is to supports generally mmio based IDEs
>>  which are supported by "pata_platform" driver in linux kernel.
>>
>> I wonder where to put function prototype for mmio_ide_init().
>> Currently, it is in r2d.c, but I believe it can be in more common place.
>>
>> Any suggestions?
>>
> ide.c is likely the best place for it. It looks like there is a bit of
> overlap with pmac_ide though. ARM and others that use pata_platform will
> want to use this as well.

I confirmed that the mmio_ide patch works fine for SH4 system emulation.
I hope it to be merged into trunk.

By the way, I guess pmac_ide functions can be re-implemented with
mmio_ide functions.  Before trying this work, I want working kernel
and disk image for PowerMAC(g3bw) system emulation to check if new
implementation works fine or not.

The kernel and disk image for PREP are found at the following URL,
http://www.oszoo.org/wiki/index.php/Debian_Etch_ppc_(PowerPC)_-_Qemu_Ready
But PREP's ide feature does not use pmac_ide but uses isa_ide, so it
does not suit for my purpose.

Any indications or comments will be appreciated.

Regards,
Shin-ichiro KAWASAKI

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
  2008-09-22 19:00 ` takasi-y
  2008-09-23  8:55 ` Paul Mundt
@ 2008-10-26 15:17 ` takasi-y
  2008-10-26 15:54   ` Blue Swirl
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 0/3] take 2. " takasi-y
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 22+ messages in thread
From: takasi-y @ 2008-10-26 15:17 UTC (permalink / raw)
  To: qemu-devel

This patch adds emulation for a CompactFlash on sh4/r2d board. 
The device is CF, but wired to be worked as True-IDE mode, and connected
 directly to SH bus. So, this code is to supports generally mmio based IDEs
 which are supported by "pata_platform" driver in linux kernel.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 Makefile.target |    1 +
 hw/ide.c        |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/r2d.c        |   11 +++++++
 3 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index e2edf9d..219bb2c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -620,6 +620,7 @@ 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
+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
diff --git a/hw/ide.c b/hw/ide.c
index 33e8b39..46218fe 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -3486,6 +3486,95 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
 }
 
 /***********************************************************/
+/* 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 (int *mmio, BlockDriverState *hd0, BlockDriverState *hd1,
+	qemu_irq irq, int shift)
+{
+    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+    IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+    int *io;
+
+    ide_init2(ide, hd0, hd1, irq);
+
+    s->dev = ide;
+    s->shift = shift;
+
+    mmio[0] = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+    mmio[1] = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+}
+
+/***********************************************************/
 /* CF-ATA Microdrive */
 
 #define METADATA_SIZE	0x20
diff --git a/hw/r2d.c b/hw/r2d.c
index 58c93e8..078f6a4 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -133,6 +133,10 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
 {
     CPUState *env;
     struct SH7750State *s;
+    BlockDriverState *cf;
+    int mmio[2];
+    extern void mmio_ide_init (int*, BlockDriverState*, BlockDriverState*,
+        qemu_irq, int);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -148,6 +152,13 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
     /* Register peripherals */
     r2d_fpga_init(0x04000000);
     s = sh7750_init(env);
+
+    /* 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);
+    cpu_register_physical_memory(0x14001000, 0x20, mmio[0]);
+    cpu_register_physical_memory(0x1400080c, 4, mmio[1]);
+
     /* Todo: register on board registers */
     {
       int kernel_size;
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 0/3] take 2. sh4: mmio based CF support on r2d board.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
                   ` (2 preceding siblings ...)
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board takasi-y
@ 2008-10-26 15:17 ` takasi-y
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support takasi-y
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller takasi-y
  5 siblings, 0 replies; 22+ messages in thread
From: takasi-y @ 2008-10-26 15:17 UTC (permalink / raw)
  To: qemu-devel

Hi,
This is second attempt of "sh4: mmio based CF support on r2d board",
with IRQ support and my signed-off line this time.

This consists of following patches.
[PATCH 1/3] sh4: mmio based CF support on r2d board.
[PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support.
[PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller.

1 is just same as I sent at 2008-09-23. Skip if you've already applied it.
2 adds IRL mode interrupt to sh_intc and sh7750.
3 adds interrupt controller in FPGA on r2d board, and use it for CF.
/yoshii

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
                   ` (3 preceding siblings ...)
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 0/3] take 2. " takasi-y
@ 2008-10-26 15:17 ` takasi-y
  2008-10-26 16:09   ` Blue Swirl
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller takasi-y
  5 siblings, 1 reply; 22+ messages in thread
From: takasi-y @ 2008-10-26 15:17 UTC (permalink / raw)
  To: qemu-devel

This patch adds IRL(4bit encoded interrupt input) support to SH. 

This exports following interface functions
 void sh_intc_set_irl(struct intc_source *s, int n) for CPU
 wire sh7750_irl(SH7750State *s) for Board.
and
 void wire_drive(wire w, int n) for actual operation.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>

---
 hw/sh.h      |   26 ++++++++++++++++++++++++++
 hw/sh7750.c  |   40 +++++++++++++++++++++++++++++++++++++++-
 hw/sh_intc.c |   14 ++++++++++++++
 hw/sh_intc.h |    2 ++
 4 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/hw/sh.h b/hw/sh.h
index 50a1ae9..4ddcbf0 100644
--- a/hw/sh.h
+++ b/hw/sh.h
@@ -45,4 +45,30 @@ void sh_serial_init (target_phys_addr_t base, int feat,
 /* tc58128.c */
 int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
 
+/* wire: simple abstraction of inter-module pin to pin connection. */
+
+typedef void (*wire_receiver)(void *o, int n);
+struct wire_t {
+	void *obj;
+	wire_receiver rcv;
+};
+typedef struct wire_t *wire;
+
+static inline wire wire_new(void)
+{
+	return (wire)qemu_mallocz(sizeof(struct wire_t));
+}
+
+static inline wire wire_set_receiver(wire w, void *rcv, void *obj)
+{
+	w->rcv = (wire_receiver)rcv;
+	w->obj = obj;
+	return w;
+}
+
+static inline void wire_drive(wire w, int n)
+{
+	w->rcv(w->obj, n);
+}
+
 #endif
diff --git a/hw/sh7750.c b/hw/sh7750.c
index 62c226e..4fe89ba 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -412,7 +412,9 @@ enum {
 	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 +430,8 @@ enum {
 
 	/* interrupt groups */
 	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+	/* irl bundle */
+	IRL,
 
 	NR_SOURCES,
 };
@@ -529,6 +533,29 @@ static struct intc_group groups_pci[] = {
 		   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 +744,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
 				 NULL, 0);
     }
 
+    sh_intc_register_sources(&s->intc,
+				_INTC_ARRAY(vectors_irl),
+				_INTC_ARRAY(groups_irl));
     return s;
 }
+
+wire sh7750_irl(SH7750State *s)
+{
+    sh_intc_toggle_source(sh_intc_source(&s->intc, IRL),1,0);
+    return wire_set_receiver(wire_new(), sh_intc_set_irl,
+		 sh_intc_source(&s->intc, IRL));
+}
+
diff --git a/hw/sh_intc.c b/hw/sh_intc.c
index 8d1674a..eadb4f2 100644
--- a/hw/sh_intc.c
+++ b/hw/sh_intc.c
@@ -451,3 +451,17 @@ int sh_intc_init(struct intc_desc *desc,
 
     return 0;
 }
+
+/* Assert IRL<n>if n=0..14, otherwise Deassert all */
+void sh_intc_set_irl(struct intc_source *s, int n)
+{
+    int i=0;
+    while((s = sh_intc_source(s->parent, s->next_enum_id))) {
+	if(n == i)
+	    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);
+	i++;
+    }
+}
diff --git a/hw/sh_intc.h b/hw/sh_intc.h
index d22a4a2..fc4c5e6 100644
--- a/hw/sh_intc.h
+++ b/hw/sh_intc.h
@@ -72,4 +72,6 @@ int sh_intc_init(struct intc_desc *desc,
 		 struct intc_prio_reg *prio_regs,
 		 int nr_prio_regs);
 
+void sh_intc_set_irl(struct intc_source *s, int n);
+
 #endif /* __SH_INTC_H__ */
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller.
  2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
                   ` (4 preceding siblings ...)
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support takasi-y
@ 2008-10-26 15:17 ` takasi-y
  2008-10-28 20:58   ` [Qemu-devel] [PATCH 3/3] take3 " takasi-y
  5 siblings, 1 reply; 22+ messages in thread
From: takasi-y @ 2008-10-26 15:17 UTC (permalink / raw)
  To: qemu-devel

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

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: pmac kernel & disk image wanted (was Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.)
  2008-10-08 15:20   ` pmac kernel & disk image wanted (was Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.) Shin-ichiro KAWASAKI
@ 2008-10-26 15:35     ` Andreas Färber
  0 siblings, 0 replies; 22+ messages in thread
From: Andreas Färber @ 2008-10-26 15:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: Shin-ichiro KAWASAKI


Am 08.10.2008 um 17:20 schrieb Shin-ichiro KAWASAKI:

> I guess pmac_ide functions can be re-implemented with
> mmio_ide functions.  Before trying this work, I want working kernel
> and disk image for PowerMAC(g3bw) system emulation to check if new
> implementation works fine or not.
>
> The kernel and disk image for PREP are found at the following URL,
> http://www.oszoo.org/wiki/index.php/Debian_Etch_ppc_(PowerPC)_-_Qemu_Ready
> But PREP's ide feature does not use pmac_ide but uses isa_ide, so it
> does not suit for my purpose.

I was recently told PReP were the only working Linux kernel in QEMU.  
That's what we're using for the TCG conversion.

g3bw is based on the OpenHackWare OpenFirmware implementation, which  
has some issues booting.

Andreas

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board takasi-y
@ 2008-10-26 15:54   ` Blue Swirl
  2008-10-27  1:29     ` andrzej zaborowski
  2008-10-27 18:57     ` takasi-y
  0 siblings, 2 replies; 22+ messages in thread
From: Blue Swirl @ 2008-10-26 15:54 UTC (permalink / raw)
  To: qemu-devel

On 10/26/08, takasi-y@ops.dti.ne.jp <takasi-y@ops.dti.ne.jp> wrote:
> This patch adds emulation for a CompactFlash on sh4/r2d board.
>  The device is CF, but wired to be worked as True-IDE mode, and connected
>   directly to SH bus. So, this code is to supports generally mmio based IDEs
>   which are supported by "pata_platform" driver in linux kernel.

+    if(addr & 7)

I'd add a space between if and (.

+static uint32_t mmio_ide_status_read (void *opaque,target_phys_addr_t addr)

Please add a space between the comma after opaque and target_phys_addr_t.

>  +void mmio_ide_init (int *mmio, BlockDriverState *hd0, BlockDriverState *hd1,
>  +       qemu_irq irq, int shift)
>  +{
>  +    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
>  +    IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
>  +    int *io;
>  +
>  +    ide_init2(ide, hd0, hd1, irq);
>  +
>  +    s->dev = ide;
>  +    s->shift = shift;
>  +
>  +    mmio[0] = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
>  +    mmio[1] = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
>  +}

It would be better to make the init function take instead of mmio
pointer, two target_phys_addr_t parameters and do the physical memory
registration there.

>  +    extern void mmio_ide_init (int*, BlockDriverState*, BlockDriverState*,
>  +        qemu_irq, int);

This should be in a .h file (maybe pc.h), without "extern" and the
parameter names should be included.

Otherwise, the whole patch looks OK.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support.
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support takasi-y
@ 2008-10-26 16:09   ` Blue Swirl
  2008-10-28 20:58     ` [Qemu-devel] [PATCH 2/3] take3 " takasi-y
  0 siblings, 1 reply; 22+ messages in thread
From: Blue Swirl @ 2008-10-26 16:09 UTC (permalink / raw)
  To: qemu-devel

On 10/26/08, takasi-y@ops.dti.ne.jp <takasi-y@ops.dti.ne.jp> wrote:
> This patch adds IRL(4bit encoded interrupt input) support to SH.
>
>  This exports following interface functions
>   void sh_intc_set_irl(struct intc_source *s, int n) for CPU
>   wire sh7750_irl(SH7750State *s) for Board.
>  and
>   void wire_drive(wire w, int n) for actual operation.
>
>  Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>

Isn't it possible to use existing qemu_irq for the signals instead? On
Sparc32, I have used qemu_irq for interrupt lines, reset signals and a
terminal count pulse, one version used it for DMA request.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-26 15:54   ` Blue Swirl
@ 2008-10-27  1:29     ` andrzej zaborowski
  2008-10-27 17:10       ` Blue Swirl
  2008-10-27 18:57     ` takasi-y
  1 sibling, 1 reply; 22+ messages in thread
From: andrzej zaborowski @ 2008-10-27  1:29 UTC (permalink / raw)
  To: qemu-devel

2008/10/26 Blue Swirl <blauwirbel@gmail.com>:
> On 10/26/08, takasi-y@ops.dti.ne.jp <takasi-y@ops.dti.ne.jp> wrote:
>> This patch adds emulation for a CompactFlash on sh4/r2d board.
>>  The device is CF, but wired to be worked as True-IDE mode, and connected
>>   directly to SH bus.

The CF-ATA code (IBM microdrive) in ide.c should expose a qemu_irq
that toggles between CF and True-IDE mode so that it can be used as
both... but it can be done another time.  I hadn't done it originally
because the pin is wired to CF mode in zaurus.

>
> +    if(addr & 7)
>
> I'd add a space between if and (.
>
> +static uint32_t mmio_ide_status_read (void *opaque,target_phys_addr_t addr)
>
> Please add a space between the comma after opaque and target_phys_addr_t.
>
>>  +void mmio_ide_init (int *mmio, BlockDriverState *hd0, BlockDriverState *hd1,
>>  +       qemu_irq irq, int shift)
>>  +{
>>  +    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
>>  +    IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
>>  +    int *io;
>>  +
>>  +    ide_init2(ide, hd0, hd1, irq);
>>  +
>>  +    s->dev = ide;
>>  +    s->shift = shift;
>>  +
>>  +    mmio[0] = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
>>  +    mmio[1] = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
>>  +}
>
> It would be better to make the init function take instead of mmio
> pointer, two target_phys_addr_t parameters and do the physical memory
> registration there.

Why would it be better?  This implementation seems more flexible.

Cheers

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-27  1:29     ` andrzej zaborowski
@ 2008-10-27 17:10       ` Blue Swirl
  2008-10-29 14:22         ` andrzej zaborowski
  0 siblings, 1 reply; 22+ messages in thread
From: Blue Swirl @ 2008-10-27 17:10 UTC (permalink / raw)
  To: qemu-devel

On 10/27/08, andrzej zaborowski <balrogg@gmail.com> wrote:
> 2008/10/26 Blue Swirl <blauwirbel@gmail.com>:
>  > It would be better to make the init function take instead of mmio
>  > pointer, two target_phys_addr_t parameters and do the physical memory
>  > registration there.
>
>
> Why would it be better?  This implementation seems more flexible.

How is this more flexible? Now r2d.c has to know the number of
registers in the IDE controller which should be internal to ide.c.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-26 15:54   ` Blue Swirl
  2008-10-27  1:29     ` andrzej zaborowski
@ 2008-10-27 18:57     ` takasi-y
  2008-10-27 19:12       ` Blue Swirl
  1 sibling, 1 reply; 22+ messages in thread
From: takasi-y @ 2008-10-27 18:57 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

Thank you for your review.

> I'd add a space between if and (.
...
> Please add a space between the comma after opaque and target_phys_addr_t.
OK. I fix the styles.

> It would be better to make the init function take instead of mmio
> pointer, two target_phys_addr_t parameters and do the physical memory
> registration there.

I wrote it because I thought it was simple and flexible.
But, after browsing other device init functions, I understand "callee register"
 is basic procedure in this program.

Looking at isa_ide_init()
# void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
#                   BlockDriverState *hd0, BlockDriverState *hd1);
as a reference, I changed the function args like following.

void mmio_ide_init(target_phys_addr_t membase, target_phys_addr_t membase2,
                   qemu_irq irq, int shift,
                   BlockDriverState *hd0, BlockDriverState *hd1)
This one is not bad at all.

> This should be in a .h file (maybe pc.h), without "extern" and the
> parameter names should be included.
Sure. But, I wonder which file is suitable. 
The system I accustomed to is like
- ide.c define function
- ide.h declare prototype
- pc.c include ide.h and refer the function.
But in QEMU, it looks like
- ide.c define function
- pc.h declare prototype
- pc.c include pc.h and refer the function.
Is it mean the prototype declaration should go into new file "r2d.h" ?

Cheers,
/yoshii

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-27 18:57     ` takasi-y
@ 2008-10-27 19:12       ` Blue Swirl
  2008-10-28 20:58         ` [Qemu-devel] [PATCH 1/3] take3 " takasi-y
  0 siblings, 1 reply; 22+ messages in thread
From: Blue Swirl @ 2008-10-27 19:12 UTC (permalink / raw)
  To: takasi-y@ops.dti.ne.jp; +Cc: qemu-devel

On 10/27/08, takasi-y@ops.dti.ne.jp <takasi-y@ops.dti.ne.jp> wrote:
>  > This should be in a .h file (maybe pc.h), without "extern" and the
>  > parameter names should be included.
>
> Sure. But, I wonder which file is suitable.
>  The system I accustomed to is like
>  - ide.c define function
>  - ide.h declare prototype
>  - pc.c include ide.h and refer the function.
>  But in QEMU, it looks like
>  - ide.c define function
>  - pc.h declare prototype
>  - pc.c include pc.h and refer the function.

I agree that the current .h system is not clear, I would prefer the
system you described. The reason is that otherwise there would be a
lot of files, many with just one function for device init.

>  Is it mean the prototype declaration should go into new file "r2d.h" ?

How about sh.h? It's already included from r2d.c.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 1/3] take3 sh4: mmio based CF support on r2d board.
  2008-10-27 19:12       ` Blue Swirl
@ 2008-10-28 20:58         ` takasi-y
  0 siblings, 0 replies; 22+ messages in thread
From: takasi-y @ 2008-10-28 20:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl

> How about sh.h? It's already included from r2d.c.
Ah, looks good. It already has some prototypes.
Here is the 3rd post.
/yoshii
--
 This patch adds emulation for a CompactFlash on sh4/r2d board.
 The device is CF, but wired to be worked as True-IDE mode, and connected
 directly to SH bus. So, this code is to supports generally mmio based
 IDEs which are supported by "pata_platform" driver in linux kernel.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 Makefile.target |    1 +
 hw/ide.c        |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/r2d.c        |    5 +++
 hw/sh.h         |    4 ++
 4 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index f9c0b34..8edae9d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -725,6 +725,7 @@ 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
+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
diff --git a/hw/ide.c b/hw/ide.c
index 33e8b39..0c9a8d2 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -3486,6 +3486,98 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
 }
 
 /***********************************************************/
+/* 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
diff --git a/hw/r2d.c b/hw/r2d.c
index 855aa41..c1fec44 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -148,6 +148,11 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
     /* Register peripherals */
     r2d_fpga_init(0x04000000);
     s = sh7750_init(env);
+
+    /* 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);
+
     /* Todo: register on board registers */
     {
       int kernel_size;
diff --git a/hw/sh.h b/hw/sh.h
index 50a1ae9..530d299 100644
--- a/hw/sh.h
+++ b/hw/sh.h
@@ -45,4 +45,8 @@ void sh_serial_init (target_phys_addr_t base, int feat,
 /* 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
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 2/3] take3 sh4: Add IRL(4bit encoded interrupt input) support.
  2008-10-26 16:09   ` Blue Swirl
@ 2008-10-28 20:58     ` takasi-y
  2008-10-29 18:09       ` [Qemu-devel] " Blue Swirl
  0 siblings, 1 reply; 22+ messages in thread
From: takasi-y @ 2008-10-28 20:58 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

> Isn't it possible to use existing qemu_irq for the signals instead? On
> Sparc32, I have used qemu_irq for interrupt lines, reset signals and a
> terminal count pulse, one version used it for DMA request.

I have re-written them using qemu_irq.
This use qemu_irq as multi-level signal. I mean LEVEL as in
 qemu_set_irq(irq, LEVEL) is {0...15} but {0,1}.

/yoshii
--

This patch adds IRL(4bit encoded 15 level interrupt input) support
  to SH using qemu_irq as a multi level (!=on/off) signal.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 hw/sh.h      |    3 +++
 hw/sh7750.c  |   40 +++++++++++++++++++++++++++++++++++++++-
 hw/sh_intc.c |   15 +++++++++++++++
 hw/sh_intc.h |    2 ++
 4 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/hw/sh.h b/hw/sh.h
index 530d299..9e864b0 100644
--- a/hw/sh.h
+++ b/hw/sh.h
@@ -42,6 +42,9 @@ void sh_serial_init (target_phys_addr_t base, int feat,
 		     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);
 
diff --git a/hw/sh7750.c b/hw/sh7750.c
index 62c226e..ace3b83 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -412,7 +412,9 @@ enum {
 	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 +430,8 @@ enum {
 
 	/* interrupt groups */
 	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+	/* irl bundle */
+	IRL,
 
 	NR_SOURCES,
 };
@@ -529,6 +533,29 @@ static struct intc_group groups_pci[] = {
 		   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 +744,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
 				 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];
+}
+
diff --git a/hw/sh_intc.c b/hw/sh_intc.c
index 8d1674a..63a781b 100644
--- a/hw/sh_intc.c
+++ b/hw/sh_intc.c
@@ -451,3 +451,18 @@ int sh_intc_init(struct intc_desc *desc,
 
     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);
+    }
+}
diff --git a/hw/sh_intc.h b/hw/sh_intc.h
index d22a4a2..b5fe398 100644
--- a/hw/sh_intc.h
+++ b/hw/sh_intc.h
@@ -72,4 +72,6 @@ int sh_intc_init(struct intc_desc *desc,
 		 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__ */
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 3/3] take3 sh4: Add r2d onboard FPGA IRQ controller.
  2008-10-26 15:17 ` [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller takasi-y
@ 2008-10-28 20:58   ` takasi-y
  0 siblings, 0 replies; 22+ messages in thread
From: takasi-y @ 2008-10-28 20:58 UTC (permalink / raw)
  To: qemu-devel

Re-written for qemu_irq based version of IRL.
/yoshii
--

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

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 hw/r2d.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/hw/r2d.c b/hw/r2d.c
index c1fec44..f818711 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,53 @@ typedef struct {
     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;
@@ -68,6 +116,8 @@ static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
     addr -= s->base;
 
     switch (addr) {
+    case PA_IRLMSK:
+        return s->irlmsk;
     case PA_OUTPORT:
 	return s->outport;
     case PA_POWOFF:
@@ -87,6 +137,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 +165,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, 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_init(ram_addr_t ram_size, int vga_ram_size,
@@ -133,6 +190,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
 {
     CPUState *env;
     struct SH7750State *s;
+    qemu_irq *irq;
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -146,12 +204,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, 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 */
     {
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-27 17:10       ` Blue Swirl
@ 2008-10-29 14:22         ` andrzej zaborowski
  2008-10-29 18:37           ` Blue Swirl
  0 siblings, 1 reply; 22+ messages in thread
From: andrzej zaborowski @ 2008-10-29 14:22 UTC (permalink / raw)
  To: qemu-devel

2008/10/27 Blue Swirl <blauwirbel@gmail.com>:
> On 10/27/08, andrzej zaborowski <balrogg@gmail.com> wrote:
>> 2008/10/26 Blue Swirl <blauwirbel@gmail.com>:
>>  > It would be better to make the init function take instead of mmio
>>  > pointer, two target_phys_addr_t parameters and do the physical memory
>>  > registration there.
>>
>>
>> Why would it be better?  This implementation seems more flexible.
>
> How is this more flexible? Now r2d.c has to know the number of
> registers in the IDE controller which should be internal to ide.c.

I think the size of the mapping is not related to the number of the
registers - it should be the same as the mapping on the real machine.
For example CF has 26 address pins so the mapping must be 2^26 bytes
for a CF card's io region, additionally the prcoessor may have
registers that let software remap or unmap those.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] take3 sh4: Add IRL(4bit encoded interrupt input) support.
  2008-10-28 20:58     ` [Qemu-devel] [PATCH 2/3] take3 " takasi-y
@ 2008-10-29 18:09       ` Blue Swirl
  2008-10-30 17:28         ` takasi-y
  0 siblings, 1 reply; 22+ messages in thread
From: Blue Swirl @ 2008-10-29 18:09 UTC (permalink / raw)
  To: takasi-y@ops.dti.ne.jp; +Cc: qemu-devel

On 10/28/08, takasi-y@ops.dti.ne.jp <takasi-y@ops.dti.ne.jp> wrote:
> > Isn't it possible to use existing qemu_irq for the signals instead? On
>  > Sparc32, I have used qemu_irq for interrupt lines, reset signals and a
>  > terminal count pulse, one version used it for DMA request.
>
>  I have re-written them using qemu_irq.
>  This use qemu_irq as multi-level signal. I mean LEVEL as in
>   qemu_set_irq(irq, LEVEL) is {0...15} but {0,1}.

If an irq is active at some level, and another irq at some other level
arrives, doesn't the first one get lost? Maybe SH has edge-triggered
irqs and this is OK, I don't know.

Sparc32 has similar 15 level interrupt system with priorities. I've
used a separate qemu_irq for each of these, but perhaps your way could
work if I used a bitmap.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board.
  2008-10-29 14:22         ` andrzej zaborowski
@ 2008-10-29 18:37           ` Blue Swirl
  0 siblings, 0 replies; 22+ messages in thread
From: Blue Swirl @ 2008-10-29 18:37 UTC (permalink / raw)
  To: qemu-devel

On 10/29/08, andrzej zaborowski <balrogg@gmail.com> wrote:
> 2008/10/27 Blue Swirl <blauwirbel@gmail.com>:
>
> > On 10/27/08, andrzej zaborowski <balrogg@gmail.com> wrote:
>  >> 2008/10/26 Blue Swirl <blauwirbel@gmail.com>:
>  >>  > It would be better to make the init function take instead of mmio
>  >>  > pointer, two target_phys_addr_t parameters and do the physical memory
>  >>  > registration there.
>  >>
>  >>
>  >> Why would it be better?  This implementation seems more flexible.
>  >
>  > How is this more flexible? Now r2d.c has to know the number of
>  > registers in the IDE controller which should be internal to ide.c.
>
>
> I think the size of the mapping is not related to the number of the
>  registers - it should be the same as the mapping on the real machine.

Yes¸ but I think more exotic setups should be done by some kind of
glue logic, that way the interface to the device stays simple.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 2/3] take3 sh4: Add IRL(4bit encoded interrupt input) support.
  2008-10-29 18:09       ` [Qemu-devel] " Blue Swirl
@ 2008-10-30 17:28         ` takasi-y
  0 siblings, 0 replies; 22+ messages in thread
From: takasi-y @ 2008-10-30 17:28 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

Hi,

> If an irq is active at some level, and another irq at some other level
> arrives, doesn't the first one get lost? Maybe SH has edge-triggered
> irqs and this is OK, I don't know.
It is level, and is OK, though it is not clear if it really will lost not.
I guess it will be, because HW manual doesn't show a register to hold
pending state, and says not to alter the signal until it is processed.
But anyway, It wont be a problem. 
Because, AFAIK, they always have external HW to resend the unhandled irq.
Actually, the implementation is simply a priority encoder. But with irq
source holding request until software clears it, it works as resend.

> Sparc32 has similar 15 level interrupt system with priorities. I've
> used a separate qemu_irq for each of these, but perhaps your way could
> work if I used a bitmap.
I have tried 16 signals version too, because I thought it would be simpler.
But I found it is not only just moving of priority encoder from FPGA to CPU,
but also I have to add state variable to hold pending state.
And, IMHO, interfaces should not be changed from real HW. Or we will be
in trouble when generate emulation code using hardware description.
# I can't do it now. But it is what I would like to do...
/yoshii

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2008-10-30 17:29 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-22 16:31 [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board yoshii.takashi
2008-09-22 19:00 ` takasi-y
2008-09-23  8:55 ` Paul Mundt
2008-10-08 15:20   ` pmac kernel & disk image wanted (was Re: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board.) Shin-ichiro KAWASAKI
2008-10-26 15:35     ` Andreas Färber
2008-10-26 15:17 ` [Qemu-devel] [PATCH 1/3] sh4: mmio based CF support on r2d board takasi-y
2008-10-26 15:54   ` Blue Swirl
2008-10-27  1:29     ` andrzej zaborowski
2008-10-27 17:10       ` Blue Swirl
2008-10-29 14:22         ` andrzej zaborowski
2008-10-29 18:37           ` Blue Swirl
2008-10-27 18:57     ` takasi-y
2008-10-27 19:12       ` Blue Swirl
2008-10-28 20:58         ` [Qemu-devel] [PATCH 1/3] take3 " takasi-y
2008-10-26 15:17 ` [Qemu-devel] [PATCH 0/3] take 2. " takasi-y
2008-10-26 15:17 ` [Qemu-devel] [PATCH 2/3] sh4: Add IRL(4bit encoded interrupt input) support takasi-y
2008-10-26 16:09   ` Blue Swirl
2008-10-28 20:58     ` [Qemu-devel] [PATCH 2/3] take3 " takasi-y
2008-10-29 18:09       ` [Qemu-devel] " Blue Swirl
2008-10-30 17:28         ` takasi-y
2008-10-26 15:17 ` [Qemu-devel] [PATCH 3/3] sh4: Add r2d onboard FPGA IRQ controller takasi-y
2008-10-28 20:58   ` [Qemu-devel] [PATCH 3/3] take3 " takasi-y

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).