|
|
1.1 ! root 1: /* ! 2: * QEMU IDE Emulation: PCI Bus support. ! 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 <hw/pc.h> ! 27: #include <hw/pci.h> ! 28: #include <hw/isa.h> ! 29: #include "block.h" ! 30: #include "block_int.h" ! 31: #include "sysemu.h" ! 32: #include "dma.h" ! 33: ! 34: #include <hw/ide/pci.h> ! 35: ! 36: void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) ! 37: { ! 38: BMDMAState *bm = opaque; ! 39: #ifdef DEBUG_IDE ! 40: printf("%s: 0x%08x\n", __func__, val); ! 41: #endif ! 42: if (!(val & BM_CMD_START)) { ! 43: /* XXX: do it better */ ! 44: ide_dma_cancel(bm); ! 45: bm->cmd = val & 0x09; ! 46: } else { ! 47: if (!(bm->status & BM_STATUS_DMAING)) { ! 48: bm->status |= BM_STATUS_DMAING; ! 49: /* start dma transfer if possible */ ! 50: if (bm->dma_cb) ! 51: bm->dma_cb(bm, 0); ! 52: } ! 53: bm->cmd = val & 0x09; ! 54: } ! 55: } ! 56: ! 57: uint32_t bmdma_addr_readb(void *opaque, uint32_t addr) ! 58: { ! 59: BMDMAState *bm = opaque; ! 60: uint32_t val; ! 61: val = (bm->addr >> ((addr & 3) * 8)) & 0xff; ! 62: #ifdef DEBUG_IDE ! 63: printf("%s: 0x%08x\n", __func__, val); ! 64: #endif ! 65: return val; ! 66: } ! 67: ! 68: void bmdma_addr_writeb(void *opaque, uint32_t addr, uint32_t val) ! 69: { ! 70: BMDMAState *bm = opaque; ! 71: int shift = (addr & 3) * 8; ! 72: #ifdef DEBUG_IDE ! 73: printf("%s: 0x%08x\n", __func__, val); ! 74: #endif ! 75: bm->addr &= ~(0xFF << shift); ! 76: bm->addr |= ((val & 0xFF) << shift) & ~3; ! 77: bm->cur_addr = bm->addr; ! 78: } ! 79: ! 80: uint32_t bmdma_addr_readw(void *opaque, uint32_t addr) ! 81: { ! 82: BMDMAState *bm = opaque; ! 83: uint32_t val; ! 84: val = (bm->addr >> ((addr & 3) * 8)) & 0xffff; ! 85: #ifdef DEBUG_IDE ! 86: printf("%s: 0x%08x\n", __func__, val); ! 87: #endif ! 88: return val; ! 89: } ! 90: ! 91: void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val) ! 92: { ! 93: BMDMAState *bm = opaque; ! 94: int shift = (addr & 3) * 8; ! 95: #ifdef DEBUG_IDE ! 96: printf("%s: 0x%08x\n", __func__, val); ! 97: #endif ! 98: bm->addr &= ~(0xFFFF << shift); ! 99: bm->addr |= ((val & 0xFFFF) << shift) & ~3; ! 100: bm->cur_addr = bm->addr; ! 101: } ! 102: ! 103: uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) ! 104: { ! 105: BMDMAState *bm = opaque; ! 106: uint32_t val; ! 107: val = bm->addr; ! 108: #ifdef DEBUG_IDE ! 109: printf("%s: 0x%08x\n", __func__, val); ! 110: #endif ! 111: return val; ! 112: } ! 113: ! 114: void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val) ! 115: { ! 116: BMDMAState *bm = opaque; ! 117: #ifdef DEBUG_IDE ! 118: printf("%s: 0x%08x\n", __func__, val); ! 119: #endif ! 120: bm->addr = val & ~3; ! 121: bm->cur_addr = bm->addr; ! 122: } ! 123: ! 124: static const VMStateDescription vmstate_bmdma = { ! 125: .name = "ide bmdma", ! 126: .version_id = 3, ! 127: .minimum_version_id = 0, ! 128: .minimum_version_id_old = 0, ! 129: .fields = (VMStateField []) { ! 130: VMSTATE_UINT8(cmd, BMDMAState), ! 131: VMSTATE_UINT8(status, BMDMAState), ! 132: VMSTATE_UINT32(addr, BMDMAState), ! 133: VMSTATE_INT64(sector_num, BMDMAState), ! 134: VMSTATE_UINT32(nsector, BMDMAState), ! 135: VMSTATE_UINT8(unit, BMDMAState), ! 136: VMSTATE_END_OF_LIST() ! 137: } ! 138: }; ! 139: ! 140: static int ide_pci_post_load(void *opaque, int version_id) ! 141: { ! 142: PCIIDEState *d = opaque; ! 143: int i; ! 144: ! 145: for(i = 0; i < 2; i++) { ! 146: /* current versions always store 0/1, but older version ! 147: stored bigger values. We only need last bit */ ! 148: d->bmdma[i].unit &= 1; ! 149: } ! 150: return 0; ! 151: } ! 152: ! 153: const VMStateDescription vmstate_ide_pci = { ! 154: .name = "ide", ! 155: .version_id = 3, ! 156: .minimum_version_id = 0, ! 157: .minimum_version_id_old = 0, ! 158: .post_load = ide_pci_post_load, ! 159: .fields = (VMStateField []) { ! 160: VMSTATE_PCI_DEVICE(dev, PCIIDEState), ! 161: VMSTATE_STRUCT_ARRAY(bmdma, PCIIDEState, 2, 0, ! 162: vmstate_bmdma, BMDMAState), ! 163: VMSTATE_IDE_BUS_ARRAY(bus, PCIIDEState, 2), ! 164: VMSTATE_IDE_DRIVES(bus[0].ifs, PCIIDEState), ! 165: VMSTATE_IDE_DRIVES(bus[1].ifs, PCIIDEState), ! 166: VMSTATE_END_OF_LIST() ! 167: } ! 168: }; ! 169: ! 170: void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table) ! 171: { ! 172: PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); ! 173: static const int bus[4] = { 0, 0, 1, 1 }; ! 174: static const int unit[4] = { 0, 1, 0, 1 }; ! 175: int i; ! 176: ! 177: for (i = 0; i < 4; i++) { ! 178: if (hd_table[i] == NULL) ! 179: continue; ! 180: ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]); ! 181: } ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.