1 /* 2 * QEMU IDE Emulation: mmio support (for embedded). 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * Copyright (c) 2006 Openedhand Ltd. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 #include <hw/hw.h> 26 #include "block.h" 27 #include "block_int.h" 28 #include "sysemu.h" 29 #include "dma.h" 30 31 #include <hw/ide/internal.h> 32 33 /***********************************************************/ 34 /* MMIO based ide port 35 * This emulates IDE device connected directly to the CPU bus without 36 * dedicated ide controller, which is often seen on embedded boards. 37 */ 38 39 typedef struct { 40 IDEBus *bus; 41 int shift; 42 } MMIOState; 43 44 static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr) 45 { 46 MMIOState *s = (MMIOState*)opaque; 47 IDEBus *bus = s->bus; 48 addr >>= s->shift; 49 if (addr & 7) 50 return ide_ioport_read(bus, addr); 51 else 52 return ide_data_readw(bus, 0); 53 } 54 55 static void mmio_ide_write (void *opaque, target_phys_addr_t addr, 56 uint32_t val) 57 { 58 MMIOState *s = (MMIOState*)opaque; 59 IDEBus *bus = s->bus; 60 addr >>= s->shift; 61 if (addr & 7) 62 ide_ioport_write(bus, addr, val); 63 else 64 ide_data_writew(bus, 0, val); 65 } 66 67 static CPUReadMemoryFunc * const mmio_ide_reads[] = { 68 mmio_ide_read, 69 mmio_ide_read, 70 mmio_ide_read, 71 }; 72 73 static CPUWriteMemoryFunc * const mmio_ide_writes[] = { 74 mmio_ide_write, 75 mmio_ide_write, 76 mmio_ide_write, 77 }; 78 79 static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr) 80 { 81 MMIOState *s= (MMIOState*)opaque; 82 IDEBus *bus = s->bus; 83 return ide_status_read(bus, 0); 84 } 85 86 static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr, 87 uint32_t val) 88 { 89 MMIOState *s = (MMIOState*)opaque; 90 IDEBus *bus = s->bus; 91 ide_cmd_write(bus, 0, val); 92 } 93 94 static CPUReadMemoryFunc * const mmio_ide_status[] = { 95 mmio_ide_status_read, 96 mmio_ide_status_read, 97 mmio_ide_status_read, 98 }; 99 100 static CPUWriteMemoryFunc * const mmio_ide_cmd[] = { 101 mmio_ide_cmd_write, 102 mmio_ide_cmd_write, 103 mmio_ide_cmd_write, 104 }; 105 106 static void mmio_ide_save(QEMUFile* f, void *opaque) 107 { 108 MMIOState *s = opaque; 109 110 idebus_save(f, s->bus); 111 ide_save(f, &s->bus->ifs[0]); 112 ide_save(f, &s->bus->ifs[1]); 113 } 114 115 static int mmio_ide_load(QEMUFile* f, void *opaque, int version_id) 116 { 117 MMIOState *s = opaque; 118 119 idebus_load(f, s->bus, version_id); 120 ide_load(f, &s->bus->ifs[0], version_id); 121 ide_load(f, &s->bus->ifs[1], version_id); 122 return 0; 123 } 124 125 void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, 126 qemu_irq irq, int shift, 127 DriveInfo *hd0, DriveInfo *hd1) 128 { 129 MMIOState *s = qemu_mallocz(sizeof(MMIOState)); 130 IDEBus *bus = qemu_mallocz(sizeof(*bus)); 131 int mem1, mem2; 132 133 ide_init2(bus, hd0, hd1, irq); 134 135 s->bus = bus; 136 s->shift = shift; 137 138 mem1 = cpu_register_io_memory(mmio_ide_reads, mmio_ide_writes, s); 139 mem2 = cpu_register_io_memory(mmio_ide_status, mmio_ide_cmd, s); 140 cpu_register_physical_memory(membase, 16 << shift, mem1); 141 cpu_register_physical_memory(membase2, 2 << shift, mem2); 142 register_savevm("mmio-ide", 0, 3, mmio_ide_save, mmio_ide_load, s); 143 } 144 145