| 
									
										
										
										
											2008-08-30 09:51:20 +00:00
										 |  |  | #ifndef HW_ISA_H
 | 
					
						
							|  |  |  | #define HW_ISA_H
 | 
					
						
							| 
									
										
										
										
											2009-07-31 12:30:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | /* ISA bus */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:19:49 +01:00
										 |  |  | #include "exec/memory.h"
 | 
					
						
							| 
									
										
										
										
											2016-03-16 10:24:54 +01:00
										 |  |  | #include "exec/ioport.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/qdev.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-31 12:30:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 09:19:35 +02:00
										 |  |  | #define ISA_NUM_IRQS 16
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 11:52:49 -06:00
										 |  |  | #define TYPE_ISA_DEVICE "isa-device"
 | 
					
						
							|  |  |  | #define ISA_DEVICE(obj) \
 | 
					
						
							|  |  |  |      OBJECT_CHECK(ISADevice, (obj), TYPE_ISA_DEVICE) | 
					
						
							|  |  |  | #define ISA_DEVICE_CLASS(klass) \
 | 
					
						
							|  |  |  |      OBJECT_CLASS_CHECK(ISADeviceClass, (klass), TYPE_ISA_DEVICE) | 
					
						
							|  |  |  | #define ISA_DEVICE_GET_CLASS(obj) \
 | 
					
						
							|  |  |  |      OBJECT_GET_CLASS(ISADeviceClass, (obj), TYPE_ISA_DEVICE) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-02 09:00:20 +02:00
										 |  |  | #define TYPE_ISA_BUS "ISA"
 | 
					
						
							|  |  |  | #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-22 10:34:56 -05:00
										 |  |  | #define TYPE_APPLE_SMC "isa-applesmc"
 | 
					
						
							| 
									
										
										
										
											2015-02-20 18:22:11 +00:00
										 |  |  | #define APPLESMC_MAX_DATA_LENGTH       32
 | 
					
						
							|  |  |  | #define APPLESMC_PROP_IO_BASE "iobase"
 | 
					
						
							| 
									
										
										
										
											2013-12-22 10:34:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 18:22:11 +00:00
										 |  |  | static inline uint16_t applesmc_port(void) | 
					
						
							| 
									
										
										
										
											2013-12-22 10:34:56 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-20 18:22:11 +00:00
										 |  |  |     Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (obj) { | 
					
						
							| 
									
										
										
										
											2017-06-07 20:36:12 +04:00
										 |  |  |         return object_property_get_uint(obj, APPLESMC_PROP_IO_BASE, NULL); | 
					
						
							| 
									
										
										
										
											2015-02-20 18:22:11 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2013-12-22 10:34:56 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:57 -05:00
										 |  |  | #define TYPE_ISADMA "isa-dma"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ISADMA_CLASS(klass) \
 | 
					
						
							|  |  |  |     OBJECT_CLASS_CHECK(IsaDmaClass, (klass), TYPE_ISADMA) | 
					
						
							|  |  |  | #define ISADMA_GET_CLASS(obj) \
 | 
					
						
							|  |  |  |     OBJECT_GET_CLASS(IsaDmaClass, (obj), TYPE_ISADMA) | 
					
						
							|  |  |  | #define ISADMA(obj) \
 | 
					
						
							|  |  |  |     INTERFACE_CHECK(IsaDma, (obj), TYPE_ISADMA) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct IsaDma { | 
					
						
							|  |  |  |     Object parent; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef enum { | 
					
						
							|  |  |  |     ISADMA_TRANSFER_VERIFY, | 
					
						
							|  |  |  |     ISADMA_TRANSFER_READ, | 
					
						
							|  |  |  |     ISADMA_TRANSFER_WRITE, | 
					
						
							|  |  |  |     ISADMA_TRANSFER_ILLEGAL, | 
					
						
							|  |  |  | } IsaDmaTransferMode; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 12:55:26 +01:00
										 |  |  | typedef int (*IsaDmaTransferHandler)(void *opaque, int nchan, int pos, | 
					
						
							|  |  |  |                                      int size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:57 -05:00
										 |  |  | typedef struct IsaDmaClass { | 
					
						
							|  |  |  |     InterfaceClass parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IsaDmaTransferMode (*get_transfer_mode)(IsaDma *obj, int nchan); | 
					
						
							|  |  |  |     bool (*has_autoinitialization)(IsaDma *obj, int nchan); | 
					
						
							|  |  |  |     int (*read_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); | 
					
						
							|  |  |  |     int (*write_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len); | 
					
						
							|  |  |  |     void (*hold_DREQ)(IsaDma *obj, int nchan); | 
					
						
							|  |  |  |     void (*release_DREQ)(IsaDma *obj, int nchan); | 
					
						
							|  |  |  |     void (*schedule)(IsaDma *obj); | 
					
						
							|  |  |  |     void (*register_channel)(IsaDma *obj, int nchan, | 
					
						
							| 
									
										
										
										
											2016-03-09 12:55:26 +01:00
										 |  |  |                              IsaDmaTransferHandler transfer_handler, | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:57 -05:00
										 |  |  |                              void *opaque); | 
					
						
							|  |  |  | } IsaDmaClass; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 11:52:49 -06:00
										 |  |  | typedef struct ISADeviceClass { | 
					
						
							|  |  |  |     DeviceClass parent_class; | 
					
						
							|  |  |  | } ISADeviceClass; | 
					
						
							| 
									
										
										
										
											2009-07-31 12:30:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:52 +01:00
										 |  |  | struct ISABus { | 
					
						
							| 
									
										
										
										
											2013-06-07 14:11:07 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     BusState parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-01 09:12:50 +01:00
										 |  |  |     MemoryRegion *address_space; | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:52 +01:00
										 |  |  |     MemoryRegion *address_space_io; | 
					
						
							|  |  |  |     qemu_irq *irqs; | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:57 -05:00
										 |  |  |     IsaDma *dma[2]; | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:52 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-31 12:30:14 +02:00
										 |  |  | struct ISADevice { | 
					
						
							| 
									
										
										
										
											2013-06-07 13:49:13 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     DeviceState parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 11:36:14 +02:00
										 |  |  |     uint32_t isairq[2]; | 
					
						
							| 
									
										
										
										
											2011-08-10 15:28:12 -07:00
										 |  |  |     int nirqs; | 
					
						
							| 
									
										
										
										
											2011-08-15 11:59:09 -07:00
										 |  |  |     int ioport_id; | 
					
						
							| 
									
										
										
										
											2009-07-31 12:30:14 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-01 09:12:50 +01:00
										 |  |  | ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space, | 
					
						
							| 
									
										
											  
											
												isa: Clean up error handling around isa_bus_new()
We can have at most one ISA bus.  If you try to create another one,
isa_bus_new() complains to stderr and returns null.
isa_bus_new() is called in two contexts, machine's init() and device's
realize() methods.  Since complaining to stderr is not proper in the
latter context, convert isa_bus_new() to Error.
Machine's init():
* mips_jazz_init(), called from the init() methods of machines
  "magnum" and "pica"
* mips_r4k_init(), the init() method of machine "mips"
* pc_init1() called from the init() methods of non-q35 PC machines
* typhoon_init(), called from clipper_init(), the init() method of
  machine "clipper"
These callers always create the first ISA bus, hence isa_bus_new()
can't fail.  Simply pass &error_abort.
Device's realize():
* i82378_realize(), of PCI device "i82378"
* ich9_lpc_realize(), of PCI device "ICH9-LPC"
* pci_ebus_realize(), of PCI device "ebus"
* piix3_realize(), of PCI device "pci-piix3", abstract parent of
  "PIIX3" and "PIIX3-xen"
* piix4_realize(), of PCI device "PIIX4"
* vt82c686b_realize(), of PCI device "VT82C686B"
Propagate the error.  Note that these devices are typically created
only by machine init() methods with qdev_init_nofail() or similar.  If
we screwed up and created an ISA bus before that call, we now give up
right away.  Before, we'd hobble on, and typically die in
isa_bus_irqs().  Similar if someone finds a way to hot-plug one of
these critters.
Cc: Richard Henderson <rth@twiddle.net>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: "Hervé Poussineau" <hpoussin@reactos.org>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <1450370121-5768-11-git-send-email-armbru@redhat.com>
											
										 
											2015-12-17 17:35:18 +01:00
										 |  |  |                     MemoryRegion *address_space_io, Error **errp); | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  | void isa_bus_irqs(ISABus *bus, qemu_irq *irqs); | 
					
						
							|  |  |  | qemu_irq isa_get_irq(ISADevice *dev, int isairq); | 
					
						
							| 
									
										
										
										
											2009-09-10 11:43:27 +02:00
										 |  |  | void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq); | 
					
						
							| 
									
										
										
										
											2016-06-22 15:24:56 +03:00
										 |  |  | void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq); | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:57 -05:00
										 |  |  | void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16); | 
					
						
							|  |  |  | IsaDma *isa_get_dma(ISABus *bus, int nchan); | 
					
						
							| 
									
										
										
										
											2011-08-15 17:17:35 +03:00
										 |  |  | MemoryRegion *isa_address_space(ISADevice *dev); | 
					
						
							| 
									
										
										
										
											2012-09-19 12:50:02 +01:00
										 |  |  | MemoryRegion *isa_address_space_io(ISADevice *dev); | 
					
						
							| 
									
										
										
										
											2011-12-15 22:09:51 +01:00
										 |  |  | ISADevice *isa_create(ISABus *bus, const char *name); | 
					
						
							|  |  |  | ISADevice *isa_try_create(ISABus *bus, const char *name); | 
					
						
							|  |  |  | ISADevice *isa_create_simple(ISABus *bus, const char *name); | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-08 16:58:57 +02:00
										 |  |  | ISADevice *isa_vga_init(ISABus *bus); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-26 14:52:44 +03:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * isa_register_ioport: Install an I/O port region on the ISA bus. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Register an I/O port region via memory_region_add_subregion | 
					
						
							|  |  |  |  * inside the ISA I/O address space. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @dev: the ISADevice against which these are registered; may be NULL. | 
					
						
							|  |  |  |  * @io: the #MemoryRegion being registered. | 
					
						
							|  |  |  |  * @start: the base I/O port. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * isa_register_portio_list: Initialize a set of ISA io ports | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Several ISA devices have many dis-joint I/O ports.  Worse, these I/O | 
					
						
							|  |  |  |  * ports can be interleaved with I/O ports from other devices.  This | 
					
						
							|  |  |  |  * function makes it easy to create multiple MemoryRegions for a single | 
					
						
							|  |  |  |  * device and use the legacy portio routines. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @dev: the ISADevice against which these are registered; may be NULL. | 
					
						
							| 
									
										
										
										
											2016-07-13 02:11:59 +02:00
										 |  |  |  * @piolist: the PortioList associated with the io ports | 
					
						
							| 
									
										
										
										
											2011-09-26 14:52:44 +03:00
										 |  |  |  * @start: the base I/O port against which the portio->offset is applied. | 
					
						
							|  |  |  |  * @portio: the ports, sorted by offset. | 
					
						
							| 
									
										
										
										
											2013-08-13 12:38:34 +02:00
										 |  |  |  * @opaque: passed into the portio callbacks. | 
					
						
							| 
									
										
										
										
											2011-09-26 14:52:44 +03:00
										 |  |  |  * @name: passed into memory_region_init_io. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-07-13 02:11:59 +02:00
										 |  |  | void isa_register_portio_list(ISADevice *dev, | 
					
						
							|  |  |  |                               PortioList *piolist, | 
					
						
							|  |  |  |                               uint16_t start, | 
					
						
							| 
									
										
										
										
											2011-09-26 14:52:44 +03:00
										 |  |  |                               const MemoryRegionPortio *portio, | 
					
						
							|  |  |  |                               void *opaque, const char *name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-17 15:39:43 +01:00
										 |  |  | static inline ISABus *isa_bus_from_device(ISADevice *d) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-20 18:56:18 +01:00
										 |  |  |     return ISA_BUS(qdev_get_parent_bus(DEVICE(d))); | 
					
						
							| 
									
										
										
										
											2012-03-17 15:39:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:58 -05:00
										 |  |  | /* i8257.c */ | 
					
						
							| 
									
										
										
										
											2016-02-03 11:28:55 -05:00
										 |  |  | void DMA_init(ISABus *bus, int high_page_enable); | 
					
						
							| 
									
										
										
										
											2008-08-30 09:51:20 +00:00
										 |  |  | #endif
 |