1*db3e6379SDeniz Eren /* 2*db3e6379SDeniz Eren * MIOe-3680 PCI CAN device (SJA1000 based) emulation 3*db3e6379SDeniz Eren * 4*db3e6379SDeniz Eren * Copyright (c) 2016 Deniz Eren (deniz.eren@icloud.com) 5*db3e6379SDeniz Eren * 6*db3e6379SDeniz Eren * Based on Kvaser PCI CAN device (SJA1000 based) emulation implemented by 7*db3e6379SDeniz Eren * Jin Yang and Pavel Pisa 8*db3e6379SDeniz Eren * 9*db3e6379SDeniz Eren * Permission is hereby granted, free of charge, to any person obtaining a copy 10*db3e6379SDeniz Eren * of this software and associated documentation files (the "Software"), to deal 11*db3e6379SDeniz Eren * in the Software without restriction, including without limitation the rights 12*db3e6379SDeniz Eren * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13*db3e6379SDeniz Eren * copies of the Software, and to permit persons to whom the Software is 14*db3e6379SDeniz Eren * furnished to do so, subject to the following conditions: 15*db3e6379SDeniz Eren * 16*db3e6379SDeniz Eren * The above copyright notice and this permission notice shall be included in 17*db3e6379SDeniz Eren * all copies or substantial portions of the Software. 18*db3e6379SDeniz Eren * 19*db3e6379SDeniz Eren * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20*db3e6379SDeniz Eren * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21*db3e6379SDeniz Eren * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22*db3e6379SDeniz Eren * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23*db3e6379SDeniz Eren * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24*db3e6379SDeniz Eren * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25*db3e6379SDeniz Eren * THE SOFTWARE. 26*db3e6379SDeniz Eren */ 27*db3e6379SDeniz Eren 28*db3e6379SDeniz Eren #include "qemu/osdep.h" 29*db3e6379SDeniz Eren #include "qemu/event_notifier.h" 30*db3e6379SDeniz Eren #include "qemu/thread.h" 31*db3e6379SDeniz Eren #include "qemu/sockets.h" 32*db3e6379SDeniz Eren #include "qapi/error.h" 33*db3e6379SDeniz Eren #include "chardev/char.h" 34*db3e6379SDeniz Eren #include "hw/hw.h" 35*db3e6379SDeniz Eren #include "hw/pci/pci.h" 36*db3e6379SDeniz Eren #include "net/can_emu.h" 37*db3e6379SDeniz Eren 38*db3e6379SDeniz Eren #include "can_sja1000.h" 39*db3e6379SDeniz Eren 40*db3e6379SDeniz Eren #define TYPE_CAN_PCI_DEV "mioe3680_pci" 41*db3e6379SDeniz Eren 42*db3e6379SDeniz Eren #define MIOe3680_PCI_DEV(obj) \ 43*db3e6379SDeniz Eren OBJECT_CHECK(Mioe3680PCIState, (obj), TYPE_CAN_PCI_DEV) 44*db3e6379SDeniz Eren 45*db3e6379SDeniz Eren /* the PCI device and vendor IDs */ 46*db3e6379SDeniz Eren #ifndef MIOe3680_PCI_VENDOR_ID1 47*db3e6379SDeniz Eren #define MIOe3680_PCI_VENDOR_ID1 0x13fe 48*db3e6379SDeniz Eren #endif 49*db3e6379SDeniz Eren 50*db3e6379SDeniz Eren #ifndef MIOe3680_PCI_DEVICE_ID1 51*db3e6379SDeniz Eren #define MIOe3680_PCI_DEVICE_ID1 0xc302 52*db3e6379SDeniz Eren #endif 53*db3e6379SDeniz Eren 54*db3e6379SDeniz Eren #define MIOe3680_PCI_SJA_COUNT 2 55*db3e6379SDeniz Eren #define MIOe3680_PCI_SJA_RANGE 0x400 56*db3e6379SDeniz Eren 57*db3e6379SDeniz Eren #define MIOe3680_PCI_BYTES_PER_SJA 0x80 58*db3e6379SDeniz Eren 59*db3e6379SDeniz Eren typedef struct Mioe3680PCIState { 60*db3e6379SDeniz Eren /*< private >*/ 61*db3e6379SDeniz Eren PCIDevice dev; 62*db3e6379SDeniz Eren /*< public >*/ 63*db3e6379SDeniz Eren MemoryRegion sja_io[MIOe3680_PCI_SJA_COUNT]; 64*db3e6379SDeniz Eren 65*db3e6379SDeniz Eren CanSJA1000State sja_state[MIOe3680_PCI_SJA_COUNT]; 66*db3e6379SDeniz Eren qemu_irq irq; 67*db3e6379SDeniz Eren 68*db3e6379SDeniz Eren char *model; /* The model that support, only SJA1000 now. */ 69*db3e6379SDeniz Eren CanBusState *canbus[MIOe3680_PCI_SJA_COUNT]; 70*db3e6379SDeniz Eren } Mioe3680PCIState; 71*db3e6379SDeniz Eren 72*db3e6379SDeniz Eren static void mioe3680_pci_reset(DeviceState *dev) 73*db3e6379SDeniz Eren { 74*db3e6379SDeniz Eren Mioe3680PCIState *d = MIOe3680_PCI_DEV(dev); 75*db3e6379SDeniz Eren int i; 76*db3e6379SDeniz Eren 77*db3e6379SDeniz Eren for (i = 0 ; i < MIOe3680_PCI_SJA_COUNT; i++) { 78*db3e6379SDeniz Eren can_sja_hardware_reset(&d->sja_state[i]); 79*db3e6379SDeniz Eren } 80*db3e6379SDeniz Eren } 81*db3e6379SDeniz Eren 82*db3e6379SDeniz Eren static uint64_t mioe3680_pci_sja1_io_read(void *opaque, hwaddr addr, 83*db3e6379SDeniz Eren unsigned size) 84*db3e6379SDeniz Eren { 85*db3e6379SDeniz Eren Mioe3680PCIState *d = opaque; 86*db3e6379SDeniz Eren CanSJA1000State *s = &d->sja_state[0]; 87*db3e6379SDeniz Eren 88*db3e6379SDeniz Eren if (addr >= MIOe3680_PCI_BYTES_PER_SJA) { 89*db3e6379SDeniz Eren return 0; 90*db3e6379SDeniz Eren } 91*db3e6379SDeniz Eren 92*db3e6379SDeniz Eren return can_sja_mem_read(s, addr >> 2, size); 93*db3e6379SDeniz Eren } 94*db3e6379SDeniz Eren 95*db3e6379SDeniz Eren static void mioe3680_pci_sja1_io_write(void *opaque, hwaddr addr, uint64_t data, 96*db3e6379SDeniz Eren unsigned size) 97*db3e6379SDeniz Eren { 98*db3e6379SDeniz Eren Mioe3680PCIState *d = opaque; 99*db3e6379SDeniz Eren CanSJA1000State *s = &d->sja_state[0]; 100*db3e6379SDeniz Eren 101*db3e6379SDeniz Eren if (addr >= MIOe3680_PCI_BYTES_PER_SJA) { 102*db3e6379SDeniz Eren return; 103*db3e6379SDeniz Eren } 104*db3e6379SDeniz Eren 105*db3e6379SDeniz Eren can_sja_mem_write(s, addr >> 2, data, size); 106*db3e6379SDeniz Eren } 107*db3e6379SDeniz Eren 108*db3e6379SDeniz Eren static uint64_t mioe3680_pci_sja2_io_read(void *opaque, hwaddr addr, 109*db3e6379SDeniz Eren unsigned size) 110*db3e6379SDeniz Eren { 111*db3e6379SDeniz Eren Mioe3680PCIState *d = opaque; 112*db3e6379SDeniz Eren CanSJA1000State *s = &d->sja_state[1]; 113*db3e6379SDeniz Eren 114*db3e6379SDeniz Eren if (addr >= MIOe3680_PCI_BYTES_PER_SJA) { 115*db3e6379SDeniz Eren return 0; 116*db3e6379SDeniz Eren } 117*db3e6379SDeniz Eren 118*db3e6379SDeniz Eren return can_sja_mem_read(s, addr >> 2, size); 119*db3e6379SDeniz Eren } 120*db3e6379SDeniz Eren 121*db3e6379SDeniz Eren static void mioe3680_pci_sja2_io_write(void *opaque, hwaddr addr, uint64_t data, 122*db3e6379SDeniz Eren unsigned size) 123*db3e6379SDeniz Eren { 124*db3e6379SDeniz Eren Mioe3680PCIState *d = opaque; 125*db3e6379SDeniz Eren CanSJA1000State *s = &d->sja_state[1]; 126*db3e6379SDeniz Eren 127*db3e6379SDeniz Eren if (addr >= MIOe3680_PCI_BYTES_PER_SJA) { 128*db3e6379SDeniz Eren return; 129*db3e6379SDeniz Eren } 130*db3e6379SDeniz Eren 131*db3e6379SDeniz Eren can_sja_mem_write(s, addr >> 2, data, size); 132*db3e6379SDeniz Eren } 133*db3e6379SDeniz Eren 134*db3e6379SDeniz Eren static const MemoryRegionOps mioe3680_pci_sja1_io_ops = { 135*db3e6379SDeniz Eren .read = mioe3680_pci_sja1_io_read, 136*db3e6379SDeniz Eren .write = mioe3680_pci_sja1_io_write, 137*db3e6379SDeniz Eren .endianness = DEVICE_LITTLE_ENDIAN, 138*db3e6379SDeniz Eren .impl = { 139*db3e6379SDeniz Eren .max_access_size = 1, 140*db3e6379SDeniz Eren }, 141*db3e6379SDeniz Eren }; 142*db3e6379SDeniz Eren 143*db3e6379SDeniz Eren static const MemoryRegionOps mioe3680_pci_sja2_io_ops = { 144*db3e6379SDeniz Eren .read = mioe3680_pci_sja2_io_read, 145*db3e6379SDeniz Eren .write = mioe3680_pci_sja2_io_write, 146*db3e6379SDeniz Eren .endianness = DEVICE_LITTLE_ENDIAN, 147*db3e6379SDeniz Eren .impl = { 148*db3e6379SDeniz Eren .max_access_size = 1, 149*db3e6379SDeniz Eren }, 150*db3e6379SDeniz Eren }; 151*db3e6379SDeniz Eren 152*db3e6379SDeniz Eren static void mioe3680_pci_realize(PCIDevice *pci_dev, Error **errp) 153*db3e6379SDeniz Eren { 154*db3e6379SDeniz Eren Mioe3680PCIState *d = MIOe3680_PCI_DEV(pci_dev); 155*db3e6379SDeniz Eren uint8_t *pci_conf; 156*db3e6379SDeniz Eren int i; 157*db3e6379SDeniz Eren 158*db3e6379SDeniz Eren pci_conf = pci_dev->config; 159*db3e6379SDeniz Eren pci_conf[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ 160*db3e6379SDeniz Eren 161*db3e6379SDeniz Eren d->irq = pci_allocate_irq(&d->dev); 162*db3e6379SDeniz Eren 163*db3e6379SDeniz Eren for (i = 0 ; i < MIOe3680_PCI_SJA_COUNT; i++) { 164*db3e6379SDeniz Eren can_sja_init(&d->sja_state[i], d->irq); 165*db3e6379SDeniz Eren } 166*db3e6379SDeniz Eren 167*db3e6379SDeniz Eren for (i = 0 ; i < MIOe3680_PCI_SJA_COUNT; i++) { 168*db3e6379SDeniz Eren if (can_sja_connect_to_bus(&d->sja_state[i], d->canbus[i]) < 0) { 169*db3e6379SDeniz Eren error_setg(errp, "can_sja_connect_to_bus failed"); 170*db3e6379SDeniz Eren return; 171*db3e6379SDeniz Eren } 172*db3e6379SDeniz Eren } 173*db3e6379SDeniz Eren 174*db3e6379SDeniz Eren memory_region_init_io(&d->sja_io[0], OBJECT(d), &mioe3680_pci_sja1_io_ops, 175*db3e6379SDeniz Eren d, "mioe3680_pci-sja1", MIOe3680_PCI_SJA_RANGE); 176*db3e6379SDeniz Eren memory_region_init_io(&d->sja_io[1], OBJECT(d), &mioe3680_pci_sja2_io_ops, 177*db3e6379SDeniz Eren d, "mioe3680_pci-sja2", MIOe3680_PCI_SJA_RANGE); 178*db3e6379SDeniz Eren 179*db3e6379SDeniz Eren for (i = 0 ; i < MIOe3680_PCI_SJA_COUNT; i++) { 180*db3e6379SDeniz Eren pci_register_bar(&d->dev, /*BAR*/ i, PCI_BASE_ADDRESS_SPACE_IO, 181*db3e6379SDeniz Eren &d->sja_io[i]); 182*db3e6379SDeniz Eren } 183*db3e6379SDeniz Eren } 184*db3e6379SDeniz Eren 185*db3e6379SDeniz Eren static void mioe3680_pci_exit(PCIDevice *pci_dev) 186*db3e6379SDeniz Eren { 187*db3e6379SDeniz Eren Mioe3680PCIState *d = MIOe3680_PCI_DEV(pci_dev); 188*db3e6379SDeniz Eren int i; 189*db3e6379SDeniz Eren 190*db3e6379SDeniz Eren for (i = 0 ; i < MIOe3680_PCI_SJA_COUNT; i++) { 191*db3e6379SDeniz Eren can_sja_disconnect(&d->sja_state[i]); 192*db3e6379SDeniz Eren } 193*db3e6379SDeniz Eren 194*db3e6379SDeniz Eren qemu_free_irq(d->irq); 195*db3e6379SDeniz Eren } 196*db3e6379SDeniz Eren 197*db3e6379SDeniz Eren static const VMStateDescription vmstate_mioe3680_pci = { 198*db3e6379SDeniz Eren .name = "mioe3680_pci", 199*db3e6379SDeniz Eren .version_id = 1, 200*db3e6379SDeniz Eren .minimum_version_id = 1, 201*db3e6379SDeniz Eren .minimum_version_id_old = 1, 202*db3e6379SDeniz Eren .fields = (VMStateField[]) { 203*db3e6379SDeniz Eren VMSTATE_PCI_DEVICE(dev, Mioe3680PCIState), 204*db3e6379SDeniz Eren VMSTATE_STRUCT(sja_state[0], Mioe3680PCIState, 0, vmstate_can_sja, 205*db3e6379SDeniz Eren CanSJA1000State), 206*db3e6379SDeniz Eren VMSTATE_STRUCT(sja_state[1], Mioe3680PCIState, 0, vmstate_can_sja, 207*db3e6379SDeniz Eren CanSJA1000State), 208*db3e6379SDeniz Eren VMSTATE_END_OF_LIST() 209*db3e6379SDeniz Eren } 210*db3e6379SDeniz Eren }; 211*db3e6379SDeniz Eren 212*db3e6379SDeniz Eren static void mioe3680_pci_instance_init(Object *obj) 213*db3e6379SDeniz Eren { 214*db3e6379SDeniz Eren Mioe3680PCIState *d = MIOe3680_PCI_DEV(obj); 215*db3e6379SDeniz Eren 216*db3e6379SDeniz Eren object_property_add_link(obj, "canbus0", TYPE_CAN_BUS, 217*db3e6379SDeniz Eren (Object **)&d->canbus[0], 218*db3e6379SDeniz Eren qdev_prop_allow_set_link_before_realize, 219*db3e6379SDeniz Eren 0, &error_abort); 220*db3e6379SDeniz Eren object_property_add_link(obj, "canbus1", TYPE_CAN_BUS, 221*db3e6379SDeniz Eren (Object **)&d->canbus[1], 222*db3e6379SDeniz Eren qdev_prop_allow_set_link_before_realize, 223*db3e6379SDeniz Eren 0, &error_abort); 224*db3e6379SDeniz Eren } 225*db3e6379SDeniz Eren 226*db3e6379SDeniz Eren static void mioe3680_pci_class_init(ObjectClass *klass, void *data) 227*db3e6379SDeniz Eren { 228*db3e6379SDeniz Eren DeviceClass *dc = DEVICE_CLASS(klass); 229*db3e6379SDeniz Eren PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 230*db3e6379SDeniz Eren 231*db3e6379SDeniz Eren k->realize = mioe3680_pci_realize; 232*db3e6379SDeniz Eren k->exit = mioe3680_pci_exit; 233*db3e6379SDeniz Eren k->vendor_id = MIOe3680_PCI_VENDOR_ID1; 234*db3e6379SDeniz Eren k->device_id = MIOe3680_PCI_DEVICE_ID1; 235*db3e6379SDeniz Eren k->revision = 0x00; 236*db3e6379SDeniz Eren k->class_id = 0x000c09; 237*db3e6379SDeniz Eren k->subsystem_vendor_id = MIOe3680_PCI_VENDOR_ID1; 238*db3e6379SDeniz Eren k->subsystem_id = MIOe3680_PCI_DEVICE_ID1; 239*db3e6379SDeniz Eren dc->desc = "Mioe3680 PCICANx"; 240*db3e6379SDeniz Eren dc->vmsd = &vmstate_mioe3680_pci; 241*db3e6379SDeniz Eren set_bit(DEVICE_CATEGORY_MISC, dc->categories); 242*db3e6379SDeniz Eren dc->reset = mioe3680_pci_reset; 243*db3e6379SDeniz Eren } 244*db3e6379SDeniz Eren 245*db3e6379SDeniz Eren static const TypeInfo mioe3680_pci_info = { 246*db3e6379SDeniz Eren .name = TYPE_CAN_PCI_DEV, 247*db3e6379SDeniz Eren .parent = TYPE_PCI_DEVICE, 248*db3e6379SDeniz Eren .instance_size = sizeof(Mioe3680PCIState), 249*db3e6379SDeniz Eren .class_init = mioe3680_pci_class_init, 250*db3e6379SDeniz Eren .instance_init = mioe3680_pci_instance_init, 251*db3e6379SDeniz Eren .interfaces = (InterfaceInfo[]) { 252*db3e6379SDeniz Eren { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 253*db3e6379SDeniz Eren { }, 254*db3e6379SDeniz Eren }, 255*db3e6379SDeniz Eren }; 256*db3e6379SDeniz Eren 257*db3e6379SDeniz Eren static void mioe3680_pci_register_types(void) 258*db3e6379SDeniz Eren { 259*db3e6379SDeniz Eren type_register_static(&mioe3680_pci_info); 260*db3e6379SDeniz Eren } 261*db3e6379SDeniz Eren 262*db3e6379SDeniz Eren type_init(mioe3680_pci_register_types) 263