blueswir1 | 79383c9 | 2008-08-30 09:51:20 +0000 | [diff] [blame] | 1 | #ifndef HW_ISA_H |
| 2 | #define HW_ISA_H |
Gerd Hoffmann | f915a11 | 2009-07-31 12:30:14 +0200 | [diff] [blame] | 3 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 4 | /* ISA bus */ |
| 5 | |
Paolo Bonzini | 022c62c | 2012-12-17 18:19:49 +0100 | [diff] [blame] | 6 | #include "exec/memory.h" |
Paolo Bonzini | df43d49 | 2016-03-16 10:24:54 +0100 | [diff] [blame] | 7 | #include "exec/ioport.h" |
Markus Armbruster | a27bd6c | 2019-08-12 07:23:51 +0200 | [diff] [blame] | 8 | #include "hw/qdev-core.h" |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 9 | #include "qom/object.h" |
Gerd Hoffmann | f915a11 | 2009-07-31 12:30:14 +0200 | [diff] [blame] | 10 | |
Jan Kiszka | b881fbe | 2011-10-07 09:19:35 +0200 | [diff] [blame] | 11 | #define ISA_NUM_IRQS 16 |
| 12 | |
Anthony Liguori | 8f04ee0 | 2011-12-04 11:52:49 -0600 | [diff] [blame] | 13 | #define TYPE_ISA_DEVICE "isa-device" |
Eduardo Habkost | a489d19 | 2020-09-16 14:25:18 -0400 | [diff] [blame] | 14 | OBJECT_DECLARE_TYPE(ISADevice, ISADeviceClass, ISA_DEVICE) |
Anthony Liguori | 8f04ee0 | 2011-12-04 11:52:49 -0600 | [diff] [blame] | 15 | |
Anthony Liguori | 0d93692 | 2012-05-02 09:00:20 +0200 | [diff] [blame] | 16 | #define TYPE_ISA_BUS "ISA" |
Eduardo Habkost | 8063396 | 2020-09-16 14:25:19 -0400 | [diff] [blame] | 17 | OBJECT_DECLARE_SIMPLE_TYPE(ISABus, ISA_BUS) |
Anthony Liguori | 0d93692 | 2012-05-02 09:00:20 +0200 | [diff] [blame] | 18 | |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 19 | #define TYPE_ISADMA "isa-dma" |
| 20 | |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 21 | typedef struct IsaDmaClass IsaDmaClass; |
Eduardo Habkost | 8110fa1 | 2020-08-31 17:07:33 -0400 | [diff] [blame] | 22 | DECLARE_CLASS_CHECKERS(IsaDmaClass, ISADMA, |
| 23 | TYPE_ISADMA) |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 24 | #define ISADMA(obj) \ |
| 25 | INTERFACE_CHECK(IsaDma, (obj), TYPE_ISADMA) |
| 26 | |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 27 | typedef enum { |
| 28 | ISADMA_TRANSFER_VERIFY, |
| 29 | ISADMA_TRANSFER_READ, |
| 30 | ISADMA_TRANSFER_WRITE, |
| 31 | ISADMA_TRANSFER_ILLEGAL, |
| 32 | } IsaDmaTransferMode; |
| 33 | |
Markus Armbruster | bd36a61 | 2016-03-09 12:55:26 +0100 | [diff] [blame] | 34 | typedef int (*IsaDmaTransferHandler)(void *opaque, int nchan, int pos, |
| 35 | int size); |
| 36 | |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 37 | struct IsaDmaClass { |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 38 | InterfaceClass parent; |
| 39 | |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 40 | bool (*has_autoinitialization)(IsaDma *obj, int nchan); |
| 41 | int (*read_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); |
| 42 | int (*write_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); |
| 43 | void (*hold_DREQ)(IsaDma *obj, int nchan); |
| 44 | void (*release_DREQ)(IsaDma *obj, int nchan); |
| 45 | void (*schedule)(IsaDma *obj); |
| 46 | void (*register_channel)(IsaDma *obj, int nchan, |
Markus Armbruster | bd36a61 | 2016-03-09 12:55:26 +0100 | [diff] [blame] | 47 | IsaDmaTransferHandler transfer_handler, |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 48 | void *opaque); |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 49 | }; |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 50 | |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 51 | struct ISADeviceClass { |
Anthony Liguori | 8f04ee0 | 2011-12-04 11:52:49 -0600 | [diff] [blame] | 52 | DeviceClass parent_class; |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 53 | }; |
Gerd Hoffmann | f915a11 | 2009-07-31 12:30:14 +0200 | [diff] [blame] | 54 | |
Hervé Poussineau | d1a1be1 | 2011-12-15 22:09:52 +0100 | [diff] [blame] | 55 | struct ISABus { |
Andreas Färber | 2ae0e48 | 2013-06-07 14:11:07 +0200 | [diff] [blame] | 56 | /*< private >*/ |
| 57 | BusState parent_obj; |
| 58 | /*< public >*/ |
| 59 | |
Hervé Poussineau | bb2ed00 | 2015-02-01 09:12:50 +0100 | [diff] [blame] | 60 | MemoryRegion *address_space; |
Hervé Poussineau | d1a1be1 | 2011-12-15 22:09:52 +0100 | [diff] [blame] | 61 | MemoryRegion *address_space_io; |
| 62 | qemu_irq *irqs; |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 63 | IsaDma *dma[2]; |
Hervé Poussineau | d1a1be1 | 2011-12-15 22:09:52 +0100 | [diff] [blame] | 64 | }; |
| 65 | |
Gerd Hoffmann | f915a11 | 2009-07-31 12:30:14 +0200 | [diff] [blame] | 66 | struct ISADevice { |
Andreas Färber | 4a17cc4 | 2013-06-07 13:49:13 +0200 | [diff] [blame] | 67 | /*< private >*/ |
| 68 | DeviceState parent_obj; |
| 69 | /*< public >*/ |
| 70 | |
Richard Henderson | ebf47c2 | 2011-08-15 11:59:09 -0700 | [diff] [blame] | 71 | int ioport_id; |
Gerd Hoffmann | f915a11 | 2009-07-31 12:30:14 +0200 | [diff] [blame] | 72 | }; |
| 73 | |
Hervé Poussineau | bb2ed00 | 2015-02-01 09:12:50 +0100 | [diff] [blame] | 74 | ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space, |
Markus Armbruster | d10e543 | 2015-12-17 17:35:18 +0100 | [diff] [blame] | 75 | MemoryRegion *address_space_io, Error **errp); |
Hervé Poussineau | 48a18b3 | 2011-12-15 22:09:51 +0100 | [diff] [blame] | 76 | void isa_bus_irqs(ISABus *bus, qemu_irq *irqs); |
Paolo Bonzini | 3c29e18 | 2019-12-13 13:00:43 +0100 | [diff] [blame] | 77 | qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq); |
Paolo Bonzini | 3c29e18 | 2019-12-13 13:00:43 +0100 | [diff] [blame] | 78 | void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq); |
Hervé Poussineau | 5484f30 | 2016-02-03 11:28:57 -0500 | [diff] [blame] | 79 | void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16); |
| 80 | IsaDma *isa_get_dma(ISABus *bus, int nchan); |
Avi Kivity | c839ade | 2011-08-15 17:17:35 +0300 | [diff] [blame] | 81 | MemoryRegion *isa_address_space(ISADevice *dev); |
Julien Grall | ac10027 | 2012-09-19 12:50:02 +0100 | [diff] [blame] | 82 | MemoryRegion *isa_address_space_io(ISADevice *dev); |
Markus Armbruster | 0fe9d90 | 2020-06-10 07:32:07 +0200 | [diff] [blame] | 83 | ISADevice *isa_new(const char *name); |
| 84 | ISADevice *isa_try_new(const char *name); |
| 85 | bool isa_realize_and_unref(ISADevice *dev, ISABus *bus, Error **errp); |
Hervé Poussineau | 48a18b3 | 2011-12-15 22:09:51 +0100 | [diff] [blame] | 86 | ISADevice *isa_create_simple(ISABus *bus, const char *name); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 87 | |
Aurelien Jarno | 14e7a64 | 2012-09-08 16:58:57 +0200 | [diff] [blame] | 88 | ISADevice *isa_vga_init(ISABus *bus); |
Gerd Hoffmann | a53e581 | 2020-04-29 15:59:53 +0200 | [diff] [blame] | 89 | void isa_build_aml(ISABus *bus, Aml *scope); |
Aurelien Jarno | 14e7a64 | 2012-09-08 16:58:57 +0200 | [diff] [blame] | 90 | |
Avi Kivity | d750073 | 2011-09-26 14:52:44 +0300 | [diff] [blame] | 91 | /** |
| 92 | * isa_register_ioport: Install an I/O port region on the ISA bus. |
| 93 | * |
| 94 | * Register an I/O port region via memory_region_add_subregion |
| 95 | * inside the ISA I/O address space. |
| 96 | * |
| 97 | * @dev: the ISADevice against which these are registered; may be NULL. |
| 98 | * @io: the #MemoryRegion being registered. |
| 99 | * @start: the base I/O port. |
| 100 | */ |
| 101 | void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start); |
| 102 | |
| 103 | /** |
| 104 | * isa_register_portio_list: Initialize a set of ISA io ports |
| 105 | * |
| 106 | * Several ISA devices have many dis-joint I/O ports. Worse, these I/O |
| 107 | * ports can be interleaved with I/O ports from other devices. This |
| 108 | * function makes it easy to create multiple MemoryRegions for a single |
| 109 | * device and use the legacy portio routines. |
| 110 | * |
| 111 | * @dev: the ISADevice against which these are registered; may be NULL. |
Marc-André Lureau | e305a16 | 2016-07-13 02:11:59 +0200 | [diff] [blame] | 112 | * @piolist: the PortioList associated with the io ports |
Avi Kivity | d750073 | 2011-09-26 14:52:44 +0300 | [diff] [blame] | 113 | * @start: the base I/O port against which the portio->offset is applied. |
| 114 | * @portio: the ports, sorted by offset. |
Hervé Poussineau | 520902a | 2013-08-13 12:38:34 +0200 | [diff] [blame] | 115 | * @opaque: passed into the portio callbacks. |
Avi Kivity | d750073 | 2011-09-26 14:52:44 +0300 | [diff] [blame] | 116 | * @name: passed into memory_region_init_io. |
Thomas Huth | 9405d87 | 2021-04-16 14:52:56 +0200 | [diff] [blame] | 117 | * |
| 118 | * Returns: 0 on success, negative error code otherwise (e.g. if the |
| 119 | * ISA bus is not available) |
Avi Kivity | d750073 | 2011-09-26 14:52:44 +0300 | [diff] [blame] | 120 | */ |
Thomas Huth | 9405d87 | 2021-04-16 14:52:56 +0200 | [diff] [blame] | 121 | int isa_register_portio_list(ISADevice *dev, |
| 122 | PortioList *piolist, |
| 123 | uint16_t start, |
| 124 | const MemoryRegionPortio *portio, |
| 125 | void *opaque, const char *name); |
Avi Kivity | d750073 | 2011-09-26 14:52:44 +0300 | [diff] [blame] | 126 | |
Hervé Poussineau | a527b54 | 2012-03-17 15:39:43 +0100 | [diff] [blame] | 127 | static inline ISABus *isa_bus_from_device(ISADevice *d) |
| 128 | { |
Andreas Färber | 3e7b8f4 | 2013-01-20 18:56:18 +0100 | [diff] [blame] | 129 | return ISA_BUS(qdev_get_parent_bus(DEVICE(d))); |
Hervé Poussineau | a527b54 | 2012-03-17 15:39:43 +0100 | [diff] [blame] | 130 | } |
| 131 | |
Hervé Poussineau | 9b74b19 | 2018-01-06 16:37:29 +0100 | [diff] [blame] | 132 | #define TYPE_PIIX4_PCI_DEVICE "piix4-isa" |
| 133 | |
blueswir1 | 79383c9 | 2008-08-30 09:51:20 +0000 | [diff] [blame] | 134 | #endif |