ahci-allwinner.c (4624B)
1/* 2 * QEMU Allwinner AHCI Emulation 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include "qemu/osdep.h" 19#include "qemu/error-report.h" 20#include "qemu/module.h" 21#include "sysemu/dma.h" 22#include "hw/ide/internal.h" 23#include "migration/vmstate.h" 24#include "ahci_internal.h" 25 26#include "trace.h" 27 28#define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4) 29#define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4) 30#define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4) 31#define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4) 32#define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4) 33#define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4) 34#define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4) 35#define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4) 36#define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4) 37#define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4) 38#define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4) 39#define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4) 40#define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4) 41#define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4) 42#define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4) 43#define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4) 44#define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4) 45#define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) 46#define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) 47 48static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr, 49 unsigned size) 50{ 51 AllwinnerAHCIState *a = opaque; 52 AHCIState *s = &(SYSBUS_AHCI(a)->ahci); 53 uint64_t val = a->regs[addr / 4]; 54 55 switch (addr / 4) { 56 case ALLWINNER_AHCI_PHYCS0R: 57 val |= 0x2 << 28; 58 break; 59 case ALLWINNER_AHCI_PHYCS2R: 60 val &= ~(0x1 << 24); 61 break; 62 } 63 trace_allwinner_ahci_mem_read(s, a, addr, val, size); 64 return val; 65} 66 67static void allwinner_ahci_mem_write(void *opaque, hwaddr addr, 68 uint64_t val, unsigned size) 69{ 70 AllwinnerAHCIState *a = opaque; 71 AHCIState *s = &(SYSBUS_AHCI(a)->ahci); 72 73 trace_allwinner_ahci_mem_write(s, a, addr, val, size); 74 a->regs[addr / 4] = val; 75} 76 77static const MemoryRegionOps allwinner_ahci_mem_ops = { 78 .read = allwinner_ahci_mem_read, 79 .write = allwinner_ahci_mem_write, 80 .valid.min_access_size = 4, 81 .valid.max_access_size = 4, 82 .endianness = DEVICE_LITTLE_ENDIAN, 83}; 84 85static void allwinner_ahci_init(Object *obj) 86{ 87 SysbusAHCIState *s = SYSBUS_AHCI(obj); 88 AllwinnerAHCIState *a = ALLWINNER_AHCI(obj); 89 90 memory_region_init_io(&a->mmio, obj, &allwinner_ahci_mem_ops, a, 91 "allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE); 92 memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF, 93 &a->mmio); 94} 95 96static const VMStateDescription vmstate_allwinner_ahci = { 97 .name = "allwinner-ahci", 98 .version_id = 1, 99 .minimum_version_id = 1, 100 .fields = (VMStateField[]) { 101 VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState, 102 ALLWINNER_AHCI_MMIO_SIZE / 4), 103 VMSTATE_END_OF_LIST() 104 } 105}; 106 107static void allwinner_ahci_class_init(ObjectClass *klass, void *data) 108{ 109 DeviceClass *dc = DEVICE_CLASS(klass); 110 111 dc->vmsd = &vmstate_allwinner_ahci; 112} 113 114static const TypeInfo allwinner_ahci_info = { 115 .name = TYPE_ALLWINNER_AHCI, 116 .parent = TYPE_SYSBUS_AHCI, 117 .instance_size = sizeof(AllwinnerAHCIState), 118 .instance_init = allwinner_ahci_init, 119 .class_init = allwinner_ahci_class_init, 120}; 121 122static void sysbus_ahci_register_types(void) 123{ 124 type_register_static(&allwinner_ahci_info); 125} 126 127type_init(sysbus_ahci_register_types)