From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KhqVk-0005CQ-E9 for qemu-devel@nongnu.org; Mon, 22 Sep 2008 14:51:52 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KhqVj-0005C3-Ll for qemu-devel@nongnu.org; Mon, 22 Sep 2008 14:51:51 -0400 Received: from [199.232.76.173] (port=58945 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KhqVj-0005C0-GQ for qemu-devel@nongnu.org; Mon, 22 Sep 2008 14:51:51 -0400 Received: from smtp12.dti.ne.jp ([202.216.231.187]:43169) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KhqVi-0006dp-IJ for qemu-devel@nongnu.org; Mon, 22 Sep 2008 14:51:51 -0400 Received: from ubuny (KHP059140016099.ppp-bb.dion.ne.jp [59.140.16.99]) by smtp12.dti.ne.jp (3.11s) with ESMTP AUTH id m8MIpkCN014230 for ; Tue, 23 Sep 2008 03:51:46 +0900 (JST) Resent-Message-Id: <200809221851.m8MIpkCN014230@smtp12.dti.ne.jp> Date: Tue, 23 Sep 2008 01:31:36 +0900 From: yoshii.takashi@gmail.com Message-Id: <20080923013136.490117fd.yoshii.takashi@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-To: qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH] sh4: mmio based CF support on r2d board. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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;