| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU Empty Slot | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The empty_slot device emulates known to a bus but not connected devices. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2010 Artyom Tarasenko | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This code is licensed under the GNU GPL v2 or (at your option) any later | 
					
						
							|  |  |  |  * version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "hw.h"
 | 
					
						
							|  |  |  | #include "sysbus.h"
 | 
					
						
							|  |  |  | #include "empty_slot.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //#define DEBUG_EMPTY_SLOT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_EMPTY_SLOT
 | 
					
						
							|  |  |  | #define DPRINTF(fmt, ...)                                       \
 | 
					
						
							|  |  |  |     do { printf("empty_slot: " fmt , ## __VA_ARGS__); } while (0) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define DPRINTF(fmt, ...) do {} while (0)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct EmptySlot { | 
					
						
							|  |  |  |     SysBusDevice busdev; | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  |     uint64_t size; | 
					
						
							|  |  |  | } EmptySlot; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  | static uint64_t empty_slot_read(void *opaque, target_phys_addr_t addr, | 
					
						
							|  |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     DPRINTF("read from " TARGET_FMT_plx "\n", addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  | static void empty_slot_write(void *opaque, target_phys_addr_t addr, | 
					
						
							|  |  |  |                              uint64_t val, unsigned size) | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  |     DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr); | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  | static const MemoryRegionOps empty_slot_ops = { | 
					
						
							|  |  |  |     .read = empty_slot_read, | 
					
						
							|  |  |  |     .write = empty_slot_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void empty_slot_init(target_phys_addr_t addr, uint64_t slot_size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-04-14 19:19:00 +02:00
										 |  |  |     if (slot_size > 0) { | 
					
						
							|  |  |  |         /* Only empty slots larger than 0 byte need handling. */ | 
					
						
							|  |  |  |         DeviceState *dev; | 
					
						
							|  |  |  |         SysBusDevice *s; | 
					
						
							|  |  |  |         EmptySlot *e; | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-14 19:19:00 +02:00
										 |  |  |         dev = qdev_create(NULL, "empty_slot"); | 
					
						
							|  |  |  |         s = sysbus_from_qdev(dev); | 
					
						
							|  |  |  |         e = FROM_SYSBUS(EmptySlot, s); | 
					
						
							|  |  |  |         e->size = slot_size; | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-14 19:19:00 +02:00
										 |  |  |         qdev_init_nofail(dev); | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-14 19:19:00 +02:00
										 |  |  |         sysbus_mmio_map(s, 0, addr); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int empty_slot_init1(SysBusDevice *dev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     EmptySlot *s = FROM_SYSBUS(EmptySlot, dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:19:29 +02:00
										 |  |  |     memory_region_init_io(&s->iomem, &empty_slot_ops, s, | 
					
						
							|  |  |  |                           "empty-slot", s->size); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &s->iomem); | 
					
						
							| 
									
										
										
										
											2010-04-17 01:10:04 +02:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static SysBusDeviceInfo empty_slot_info = { | 
					
						
							|  |  |  |     .init = empty_slot_init1, | 
					
						
							|  |  |  |     .qdev.name  = "empty_slot", | 
					
						
							|  |  |  |     .qdev.size  = sizeof(EmptySlot), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void empty_slot_register_devices(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     sysbus_register_withprop(&empty_slot_info); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | device_init(empty_slot_register_devices); |