xref: /openbmc/qemu/hw/net/can/can_kvaser_pci.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
1321af2f5SPavel Pisa /*
2321af2f5SPavel Pisa  * Kvaser PCI CAN device (SJA1000 based) emulation
3321af2f5SPavel Pisa  *
4321af2f5SPavel Pisa  * Copyright (c) 2013-2014 Jin Yang
5321af2f5SPavel Pisa  * Copyright (c) 2014-2018 Pavel Pisa
6321af2f5SPavel Pisa  *
7321af2f5SPavel Pisa  * Partially based on educational PCIexpress APOHW hardware
8321af2f5SPavel Pisa  * emulator used fro class A0B36APO at CTU FEE course by
9321af2f5SPavel Pisa  *    Rostislav Lisovy and Pavel Pisa
10321af2f5SPavel Pisa  *
11321af2f5SPavel Pisa  * Initial development supported by Google GSoC 2013 from RTEMS project slot
12321af2f5SPavel Pisa  *
13321af2f5SPavel Pisa  * Permission is hereby granted, free of charge, to any person obtaining a copy
14321af2f5SPavel Pisa  * of this software and associated documentation files (the "Software"), to deal
15321af2f5SPavel Pisa  * in the Software without restriction, including without limitation the rights
16321af2f5SPavel Pisa  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17321af2f5SPavel Pisa  * copies of the Software, and to permit persons to whom the Software is
18321af2f5SPavel Pisa  * furnished to do so, subject to the following conditions:
19321af2f5SPavel Pisa  *
20321af2f5SPavel Pisa  * The above copyright notice and this permission notice shall be included in
21321af2f5SPavel Pisa  * all copies or substantial portions of the Software.
22321af2f5SPavel Pisa  *
23321af2f5SPavel Pisa  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24321af2f5SPavel Pisa  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25321af2f5SPavel Pisa  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26321af2f5SPavel Pisa  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27321af2f5SPavel Pisa  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28321af2f5SPavel Pisa  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29321af2f5SPavel Pisa  * THE SOFTWARE.
30321af2f5SPavel Pisa  */
31321af2f5SPavel Pisa 
32321af2f5SPavel Pisa #include "qemu/osdep.h"
33321af2f5SPavel Pisa #include "qemu/event_notifier.h"
340b8fa32fSMarkus Armbruster #include "qemu/module.h"
35321af2f5SPavel Pisa #include "qemu/thread.h"
36321af2f5SPavel Pisa #include "qemu/sockets.h"
37321af2f5SPavel Pisa #include "qapi/error.h"
38321af2f5SPavel Pisa #include "chardev/char.h"
3964552b6bSMarkus Armbruster #include "hw/irq.h"
40edf5ca5dSMarkus Armbruster #include "hw/pci/pci_device.h"
41a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
42d6454270SMarkus Armbruster #include "migration/vmstate.h"
43321af2f5SPavel Pisa #include "net/can_emu.h"
44321af2f5SPavel Pisa 
45321af2f5SPavel Pisa #include "can_sja1000.h"
46db1015e9SEduardo Habkost #include "qom/object.h"
47321af2f5SPavel Pisa 
48321af2f5SPavel Pisa #define TYPE_CAN_PCI_DEV "kvaser_pci"
49321af2f5SPavel Pisa 
50db1015e9SEduardo Habkost typedef struct KvaserPCIState KvaserPCIState;
518110fa1dSEduardo Habkost DECLARE_INSTANCE_CHECKER(KvaserPCIState, KVASER_PCI_DEV,
528110fa1dSEduardo Habkost                          TYPE_CAN_PCI_DEV)
53321af2f5SPavel Pisa 
54321af2f5SPavel Pisa #ifndef KVASER_PCI_VENDOR_ID1
55321af2f5SPavel Pisa #define KVASER_PCI_VENDOR_ID1     0x10e8    /* the PCI device and vendor IDs */
56321af2f5SPavel Pisa #endif
57321af2f5SPavel Pisa 
58321af2f5SPavel Pisa #ifndef KVASER_PCI_DEVICE_ID1
59321af2f5SPavel Pisa #define KVASER_PCI_DEVICE_ID1     0x8406
60321af2f5SPavel Pisa #endif
61321af2f5SPavel Pisa 
62321af2f5SPavel Pisa #define KVASER_PCI_S5920_RANGE    0x80
63321af2f5SPavel Pisa #define KVASER_PCI_SJA_RANGE      0x80
64321af2f5SPavel Pisa #define KVASER_PCI_XILINX_RANGE   0x8
65321af2f5SPavel Pisa 
66321af2f5SPavel Pisa #define KVASER_PCI_BYTES_PER_SJA  0x20
67321af2f5SPavel Pisa 
68321af2f5SPavel Pisa #define S5920_OMB                 0x0C
69321af2f5SPavel Pisa #define S5920_IMB                 0x1C
70321af2f5SPavel Pisa #define S5920_MBEF                0x34
71321af2f5SPavel Pisa #define S5920_INTCSR              0x38
72321af2f5SPavel Pisa #define S5920_RCR                 0x3C
73321af2f5SPavel Pisa #define S5920_PTCR                0x60
74321af2f5SPavel Pisa 
75321af2f5SPavel Pisa #define S5920_INTCSR_ADDON_INTENABLE_M        0x2000
76321af2f5SPavel Pisa #define S5920_INTCSR_INTERRUPT_ASSERTED_M     0x800000
77321af2f5SPavel Pisa 
78321af2f5SPavel Pisa #define KVASER_PCI_XILINX_VERINT  7   /* Lower nibble simulate interrupts,
79321af2f5SPavel Pisa                                          high nibble version number. */
80321af2f5SPavel Pisa 
81321af2f5SPavel Pisa #define KVASER_PCI_XILINX_VERSION_NUMBER 13
82321af2f5SPavel Pisa 
83db1015e9SEduardo Habkost struct KvaserPCIState {
84321af2f5SPavel Pisa     /*< private >*/
85321af2f5SPavel Pisa     PCIDevice       dev;
86321af2f5SPavel Pisa     /*< public >*/
87321af2f5SPavel Pisa     MemoryRegion    s5920_io;
88321af2f5SPavel Pisa     MemoryRegion    sja_io;
89321af2f5SPavel Pisa     MemoryRegion    xilinx_io;
90321af2f5SPavel Pisa 
91321af2f5SPavel Pisa     CanSJA1000State sja_state;
92321af2f5SPavel Pisa     qemu_irq        irq;
93321af2f5SPavel Pisa 
94321af2f5SPavel Pisa     uint32_t        s5920_intcsr;
95321af2f5SPavel Pisa     uint32_t        s5920_irqstate;
96321af2f5SPavel Pisa 
97321af2f5SPavel Pisa     CanBusState     *canbus;
98db1015e9SEduardo Habkost };
99321af2f5SPavel Pisa 
kvaser_pci_irq_handler(void * opaque,int irq_num,int level)100321af2f5SPavel Pisa static void kvaser_pci_irq_handler(void *opaque, int irq_num, int level)
101321af2f5SPavel Pisa {
102321af2f5SPavel Pisa     KvaserPCIState *d = (KvaserPCIState *)opaque;
103321af2f5SPavel Pisa 
104321af2f5SPavel Pisa     d->s5920_irqstate = level;
105321af2f5SPavel Pisa     if (d->s5920_intcsr & S5920_INTCSR_ADDON_INTENABLE_M) {
106321af2f5SPavel Pisa         pci_set_irq(&d->dev, level);
107321af2f5SPavel Pisa     }
108321af2f5SPavel Pisa }
109321af2f5SPavel Pisa 
kvaser_pci_reset(DeviceState * dev)110321af2f5SPavel Pisa static void kvaser_pci_reset(DeviceState *dev)
111321af2f5SPavel Pisa {
112321af2f5SPavel Pisa     KvaserPCIState *d = KVASER_PCI_DEV(dev);
113321af2f5SPavel Pisa     CanSJA1000State *s = &d->sja_state;
114321af2f5SPavel Pisa 
115321af2f5SPavel Pisa     can_sja_hardware_reset(s);
116321af2f5SPavel Pisa }
117321af2f5SPavel Pisa 
kvaser_pci_s5920_io_read(void * opaque,hwaddr addr,unsigned size)118321af2f5SPavel Pisa static uint64_t kvaser_pci_s5920_io_read(void *opaque, hwaddr addr,
119321af2f5SPavel Pisa                                          unsigned size)
120321af2f5SPavel Pisa {
121321af2f5SPavel Pisa     KvaserPCIState *d = opaque;
122321af2f5SPavel Pisa     uint64_t val;
123321af2f5SPavel Pisa 
124321af2f5SPavel Pisa     switch (addr) {
125321af2f5SPavel Pisa     case S5920_INTCSR:
126321af2f5SPavel Pisa         val = d->s5920_intcsr;
127321af2f5SPavel Pisa         val &= ~S5920_INTCSR_INTERRUPT_ASSERTED_M;
128321af2f5SPavel Pisa         if (d->s5920_irqstate) {
129321af2f5SPavel Pisa             val |= S5920_INTCSR_INTERRUPT_ASSERTED_M;
130321af2f5SPavel Pisa         }
131321af2f5SPavel Pisa         return val;
132321af2f5SPavel Pisa     }
133321af2f5SPavel Pisa     return 0;
134321af2f5SPavel Pisa }
135321af2f5SPavel Pisa 
kvaser_pci_s5920_io_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)136321af2f5SPavel Pisa static void kvaser_pci_s5920_io_write(void *opaque, hwaddr addr, uint64_t data,
137321af2f5SPavel Pisa                                       unsigned size)
138321af2f5SPavel Pisa {
139321af2f5SPavel Pisa     KvaserPCIState *d = opaque;
140321af2f5SPavel Pisa 
141321af2f5SPavel Pisa     switch (addr) {
142321af2f5SPavel Pisa     case S5920_INTCSR:
143321af2f5SPavel Pisa         if (d->s5920_irqstate &&
144321af2f5SPavel Pisa             ((d->s5920_intcsr ^ data) & S5920_INTCSR_ADDON_INTENABLE_M)) {
145321af2f5SPavel Pisa             pci_set_irq(&d->dev, !!(data & S5920_INTCSR_ADDON_INTENABLE_M));
146321af2f5SPavel Pisa         }
147321af2f5SPavel Pisa         d->s5920_intcsr = data;
148321af2f5SPavel Pisa         break;
149321af2f5SPavel Pisa     }
150321af2f5SPavel Pisa }
151321af2f5SPavel Pisa 
kvaser_pci_sja_io_read(void * opaque,hwaddr addr,unsigned size)152321af2f5SPavel Pisa static uint64_t kvaser_pci_sja_io_read(void *opaque, hwaddr addr, unsigned size)
153321af2f5SPavel Pisa {
154321af2f5SPavel Pisa     KvaserPCIState *d = opaque;
155321af2f5SPavel Pisa     CanSJA1000State *s = &d->sja_state;
156321af2f5SPavel Pisa 
157321af2f5SPavel Pisa     if (addr >= KVASER_PCI_BYTES_PER_SJA) {
158321af2f5SPavel Pisa         return 0;
159321af2f5SPavel Pisa     }
160321af2f5SPavel Pisa 
161321af2f5SPavel Pisa     return can_sja_mem_read(s, addr, size);
162321af2f5SPavel Pisa }
163321af2f5SPavel Pisa 
kvaser_pci_sja_io_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)164321af2f5SPavel Pisa static void kvaser_pci_sja_io_write(void *opaque, hwaddr addr, uint64_t data,
165321af2f5SPavel Pisa                                     unsigned size)
166321af2f5SPavel Pisa {
167321af2f5SPavel Pisa     KvaserPCIState *d = opaque;
168321af2f5SPavel Pisa     CanSJA1000State *s = &d->sja_state;
169321af2f5SPavel Pisa 
170321af2f5SPavel Pisa     if (addr >= KVASER_PCI_BYTES_PER_SJA) {
171321af2f5SPavel Pisa         return;
172321af2f5SPavel Pisa     }
173321af2f5SPavel Pisa 
174321af2f5SPavel Pisa     can_sja_mem_write(s, addr, data, size);
175321af2f5SPavel Pisa }
176321af2f5SPavel Pisa 
kvaser_pci_xilinx_io_read(void * opaque,hwaddr addr,unsigned size)177321af2f5SPavel Pisa static uint64_t kvaser_pci_xilinx_io_read(void *opaque, hwaddr addr,
178321af2f5SPavel Pisa                                           unsigned size)
179321af2f5SPavel Pisa {
180321af2f5SPavel Pisa     switch (addr) {
181321af2f5SPavel Pisa     case KVASER_PCI_XILINX_VERINT:
182321af2f5SPavel Pisa         return (KVASER_PCI_XILINX_VERSION_NUMBER << 4) | 0;
183321af2f5SPavel Pisa     }
184321af2f5SPavel Pisa 
185321af2f5SPavel Pisa     return 0;
186321af2f5SPavel Pisa }
187321af2f5SPavel Pisa 
kvaser_pci_xilinx_io_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)188321af2f5SPavel Pisa static void kvaser_pci_xilinx_io_write(void *opaque, hwaddr addr, uint64_t data,
189321af2f5SPavel Pisa                              unsigned size)
190321af2f5SPavel Pisa {
191321af2f5SPavel Pisa 
192321af2f5SPavel Pisa }
193321af2f5SPavel Pisa 
194321af2f5SPavel Pisa static const MemoryRegionOps kvaser_pci_s5920_io_ops = {
195321af2f5SPavel Pisa     .read = kvaser_pci_s5920_io_read,
196321af2f5SPavel Pisa     .write = kvaser_pci_s5920_io_write,
197321af2f5SPavel Pisa     .endianness = DEVICE_LITTLE_ENDIAN,
198321af2f5SPavel Pisa     .impl = {
199321af2f5SPavel Pisa         .min_access_size = 4,
200321af2f5SPavel Pisa         .max_access_size = 4,
201321af2f5SPavel Pisa     },
202321af2f5SPavel Pisa };
203321af2f5SPavel Pisa 
204321af2f5SPavel Pisa static const MemoryRegionOps kvaser_pci_sja_io_ops = {
205321af2f5SPavel Pisa     .read = kvaser_pci_sja_io_read,
206321af2f5SPavel Pisa     .write = kvaser_pci_sja_io_write,
207321af2f5SPavel Pisa     .endianness = DEVICE_LITTLE_ENDIAN,
208321af2f5SPavel Pisa     .impl = {
209321af2f5SPavel Pisa         .max_access_size = 1,
210321af2f5SPavel Pisa     },
211321af2f5SPavel Pisa };
212321af2f5SPavel Pisa 
213321af2f5SPavel Pisa static const MemoryRegionOps kvaser_pci_xilinx_io_ops = {
214321af2f5SPavel Pisa     .read = kvaser_pci_xilinx_io_read,
215321af2f5SPavel Pisa     .write = kvaser_pci_xilinx_io_write,
216321af2f5SPavel Pisa     .endianness = DEVICE_LITTLE_ENDIAN,
217321af2f5SPavel Pisa     .impl = {
218321af2f5SPavel Pisa         .max_access_size = 1,
219321af2f5SPavel Pisa     },
220321af2f5SPavel Pisa };
221321af2f5SPavel Pisa 
kvaser_pci_realize(PCIDevice * pci_dev,Error ** errp)222321af2f5SPavel Pisa static void kvaser_pci_realize(PCIDevice *pci_dev, Error **errp)
223321af2f5SPavel Pisa {
224321af2f5SPavel Pisa     KvaserPCIState *d = KVASER_PCI_DEV(pci_dev);
225321af2f5SPavel Pisa     CanSJA1000State *s = &d->sja_state;
226321af2f5SPavel Pisa     uint8_t *pci_conf;
227321af2f5SPavel Pisa 
228321af2f5SPavel Pisa     pci_conf = pci_dev->config;
229321af2f5SPavel Pisa     pci_conf[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
230321af2f5SPavel Pisa 
231321af2f5SPavel Pisa     d->irq = qemu_allocate_irq(kvaser_pci_irq_handler, d, 0);
232321af2f5SPavel Pisa 
233321af2f5SPavel Pisa     can_sja_init(s, d->irq);
234321af2f5SPavel Pisa 
235321af2f5SPavel Pisa     if (can_sja_connect_to_bus(s, d->canbus) < 0) {
236321af2f5SPavel Pisa         error_setg(errp, "can_sja_connect_to_bus failed");
237321af2f5SPavel Pisa         return;
238321af2f5SPavel Pisa     }
239321af2f5SPavel Pisa 
240321af2f5SPavel Pisa     memory_region_init_io(&d->s5920_io, OBJECT(d), &kvaser_pci_s5920_io_ops,
241321af2f5SPavel Pisa                           d, "kvaser_pci-s5920", KVASER_PCI_S5920_RANGE);
242321af2f5SPavel Pisa     memory_region_init_io(&d->sja_io, OBJECT(d), &kvaser_pci_sja_io_ops,
243321af2f5SPavel Pisa                           d, "kvaser_pci-sja", KVASER_PCI_SJA_RANGE);
244321af2f5SPavel Pisa     memory_region_init_io(&d->xilinx_io, OBJECT(d), &kvaser_pci_xilinx_io_ops,
245321af2f5SPavel Pisa                           d, "kvaser_pci-xilinx", KVASER_PCI_XILINX_RANGE);
246321af2f5SPavel Pisa 
247321af2f5SPavel Pisa     pci_register_bar(&d->dev, /*BAR*/ 0, PCI_BASE_ADDRESS_SPACE_IO,
248321af2f5SPavel Pisa                                             &d->s5920_io);
249321af2f5SPavel Pisa     pci_register_bar(&d->dev, /*BAR*/ 1, PCI_BASE_ADDRESS_SPACE_IO,
250321af2f5SPavel Pisa                                             &d->sja_io);
251321af2f5SPavel Pisa     pci_register_bar(&d->dev, /*BAR*/ 2, PCI_BASE_ADDRESS_SPACE_IO,
252321af2f5SPavel Pisa                                             &d->xilinx_io);
253321af2f5SPavel Pisa }
254321af2f5SPavel Pisa 
kvaser_pci_exit(PCIDevice * pci_dev)255321af2f5SPavel Pisa static void kvaser_pci_exit(PCIDevice *pci_dev)
256321af2f5SPavel Pisa {
257321af2f5SPavel Pisa     KvaserPCIState *d = KVASER_PCI_DEV(pci_dev);
258321af2f5SPavel Pisa     CanSJA1000State *s = &d->sja_state;
259321af2f5SPavel Pisa 
260321af2f5SPavel Pisa     can_sja_disconnect(s);
261321af2f5SPavel Pisa 
262321af2f5SPavel Pisa     qemu_free_irq(d->irq);
263321af2f5SPavel Pisa }
264321af2f5SPavel Pisa 
265321af2f5SPavel Pisa static const VMStateDescription vmstate_kvaser_pci = {
266321af2f5SPavel Pisa     .name = "kvaser_pci",
267321af2f5SPavel Pisa     .version_id = 1,
268321af2f5SPavel Pisa     .minimum_version_id = 1,
2691de81b42SRichard Henderson     .fields = (const VMStateField[]) {
270321af2f5SPavel Pisa         VMSTATE_PCI_DEVICE(dev, KvaserPCIState),
271a62ed5d1SPaolo Bonzini         /* Load this before sja_state.  */
272a62ed5d1SPaolo Bonzini         VMSTATE_UINT32(s5920_intcsr, KvaserPCIState),
273321af2f5SPavel Pisa         VMSTATE_STRUCT(sja_state, KvaserPCIState, 0, vmstate_can_sja,
274321af2f5SPavel Pisa                        CanSJA1000State),
275321af2f5SPavel Pisa         VMSTATE_END_OF_LIST()
276321af2f5SPavel Pisa     }
277321af2f5SPavel Pisa };
278321af2f5SPavel Pisa 
kvaser_pci_instance_init(Object * obj)279321af2f5SPavel Pisa static void kvaser_pci_instance_init(Object *obj)
280321af2f5SPavel Pisa {
281321af2f5SPavel Pisa     KvaserPCIState *d = KVASER_PCI_DEV(obj);
282321af2f5SPavel Pisa 
283321af2f5SPavel Pisa     object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
284321af2f5SPavel Pisa                              (Object **)&d->canbus,
285321af2f5SPavel Pisa                              qdev_prop_allow_set_link_before_realize,
286d2623129SMarkus Armbruster                              0);
287321af2f5SPavel Pisa }
288321af2f5SPavel Pisa 
kvaser_pci_class_init(ObjectClass * klass,void * data)289321af2f5SPavel Pisa static void kvaser_pci_class_init(ObjectClass *klass, void *data)
290321af2f5SPavel Pisa {
291321af2f5SPavel Pisa     DeviceClass *dc = DEVICE_CLASS(klass);
292321af2f5SPavel Pisa     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
293321af2f5SPavel Pisa 
294321af2f5SPavel Pisa     k->realize = kvaser_pci_realize;
295321af2f5SPavel Pisa     k->exit = kvaser_pci_exit;
296321af2f5SPavel Pisa     k->vendor_id = KVASER_PCI_VENDOR_ID1;
297321af2f5SPavel Pisa     k->device_id = KVASER_PCI_DEVICE_ID1;
298321af2f5SPavel Pisa     k->revision = 0x00;
299321af2f5SPavel Pisa     k->class_id = 0x00ff00;
300321af2f5SPavel Pisa     dc->desc = "Kvaser PCICANx";
301321af2f5SPavel Pisa     dc->vmsd = &vmstate_kvaser_pci;
302*e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, kvaser_pci_reset);
303321af2f5SPavel Pisa     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
304321af2f5SPavel Pisa }
305321af2f5SPavel Pisa 
306321af2f5SPavel Pisa static const TypeInfo kvaser_pci_info = {
307321af2f5SPavel Pisa     .name          = TYPE_CAN_PCI_DEV,
308321af2f5SPavel Pisa     .parent        = TYPE_PCI_DEVICE,
309321af2f5SPavel Pisa     .instance_size = sizeof(KvaserPCIState),
310321af2f5SPavel Pisa     .class_init    = kvaser_pci_class_init,
311321af2f5SPavel Pisa     .instance_init = kvaser_pci_instance_init,
312321af2f5SPavel Pisa     .interfaces = (InterfaceInfo[]) {
313321af2f5SPavel Pisa         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
314321af2f5SPavel Pisa         { },
315321af2f5SPavel Pisa     },
316321af2f5SPavel Pisa };
317321af2f5SPavel Pisa 
kvaser_pci_register_types(void)318321af2f5SPavel Pisa static void kvaser_pci_register_types(void)
319321af2f5SPavel Pisa {
320321af2f5SPavel Pisa     type_register_static(&kvaser_pci_info);
321321af2f5SPavel Pisa }
322321af2f5SPavel Pisa 
323321af2f5SPavel Pisa type_init(kvaser_pci_register_types)
324