diff options
Diffstat (limited to 'hw')
96 files changed, 2076 insertions, 1431 deletions
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 28fe1ff3a3..9d1b508e16 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -327,7 +327,7 @@ struct virtio_9p_config uint16_t tag_len; /* Variable size tag name */ uint8_t tag[0]; -} __attribute__((packed)); +} QEMU_PACKED; typedef struct V9fsMkState { V9fsPDU *pdu; diff --git a/hw/acpi.c b/hw/acpi.c index d04b965977..1cf35e116a 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -32,7 +32,7 @@ struct acpi_table_header { uint32_t oem_revision; /* OEM revision number */ char asl_compiler_id[4]; /* ASL compiler vendor ID */ uint32_t asl_compiler_revision; /* ASL compiler revision number */ -} __attribute__((packed)); +} QEMU_PACKED; #define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) #define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */ diff --git a/hw/an5206.c b/hw/an5206.c index 481ae60449..04ca420a90 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -12,7 +12,6 @@ #include "boards.h" #include "loader.h" #include "elf.h" -#include "exec-memory.h" #define KERNEL_LOAD_ADDR 0x10000 #define AN5206_MBAR_ADDR 0x10000000 @@ -38,9 +37,6 @@ static void an5206_init(ram_addr_t ram_size, int kernel_size; uint64_t elf_entry; target_phys_addr_t entry; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *sram = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "m5206"; @@ -56,12 +52,12 @@ static void an5206_init(ram_addr_t ram_size, env->rambar0 = AN5206_RAMBAR_ADDR | 1; /* DRAM at address zero */ - memory_region_init_ram(ram, NULL, "an5206.ram", ram_size); - memory_region_add_subregion(address_space_mem, 0, ram); + cpu_register_physical_memory(0, ram_size, + qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM); /* Internal SRAM. */ - memory_region_init_ram(sram, NULL, "an5206.sram", 512); - memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram); + cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512, + qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM); mcf5206_init(AN5206_MBAR_ADDR, env); diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 6ee2068128..c232946280 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -71,6 +71,7 @@ typedef struct APBState { PCIBus *bus; MemoryRegion apb_config; MemoryRegion pci_config; + MemoryRegion pci_mmio; MemoryRegion pci_ioport; uint32_t iommu[4]; uint32_t pci_control[16]; @@ -336,12 +337,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, sysbus_mmio_map(s, 2, special_base + 0x2000000ULL); d = FROM_SYSBUS(APBState, s); + memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL); + memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio); + d->bus = pci_register_bus(&d->busdev.qdev, "pci", - pci_apb_set_irq, pci_pbm_map_irq, d, - get_system_memory(), - get_system_io(), - 0, 32); - pci_bus_set_mem_base(d->bus, mem_base); + pci_apb_set_irq, pci_pbm_map_irq, d, + &d->pci_mmio, + get_system_io(), + 0, 32); for (i = 0; i < 32; i++) { sysbus_connect_irq(s, i, pic[i]); diff --git a/hw/arm-misc.h b/hw/arm-misc.h index af403a159a..f8a747289b 100644 --- a/hw/arm-misc.h +++ b/hw/arm-misc.h @@ -11,16 +11,13 @@ #ifndef ARM_MISC_H #define ARM_MISC_H 1 -#include "memory.h" - /* The CPU is also modeled as an interrupt controller. */ #define ARM_PIC_CPU_IRQ 0 #define ARM_PIC_CPU_FIQ 1 qemu_irq *arm_pic_init_cpu(CPUState *env); /* armv7m.c */ -qemu_irq *armv7m_init(MemoryRegion *address_space_mem, - int flash_size, int sram_size, +qemu_irq *armv7m_init(int flash_size, int sram_size, const char *kernel_filename, const char *cpu_model); /* arm_boot.c */ diff --git a/hw/armv7m.c b/hw/armv7m.c index 28d41b82a6..a932f16a44 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -156,8 +156,7 @@ static void armv7m_reset(void *opaque) flash_size and sram_size are in kb. Returns the NVIC array. */ -qemu_irq *armv7m_init(MemoryRegion *address_space_mem, - int flash_size, int sram_size, +qemu_irq *armv7m_init(int flash_size, int sram_size, const char *kernel_filename, const char *cpu_model) { CPUState *env; @@ -170,9 +169,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem, uint64_t lowaddr; int i; int big_endian; - MemoryRegion *sram = g_new(MemoryRegion, 1); - MemoryRegion *flash = g_new(MemoryRegion, 1); - MemoryRegion *hack = g_new(MemoryRegion, 1); flash_size *= 1024; sram_size *= 1024; @@ -198,11 +194,12 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem, #endif /* Flash programming is done via the SCU, so pretend it is ROM. */ - memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size); - memory_region_set_readonly(flash, true); - memory_region_add_subregion(address_space_mem, 0, flash); - memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size); - memory_region_add_subregion(address_space_mem, 0x20000000, sram); + cpu_register_physical_memory(0, flash_size, + qemu_ram_alloc(NULL, "armv7m.flash", + flash_size) | IO_MEM_ROM); + cpu_register_physical_memory(0x20000000, sram_size, + qemu_ram_alloc(NULL, "armv7m.sram", + sram_size) | IO_MEM_RAM); armv7m_bitband_init(); nvic = qdev_create(NULL, "armv7m_nvic"); @@ -235,8 +232,9 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem, /* Hack to map an additional page of ram at the top of the address space. This stops qemu complaining about executing code outside RAM when returning from an exception. */ - memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000); - memory_region_add_subregion(address_space_mem, 0xfffff000, hack); + cpu_register_physical_memory(0xfffff000, 0x1000, + qemu_ram_alloc(NULL, "armv7m.hack", + 0x1000) | IO_MEM_RAM); qemu_register_reset(armv7m_reset, env); return pic; diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index 73eb39d43b..06200e257a 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -31,7 +31,6 @@ #include "elf.h" #include "cris-boot.h" #include "blockdev.h" -#include "exec-memory.h" #define D(x) #define DNAND(x) @@ -260,9 +259,8 @@ void axisdev88_init (ram_addr_t ram_size, int i; int nand_regs; int gpio_regs; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *phys_ram = g_new(MemoryRegion, 1); - MemoryRegion *phys_intmem = g_new(MemoryRegion, 1); + ram_addr_t phys_ram; + ram_addr_t phys_intmem; /* init CPUs */ if (cpu_model == NULL) { @@ -271,13 +269,15 @@ void axisdev88_init (ram_addr_t ram_size, env = cpu_init(cpu_model); /* allocate RAM */ - memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size); - memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram); + phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size); + cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the internal memory. */ - memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE); - memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem); + phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE); + cpu_register_physical_memory(0x38000000, INTMEM_SIZE, + phys_intmem | IO_MEM_RAM); + /* Attach a NAND flash to CS1. */ nand = drive_get(IF_MTD, 0, 0); diff --git a/hw/bt.h b/hw/bt.h index 3797254691..a48b8d4b13 100644 --- a/hw/bt.h +++ b/hw/bt.h @@ -26,7 +26,7 @@ /* BD Address */ typedef struct { uint8_t b[6]; -} __attribute__((packed)) bdaddr_t; +} QEMU_PACKED bdaddr_t; #define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) #define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}) @@ -446,13 +446,13 @@ typedef struct { uint8_t lap[3]; uint8_t length; /* 1.28s units */ uint8_t num_rsp; -} __attribute__ ((packed)) inquiry_cp; +} QEMU_PACKED inquiry_cp; #define INQUIRY_CP_SIZE 5 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) status_bdaddr_rp; +} QEMU_PACKED status_bdaddr_rp; #define STATUS_BDADDR_RP_SIZE 7 #define OCF_INQUIRY_CANCEL 0x0002 @@ -464,7 +464,7 @@ typedef struct { uint8_t lap[3]; uint8_t length; /* 1.28s units */ uint8_t num_rsp; -} __attribute__ ((packed)) periodic_inquiry_cp; +} QEMU_PACKED periodic_inquiry_cp; #define PERIODIC_INQUIRY_CP_SIZE 9 #define OCF_EXIT_PERIODIC_INQUIRY 0x0004 @@ -477,55 +477,55 @@ typedef struct { uint8_t pscan_mode; uint16_t clock_offset; uint8_t role_switch; -} __attribute__ ((packed)) create_conn_cp; +} QEMU_PACKED create_conn_cp; #define CREATE_CONN_CP_SIZE 13 #define OCF_DISCONNECT 0x0006 typedef struct { uint16_t handle; uint8_t reason; -} __attribute__ ((packed)) disconnect_cp; +} QEMU_PACKED disconnect_cp; #define DISCONNECT_CP_SIZE 3 #define OCF_ADD_SCO 0x0007 typedef struct { uint16_t handle; uint16_t pkt_type; -} __attribute__ ((packed)) add_sco_cp; +} QEMU_PACKED add_sco_cp; #define ADD_SCO_CP_SIZE 4 #define OCF_CREATE_CONN_CANCEL 0x0008 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) create_conn_cancel_cp; +} QEMU_PACKED create_conn_cancel_cp; #define CREATE_CONN_CANCEL_CP_SIZE 6 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) create_conn_cancel_rp; +} QEMU_PACKED create_conn_cancel_rp; #define CREATE_CONN_CANCEL_RP_SIZE 7 #define OCF_ACCEPT_CONN_REQ 0x0009 typedef struct { bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) accept_conn_req_cp; +} QEMU_PACKED accept_conn_req_cp; #define ACCEPT_CONN_REQ_CP_SIZE 7 #define OCF_REJECT_CONN_REQ 0x000A typedef struct { bdaddr_t bdaddr; uint8_t reason; -} __attribute__ ((packed)) reject_conn_req_cp; +} QEMU_PACKED reject_conn_req_cp; #define REJECT_CONN_REQ_CP_SIZE 7 #define OCF_LINK_KEY_REPLY 0x000B typedef struct { bdaddr_t bdaddr; uint8_t link_key[16]; -} __attribute__ ((packed)) link_key_reply_cp; +} QEMU_PACKED link_key_reply_cp; #define LINK_KEY_REPLY_CP_SIZE 22 #define OCF_LINK_KEY_NEG_REPLY 0x000C @@ -535,7 +535,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t pin_len; uint8_t pin_code[16]; -} __attribute__ ((packed)) pin_code_reply_cp; +} QEMU_PACKED pin_code_reply_cp; #define PIN_CODE_REPLY_CP_SIZE 23 #define OCF_PIN_CODE_NEG_REPLY 0x000E @@ -544,32 +544,32 @@ typedef struct { typedef struct { uint16_t handle; uint16_t pkt_type; -} __attribute__ ((packed)) set_conn_ptype_cp; +} QEMU_PACKED set_conn_ptype_cp; #define SET_CONN_PTYPE_CP_SIZE 4 #define OCF_AUTH_REQUESTED 0x0011 typedef struct { uint16_t handle; -} __attribute__ ((packed)) auth_requested_cp; +} QEMU_PACKED auth_requested_cp; #define AUTH_REQUESTED_CP_SIZE 2 #define OCF_SET_CONN_ENCRYPT 0x0013 typedef struct { uint16_t handle; uint8_t encrypt; -} __attribute__ ((packed)) set_conn_encrypt_cp; +} QEMU_PACKED set_conn_encrypt_cp; #define SET_CONN_ENCRYPT_CP_SIZE 3 #define OCF_CHANGE_CONN_LINK_KEY 0x0015 typedef struct { uint16_t handle; -} __attribute__ ((packed)) change_conn_link_key_cp; +} QEMU_PACKED change_conn_link_key_cp; #define CHANGE_CONN_LINK_KEY_CP_SIZE 2 #define OCF_MASTER_LINK_KEY 0x0017 typedef struct { uint8_t key_flag; -} __attribute__ ((packed)) master_link_key_cp; +} QEMU_PACKED master_link_key_cp; #define MASTER_LINK_KEY_CP_SIZE 1 #define OCF_REMOTE_NAME_REQ 0x0019 @@ -578,50 +578,50 @@ typedef struct { uint8_t pscan_rep_mode; uint8_t pscan_mode; uint16_t clock_offset; -} __attribute__ ((packed)) remote_name_req_cp; +} QEMU_PACKED remote_name_req_cp; #define REMOTE_NAME_REQ_CP_SIZE 10 #define OCF_REMOTE_NAME_REQ_CANCEL 0x001A typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) remote_name_req_cancel_cp; +} QEMU_PACKED remote_name_req_cancel_cp; #define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) remote_name_req_cancel_rp; +} QEMU_PACKED remote_name_req_cancel_rp; #define REMOTE_NAME_REQ_CANCEL_RP_SIZE 7 #define OCF_READ_REMOTE_FEATURES 0x001B typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_remote_features_cp; +} QEMU_PACKED read_remote_features_cp; #define READ_REMOTE_FEATURES_CP_SIZE 2 #define OCF_READ_REMOTE_EXT_FEATURES 0x001C typedef struct { uint16_t handle; uint8_t page_num; -} __attribute__ ((packed)) read_remote_ext_features_cp; +} QEMU_PACKED read_remote_ext_features_cp; #define READ_REMOTE_EXT_FEATURES_CP_SIZE 3 #define OCF_READ_REMOTE_VERSION 0x001D typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_remote_version_cp; +} QEMU_PACKED read_remote_version_cp; #define READ_REMOTE_VERSION_CP_SIZE 2 #define OCF_READ_CLOCK_OFFSET 0x001F typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_clock_offset_cp; +} QEMU_PACKED read_clock_offset_cp; #define READ_CLOCK_OFFSET_CP_SIZE 2 #define OCF_READ_LMP_HANDLE 0x0020 typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_lmp_handle_cp; +} QEMU_PACKED read_lmp_handle_cp; #define READ_LMP_HANDLE_CP_SIZE 2 typedef struct { @@ -629,7 +629,7 @@ typedef struct { uint16_t handle; uint8_t lmp_handle; uint32_t reserved; -} __attribute__ ((packed)) read_lmp_handle_rp; +} QEMU_PACKED read_lmp_handle_rp; #define READ_LMP_HANDLE_RP_SIZE 8 #define OCF_SETUP_SYNC_CONN 0x0028 @@ -641,7 +641,7 @@ typedef struct { uint16_t voice_setting; uint8_t retrans_effort; uint16_t pkt_type; -} __attribute__ ((packed)) setup_sync_conn_cp; +} QEMU_PACKED setup_sync_conn_cp; #define SETUP_SYNC_CONN_CP_SIZE 17 #define OCF_ACCEPT_SYNC_CONN_REQ 0x0029 @@ -653,14 +653,14 @@ typedef struct { uint16_t voice_setting; uint8_t retrans_effort; uint16_t pkt_type; -} __attribute__ ((packed)) accept_sync_conn_req_cp; +} QEMU_PACKED accept_sync_conn_req_cp; #define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21 #define OCF_REJECT_SYNC_CONN_REQ 0x002A typedef struct { bdaddr_t bdaddr; uint8_t reason; -} __attribute__ ((packed)) reject_sync_conn_req_cp; +} QEMU_PACKED reject_sync_conn_req_cp; #define REJECT_SYNC_CONN_REQ_CP_SIZE 7 /* Link Policy */ @@ -671,7 +671,7 @@ typedef struct { uint16_t handle; uint16_t max_interval; uint16_t min_interval; -} __attribute__ ((packed)) hold_mode_cp; +} QEMU_PACKED hold_mode_cp; #define HOLD_MODE_CP_SIZE 6 #define OCF_SNIFF_MODE 0x0003 @@ -681,13 +681,13 @@ typedef struct { uint16_t min_interval; uint16_t attempt; uint16_t timeout; -} __attribute__ ((packed)) sniff_mode_cp; +} QEMU_PACKED sniff_mode_cp; #define SNIFF_MODE_CP_SIZE 10 #define OCF_EXIT_SNIFF_MODE 0x0004 typedef struct { uint16_t handle; -} __attribute__ ((packed)) exit_sniff_mode_cp; +} QEMU_PACKED exit_sniff_mode_cp; #define EXIT_SNIFF_MODE_CP_SIZE 2 #define OCF_PARK_MODE 0x0005 @@ -695,13 +695,13 @@ typedef struct { uint16_t handle; uint16_t max_interval; uint16_t min_interval; -} __attribute__ ((packed)) park_mode_cp; +} QEMU_PACKED park_mode_cp; #define PARK_MODE_CP_SIZE 6 #define OCF_EXIT_PARK_MODE 0x0006 typedef struct { uint16_t handle; -} __attribute__ ((packed)) exit_park_mode_cp; +} QEMU_PACKED exit_park_mode_cp; #define EXIT_PARK_MODE_CP_SIZE 2 #define OCF_QOS_SETUP 0x0007 @@ -711,56 +711,56 @@ typedef struct { uint32_t peak_bandwidth; /* Byte per seconds */ uint32_t latency; /* Microseconds */ uint32_t delay_variation; /* Microseconds */ -} __attribute__ ((packed)) hci_qos; +} QEMU_PACKED hci_qos; #define HCI_QOS_CP_SIZE 17 typedef struct { uint16_t handle; uint8_t flags; /* Reserved */ hci_qos qos; -} __attribute__ ((packed)) qos_setup_cp; +} QEMU_PACKED qos_setup_cp; #define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE) #define OCF_ROLE_DISCOVERY 0x0009 typedef struct { uint16_t handle; -} __attribute__ ((packed)) role_discovery_cp; +} QEMU_PACKED role_discovery_cp; #define ROLE_DISCOVERY_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; uint8_t role; -} __attribute__ ((packed)) role_discovery_rp; +} QEMU_PACKED role_discovery_rp; #define ROLE_DISCOVERY_RP_SIZE 4 #define OCF_SWITCH_ROLE 0x000B typedef struct { bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) switch_role_cp; +} QEMU_PACKED switch_role_cp; #define SWITCH_ROLE_CP_SIZE 7 #define OCF_READ_LINK_POLICY 0x000C typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_link_policy_cp; +} QEMU_PACKED read_link_policy_cp; #define READ_LINK_POLICY_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; uint16_t policy; -} __attribute__ ((packed)) read_link_policy_rp; +} QEMU_PACKED read_link_policy_rp; #define READ_LINK_POLICY_RP_SIZE 5 #define OCF_WRITE_LINK_POLICY 0x000D typedef struct { uint16_t handle; uint16_t policy; -} __attribute__ ((packed)) write_link_policy_cp; +} QEMU_PACKED write_link_policy_cp; #define WRITE_LINK_POLICY_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) write_link_policy_rp; +} QEMU_PACKED write_link_policy_rp; #define WRITE_LINK_POLICY_RP_SIZE 3 #define OCF_READ_DEFAULT_LINK_POLICY 0x000E @@ -776,7 +776,7 @@ typedef struct { uint16_t max_local_latency; uint16_t min_remote_timeout; uint16_t min_local_timeout; -} __attribute__ ((packed)) sniff_subrate_cp; +} QEMU_PACKED sniff_subrate_cp; #define SNIFF_SUBRATE_CP_SIZE 10 /* Host Controller and Baseband */ @@ -785,7 +785,7 @@ typedef struct { #define OCF_SET_EVENT_MASK 0x0001 typedef struct { uint8_t mask[8]; -} __attribute__ ((packed)) set_event_mask_cp; +} QEMU_PACKED set_event_mask_cp; #define SET_EVENT_MASK_CP_SIZE 8 #define OCF_RESET 0x0003 @@ -795,7 +795,7 @@ typedef struct { uint8_t flt_type; uint8_t cond_type; uint8_t condition[0]; -} __attribute__ ((packed)) set_event_flt_cp; +} QEMU_PACKED set_event_flt_cp; #define SET_EVENT_FLT_CP_SIZE 2 enum bt_filter_type { @@ -821,26 +821,26 @@ enum conn_setup_cond { #define OCF_FLUSH 0x0008 typedef struct { uint16_t handle; -} __attribute__ ((packed)) flush_cp; +} QEMU_PACKED flush_cp; #define FLUSH_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) flush_rp; +} QEMU_PACKED flush_rp; #define FLUSH_RP_SIZE 3 #define OCF_READ_PIN_TYPE 0x0009 typedef struct { uint8_t status; uint8_t pin_type; -} __attribute__ ((packed)) read_pin_type_rp; +} QEMU_PACKED read_pin_type_rp; #define READ_PIN_TYPE_RP_SIZE 2 #define OCF_WRITE_PIN_TYPE 0x000A typedef struct { uint8_t pin_type; -} __attribute__ ((packed)) write_pin_type_cp; +} QEMU_PACKED write_pin_type_cp; #define WRITE_PIN_TYPE_CP_SIZE 1 #define OCF_CREATE_NEW_UNIT_KEY 0x000B @@ -849,89 +849,89 @@ typedef struct { typedef struct { bdaddr_t bdaddr; uint8_t read_all; -} __attribute__ ((packed)) read_stored_link_key_cp; +} QEMU_PACKED read_stored_link_key_cp; #define READ_STORED_LINK_KEY_CP_SIZE 7 typedef struct { uint8_t status; uint16_t max_keys; uint16_t num_keys; -} __attribute__ ((packed)) read_stored_link_key_rp; +} QEMU_PACKED read_stored_link_key_rp; #define READ_STORED_LINK_KEY_RP_SIZE 5 #define OCF_WRITE_STORED_LINK_KEY 0x0011 typedef struct { uint8_t num_keys; /* variable length part */ -} __attribute__ ((packed)) write_stored_link_key_cp; +} QEMU_PACKED write_stored_link_key_cp; #define WRITE_STORED_LINK_KEY_CP_SIZE 1 typedef struct { uint8_t status; uint8_t num_keys; -} __attribute__ ((packed)) write_stored_link_key_rp; +} QEMU_PACKED write_stored_link_key_rp; #define READ_WRITE_LINK_KEY_RP_SIZE 2 #define OCF_DELETE_STORED_LINK_KEY 0x0012 typedef struct { bdaddr_t bdaddr; uint8_t delete_all; -} __attribute__ ((packed)) delete_stored_link_key_cp; +} QEMU_PACKED delete_stored_link_key_cp; #define DELETE_STORED_LINK_KEY_CP_SIZE 7 typedef struct { uint8_t status; uint16_t num_keys; -} __attribute__ ((packed)) delete_stored_link_key_rp; +} QEMU_PACKED delete_stored_link_key_rp; #define DELETE_STORED_LINK_KEY_RP_SIZE 3 #define OCF_CHANGE_LOCAL_NAME 0x0013 typedef struct { char name[248]; -} __attribute__ ((packed)) change_local_name_cp; +} QEMU_PACKED change_local_name_cp; #define CHANGE_LOCAL_NAME_CP_SIZE 248 #define OCF_READ_LOCAL_NAME 0x0014 typedef struct { uint8_t status; char name[248]; -} __attribute__ ((packed)) read_local_name_rp; +} QEMU_PACKED read_local_name_rp; #define READ_LOCAL_NAME_RP_SIZE 249 #define OCF_READ_CONN_ACCEPT_TIMEOUT 0x0015 typedef struct { uint8_t status; uint16_t timeout; -} __attribute__ ((packed)) read_conn_accept_timeout_rp; +} QEMU_PACKED read_conn_accept_timeout_rp; #define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3 #define OCF_WRITE_CONN_ACCEPT_TIMEOUT 0x0016 typedef struct { uint16_t timeout; -} __attribute__ ((packed)) write_conn_accept_timeout_cp; +} QEMU_PACKED write_conn_accept_timeout_cp; #define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2 #define OCF_READ_PAGE_TIMEOUT 0x0017 typedef struct { uint8_t status; uint16_t timeout; -} __attribute__ ((packed)) read_page_timeout_rp; +} QEMU_PACKED read_page_timeout_rp; #define READ_PAGE_TIMEOUT_RP_SIZE 3 #define OCF_WRITE_PAGE_TIMEOUT 0x0018 typedef struct { uint16_t timeout; -} __attribute__ ((packed)) write_page_timeout_cp; +} QEMU_PACKED write_page_timeout_cp; #define WRITE_PAGE_TIMEOUT_CP_SIZE 2 #define OCF_READ_SCAN_ENABLE 0x0019 typedef struct { uint8_t status; uint8_t enable; -} __attribute__ ((packed)) read_scan_enable_rp; +} QEMU_PACKED read_scan_enable_rp; #define READ_SCAN_ENABLE_RP_SIZE 2 #define OCF_WRITE_SCAN_ENABLE 0x001A typedef struct { uint8_t scan_enable; -} __attribute__ ((packed)) write_scan_enable_cp; +} QEMU_PACKED write_scan_enable_cp; #define WRITE_SCAN_ENABLE_CP_SIZE 1 enum scan_enable_bits { @@ -945,14 +945,14 @@ typedef struct { uint8_t status; uint16_t interval; uint16_t window; -} __attribute__ ((packed)) read_page_activity_rp; +} QEMU_PACKED read_page_activity_rp; #define READ_PAGE_ACTIVITY_RP_SIZE 5 #define OCF_WRITE_PAGE_ACTIVITY 0x001C typedef struct { uint16_t interval; uint16_t window; -} __attribute__ ((packed)) write_page_activity_cp; +} QEMU_PACKED write_page_activity_cp; #define WRITE_PAGE_ACTIVITY_CP_SIZE 4 #define OCF_READ_INQ_ACTIVITY 0x001D @@ -960,14 +960,14 @@ typedef struct { uint8_t status; uint16_t interval; uint16_t window; -} __attribute__ ((packed)) read_inq_activity_rp; +} QEMU_PACKED read_inq_activity_rp; #define READ_INQ_ACTIVITY_RP_SIZE 5 #define OCF_WRITE_INQ_ACTIVITY 0x001E typedef struct { uint16_t interval; uint16_t window; -} __attribute__ ((packed)) write_inq_activity_cp; +} QEMU_PACKED write_inq_activity_cp; #define WRITE_INQ_ACTIVITY_CP_SIZE 4 #define OCF_READ_AUTH_ENABLE 0x001F @@ -989,26 +989,26 @@ typedef struct { typedef struct { uint8_t status; uint8_t dev_class[3]; -} __attribute__ ((packed)) read_class_of_dev_rp; +} QEMU_PACKED read_class_of_dev_rp; #define READ_CLASS_OF_DEV_RP_SIZE 4 #define OCF_WRITE_CLASS_OF_DEV 0x0024 typedef struct { uint8_t dev_class[3]; -} __attribute__ ((packed)) write_class_of_dev_cp; +} QEMU_PACKED write_class_of_dev_cp; #define WRITE_CLASS_OF_DEV_CP_SIZE 3 #define OCF_READ_VOICE_SETTING 0x0025 typedef struct { uint8_t status; uint16_t voice_setting; -} __attribute__ ((packed)) read_voice_setting_rp; +} QEMU_PACKED read_voice_setting_rp; #define READ_VOICE_SETTING_RP_SIZE 3 #define OCF_WRITE_VOICE_SETTING 0x0026 typedef struct { uint16_t voice_setting; -} __attribute__ ((packed)) write_voice_setting_cp; +} QEMU_PACKED write_voice_setting_cp; #define WRITE_VOICE_SETTING_CP_SIZE 2 #define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT 0x0027 @@ -1027,13 +1027,13 @@ typedef struct { typedef struct { uint16_t handle; uint8_t type; -} __attribute__ ((packed)) read_transmit_power_level_cp; +} QEMU_PACKED read_transmit_power_level_cp; #define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 typedef struct { uint8_t status; uint16_t handle; int8_t level; -} __attribute__ ((packed)) read_transmit_power_level_rp; +} QEMU_PACKED read_transmit_power_level_rp; #define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 #define OCF_HOST_BUFFER_SIZE 0x0033 @@ -1042,7 +1042,7 @@ typedef struct { uint8_t sco_mtu; uint16_t acl_max_pkt; uint16_t sco_max_pkt; -} __attribute__ ((packed)) host_buffer_size_cp; +} QEMU_PACKED host_buffer_size_cp; #define HOST_BUFFER_SIZE_CP_SIZE 7 #define OCF_HOST_NUMBER_OF_COMPLETED_PACKETS 0x0035 @@ -1052,19 +1052,19 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t link_sup_to; -} __attribute__ ((packed)) read_link_supervision_timeout_rp; +} QEMU_PACKED read_link_supervision_timeout_rp; #define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5 #define OCF_WRITE_LINK_SUPERVISION_TIMEOUT 0x0037 typedef struct { uint16_t handle; uint16_t link_sup_to; -} __attribute__ ((packed)) write_link_supervision_timeout_cp; +} QEMU_PACKED write_link_supervision_timeout_cp; #define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) write_link_supervision_timeout_rp; +} QEMU_PACKED write_link_supervision_timeout_rp; #define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3 #define OCF_READ_NUM_SUPPORTED_IAC 0x0038 @@ -1075,14 +1075,14 @@ typedef struct { uint8_t status; uint8_t num_current_iac; uint8_t lap[MAX_IAC_LAP][3]; -} __attribute__ ((packed)) read_current_iac_lap_rp; +} QEMU_PACKED read_current_iac_lap_rp; #define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP #define OCF_WRITE_CURRENT_IAC_LAP 0x003A typedef struct { uint8_t num_current_iac; uint8_t lap[MAX_IAC_LAP][3]; -} __attribute__ ((packed)) write_current_iac_lap_cp; +} QEMU_PACKED write_current_iac_lap_cp; #define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP #define OCF_READ_PAGE_SCAN_PERIOD_MODE 0x003B @@ -1096,45 +1096,45 @@ typedef struct { #define OCF_SET_AFH_CLASSIFICATION 0x003F typedef struct { uint8_t map[10]; -} __attribute__ ((packed)) set_afh_classification_cp; +} QEMU_PACKED set_afh_classification_cp; #define SET_AFH_CLASSIFICATION_CP_SIZE 10 typedef struct { uint8_t status; -} __attribute__ ((packed)) set_afh_classification_rp; +} QEMU_PACKED set_afh_classification_rp; #define SET_AFH_CLASSIFICATION_RP_SIZE 1 #define OCF_READ_INQUIRY_SCAN_TYPE 0x0042 typedef struct { uint8_t status; uint8_t type; -} __attribute__ ((packed)) read_inquiry_scan_type_rp; +} QEMU_PACKED read_inquiry_scan_type_rp; #define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2 #define OCF_WRITE_INQUIRY_SCAN_TYPE 0x0043 typedef struct { uint8_t type; -} __attribute__ ((packed)) write_inquiry_scan_type_cp; +} QEMU_PACKED write_inquiry_scan_type_cp; #define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_inquiry_scan_type_rp; +} QEMU_PACKED write_inquiry_scan_type_rp; #define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1 #define OCF_READ_INQUIRY_MODE 0x0044 typedef struct { uint8_t status; uint8_t mode; -} __attribute__ ((packed)) read_inquiry_mode_rp; +} QEMU_PACKED read_inquiry_mode_rp; #define READ_INQUIRY_MODE_RP_SIZE 2 #define OCF_WRITE_INQUIRY_MODE 0x0045 typedef struct { uint8_t mode; -} __attribute__ ((packed)) write_inquiry_mode_cp; +} QEMU_PACKED write_inquiry_mode_cp; #define WRITE_INQUIRY_MODE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_inquiry_mode_rp; +} QEMU_PACKED write_inquiry_mode_rp; #define WRITE_INQUIRY_MODE_RP_SIZE 1 #define OCF_READ_PAGE_SCAN_TYPE 0x0046 @@ -1145,17 +1145,17 @@ typedef struct { typedef struct { uint8_t status; uint8_t mode; -} __attribute__ ((packed)) read_afh_mode_rp; +} QEMU_PACKED read_afh_mode_rp; #define READ_AFH_MODE_RP_SIZE 2 #define OCF_WRITE_AFH_MODE 0x0049 typedef struct { uint8_t mode; -} __attribute__ ((packed)) write_afh_mode_cp; +} QEMU_PACKED write_afh_mode_cp; #define WRITE_AFH_MODE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_afh_mode_rp; +} QEMU_PACKED write_afh_mode_rp; #define WRITE_AFH_MODE_RP_SIZE 1 #define OCF_READ_EXT_INQUIRY_RESPONSE 0x0051 @@ -1163,18 +1163,18 @@ typedef struct { uint8_t status; uint8_t fec; uint8_t data[240]; -} __attribute__ ((packed)) read_ext_inquiry_response_rp; +} QEMU_PACKED read_ext_inquiry_response_rp; #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242 #define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052 typedef struct { uint8_t fec; uint8_t data[240]; -} __attribute__ ((packed)) write_ext_inquiry_response_cp; +} QEMU_PACKED write_ext_inquiry_response_cp; #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_ext_inquiry_response_rp; +} QEMU_PACKED write_ext_inquiry_response_rp; #define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1 /* Informational Parameters */ @@ -1188,34 +1188,34 @@ typedef struct { uint8_t lmp_ver; uint16_t manufacturer; uint16_t lmp_subver; -} __attribute__ ((packed)) read_local_version_rp; +} QEMU_PACKED read_local_version_rp; #define READ_LOCAL_VERSION_RP_SIZE 9 #define OCF_READ_LOCAL_COMMANDS 0x0002 typedef struct { uint8_t status; uint8_t commands[64]; -} __attribute__ ((packed)) read_local_commands_rp; +} QEMU_PACKED read_local_commands_rp; #define READ_LOCAL_COMMANDS_RP_SIZE 65 #define OCF_READ_LOCAL_FEATURES 0x0003 typedef struct { uint8_t status; uint8_t features[8]; -} __attribute__ ((packed)) read_local_features_rp; +} QEMU_PACKED read_local_features_rp; #define READ_LOCAL_FEATURES_RP_SIZE 9 #define OCF_READ_LOCAL_EXT_FEATURES 0x0004 typedef struct { uint8_t page_num; -} __attribute__ ((packed)) read_local_ext_features_cp; +} QEMU_PACKED read_local_ext_features_cp; #define READ_LOCAL_EXT_FEATURES_CP_SIZE 1 typedef struct { uint8_t status; uint8_t page_num; uint8_t max_page_num; uint8_t features[8]; -} __attribute__ ((packed)) read_local_ext_features_rp; +} QEMU_PACKED read_local_ext_features_rp; #define READ_LOCAL_EXT_FEATURES_RP_SIZE 11 #define OCF_READ_BUFFER_SIZE 0x0005 @@ -1225,21 +1225,21 @@ typedef struct { uint8_t sco_mtu; uint16_t acl_max_pkt; uint16_t sco_max_pkt; -} __attribute__ ((packed)) read_buffer_size_rp; +} QEMU_PACKED read_buffer_size_rp; #define READ_BUFFER_SIZE_RP_SIZE 8 #define OCF_READ_COUNTRY_CODE 0x0007 typedef struct { uint8_t status; uint8_t country_code; -} __attribute__ ((packed)) read_country_code_rp; +} QEMU_PACKED read_country_code_rp; #define READ_COUNTRY_CODE_RP_SIZE 2 #define OCF_READ_BD_ADDR 0x0009 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) read_bd_addr_rp; +} QEMU_PACKED read_bd_addr_rp; #define READ_BD_ADDR_RP_SIZE 7 /* Status params */ @@ -1250,27 +1250,27 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t counter; -} __attribute__ ((packed)) read_failed_contact_counter_rp; +} QEMU_PACKED read_failed_contact_counter_rp; #define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4 #define OCF_RESET_FAILED_CONTACT_COUNTER 0x0002 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) reset_failed_contact_counter_rp; +} QEMU_PACKED reset_failed_contact_counter_rp; #define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4 #define OCF_READ_LINK_QUALITY 0x0003 typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_link_quality_cp; +} QEMU_PACKED read_link_quality_cp; #define READ_LINK_QUALITY_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; uint8_t link_quality; -} __attribute__ ((packed)) read_link_quality_rp; +} QEMU_PACKED read_link_quality_rp; #define READ_LINK_QUALITY_RP_SIZE 4 #define OCF_READ_RSSI 0x0005 @@ -1278,7 +1278,7 @@ typedef struct { uint8_t status; uint16_t handle; int8_t rssi; -} __attribute__ ((packed)) read_rssi_rp; +} QEMU_PACKED read_rssi_rp; #define READ_RSSI_RP_SIZE 4 #define OCF_READ_AFH_MAP 0x0006 @@ -1287,21 +1287,21 @@ typedef struct { uint16_t handle; uint8_t mode; uint8_t map[10]; -} __attribute__ ((packed)) read_afh_map_rp; +} QEMU_PACKED read_afh_map_rp; #define READ_AFH_MAP_RP_SIZE 14 #define OCF_READ_CLOCK 0x0007 typedef struct { uint16_t handle; uint8_t which_clock; -} __attribute__ ((packed)) read_clock_cp; +} QEMU_PACKED read_clock_cp; #define READ_CLOCK_CP_SIZE 3 typedef struct { uint8_t status; uint16_t handle; uint32_t clock; uint16_t accuracy; -} __attribute__ ((packed)) read_clock_rp; +} QEMU_PACKED read_clock_rp; #define READ_CLOCK_RP_SIZE 9 /* Testing commands */ @@ -1323,7 +1323,7 @@ typedef struct { uint8_t pscan_mode; uint8_t dev_class[3]; uint16_t clock_offset; -} __attribute__ ((packed)) inquiry_info; +} QEMU_PACKED inquiry_info; #define INQUIRY_INFO_SIZE 14 #define EVT_CONN_COMPLETE 0x03 @@ -1333,7 +1333,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t link_type; uint8_t encr_mode; -} __attribute__ ((packed)) evt_conn_complete; +} QEMU_PACKED evt_conn_complete; #define EVT_CONN_COMPLETE_SIZE 11 #define EVT_CONN_REQUEST 0x04 @@ -1341,7 +1341,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t dev_class[3]; uint8_t link_type; -} __attribute__ ((packed)) evt_conn_request; +} QEMU_PACKED evt_conn_request; #define EVT_CONN_REQUEST_SIZE 10 #define EVT_DISCONN_COMPLETE 0x05 @@ -1349,14 +1349,14 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t reason; -} __attribute__ ((packed)) evt_disconn_complete; +} QEMU_PACKED evt_disconn_complete; #define EVT_DISCONN_COMPLETE_SIZE 4 #define EVT_AUTH_COMPLETE 0x06 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) evt_auth_complete; +} QEMU_PACKED evt_auth_complete; #define EVT_AUTH_COMPLETE_SIZE 3 #define EVT_REMOTE_NAME_REQ_COMPLETE 0x07 @@ -1364,7 +1364,7 @@ typedef struct { uint8_t status; bdaddr_t bdaddr; char name[248]; -} __attribute__ ((packed)) evt_remote_name_req_complete; +} QEMU_PACKED evt_remote_name_req_complete; #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255 #define EVT_ENCRYPT_CHANGE 0x08 @@ -1372,14 +1372,14 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t encrypt; -} __attribute__ ((packed)) evt_encrypt_change; +} QEMU_PACKED evt_encrypt_change; #define EVT_ENCRYPT_CHANGE_SIZE 5 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) evt_change_conn_link_key_complete; +} QEMU_PACKED evt_change_conn_link_key_complete; #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3 #define EVT_MASTER_LINK_KEY_COMPLETE 0x0A @@ -1387,7 +1387,7 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t key_flag; -} __attribute__ ((packed)) evt_master_link_key_complete; +} QEMU_PACKED evt_master_link_key_complete; #define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4 #define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B @@ -1395,7 +1395,7 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t features[8]; -} __attribute__ ((packed)) evt_read_remote_features_complete; +} QEMU_PACKED evt_read_remote_features_complete; #define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11 #define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C @@ -1405,7 +1405,7 @@ typedef struct { uint8_t lmp_ver; uint16_t manufacturer; uint16_t lmp_subver; -} __attribute__ ((packed)) evt_read_remote_version_complete; +} QEMU_PACKED evt_read_remote_version_complete; #define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8 #define EVT_QOS_SETUP_COMPLETE 0x0D @@ -1414,14 +1414,14 @@ typedef struct { uint16_t handle; uint8_t flags; /* Reserved */ hci_qos qos; -} __attribute__ ((packed)) evt_qos_setup_complete; +} QEMU_PACKED evt_qos_setup_complete; #define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE) #define EVT_CMD_COMPLETE 0x0E typedef struct { uint8_t ncmd; uint16_t opcode; -} __attribute__ ((packed)) evt_cmd_complete; +} QEMU_PACKED evt_cmd_complete; #define EVT_CMD_COMPLETE_SIZE 3 #define EVT_CMD_STATUS 0x0F @@ -1429,19 +1429,19 @@ typedef struct { uint8_t status; uint8_t ncmd; uint16_t opcode; -} __attribute__ ((packed)) evt_cmd_status; +} QEMU_PACKED evt_cmd_status; #define EVT_CMD_STATUS_SIZE 4 #define EVT_HARDWARE_ERROR 0x10 typedef struct { uint8_t code; -} __attribute__ ((packed)) evt_hardware_error; +} QEMU_PACKED evt_hardware_error; #define EVT_HARDWARE_ERROR_SIZE 1 #define EVT_FLUSH_OCCURRED 0x11 typedef struct { uint16_t handle; -} __attribute__ ((packed)) evt_flush_occurred; +} QEMU_PACKED evt_flush_occurred; #define EVT_FLUSH_OCCURRED_SIZE 2 #define EVT_ROLE_CHANGE 0x12 @@ -1449,7 +1449,7 @@ typedef struct { uint8_t status; bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) evt_role_change; +} QEMU_PACKED evt_role_change; #define EVT_ROLE_CHANGE_SIZE 8 #define EVT_NUM_COMP_PKTS 0x13 @@ -1459,7 +1459,7 @@ typedef struct { uint16_t handle; uint16_t num_packets; } connection[0]; -} __attribute__ ((packed)) evt_num_comp_pkts; +} QEMU_PACKED evt_num_comp_pkts; #define EVT_NUM_COMP_PKTS_SIZE(num_hndl) (1 + 4 * (num_hndl)) #define EVT_MODE_CHANGE 0x14 @@ -1468,26 +1468,26 @@ typedef struct { uint16_t handle; uint8_t mode; uint16_t interval; -} __attribute__ ((packed)) evt_mode_change; +} QEMU_PACKED evt_mode_change; #define EVT_MODE_CHANGE_SIZE 6 #define EVT_RETURN_LINK_KEYS 0x15 typedef struct { uint8_t num_keys; /* variable length part */ -} __attribute__ ((packed)) evt_return_link_keys; +} QEMU_PACKED evt_return_link_keys; #define EVT_RETURN_LINK_KEYS_SIZE 1 #define EVT_PIN_CODE_REQ 0x16 typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) evt_pin_code_req; +} QEMU_PACKED evt_pin_code_req; #define EVT_PIN_CODE_REQ_SIZE 6 #define EVT_LINK_KEY_REQ 0x17 typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) evt_link_key_req; +} QEMU_PACKED evt_link_key_req; #define EVT_LINK_KEY_REQ_SIZE 6 #define EVT_LINK_KEY_NOTIFY 0x18 @@ -1495,7 +1495,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t link_key[16]; uint8_t key_type; -} __attribute__ ((packed)) evt_link_key_notify; +} QEMU_PACKED evt_link_key_notify; #define EVT_LINK_KEY_NOTIFY_SIZE 23 #define EVT_LOOPBACK_COMMAND 0x19 @@ -1503,14 +1503,14 @@ typedef struct { #define EVT_DATA_BUFFER_OVERFLOW 0x1A typedef struct { uint8_t link_type; -} __attribute__ ((packed)) evt_data_buffer_overflow; +} QEMU_PACKED evt_data_buffer_overflow; #define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 #define EVT_MAX_SLOTS_CHANGE 0x1B typedef struct { uint16_t handle; uint8_t max_slots; -} __attribute__ ((packed)) evt_max_slots_change; +} QEMU_PACKED evt_max_slots_change; #define EVT_MAX_SLOTS_CHANGE_SIZE 3 #define EVT_READ_CLOCK_OFFSET_COMPLETE 0x1C @@ -1518,7 +1518,7 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t clock_offset; -} __attribute__ ((packed)) evt_read_clock_offset_complete; +} QEMU_PACKED evt_read_clock_offset_complete; #define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5 #define EVT_CONN_PTYPE_CHANGED 0x1D @@ -1526,20 +1526,20 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t ptype; -} __attribute__ ((packed)) evt_conn_ptype_changed; +} QEMU_PACKED evt_conn_ptype_changed; #define EVT_CONN_PTYPE_CHANGED_SIZE 5 #define EVT_QOS_VIOLATION 0x1E typedef struct { uint16_t handle; -} __attribute__ ((packed)) evt_qos_violation; +} QEMU_PACKED evt_qos_violation; #define EVT_QOS_VIOLATION_SIZE 2 #define EVT_PSCAN_REP_MODE_CHANGE 0x20 typedef struct { bdaddr_t bdaddr; uint8_t pscan_rep_mode; -} __attribute__ ((packed)) evt_pscan_rep_mode_change; +} QEMU_PACKED evt_pscan_rep_mode_change; #define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7 #define EVT_FLOW_SPEC_COMPLETE 0x21 @@ -1549,7 +1549,7 @@ typedef struct { uint8_t flags; uint8_t direction; hci_qos qos; -} __attribute__ ((packed)) evt_flow_spec_complete; +} QEMU_PACKED evt_flow_spec_complete; #define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE) #define EVT_INQUIRY_RESULT_WITH_RSSI 0x22 @@ -1561,7 +1561,7 @@ typedef struct { uint8_t dev_class[3]; uint16_t clock_offset; int8_t rssi; -} __attribute__ ((packed)) inquiry_info_with_rssi; +} QEMU_PACKED inquiry_info_with_rssi; #define INQUIRY_INFO_WITH_RSSI_SIZE 15 typedef struct { uint8_t num_responses; @@ -1572,7 +1572,7 @@ typedef struct { uint8_t dev_class[3]; uint16_t clock_offset; int8_t rssi; -} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode; +} QEMU_PACKED inquiry_info_with_rssi_and_pscan_mode; #define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 16 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE 0x23 @@ -1582,7 +1582,7 @@ typedef struct { uint8_t page_num; uint8_t max_page_num; uint8_t features[8]; -} __attribute__ ((packed)) evt_read_remote_ext_features_complete; +} QEMU_PACKED evt_read_remote_ext_features_complete; #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13 #define EVT_SYNC_CONN_COMPLETE 0x2C @@ -1596,7 +1596,7 @@ typedef struct { uint16_t rx_pkt_len; uint16_t tx_pkt_len; uint8_t air_mode; -} __attribute__ ((packed)) evt_sync_conn_complete; +} QEMU_PACKED evt_sync_conn_complete; #define EVT_SYNC_CONN_COMPLETE_SIZE 17 #define EVT_SYNC_CONN_CHANGED 0x2D @@ -1607,7 +1607,7 @@ typedef struct { uint8_t retrans_window; uint16_t rx_pkt_len; uint16_t tx_pkt_len; -} __attribute__ ((packed)) evt_sync_conn_changed; +} QEMU_PACKED evt_sync_conn_changed; #define EVT_SYNC_CONN_CHANGED_SIZE 9 #define EVT_SNIFF_SUBRATE 0x2E @@ -1618,7 +1618,7 @@ typedef struct { uint16_t max_local_latency; uint16_t min_remote_timeout; uint16_t min_local_timeout; -} __attribute__ ((packed)) evt_sniff_subrate; +} QEMU_PACKED evt_sniff_subrate; #define EVT_SNIFF_SUBRATE_SIZE 11 #define EVT_EXTENDED_INQUIRY_RESULT 0x2F @@ -1630,7 +1630,7 @@ typedef struct { uint16_t clock_offset; int8_t rssi; uint8_t data[240]; -} __attribute__ ((packed)) extended_inquiry_info; +} QEMU_PACKED extended_inquiry_info; #define EXTENDED_INQUIRY_INFO_SIZE 254 #define EVT_TESTING 0xFE @@ -1656,22 +1656,22 @@ typedef struct { struct hci_command_hdr { uint16_t opcode; /* OCF & OGF */ uint8_t plen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_event_hdr { uint8_t evt; uint8_t plen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_acl_hdr { uint16_t handle; /* Handle & Flags(PB, BC) */ uint16_t dlen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_sco_hdr { uint16_t handle; uint8_t dlen; -} __attribute__ ((packed)); +} QEMU_PACKED; /* L2CAP layer defines */ @@ -1718,25 +1718,25 @@ typedef struct { uint16_t len; uint16_t cid; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_hdr; +} QEMU_PACKED l2cap_hdr; #define L2CAP_HDR_SIZE 4 typedef struct { uint8_t code; uint8_t ident; uint16_t len; -} __attribute__ ((packed)) l2cap_cmd_hdr; +} QEMU_PACKED l2cap_cmd_hdr; #define L2CAP_CMD_HDR_SIZE 4 typedef struct { uint16_t reason; -} __attribute__ ((packed)) l2cap_cmd_rej; +} QEMU_PACKED l2cap_cmd_rej; #define L2CAP_CMD_REJ_SIZE 2 typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_cmd_rej_cid; +} QEMU_PACKED l2cap_cmd_rej_cid; #define L2CAP_CMD_REJ_CID_SIZE 4 /* reject reason */ @@ -1749,7 +1749,7 @@ enum bt_l2cap_rej_reason { typedef struct { uint16_t psm; uint16_t scid; -} __attribute__ ((packed)) l2cap_conn_req; +} QEMU_PACKED l2cap_conn_req; #define L2CAP_CONN_REQ_SIZE 4 typedef struct { @@ -1757,7 +1757,7 @@ typedef struct { uint16_t scid; uint16_t result; uint16_t status; -} __attribute__ ((packed)) l2cap_conn_rsp; +} QEMU_PACKED l2cap_conn_rsp; #define L2CAP_CONN_RSP_SIZE 8 /* connect result */ @@ -1780,7 +1780,7 @@ typedef struct { uint16_t dcid; uint16_t flags; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_conf_req; +} QEMU_PACKED l2cap_conf_req; #define L2CAP_CONF_REQ_SIZE(datalen) (4 + (datalen)) typedef struct { @@ -1788,7 +1788,7 @@ typedef struct { uint16_t flags; uint16_t result; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_conf_rsp; +} QEMU_PACKED l2cap_conf_rsp; #define L2CAP_CONF_RSP_SIZE(datalen) (6 + datalen) enum bt_l2cap_conf_res { @@ -1802,7 +1802,7 @@ typedef struct { uint8_t type; uint8_t len; uint8_t val[0]; -} __attribute__ ((packed)) l2cap_conf_opt; +} QEMU_PACKED l2cap_conf_opt; #define L2CAP_CONF_OPT_SIZE 2 enum bt_l2cap_conf_val { @@ -1821,7 +1821,7 @@ typedef struct { uint32_t peak_bandwidth; uint32_t latency; uint32_t delay_variation; -} __attribute__ ((packed)) l2cap_conf_opt_qos; +} QEMU_PACKED l2cap_conf_opt_qos; #define L2CAP_CONF_OPT_QOS_SIZE 22 enum bt_l2cap_conf_opt_qos_st { @@ -1841,25 +1841,25 @@ enum bt_l2cap_mode { typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_disconn_req; +} QEMU_PACKED l2cap_disconn_req; #define L2CAP_DISCONN_REQ_SIZE 4 typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_disconn_rsp; +} QEMU_PACKED l2cap_disconn_rsp; #define L2CAP_DISCONN_RSP_SIZE 4 typedef struct { uint16_t type; -} __attribute__ ((packed)) l2cap_info_req; +} QEMU_PACKED l2cap_info_req; #define L2CAP_INFO_REQ_SIZE 2 typedef struct { uint16_t type; uint16_t result; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_info_rsp; +} QEMU_PACKED l2cap_info_rsp; #define L2CAP_INFO_RSP_SIZE 4 /* info type */ diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index ec7ea8207b..4d0ef0d54c 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2424,7 +2424,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s) { unsigned mode; - memory_region_transaction_begin(); if ((s->vga.sr[0x17] & 0x44) == 0x44) { goto generic_io; } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { @@ -2444,7 +2443,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s) unmap_linear_vram(s); } } - memory_region_transaction_commit(); } diff --git a/hw/collie.c b/hw/collie.c index 0b955e04f1..156404d9f3 100644 --- a/hw/collie.c +++ b/hw/collie.c @@ -26,7 +26,7 @@ static void collie_init(ram_addr_t ram_size, { StrongARMState *s; DriveInfo *dinfo; - MemoryRegion *phys_flash = g_new(MemoryRegion, 2); + ram_addr_t phys_flash; if (!cpu_model) { cpu_model = "sa1110"; @@ -34,19 +34,17 @@ static void collie_init(ram_addr_t ram_size, s = sa1110_init(collie_binfo.ram_size, cpu_model); - memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le, - NULL, "collie.fl1", 0x02000000); + phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(SA_CS0, &phys_flash[0], + pflash_cfi01_register(SA_CS0, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), - 512, 4, 0x00, 0x00, 0x00, 0x00); + 512, 4, 0x00, 0x00, 0x00, 0x00, 0); - memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le, - NULL, "collie.fl2", 0x02000000); + phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 1); - pflash_cfi01_register(SA_CS1, &phys_flash[1], + pflash_cfi01_register(SA_CS1, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), - 512, 4, 0x00, 0x00, 0x00, 0x00); + 512, 4, 0x00, 0x00, 0x00, 0x00, 0); sysbus_create_simple("scoop", 0x40800000, NULL); diff --git a/hw/dec_pci.c b/hw/dec_pci.c index 1aec06611c..a35f382052 100644 --- a/hw/dec_pci.c +++ b/hw/dec_pci.c @@ -80,15 +80,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) static int pci_dec_21154_init_device(SysBusDevice *dev) { DECState *s; + int pci_mem_config, pci_mem_data; s = FROM_SYSBUS(DECState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, - &s->host_state, "pci-data-idx", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + pci_mem_data = pci_host_data_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); return 0; } diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c index 30146b9c9d..eed9e3843c 100644 --- a/hw/dummy_m68k.c +++ b/hw/dummy_m68k.c @@ -10,7 +10,6 @@ #include "boards.h" #include "loader.h" #include "elf.h" -#include "exec-memory.h" #define KERNEL_LOAD_ADDR 0x10000 @@ -22,8 +21,6 @@ static void dummy_m68k_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); int kernel_size; uint64_t elf_entry; target_phys_addr_t entry; @@ -40,8 +37,8 @@ static void dummy_m68k_init(ram_addr_t ram_size, env->vbr = 0; /* RAM at address zero */ - memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size); - memory_region_add_subregion(address_space_mem, 0, ram); + cpu_register_physical_memory(0, ram_size, + qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM); /* Load kernel. */ if (kernel_filename) { diff --git a/hw/flash.h b/hw/flash.h index 7fb012bb06..270be5e127 100644 --- a/hw/flash.h +++ b/hw/flash.h @@ -1,27 +1,21 @@ -#include "memory.h" - /* NOR flash devices */ typedef struct pflash_t pflash_t; /* pflash_cfi01.c */ -extern const MemoryRegionOps pflash_cfi01_ops_be; -extern const MemoryRegionOps pflash_cfi01_ops_le; -extern const MemoryRegionOps pflash_cfi02_ops_be; -extern const MemoryRegionOps pflash_cfi02_ops_le; - -pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3); + uint16_t id2, uint16_t id3, int be); /* pflash_cfi02.c */ -pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, - uint16_t unlock_addr0, uint16_t unlock_addr1); + uint16_t unlock_addr0, uint16_t unlock_addr1, + int be); /* nand.c */ DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id); @@ -42,12 +36,7 @@ uint32_t nand_getbuswidth(DeviceState *dev); #define NAND_MFR_MICRON 0x2c /* onenand.c */ -void onenand_base_update(void *opaque, target_phys_addr_t new); -void onenand_base_unmap(void *opaque); -void *onenand_init(BlockDriverState *bdrv, - uint16_t man_id, uint16_t dev_id, uint16_t ver_id, - int regshift, qemu_irq irq); -void *onenand_raw_otp(void *opaque); +void *onenand_raw_otp(DeviceState *onenand_device); /* ecc.c */ typedef struct { diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 663ad80116..8df265c61d 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -214,7 +214,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value) FW_CFG_DPRINTF("write %d\n", value); - if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) { + if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback && + s->cur_offset < e->len) { e->data[s->cur_offset++] = value; if (s->cur_offset == e->len) { e->callback(e->callback_opaque, e->data); diff --git a/hw/g364fb.c b/hw/g364fb.c index a7731ecfb5..5e7bcfa278 100644 --- a/hw/g364fb.c +++ b/hw/g364fb.c @@ -1,7 +1,7 @@ /* * QEMU G364 framebuffer Emulator. * - * Copyright (c) 2007-2009 Herve Poussineau + * Copyright (c) 2007-2011 Herve Poussineau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -18,27 +18,18 @@ */ #include "hw.h" -#include "mips.h" #include "console.h" #include "pixel_ops.h" - -//#define DEBUG_G364 - -#ifdef DEBUG_G364 -#define DPRINTF(fmt, ...) \ -do { printf("g364: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif -#define BADF(fmt, ...) \ -do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0) +#include "trace.h" +#include "sysbus.h" typedef struct G364State { /* hardware */ uint8_t *vram; - MemoryRegion vram_region; - int vram_size; + uint32_t vram_size; qemu_irq irq; + MemoryRegion mem_vram; + MemoryRegion mem_ctrl; /* registers */ uint8_t color_palette[256][3]; uint8_t cursor_palette[3][3]; @@ -53,31 +44,31 @@ typedef struct G364State { int blanked; } G364State; -#define REG_ID 0x000000 -#define REG_BOOT 0x080000 -#define REG_DISPLAY 0x080118 -#define REG_VDISPLAY 0x080150 -#define REG_CTLA 0x080300 -#define REG_TOP 0x080400 -#define REG_CURS_PAL 0x080508 -#define REG_CURS_POS 0x080638 -#define REG_CLR_PAL 0x080800 -#define REG_CURS_PAT 0x081000 -#define REG_RESET 0x180000 +#define REG_BOOT 0x000000 +#define REG_DISPLAY 0x000118 +#define REG_VDISPLAY 0x000150 +#define REG_CTLA 0x000300 +#define REG_TOP 0x000400 +#define REG_CURS_PAL 0x000508 +#define REG_CURS_POS 0x000638 +#define REG_CLR_PAL 0x000800 +#define REG_CURS_PAT 0x001000 +#define REG_RESET 0x100000 #define CTLA_FORCE_BLANK 0x00000400 #define CTLA_NO_CURSOR 0x00800000 static inline int check_dirty(G364State *s, ram_addr_t page) { - return memory_region_get_dirty(&s->vram_region, page, DIRTY_MEMORY_VGA); + return memory_region_get_dirty(&s->mem_vram, page, DIRTY_MEMORY_VGA); } static inline void reset_dirty(G364State *s, ram_addr_t page_min, ram_addr_t page_max) { - memory_region_reset_dirty(&s->vram_region, page_min, - page_max + TARGET_PAGE_SIZE - 1, + memory_region_reset_dirty(&s->mem_vram, + page_min, + page_max + TARGET_PAGE_SIZE - page_min - 1, DIRTY_MEMORY_VGA); } @@ -111,7 +102,8 @@ static void g364fb_draw_graphic8(G364State *s) w = 4; break; default: - BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds)); + hw_error("g364: unknown host depth %d", + ds_get_bits_per_pixel(s->ds)); return; } @@ -263,7 +255,7 @@ static void g364fb_update_display(void *opaque) } else if (s->depth == 8) { g364fb_draw_graphic8(s); } else { - BADF("unknown guest depth %d\n", s->depth); + error_report("g364: unknown guest depth %d", s->depth); } qemu_irq_raise(s->irq); @@ -276,13 +268,12 @@ static inline void g364fb_invalidate_display(void *opaque) s->blanked = 0; for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) { - memory_region_set_dirty(&s->vram_region, i); + memory_region_set_dirty(&s->mem_vram, i); } } -static void g364fb_reset(void *opaque) +static void g364fb_reset(G364State *s) { - G364State *s = opaque; qemu_irq_lower(s->irq); memset(s->color_palette, 0, sizeof(s->color_palette)); @@ -293,7 +284,7 @@ static void g364fb_reset(void *opaque) s->top_of_screen = 0; s->width = s->height = 0; memset(s->vram, 0, s->vram_size); - g364fb_invalidate_display(opaque); + g364fb_invalidate_display(s); } static void g364fb_screen_dump(void *opaque, const char *filename) @@ -305,7 +296,7 @@ static void g364fb_screen_dump(void *opaque, const char *filename) FILE *f; if (s->depth != 8) { - BADF("unknown guest depth %d\n", s->depth); + error_report("g364: unknown guest depth %d", s->depth); return; } @@ -337,7 +328,9 @@ static void g364fb_screen_dump(void *opaque, const char *filename) } /* called for accesses to io ports */ -static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) +static uint64_t g364fb_ctrl_read(void *opaque, + target_phys_addr_t addr, + unsigned int size) { G364State *s = opaque; uint32_t val; @@ -354,9 +347,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) val |= ((uint32_t)s->cursor_palette[idx][2] << 0); } else { switch (addr) { - case REG_ID: - val = 0x10; /* Mips G364 */ - break; case REG_DISPLAY: val = s->width / 4; break; @@ -368,33 +358,19 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) break; default: { - BADF("invalid read at [" TARGET_FMT_plx "]\n", addr); + error_report("g364: invalid read at [" TARGET_FMT_plx "]", + addr); val = 0; break; } } } - DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); + trace_g364fb_read(addr, val); return val; } -static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3); - if (addr & 0x2) - return v >> 16; - else - return v & 0xffff; -} - -static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr) -{ - uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3); - return (v >> (8 * (addr & 0x3))) & 0xff; -} - static void g364fb_update_depth(G364State *s) { static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 }; @@ -412,15 +388,18 @@ static void g364_invalidate_cursor_position(G364State *s) end = (ymax + 1) * ds_get_linesize(s->ds); for (i = start; i < end; i += TARGET_PAGE_SIZE) { - memory_region_set_dirty(&s->vram_region, i); + memory_region_set_dirty(&s->mem_vram, i); } } -static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +static void g364fb_ctrl_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned int size) { G364State *s = opaque; - DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); + trace_g364fb_write(addr, val); if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) { /* color palette */ @@ -443,124 +422,65 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v g364fb_invalidate_display(s); } else { switch (addr) { - case REG_ID: /* Card identifier; read-only */ - case REG_BOOT: /* Boot timing */ - case 0x80108: /* Line timing: half sync */ - case 0x80110: /* Line timing: back porch */ - case 0x80120: /* Line timing: short display */ - case 0x80128: /* Frame timing: broad pulse */ - case 0x80130: /* Frame timing: v sync */ - case 0x80138: /* Frame timing: v preequalise */ - case 0x80140: /* Frame timing: v postequalise */ - case 0x80148: /* Frame timing: v blank */ - case 0x80158: /* Line timing: line time */ - case 0x80160: /* Frame store: line start */ - case 0x80168: /* vram cycle: mem init */ - case 0x80170: /* vram cycle: transfer delay */ - case 0x80200: /* vram cycle: mask register */ - /* ignore */ - break; - case REG_TOP: - s->top_of_screen = val; - g364fb_invalidate_display(s); - break; - case REG_DISPLAY: - s->width = val * 4; - break; - case REG_VDISPLAY: - s->height = val / 2; - break; - case REG_CTLA: - s->ctla = val; - g364fb_update_depth(s); - g364fb_invalidate_display(s); - break; - case REG_CURS_POS: - g364_invalidate_cursor_position(s); - s->cursor_position = val; - g364_invalidate_cursor_position(s); - break; - case REG_RESET: - g364fb_reset(s); - break; - default: - BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); - break; + case REG_BOOT: /* Boot timing */ + case 0x00108: /* Line timing: half sync */ + case 0x00110: /* Line timing: back porch */ + case 0x00120: /* Line timing: short display */ + case 0x00128: /* Frame timing: broad pulse */ + case 0x00130: /* Frame timing: v sync */ + case 0x00138: /* Frame timing: v preequalise */ + case 0x00140: /* Frame timing: v postequalise */ + case 0x00148: /* Frame timing: v blank */ + case 0x00158: /* Line timing: line time */ + case 0x00160: /* Frame store: line start */ + case 0x00168: /* vram cycle: mem init */ + case 0x00170: /* vram cycle: transfer delay */ + case 0x00200: /* vram cycle: mask register */ + /* ignore */ + break; + case REG_TOP: + s->top_of_screen = val; + g364fb_invalidate_display(s); + break; + case REG_DISPLAY: + s->width = val * 4; + break; + case REG_VDISPLAY: + s->height = val / 2; + break; + case REG_CTLA: + s->ctla = val; + g364fb_update_depth(s); + g364fb_invalidate_display(s); + break; + case REG_CURS_POS: + g364_invalidate_cursor_position(s); + s->cursor_position = val; + g364_invalidate_cursor_position(s); + break; + case REG_RESET: + g364fb_reset(s); + break; + default: + error_report("g364: invalid write of 0x%" PRIx64 + " at [" TARGET_FMT_plx "]", val, addr); + break; } } qemu_irq_lower(s->irq); } -static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3); - - if (addr & 0x2) - val = (val << 16) | (old_val & 0x0000ffff); - else - val = val | (old_val & 0xffff0000); - g364fb_ctrl_writel(opaque, addr & ~0x3, val); -} - -static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3); - - switch (addr & 3) { - case 0: - val = val | (old_val & 0xffffff00); - break; - case 1: - val = (val << 8) | (old_val & 0xffff00ff); - break; - case 2: - val = (val << 16) | (old_val & 0xff00ffff); - break; - case 3: - val = (val << 24) | (old_val & 0x00ffffff); - break; - } - g364fb_ctrl_writel(opaque, addr & ~0x3, val); -} - static const MemoryRegionOps g364fb_ctrl_ops = { - .old_mmio = { - .read = { - g364fb_ctrl_readb, - g364fb_ctrl_readw, - g364fb_ctrl_readl, - }, - .write = { - g364fb_ctrl_writeb, - g364fb_ctrl_writew, - g364fb_ctrl_writel, - }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, + .read = g364fb_ctrl_read, + .write = g364fb_ctrl_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .impl.max_access_size = 4, }; -static int g364fb_load(QEMUFile *f, void *opaque, int version_id) +static int g364fb_post_load(void *opaque, int version_id) { G364State *s = opaque; - unsigned int i, vram_size; - - if (version_id != 1) - return -EINVAL; - - vram_size = qemu_get_be32(f); - if (vram_size < s->vram_size) - return -EINVAL; - qemu_get_buffer(f, s->vram, s->vram_size); - for (i = 0; i < 256; i++) - qemu_get_buffer(f, s->color_palette[i], 3); - for (i = 0; i < 3; i++) - qemu_get_buffer(f, s->cursor_palette[i], 3); - qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor)); - s->cursor_position = qemu_get_be32(f); - s->ctla = qemu_get_be32(f); - s->top_of_screen = qemu_get_be32(f); - s->width = qemu_get_be32(f); - s->height = qemu_get_be32(f); /* force refresh */ g364fb_update_depth(s); @@ -569,53 +489,80 @@ static int g364fb_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static void g364fb_save(QEMUFile *f, void *opaque) -{ - G364State *s = opaque; - int i; - - qemu_put_be32(f, s->vram_size); - qemu_put_buffer(f, s->vram, s->vram_size); - for (i = 0; i < 256; i++) - qemu_put_buffer(f, s->color_palette[i], 3); - for (i = 0; i < 3; i++) - qemu_put_buffer(f, s->cursor_palette[i], 3); - qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor)); - qemu_put_be32(f, s->cursor_position); - qemu_put_be32(f, s->ctla); - qemu_put_be32(f, s->top_of_screen); - qemu_put_be32(f, s->width); - qemu_put_be32(f, s->height); -} +static const VMStateDescription vmstate_g364fb = { + .name = "g364fb", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = g364fb_post_load, + .fields = (VMStateField[]) { + VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size), + VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3), + VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9), + VMSTATE_UINT16_ARRAY(cursor, G364State, 512), + VMSTATE_UINT32(cursor_position, G364State), + VMSTATE_UINT32(ctla, G364State), + VMSTATE_UINT32(top_of_screen, G364State), + VMSTATE_UINT32(width, G364State), + VMSTATE_UINT32(height, G364State), + VMSTATE_END_OF_LIST() + } +}; -int g364fb_mm_init(MemoryRegion *system_memory, - target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift, - qemu_irq irq) +static void g364fb_init(DeviceState *dev, G364State *s) { - G364State *s; - MemoryRegion *io_ctrl = g_new(MemoryRegion, 1); - - s = g_malloc0(sizeof(G364State)); - - s->vram_size = 8 * 1024 * 1024; - memory_region_init_ram(&s->vram_region, NULL, "g364fb.vram", s->vram_size); - s->vram = memory_region_get_ram_ptr(&s->vram_region); - s->irq = irq; - - qemu_register_reset(g364fb_reset, s); - register_savevm(NULL, "g364fb", 0, 1, g364fb_save, g364fb_load, s); - g364fb_reset(s); + s->vram = g_malloc0(s->vram_size); s->ds = graphic_console_init(g364fb_update_display, g364fb_invalidate_display, g364fb_screen_dump, NULL, s); - memory_region_add_subregion(system_memory, vram_base, &s->vram_region); + memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000); + memory_region_init_ram_ptr(&s->mem_vram, dev, "vram", + s->vram_size, s->vram); + memory_region_set_coalescing(&s->mem_vram); +} + +typedef struct { + SysBusDevice busdev; + G364State g364; +} G364SysBusState; - memory_region_init_io(io_ctrl, &g364fb_ctrl_ops, s, - "g364fb-ctrl", 0x200000); - memory_region_add_subregion(system_memory, ctrl_base, io_ctrl); +static int g364fb_sysbus_init(SysBusDevice *dev) +{ + G364State *s = &FROM_SYSBUS(G364SysBusState, dev)->g364; + + g364fb_init(&dev->qdev, s); + sysbus_init_irq(dev, &s->irq); + sysbus_init_mmio_region(dev, &s->mem_ctrl); + sysbus_init_mmio_region(dev, &s->mem_vram); return 0; } + +static void g364fb_sysbus_reset(DeviceState *d) +{ + G364SysBusState *s = DO_UPCAST(G364SysBusState, busdev.qdev, d); + g364fb_reset(&s->g364); +} + +static SysBusDeviceInfo g364fb_sysbus_info = { + .init = g364fb_sysbus_init, + .qdev.name = "sysbus-g364", + .qdev.desc = "G364 framebuffer", + .qdev.size = sizeof(G364SysBusState), + .qdev.vmsd = &vmstate_g364fb, + .qdev.reset = g364fb_sysbus_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size, + 8 * 1024 * 1024), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void g364fb_register(void) +{ + sysbus_register_withprop(&g364fb_sysbus_info); +} + +device_init(g364fb_register); diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index 9d3ff7d555..9a823e1c06 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -92,15 +92,16 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, static int pci_grackle_init_device(SysBusDevice *dev) { GrackleState *s; + int pci_mem_config, pci_mem_data; s = FROM_SYSBUS(GrackleState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, - &s->host_state, "pci-data-idx", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + pci_mem_data = pci_host_data_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); qemu_register_reset(pci_grackle_reset, &s->host_state); return 0; diff --git a/hw/gumstix.c b/hw/gumstix.c index d3a4bb4c67..853f7e1ee8 100644 --- a/hw/gumstix.c +++ b/hw/gumstix.c @@ -48,8 +48,7 @@ static void connex_init(ram_addr_t ram_size, { PXA2xxState *cpu; DriveInfo *dinfo; - const MemoryRegionOps *flash_ops; - MemoryRegion *flash = g_new(MemoryRegion, 1); + int be; uint32_t connex_rom = 0x01000000; uint32_t connex_ram = 0x04000000; @@ -64,15 +63,14 @@ static void connex_init(ram_addr_t ram_size, } #ifdef TARGET_WORDS_BIGENDIAN - flash_ops = &pflash_cfi01_ops_be; + be = 1; #else - flash_ops = &pflash_cfi01_ops_le; + be = 0; #endif - memory_region_init_rom_device(flash, flash_ops, - NULL, "connext.rom", connex_rom); - if (!pflash_cfi01_register(0x00000000, flash, + if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom", + connex_rom), dinfo->bdrv, sector_len, connex_rom / sector_len, - 2, 0, 0, 0, 0)) { + 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); exit(1); } @@ -89,8 +87,7 @@ static void verdex_init(ram_addr_t ram_size, { PXA2xxState *cpu; DriveInfo *dinfo; - MemoryRegion *flash = g_new(MemoryRegion, 1); - const MemoryRegionOps *flash_ops; + int be; uint32_t verdex_rom = 0x02000000; uint32_t verdex_ram = 0x10000000; @@ -105,15 +102,14 @@ static void verdex_init(ram_addr_t ram_size, } #ifdef TARGET_WORDS_BIGENDIAN - flash_ops = &pflash_cfi01_ops_be; + be = 1; #else - flash_ops = &pflash_cfi01_ops_le; + be = 0; #endif - memory_region_init_rom_device(flash, flash_ops, - NULL, "verdex.rom", verdex_rom); - if (!pflash_cfi01_register(0x00000000, flash, + if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom", + verdex_rom), dinfo->bdrv, sector_len, verdex_rom / sector_len, - 2, 0, 0, 0, 0)) { + 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); exit(1); } diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h index 8bf312ab21..6128702533 100644 --- a/hw/hpet_emul.h +++ b/hw/hpet_emul.h @@ -59,13 +59,13 @@ struct hpet_fw_entry uint64_t address; uint16_t min_tick; uint8_t page_prot; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hpet_fw_config { uint8_t count; struct hpet_fw_entry hpet[8]; -} __attribute__ ((packed)); +} QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; #endif diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 29521babf7..f4fa1545bd 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -710,6 +710,7 @@ static void ncq_cb(void *opaque, int ret) DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n", ncq_tfs->tag); + bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct); qemu_sglist_destroy(&ncq_tfs->sglist); ncq_tfs->used = 0; } @@ -756,6 +757,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, ncq_tfs->is_read = 1; DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba); + + bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, + (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE, + BDRV_ACCT_READ); ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->sglist, ncq_tfs->lba, ncq_cb, ncq_tfs); @@ -766,6 +771,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, ncq_tfs->is_read = 0; DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba); + + bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, + (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE, + BDRV_ACCT_WRITE); ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->sglist, ncq_tfs->lba, ncq_cb, ncq_tfs); diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index e456193b2b..3c29d93b47 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -244,13 +244,13 @@ typedef struct AHCICmdHdr { uint32_t status; uint64_t tbl_addr; uint32_t reserved[4]; -} __attribute__ ((packed)) AHCICmdHdr; +} QEMU_PACKED AHCICmdHdr; typedef struct AHCI_SG { uint64_t addr; uint32_t reserved; uint32_t flags_size; -} __attribute__ ((packed)) AHCI_SG; +} QEMU_PACKED AHCI_SG; typedef struct AHCIDevice AHCIDevice; @@ -258,6 +258,7 @@ typedef struct NCQTransferState { AHCIDevice *drive; BlockDriverAIOCB *aiocb; QEMUSGList sglist; + BlockAcctCookie acct; int is_read; uint16_t sector_count; uint64_t lba; @@ -320,7 +321,7 @@ typedef struct NCQFrame { uint8_t reserved8; uint8_t reserved9; uint8_t reserved10; -} __attribute__ ((packed)) NCQFrame; +} QEMU_PACKED NCQFrame; void ahci_init(AHCIState *s, DeviceState *qdev, int ports); void ahci_uninit(AHCIState *s); diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index fe2fb0b806..f38d2896ae 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -104,17 +104,20 @@ static void cd_data_to_raw(uint8_t *buf, int lba) memset(buf, 0, 288); } -static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, - int sector_size) +static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size) { int ret; switch(sector_size) { case 2048: - ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4); + bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); + ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4); + bdrv_acct_done(s->bs, &s->acct); break; case 2352: - ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4); + bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); + ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4); + bdrv_acct_done(s->bs, &s->acct); if (ret < 0) return ret; cd_data_to_raw(buf, lba); @@ -181,7 +184,7 @@ void ide_atapi_cmd_reply_end(IDEState *s) } else { /* see if a new sector must be read */ if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) { - ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); + ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size); if (ret < 0) { ide_transfer_stop(s); ide_atapi_io_error(s, ret); @@ -250,6 +253,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) s->io_buffer_index = 0; if (s->atapi_dma) { + bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ); s->status = READY_STAT | SEEK_STAT | DRQ_STAT; s->bus->dma->ops->start_dma(s->bus->dma, s, ide_atapi_cmd_read_dma_cb); @@ -322,10 +326,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) s->status = READY_STAT | SEEK_STAT; s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; ide_set_irq(s->bus); - eot: - s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); - ide_set_inactive(s); - return; + goto eot; } s->io_buffer_index = 0; @@ -343,9 +344,11 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) #ifdef DEBUG_AIO printf("aio_read_cd: lba=%u n=%d\n", s->lba, n); #endif + s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset); s->bus->dma->iov.iov_len = n * 4 * 512; qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1); + s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, &s->bus->dma->qiov, n * 4, ide_atapi_cmd_read_dma_cb, s); @@ -355,6 +358,12 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) ASC_MEDIUM_NOT_PRESENT); goto eot; } + + return; +eot: + bdrv_acct_done(s->bs, &s->acct); + s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); + ide_set_inactive(s); } /* start a CD-CDROM read command with DMA */ @@ -368,6 +377,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, s->io_buffer_size = 0; s->cd_sector_size = sector_size; + bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ); + /* XXX: check if BUSY_STAT should be set */ s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->bus->dma->ops->start_dma(s->bus->dma, s, @@ -546,13 +557,13 @@ static void cmd_get_event_status_notification(IDEState *s, uint8_t reserved3[2]; uint16_t len; uint8_t control; - } __attribute__((packed)) *gesn_cdb; + } QEMU_PACKED *gesn_cdb; struct { uint16_t len; uint8_t notification_class; uint8_t supported_events; - } __attribute((packed)) *gesn_event_header; + } QEMU_PACKED *gesn_event_header; enum notification_class_request_type { NCR_RESERVED1 = 1 << 0, diff --git a/hw/ide/core.c b/hw/ide/core.c index d145b19b0c..40abc1edd2 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -473,7 +473,10 @@ void ide_sector_read(IDEState *s) #endif if (n > s->req_nb_sectors) n = s->req_nb_sectors; + + bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); + bdrv_acct_done(s->bs, &s->acct); if (ret != 0) { if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ)) @@ -610,7 +613,10 @@ handle_rw_error: return; eot: - ide_set_inactive(s); + if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { + bdrv_acct_done(s->bs, &s->acct); + } + ide_set_inactive(s); } static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) @@ -619,6 +625,20 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) s->io_buffer_index = 0; s->io_buffer_size = 0; s->dma_cmd = dma_cmd; + + switch (dma_cmd) { + case IDE_DMA_READ: + bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, + BDRV_ACCT_READ); + break; + case IDE_DMA_WRITE: + bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, + BDRV_ACCT_WRITE); + break; + default: + break; + } + s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb); } @@ -641,7 +661,10 @@ void ide_sector_write(IDEState *s) n = s->nsector; if (n > s->req_nb_sectors) n = s->req_nb_sectors; + + bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); + bdrv_acct_done(s->bs, &s->acct); if (ret != 0) { if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY)) @@ -685,6 +708,7 @@ static void ide_flush_cb(void *opaque, int ret) } } + bdrv_acct_done(s->bs, &s->acct); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); } @@ -698,6 +722,7 @@ void ide_flush_cache(IDEState *s) return; } + bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH); acb = bdrv_aio_flush(s->bs, ide_flush_cb, s); if (acb == NULL) { ide_flush_cb(s, -EIO); diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 02e805f070..7f5ef8de1d 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -440,6 +440,7 @@ struct IDEState { int lba; int cd_sector_size; int atapi_dma; /* true if dma is requested for the packet cmd */ + BlockAcctCookie acct; /* ATA DMA state */ int io_buffer_size; QEMUSGList sg; diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 44fb3fef60..fdf5d75082 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -52,8 +52,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); - io->dma_end(opaque); - return; + goto done; } if (s->io_buffer_size > 0) { @@ -71,8 +70,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) ide_atapi_cmd_ok(s); if (io->len == 0) { - io->dma_end(opaque); - return; + goto done; } /* launch next transfer */ @@ -92,9 +90,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) /* Note: media not present is the most likely case */ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - io->dma_end(opaque); - return; + goto done; } + return; + +done: + bdrv_acct_done(s->bs, &s->acct); + io->dma_end(opaque); + return; } static void pmac_ide_transfer_cb(void *opaque, int ret) @@ -109,8 +112,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); - io->dma_end(io); - return; + goto done; } sector_num = ide_get_sector(s); @@ -130,10 +132,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) } /* end of DMA ? */ - if (io->len == 0) { - io->dma_end(io); - return; + goto done; } /* launch next transfer */ @@ -163,6 +163,12 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) if (!m->aiocb) pmac_ide_transfer_cb(io, -1); + return; +done: + if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { + bdrv_acct_done(s->bs, &s->acct); + } + io->dma_end(io); } static void pmac_ide_transfer(DBDMA_io *io) @@ -172,10 +178,22 @@ static void pmac_ide_transfer(DBDMA_io *io) s->io_buffer_size = 0; if (s->drive_kind == IDE_CD) { + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); pmac_ide_atapi_transfer_cb(io, 0); return; } + switch (s->dma_cmd) { + case IDE_DMA_READ: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); + break; + case IDE_DMA_WRITE: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); + break; + default: + break; + } + pmac_ide_transfer_cb(io, 0); } diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 3c8982ea29..281410899f 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -13,13 +13,11 @@ #include "boards.h" #include "arm-misc.h" #include "net.h" -#include "exec-memory.h" typedef struct { SysBusDevice busdev; uint32_t memsz; - MemoryRegion flash; - bool flash_mapped; + uint32_t flash_offset; uint32_t cm_osc; uint32_t cm_ctrl; uint32_t cm_lock; @@ -110,15 +108,9 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset) static void integratorcm_do_remap(integratorcm_state *s, int flash) { if (flash) { - if (s->flash_mapped) { - sysbus_del_memory(&s->busdev, &s->flash); - s->flash_mapped = false; - } + cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM); } else { - if (!s->flash_mapped) { - sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1); - s->flash_mapped = true; - } + cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM); } //??? tlb_flush (cpu_single_env, 1); } @@ -260,8 +252,7 @@ static int integratorcm_init(SysBusDevice *dev) } memcpy(integrator_spd + 73, "QEMU-MEMORY", 11); s->cm_init = 0x00000112; - memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000); - s->flash_mapped = false; + s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000); iomemtype = cpu_register_io_memory(integratorcm_readfn, integratorcm_writefn, s, @@ -465,9 +456,7 @@ static void integratorcp_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *ram_alias = g_new(MemoryRegion, 1); + ram_addr_t ram_offset; qemu_irq pic[32]; qemu_irq *cpu_pic; DeviceState *dev; @@ -480,14 +469,13 @@ static void integratorcp_init(ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - memory_region_init_ram(ram, NULL, "integrator.ram", ram_size); + ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size); /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */ /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero*/ - memory_region_add_subregion(address_space_mem, 0, ram); + cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); /* And again at address 0x80000000 */ - memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size); - memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias); + cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM); dev = qdev_create(NULL, "integrator_core"); qdev_prop_set_uint32(dev, "memsz", ram_size >> 20); diff --git a/hw/leon3.c b/hw/leon3.c index 607ec852fe..a62a9419f3 100644 --- a/hw/leon3.c +++ b/hw/leon3.c @@ -29,7 +29,6 @@ #include "loader.h" #include "elf.h" #include "trace.h" -#include "exec-memory.h" #include "grlib.h" @@ -101,9 +100,7 @@ static void leon3_generic_hw_init(ram_addr_t ram_size, const char *cpu_model) { CPUState *env; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *prom = g_new(MemoryRegion, 1); + ram_addr_t ram_offset, prom_offset; int ret; char *filename; qemu_irq *cpu_irqs = NULL; @@ -142,14 +139,14 @@ static void leon3_generic_hw_init(ram_addr_t ram_size, exit(1); } - memory_region_init_ram(ram, NULL, "leon3.ram", ram_size); - memory_region_add_subregion(address_space_mem, 0x40000000, ram); + ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size); + cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM); /* Allocate BIOS */ prom_size = 8 * 1024 * 1024; /* 8Mb */ - memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size); - memory_region_set_readonly(prom, true); - memory_region_add_subregion(address_space_mem, 0x00000000, prom); + prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size); + cpu_register_physical_memory(0x00000000, prom_size, + prom_offset | IO_MEM_ROM); /* Load boot prom */ if (bios_name == NULL) { diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c index a84007b0ed..d18aad7435 100644 --- a/hw/lm32_boards.c +++ b/hw/lm32_boards.c @@ -28,7 +28,6 @@ #include "elf.h" #include "lm32_hwsetup.h" #include "lm32.h" -#include "exec-memory.h" typedef struct { CPUState *env; @@ -77,9 +76,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used, { CPUState *env; DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *phys_ram = g_new(MemoryRegion, 1); - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_ram; + ram_addr_t phys_flash; qemu_irq *cpu_irq, irq[32]; ResetInfo *reset_info; int i; @@ -107,17 +105,16 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used, reset_info->flash_base = flash_base; - memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size); - memory_region_add_subregion(address_space_mem, ram_base, phys_ram); + phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size); + cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be, - NULL, "lm32_evr.flash", flash_size); + phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size); dinfo = drive_get(IF_PFLASH, 0, 0); /* Spansion S29NS128P */ pflash_cfi02_register(flash_base, phys_flash, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, - 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa); + 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); @@ -167,9 +164,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used, { CPUState *env; DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *phys_ram = g_new(MemoryRegion, 1); - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_ram; + ram_addr_t phys_flash; qemu_irq *cpu_irq, irq[32]; HWSetup *hw; ResetInfo *reset_info; @@ -204,17 +200,16 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used, reset_info->flash_base = flash_base; - memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size); - memory_region_add_subregion(address_space_mem, ram_base, phys_ram); + phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size); + cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be, - NULL, "lm32_uclinux.flash", flash_size); + phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size); dinfo = drive_get(IF_PFLASH, 0, 0); /* Spansion S29NS128P */ pflash_cfi02_register(flash_base, phys_flash, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, - 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa); + 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); diff --git a/hw/mainstone.c b/hw/mainstone.c index 82e957149d..4792f0e3ed 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -17,7 +17,6 @@ #include "flash.h" #include "blockdev.h" #include "sysbus.h" -#include "exec-memory.h" /* Device addresses */ #define MST_FPGA_PHYS 0x08000000 @@ -91,8 +90,7 @@ static struct arm_boot_info mainstone_binfo = { .ram_size = 0x04000000, }; -static void mainstone_common_init(MemoryRegion *address_space_mem, - ram_addr_t ram_size, +static void mainstone_common_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum mainstone_model_e model, int arm_id) @@ -103,23 +101,21 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, DeviceState *mst_irq; DriveInfo *dinfo; int i; - MemoryRegion *rom = g_new(MemoryRegion, 1); - MemoryRegion *flashes = g_new(MemoryRegion, 2); - const MemoryRegionOps *flash_ops; + int be; if (!cpu_model) cpu_model = "pxa270-c5"; /* Setup CPU & memory */ cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model); - memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM); - memory_region_set_readonly(rom, true); - memory_region_add_subregion(address_space_mem, 0, rom); + cpu_register_physical_memory(0, MAINSTONE_ROM, + qemu_ram_alloc(NULL, "mainstone.rom", + MAINSTONE_ROM) | IO_MEM_ROM); #ifdef TARGET_WORDS_BIGENDIAN - flash_ops = &pflash_cfi01_ops_be; + be = 1; #else - flash_ops = &pflash_cfi01_ops_le; + be = 0; #endif /* There are two 32MiB flash devices on the board */ for (i = 0; i < 2; i ++) { @@ -130,14 +126,13 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, exit(1); } - memory_region_init_rom_device(&flashes[i], flash_ops, - NULL, (i ? "mainstone.flash1" - : "mainstone.flash0"), - MAINSTONE_FLASH); if (!pflash_cfi01_register(mainstone_flash_base[i], - &flashes[i], dinfo->bdrv, sector_len, - MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, - 0)) { + qemu_ram_alloc(NULL, i ? "mainstone.flash1" : + "mainstone.flash0", + MAINSTONE_FLASH), + dinfo->bdrv, sector_len, + MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0, + be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); exit(1); } @@ -175,7 +170,7 @@ static void mainstone_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - mainstone_common_init(get_system_memory(), ram_size, kernel_filename, + mainstone_common_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196); } diff --git a/hw/mcf5208.c b/hw/mcf5208.c index 1c2c0c48aa..8fe507f82f 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -13,7 +13,6 @@ #include "boards.h" #include "loader.h" #include "elf.h" -#include "exec-memory.h" #define SYS_FREQ 66000000 @@ -28,7 +27,6 @@ #define PCSR_PRE_MASK 0x0f00 typedef struct { - MemoryRegion iomem; qemu_irq irq; ptimer_state *timer; uint16_t pcsr; @@ -45,7 +43,7 @@ static void m5208_timer_update(m5208_timer_state *s) } static void m5208_timer_write(void *opaque, target_phys_addr_t offset, - uint64_t value, unsigned size) + uint32_t value) { m5208_timer_state *s = (m5208_timer_state *)opaque; int prescale; @@ -106,8 +104,7 @@ static void m5208_timer_trigger(void *opaque) m5208_timer_update(s); } -static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr, - unsigned size) +static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr) { m5208_timer_state *s = (m5208_timer_state *)opaque; switch (addr) { @@ -123,14 +120,19 @@ static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr, } } -static const MemoryRegionOps m5208_timer_ops = { - .read = m5208_timer_read, - .write = m5208_timer_write, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUReadMemoryFunc * const m5208_timer_readfn[] = { + m5208_timer_read, + m5208_timer_read, + m5208_timer_read }; -static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr, - unsigned size) +static CPUWriteMemoryFunc * const m5208_timer_writefn[] = { + m5208_timer_write, + m5208_timer_write, + m5208_timer_write +}; + +static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr) { switch (addr) { case 0x110: /* SDCS0 */ @@ -152,36 +154,45 @@ static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr, } static void m5208_sys_write(void *opaque, target_phys_addr_t addr, - uint64_t value, unsigned size) + uint32_t value) { hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr); } -static const MemoryRegionOps m5208_sys_ops = { - .read = m5208_sys_read, - .write = m5208_sys_write, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUReadMemoryFunc * const m5208_sys_readfn[] = { + m5208_sys_read, + m5208_sys_read, + m5208_sys_read +}; + +static CPUWriteMemoryFunc * const m5208_sys_writefn[] = { + m5208_sys_write, + m5208_sys_write, + m5208_sys_write }; -static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic) +static void mcf5208_sys_init(qemu_irq *pic) { - MemoryRegion *iomem = g_new(MemoryRegion, 1); + int iomemtype; m5208_timer_state *s; QEMUBH *bh; int i; + iomemtype = cpu_register_io_memory(m5208_sys_readfn, + m5208_sys_writefn, NULL, + DEVICE_NATIVE_ENDIAN); /* SDRAMC. */ - memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000); - memory_region_add_subregion(address_space, 0xfc0a8000, iomem); + cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype); /* Timers. */ for (i = 0; i < 2; i++) { s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state)); bh = qemu_bh_new(m5208_timer_trigger, s); s->timer = ptimer_init(bh); - memory_region_init_io(&s->iomem, &m5208_timer_ops, s, - "m5208-timer", 0x00004000); - memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i, - &s->iomem); + iomemtype = cpu_register_io_memory(m5208_timer_readfn, + m5208_timer_writefn, s, + DEVICE_NATIVE_ENDIAN); + cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000, + iomemtype); s->irq = pic[4 + i]; } } @@ -196,9 +207,6 @@ static void mcf5208evb_init(ram_addr_t ram_size, uint64_t elf_entry; target_phys_addr_t entry; qemu_irq *pic; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *sram = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "m5208"; @@ -213,12 +221,12 @@ static void mcf5208evb_init(ram_addr_t ram_size, /* TODO: Configure BARs. */ /* DRAM at 0x40000000 */ - memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size); - memory_region_add_subregion(address_space_mem, 0x40000000, ram); + cpu_register_physical_memory(0x40000000, ram_size, + qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM); /* Internal SRAM. */ - memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384); - memory_region_add_subregion(address_space_mem, 0x80000000, sram); + cpu_register_physical_memory(0x80000000, 16384, + qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM); /* Internal peripherals. */ pic = mcf_intc_init(0xfc048000, env); @@ -227,7 +235,7 @@ static void mcf5208evb_init(ram_addr_t ram_size, mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]); mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]); - mcf5208_sys_init(address_space_mem, pic); + mcf5208_sys_init(pic); if (nb_nics > 1) { fprintf(stderr, "Too many NICs\n"); diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c index fb48e37187..cd360264c1 100644 --- a/hw/milkymist-minimac2.c +++ b/hw/milkymist-minimac2.c @@ -97,8 +97,6 @@ struct MilkymistMinimac2State { NICConf conf; char *phy_model; target_phys_addr_t buffers_base; - MemoryRegion buffers; - MemoryRegion regs_region; qemu_irq rx_irq; qemu_irq tx_irq; @@ -322,8 +320,8 @@ static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size) return size; } -static uint64_t -minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size) +static uint32_t +minimac2_read(void *opaque, target_phys_addr_t addr) { MilkymistMinimac2State *s = opaque; uint32_t r = 0; @@ -352,8 +350,7 @@ minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size) } static void -minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value, - unsigned size) +minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value) { MilkymistMinimac2State *s = opaque; @@ -398,14 +395,16 @@ minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value, } } -static const MemoryRegionOps minimac2_ops = { - .read = minimac2_read, - .write = minimac2_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUReadMemoryFunc * const minimac2_read_fn[] = { + NULL, + NULL, + &minimac2_read, +}; + +static CPUWriteMemoryFunc * const minimac2_write_fn[] = { + NULL, + NULL, + &minimac2_write, }; static int minimac2_can_rx(VLANClientState *nc) @@ -458,23 +457,25 @@ static NetClientInfo net_milkymist_minimac2_info = { static int milkymist_minimac2_init(SysBusDevice *dev) { MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev); + int regs; + ram_addr_t buffers; size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE); sysbus_init_irq(dev, &s->rx_irq); sysbus_init_irq(dev, &s->tx_irq); - memory_region_init_io(&s->regs_region, &minimac2_ops, s, - "minimac2-mmio", R_MAX * 4); - sysbus_init_mmio_region(dev, &s->regs_region); + regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s, + DEVICE_NATIVE_ENDIAN); + sysbus_init_mmio(dev, R_MAX * 4, regs); /* register buffers memory */ - memory_region_init_ram(&s->buffers, NULL, "milkymist_minimac2.buffers", - buffers_size); - s->rx0_buf = memory_region_get_ram_ptr(&s->buffers); + buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size); + s->rx0_buf = qemu_get_ram_ptr(buffers); s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE; s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE; - sysbus_add_memory(dev, s->buffers_base, &s->buffers); + cpu_register_physical_memory(s->buffers_base, buffers_size, + buffers | IO_MEM_RAM); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf, diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c index ef4d9ee2ce..fe4eedb2cb 100644 --- a/hw/milkymist-softusb.c +++ b/hw/milkymist-softusb.c @@ -49,9 +49,6 @@ struct MilkymistSoftUsbState { HIDState hid_kbd; HIDState hid_mouse; - MemoryRegion regs_region; - MemoryRegion pmem; - MemoryRegion dmem; qemu_irq irq; /* device properties */ @@ -71,8 +68,7 @@ struct MilkymistSoftUsbState { }; typedef struct MilkymistSoftUsbState MilkymistSoftUsbState; -static uint64_t softusb_read(void *opaque, target_phys_addr_t addr, - unsigned size) +static uint32_t softusb_read(void *opaque, target_phys_addr_t addr) { MilkymistSoftUsbState *s = opaque; uint32_t r = 0; @@ -95,8 +91,7 @@ static uint64_t softusb_read(void *opaque, target_phys_addr_t addr, } static void -softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value, - unsigned size) +softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value) { MilkymistSoftUsbState *s = opaque; @@ -115,14 +110,16 @@ softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value, } } -static const MemoryRegionOps softusb_mmio_ops = { - .read = softusb_read, - .write = softusb_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, +static CPUReadMemoryFunc * const softusb_read_fn[] = { + NULL, + NULL, + &softusb_read, +}; + +static CPUWriteMemoryFunc * const softusb_write_fn[] = { + NULL, + NULL, + &softusb_write, }; static inline void softusb_read_dmem(MilkymistSoftUsbState *s, @@ -259,20 +256,23 @@ static void milkymist_softusb_reset(DeviceState *d) static int milkymist_softusb_init(SysBusDevice *dev) { MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev); + int softusb_regs; + ram_addr_t pmem_ram; + ram_addr_t dmem_ram; sysbus_init_irq(dev, &s->irq); - memory_region_init_io(&s->regs_region, &softusb_mmio_ops, s, - "milkymist-softusb", R_MAX * 4); - sysbus_init_mmio_region(dev, &s->regs_region); + softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s, + DEVICE_NATIVE_ENDIAN); + sysbus_init_mmio(dev, R_MAX * 4, softusb_regs); /* register pmem and dmem */ - memory_region_init_ram(&s->pmem, NULL, "milkymist_softusb.pmem", - s->pmem_size); - sysbus_add_memory(dev, s->pmem_base, &s->pmem); - memory_region_init_ram(&s->dmem, NULL, "milkymist_softusb.dmem", - s->dmem_size); - sysbus_add_memory(dev, s->dmem_base, &s->dmem); + pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size); + cpu_register_physical_memory(s->pmem_base, s->pmem_size, + pmem_ram | IO_MEM_RAM); + dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size); + cpu_register_physical_memory(s->dmem_base, s->dmem_size, + dmem_ram | IO_MEM_RAM); hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain); hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain); diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c index 790cdcb41c..953d42f16b 100644 --- a/hw/milkymist-tmu2.c +++ b/hw/milkymist-tmu2.c @@ -73,7 +73,7 @@ enum { struct vertex { int x; int y; -} __attribute__((packed)); +} QEMU_PACKED; struct MilkymistTMU2State { SysBusDevice busdev; diff --git a/hw/milkymist.c b/hw/milkymist.c index ef21ccaba1..93288c8401 100644 --- a/hw/milkymist.c +++ b/hw/milkymist.c @@ -29,7 +29,6 @@ #include "blockdev.h" #include "milkymist-hw.h" #include "lm32.h" -#include "exec-memory.h" #define BIOS_FILENAME "mmone-bios.bin" #define BIOS_OFFSET 0x00860000 @@ -82,9 +81,8 @@ milkymist_init(ram_addr_t ram_size_not_used, CPUState *env; int kernel_size; DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *phys_sdram = g_new(MemoryRegion, 1); - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_sdram; + ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; int i; char *bios_filename; @@ -111,17 +109,17 @@ milkymist_init(ram_addr_t ram_size_not_used, cpu_lm32_set_phys_msb_ignore(env, 1); - memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size); - memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram); + phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size); + cpu_register_physical_memory(sdram_base, sdram_size, + phys_sdram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be, - NULL, "milkymist.flash", flash_size); + phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size); dinfo = drive_get(IF_PFLASH, 0, 0); /* Numonyx JS28F256J3F105 */ pflash_cfi01_register(flash_base, phys_flash, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 2, - 0x00, 0x89, 0x00, 0x1d); + 0x00, 0x89, 0x00, 0x1d, 1); /* create irq lines */ cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); diff --git a/hw/mips.h b/hw/mips.h index 97d7b9e5ad..8ce41fc4be 100644 --- a/hw/mips.h +++ b/hw/mips.h @@ -2,19 +2,12 @@ #define HW_MIPS_H /* Definitions for mips board emulation. */ -#include "memory.h" - /* gt64xxx.c */ PCIBus *gt64120_register(qemu_irq *pic); /* bonito.c */ PCIBus *bonito_init(qemu_irq *pic); -/* g364fb.c */ -int g364fb_mm_init(MemoryRegion *system_memory, target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift, - qemu_irq irq); - /* mipsnet.c */ void mipsnet_init(int base, qemu_irq irq, NICInfo *nd); diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index a74108646c..f3c9f93204 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -195,8 +195,20 @@ void mips_jazz_init (ram_addr_t ram_size, /* Video card */ switch (jazz_model) { case JAZZ_MAGNUM: - g364fb_mm_init(get_system_memory(), 0x40000000, 0x60000000, 0, - rc4030[3]); + dev = qdev_create(NULL, "sysbus-g364"); + qdev_init_nofail(dev); + sysbus = sysbus_from_qdev(dev); + sysbus_mmio_map(sysbus, 0, 0x60080000); + sysbus_mmio_map(sysbus, 1, 0x40000000); + sysbus_connect_irq(sysbus, 0, rc4030[3]); + { + /* Simple ROM, so user doesn't have to provide one */ + ram_addr_t rom_offset = qemu_ram_alloc(NULL, "g364fb.rom", 0x80000); + uint8_t *rom = qemu_get_ram_ptr(rom_offset); + cpu_register_physical_memory(0x60000000, 0x80000, + rom_offset | IO_MEM_ROM); + rom[0] = 0x10; /* Mips G364 */ + } break; case JAZZ_PICA61: isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory()); diff --git a/hw/mips_malta.c b/hw/mips_malta.c index b5c9bcfa51..a0adb566ab 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -46,7 +46,6 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" -#include "exec-memory.h" //#define DEBUG_BOARD_INIT @@ -733,6 +732,12 @@ static int64_t load_kernel (void) return kernel_entry; } +static void malta_mips_config(CPUState *env) +{ + env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | + ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC); +} + static void main_cpu_reset(void *opaque) { CPUState *env = opaque; @@ -744,6 +749,8 @@ static void main_cpu_reset(void *opaque) if (loaderparams.kernel_filename) { env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); } + + malta_mips_config(env); } static void cpu_request_exit(void *opaque, int irq, int level) @@ -763,10 +770,7 @@ void mips_malta_init (ram_addr_t ram_size, { char *filename; ram_addr_t ram_offset; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *bios = g_new(MemoryRegion, 1); - MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1); - MemoryRegion *bios_1fc = g_new(MemoryRegion, 1); + ram_addr_t bios_offset; target_long bios_size; int64_t kernel_entry; PCIBus *pci_bus; @@ -781,7 +785,7 @@ void mips_malta_init (ram_addr_t ram_size, DriveInfo *fd[MAX_FD]; int fl_idx = 0; int fl_sectors = 0; - const MemoryRegionOps *bios_ops; + int be; /* Make sure the first 3 serial ports are associated with a device. */ for(i = 0; i < 3; i++) { @@ -800,12 +804,19 @@ void mips_malta_init (ram_addr_t ram_size, cpu_model = "24Kf"; #endif } - env = cpu_init(cpu_model); - if (!env) { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); + + for (i = 0; i < smp_cpus; i++) { + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + /* Init internal devices */ + cpu_mips_irq_init_cpu(env); + cpu_mips_clock_init(env); + qemu_register_reset(main_cpu_reset, env); } - qemu_register_reset(main_cpu_reset, env); + env = first_cpu; /* allocate RAM */ if (ram_size > (256 << 20)) { @@ -814,24 +825,23 @@ void mips_malta_init (ram_addr_t ram_size, ((unsigned int)ram_size / (1 << 20))); exit(1); } -#ifdef TARGET_WORDS_BIGENDIAN - bios_ops = &pflash_cfi01_ops_be; -#else - bios_ops = &pflash_cfi01_ops_le; -#endif - ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size); - memory_region_init_rom_device(bios, bios_ops, NULL, - "mips_malta.bios", BIOS_SIZE); + bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE); + cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); /* Map the bios at two physical locations, as on the real board. */ - memory_region_init_alias(bios_1e0, "bios-1e0", bios, 0, BIOS_SIZE); - memory_region_add_subregion(address_space_mem, 0x1e000000LL, bios_1e0); - memory_region_init_alias(bios_1fc, "bios-1fc", bios, 0, BIOS_SIZE); - memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios_1fc); + cpu_register_physical_memory(0x1e000000LL, + BIOS_SIZE, bios_offset | IO_MEM_ROM); + cpu_register_physical_memory(0x1fc00000LL, + BIOS_SIZE, bios_offset | IO_MEM_ROM); +#ifdef TARGET_WORDS_BIGENDIAN + be = 1; +#else + be = 0; +#endif /* FPGA */ malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]); @@ -843,7 +853,7 @@ void mips_malta_init (ram_addr_t ram_size, loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); - write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); + write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry); } else { dinfo = drive_get(IF_PFLASH, 0, fl_idx); if (dinfo) { @@ -852,13 +862,13 @@ void mips_malta_init (ram_addr_t ram_size, fl_sectors = bios_size >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size " TARGET_FMT_lx " at " - "addr %08llx '%s' %x\n", - fl_idx, bios_size, 0x1e000000LL, + "offset %08lx addr %08llx '%s' %x\n", + fl_idx, bios_size, bios_offset, 0x1e000000LL, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi01_register(0x1e000000LL, bios, + pflash_cfi01_register(0x1e000000LL, bios_offset, dinfo->bdrv, 65536, fl_sectors, - 4, 0x0000, 0x0000, 0x0000, 0x0000); + 4, 0x0000, 0x0000, 0x0000, 0x0000, be); fl_idx++; } else { /* Load a BIOS image. */ @@ -883,7 +893,7 @@ void mips_malta_init (ram_addr_t ram_size, a neat trick which allows bi-endian firmware. */ #ifndef TARGET_WORDS_BIGENDIAN { - uint32_t *addr = memory_region_get_ram_ptr(bios); + uint32_t *addr = qemu_get_ram_ptr(bios_offset);; uint32_t *end = addr + bios_size; while (addr < end) { bswap32s(addr); @@ -895,7 +905,7 @@ void mips_malta_init (ram_addr_t ram_size, /* Board ID = 0x420 (Malta Board with CoreLV) XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should map to the board ID. */ - stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420); + stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420); /* Init internal devices */ cpu_mips_irq_init_cpu(env); @@ -960,6 +970,7 @@ static QEMUMachine mips_malta_machine = { .name = "malta", .desc = "MIPS Malta Core LV", .init = mips_malta_init, + .max_cpus = 16, .is_default = 1, }; diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index 51dc8684be..9d90568e4e 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -23,7 +23,6 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" -#include "exec-memory.h" #define MAX_IDE_BUS 2 @@ -164,8 +163,7 @@ void mips_r4k_init (ram_addr_t ram_size, { char *filename; ram_addr_t ram_offset; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *bios = g_new(MemoryRegion, 1); + ram_addr_t bios_offset; int bios_size; CPUState *env; ResetData *reset_info; @@ -229,20 +227,18 @@ void mips_r4k_init (ram_addr_t ram_size, be = 0; #endif if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { - memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE); - memory_region_set_readonly(bios, true); - memory_region_add_subregion(address_space_mem, 0x1fc00000, bios); + bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE); + cpu_register_physical_memory(0x1fc00000, BIOS_SIZE, + bios_offset | IO_MEM_ROM); + load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { uint32_t mips_rom = 0x00400000; - memory_region_init_rom_device(bios, - (be ? &pflash_cfi01_ops_be - : &pflash_cfi01_ops_le), - NULL, "mips_r4k.bios", mips_rom); - if (!pflash_cfi01_register(0x1fc00000, bios, + bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom); + if (!pflash_cfi01_register(0x1fc00000, bios_offset, dinfo->bdrv, sector_len, mips_rom / sector_len, - 4, 0, 0, 0, 0)) { + 4, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); } } diff --git a/hw/musicpal.c b/hw/musicpal.c index 5e74ee7fd7..63dd391176 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1502,7 +1502,6 @@ static void musicpal_init(ram_addr_t ram_size, unsigned long flash_size; DriveInfo *dinfo; ram_addr_t sram_off; - MemoryRegion *flash = g_new(MemoryRegion, 1); if (!cpu_model) { cpu_model = "arm926"; @@ -1566,23 +1565,21 @@ static void musicpal_init(ram_addr_t ram_size, * image is smaller than 32 MB. */ #ifdef TARGET_WORDS_BIGENDIAN - memory_region_init_rom_device(flash, &pflash_cfi02_ops_be, - NULL, "musicpal.flash", flash_size); - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash, + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, + "musicpal.flash", flash_size), dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, 2, 0x00BF, 0x236D, 0x0000, 0x0000, - 0x5555, 0x2AAA); + 0x5555, 0x2AAA, 1); #else - memory_region_init_rom_device(flash, &pflash_cfi02_ops_le, - NULL, "musicpal.flash", flash_size); - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash, + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, + "musicpal.flash", flash_size), dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, 2, 0x00BF, 0x236D, 0x0000, 0x0000, - 0x5555, 0x2AAA); + 0x5555, 0x2AAA, 0); #endif } diff --git a/hw/nseries.c b/hw/nseries.c index f7aae7a59e..af287dd6dc 100644 --- a/hw/nseries.c +++ b/hw/nseries.c @@ -32,7 +32,7 @@ #include "bt.h" #include "loader.h" #include "blockdev.h" -#include "tusb6010.h" +#include "sysbus.h" /* Nokia N8x0 support */ struct n800_s { @@ -49,10 +49,10 @@ struct n800_s { int keymap[0x80]; DeviceState *kbd; - TUSBState *usb; + DeviceState *usb; void *retu; void *tahvo; - void *nand; + DeviceState *nand; }; /* GPIO pins */ @@ -167,13 +167,21 @@ static void n8x0_nand_setup(struct n800_s *s) char *otp_region; DriveInfo *dinfo; - dinfo = drive_get(IF_MTD, 0, 0); + s->nand = qdev_create(NULL, "onenand"); + qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG); /* Either 0x40 or 0x48 are OK for the device ID */ - s->nand = onenand_init(dinfo ? dinfo->bdrv : 0, - NAND_MFR_SAMSUNG, 0x48, 0, 1, - qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO)); - omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update, - onenand_base_unmap, s->nand); + qdev_prop_set_uint16(s->nand, "device_id", 0x48); + qdev_prop_set_uint16(s->nand, "version_id", 0); + qdev_prop_set_int32(s->nand, "shift", 1); + dinfo = drive_get(IF_MTD, 0, 0); + if (dinfo && dinfo->bdrv) { + qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv); + } + qdev_init_nofail(s->nand); + sysbus_connect_irq(sysbus_from_qdev(s->nand), 0, + qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO)); + omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, + sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0)); otp_region = onenand_raw_otp(s->nand); memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac)); @@ -756,27 +764,21 @@ static void n8x0_uart_setup(struct n800_s *s) omap_uart_attach(s->cpu->uart[BT_UART], radio); } -static void n8x0_usb_power_cb(void *opaque, int line, int level) -{ - struct n800_s *s = opaque; - - tusb6010_power(s->usb, level); -} - static void n8x0_usb_setup(struct n800_s *s) { - qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO); - qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0]; - TUSBState *tusb = tusb6010_init(tusb_irq); - + SysBusDevice *dev; + s->usb = qdev_create(NULL, "tusb6010"); + dev = sysbus_from_qdev(s->usb); + qdev_init_nofail(s->usb); + sysbus_connect_irq(dev, 0, + qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO)); /* Using the NOR interface */ omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS, - tusb6010_async_io(tusb), NULL, NULL, tusb); + sysbus_mmio_get_region(dev, 0)); omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS, - tusb6010_sync_io(tusb), NULL, NULL, tusb); - - s->usb = tusb; - qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr); + sysbus_mmio_get_region(dev, 1)); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, + qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */ } /* Setup done before the main bootloader starts by some early setup code diff --git a/hw/omap.h b/hw/omap.h index db101c61f3..d9ab006ae0 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -118,11 +118,12 @@ void omap_sdrc_reset(struct omap_sdrc_s *s); /* OMAP2 general purpose memory controller */ struct omap_gpmc_s; -struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq); +struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu, + target_phys_addr_t base, + qemu_irq irq, qemu_irq drq); void omap_gpmc_reset(struct omap_gpmc_s *s); -void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem, - void (*base_upd)(void *opaque, target_phys_addr_t new), - void (*unmap)(void *opaque), void *opaque); +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem); +void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand); /* * Common IRQ numbers for level 1 interrupt handler @@ -788,6 +789,7 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); # define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420) # define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430) # define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430) +# define cpu_is_omap3630(cpu) (cpu->mpu_model == omap3630) # define cpu_is_omap15xx(cpu) \ (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu)) @@ -799,7 +801,8 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); # define cpu_class_omap1(cpu) \ (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu)) # define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu) -# define cpu_class_omap3(cpu) cpu_is_omap3430(cpu) +# define cpu_class_omap3(cpu) \ + (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu)) struct omap_mpu_state_s { enum omap_mpu_model { @@ -813,6 +816,7 @@ struct omap_mpu_state_s { omap2423, omap2430, omap3430, + omap3630, } mpu_model; CPUState *env; diff --git a/hw/omap2.c b/hw/omap2.c index 7e5820a97b..ca088d9f53 100644 --- a/hw/omap2.c +++ b/hw/omap2.c @@ -2402,7 +2402,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5)); s->sdrc = omap_sdrc_init(0x68009000); - s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]); + s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ], + s->drq[OMAP24XX_DMA_GPMC]); dinfo = drive_get(IF_SD, 0, 0); if (!dinfo) { diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c index 673dddd237..02f0c52107 100644 --- a/hw/omap_gpmc.c +++ b/hw/omap_gpmc.c @@ -27,82 +27,410 @@ /* General-Purpose Memory Controller */ struct omap_gpmc_s { qemu_irq irq; + qemu_irq drq; MemoryRegion iomem; + int accept_256; + uint8_t revision; uint8_t sysconfig; uint16_t irqst; uint16_t irqen; + uint16_t lastirq; uint16_t timeout; uint16_t config; - uint32_t prefconfig[2]; - int prefcontrol; - int preffifo; - int prefcount; struct omap_gpmc_cs_file_s { uint32_t config[7]; - target_phys_addr_t base; - size_t size; MemoryRegion *iomem; MemoryRegion container; - void (*base_update)(void *opaque, target_phys_addr_t new); - void (*unmap)(void *opaque); - void *opaque; + MemoryRegion nandiomem; + DeviceState *dev; } cs_file[8]; int ecc_cs; int ecc_ptr; uint32_t ecc_cfg; ECCState ecc[9]; + struct prefetch { + uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */ + uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */ + int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */ + int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */ + int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */ + MemoryRegion iomem; + uint8_t fifo[64]; + } prefetch; }; +#define OMAP_GPMC_8BIT 0 +#define OMAP_GPMC_16BIT 1 +#define OMAP_GPMC_NOR 0 +#define OMAP_GPMC_NAND 2 + +static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f) +{ + return (f->config[0] >> 10) & 3; +} + +static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f) +{ + /* devsize field is really 2 bits but we ignore the high + * bit to ensure consistent behaviour if the guest sets + * it (values 2 and 3 are reserved in the TRM) + */ + return (f->config[0] >> 12) & 1; +} + +/* Extract the chip-select value from the prefetch config1 register */ +static int prefetch_cs(uint32_t config1) +{ + return (config1 >> 24) & 7; +} + +static int prefetch_threshold(uint32_t config1) +{ + return (config1 >> 8) & 0x7f; +} + static void omap_gpmc_int_update(struct omap_gpmc_s *s) { - qemu_set_irq(s->irq, s->irqen & s->irqst); + /* The TRM is a bit unclear, but it seems to say that + * the TERMINALCOUNTSTATUS bit is set only on the + * transition when the prefetch engine goes from + * active to inactive, whereas the FIFOEVENTSTATUS + * bit is held high as long as the fifo has at + * least THRESHOLD bytes available. + * So we do the latter here, but TERMINALCOUNTSTATUS + * is set elsewhere. + */ + if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) { + s->irqst |= 1; + } + if ((s->irqen & s->irqst) != s->lastirq) { + s->lastirq = s->irqen & s->irqst; + qemu_set_irq(s->irq, s->lastirq); + } } -static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask) +static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value) { - /* TODO: check for overlapping regions and report access errors */ - if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) || - (base < 0 || base >= 0x40) || - (base & 0x0f & ~mask)) { - fprintf(stderr, "%s: wrong cs address mapping/decoding!\n", - __FUNCTION__); + if (s->prefetch.config1 & 4) { + qemu_set_irq(s->drq, value); + } +} + +/* Access functions for when a NAND-like device is mapped into memory: + * all addresses in the region behave like accesses to the relevant + * GPMC_NAND_DATA_i register (which is actually implemented to call these) + */ +static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque; + uint64_t v; + nand_setpins(f->dev, 0, 0, 0, 1, 0); + switch (omap_gpmc_devsize(f)) { + case OMAP_GPMC_8BIT: + v = nand_getio(f->dev); + if (size == 1) { + return v; + } + v |= (nand_getio(f->dev) << 8); + if (size == 2) { + return v; + } + v |= (nand_getio(f->dev) << 16); + v |= (nand_getio(f->dev) << 24); + return v; + case OMAP_GPMC_16BIT: + v = nand_getio(f->dev); + if (size == 1) { + /* 8 bit read from 16 bit device : probably a guest bug */ + return v & 0xff; + } + if (size == 2) { + return v; + } + v |= (nand_getio(f->dev) << 16); + return v; + default: + abort(); + } +} + +static void omap_nand_setio(DeviceState *dev, uint64_t value, + int nandsize, int size) +{ + /* Write the specified value to the NAND device, respecting + * both size of the NAND device and size of the write access. + */ + switch (nandsize) { + case OMAP_GPMC_8BIT: + switch (size) { + case 1: + nand_setio(dev, value & 0xff); + break; + case 2: + nand_setio(dev, value & 0xff); + nand_setio(dev, (value >> 8) & 0xff); + break; + case 4: + default: + nand_setio(dev, value & 0xff); + nand_setio(dev, (value >> 8) & 0xff); + nand_setio(dev, (value >> 16) & 0xff); + nand_setio(dev, (value >> 24) & 0xff); + break; + } + case OMAP_GPMC_16BIT: + switch (size) { + case 1: + /* writing to a 16bit device with 8bit access is probably a guest + * bug; pass the value through anyway. + */ + case 2: + nand_setio(dev, value & 0xffff); + break; + case 4: + default: + nand_setio(dev, value & 0xffff); + nand_setio(dev, (value >> 16) & 0xffff); + break; + } + } +} + +static void omap_nand_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque; + nand_setpins(f->dev, 0, 0, 0, 1, 0); + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); +} + +static const MemoryRegionOps omap_nand_ops = { + .read = omap_nand_read, + .write = omap_nand_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void fill_prefetch_fifo(struct omap_gpmc_s *s) +{ + /* Fill the prefetch FIFO by reading data from NAND. + * We do this synchronously, unlike the hardware which + * will do this asynchronously. We refill when the + * FIFO has THRESHOLD bytes free, and we always refill + * as much data as possible starting at the top end + * of the FIFO. + * (We have to refill at THRESHOLD rather than waiting + * for the FIFO to empty to allow for the case where + * the FIFO size isn't an exact multiple of THRESHOLD + * and we're doing DMA transfers.) + * This means we never need to handle wrap-around in + * the fifo-reading code, and the next byte of data + * to read is always fifo[63 - fifopointer]. + */ + int fptr; + int cs = prefetch_cs(s->prefetch.config1); + int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0); + int bytes; + /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE + * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND. + * Instead believe the bit that says it is always a byte count. + */ + bytes = 64 - s->prefetch.fifopointer; + if (bytes > s->prefetch.count) { + bytes = s->prefetch.count; + } + s->prefetch.count -= bytes; + s->prefetch.fifopointer += bytes; + fptr = 64 - s->prefetch.fifopointer; + /* Move the existing data in the FIFO so it sits just + * before what we're about to read in + */ + while (fptr < (64 - bytes)) { + s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes]; + fptr++; + } + while (fptr < 64) { + if (is16bit) { + uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2); + s->prefetch.fifo[fptr++] = v & 0xff; + s->prefetch.fifo[fptr++] = (v >> 8) & 0xff; + } else { + s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1); + } + } + if (s->prefetch.startengine && (s->prefetch.count == 0)) { + /* This was the final transfer: raise TERMINALCOUNTSTATUS */ + s->irqst |= 2; + s->prefetch.startengine = 0; + } + /* If there are any bytes in the FIFO at this point then + * we must raise a DMA request (either this is a final part + * transfer, or we filled the FIFO in which case we certainly + * have THRESHOLD bytes available) + */ + if (s->prefetch.fifopointer != 0) { + omap_gpmc_dma_update(s, 1); + } + omap_gpmc_int_update(s); +} + +/* Access functions for a NAND-like device when the prefetch/postwrite + * engine is enabled -- all addresses in the region behave alike: + * data is read or written to the FIFO. + */ +static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; + uint32_t data; + if (s->prefetch.config1 & 1) { + /* The TRM doesn't define the behaviour if you read from the + * FIFO when the prefetch engine is in write mode. We choose + * to always return zero. + */ + return 0; + } + /* Note that trying to read an empty fifo repeats the last byte */ + if (s->prefetch.fifopointer) { + s->prefetch.fifopointer--; + } + data = s->prefetch.fifo[63 - s->prefetch.fifopointer]; + if (s->prefetch.fifopointer == + (64 - prefetch_threshold(s->prefetch.config1))) { + /* We've drained THRESHOLD bytes now. So deassert the + * DMA request, then refill the FIFO (which will probably + * assert it again.) + */ + omap_gpmc_dma_update(s, 0); + fill_prefetch_fifo(s); + } + omap_gpmc_int_update(s); + return data; +} + +static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; + int cs = prefetch_cs(s->prefetch.config1); + if ((s->prefetch.config1 & 1) == 0) { + /* The TRM doesn't define the behaviour of writing to the + * FIFO when the prefetch engine is in read mode. We + * choose to ignore the write. + */ + return; + } + if (s->prefetch.count == 0) { + /* The TRM doesn't define the behaviour of writing to the + * FIFO if the transfer is complete. We choose to ignore. + */ return; } + /* The only reason we do any data buffering in postwrite + * mode is if we are talking to a 16 bit NAND device, in + * which case we need to buffer the first byte of the + * 16 bit word until the other byte arrives. + */ + int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0); + if (is16bit) { + /* fifopointer alternates between 64 (waiting for first + * byte of word) and 63 (waiting for second byte) + */ + if (s->prefetch.fifopointer == 64) { + s->prefetch.fifo[0] = value; + s->prefetch.fifopointer--; + } else { + value = (value << 8) | s->prefetch.fifo[0]; + omap_nand_write(&s->cs_file[cs], 0, value, 2); + s->prefetch.count--; + s->prefetch.fifopointer = 64; + } + } else { + /* Just write the byte : fifopointer remains 64 at all times */ + omap_nand_write(&s->cs_file[cs], 0, value, 1); + s->prefetch.count--; + } + if (s->prefetch.count == 0) { + /* Final transfer: raise TERMINALCOUNTSTATUS */ + s->irqst |= 2; + s->prefetch.startengine = 0; + } + omap_gpmc_int_update(s); +} + +static const MemoryRegionOps omap_prefetch_ops = { + .read = omap_gpmc_prefetch_read, + .write = omap_gpmc_prefetch_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl.min_access_size = 1, + .impl.max_access_size = 1, +}; - if (!f->opaque) +static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs) +{ + /* Return the MemoryRegion* to map/unmap for this chipselect */ + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) { + return f->iomem; + } + if ((s->prefetch.config1 & 0x80) && + (prefetch_cs(s->prefetch.config1) == cs)) { + /* The prefetch engine is enabled for this CS: map the FIFO */ + return &s->prefetch.iomem; + } + return &f->nandiomem; +} + +static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs) +{ + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + uint32_t mask = (f->config[6] >> 8) & 0xf; + uint32_t base = f->config[6] & 0x3f; + uint32_t size; + + if (!f->iomem && !f->dev) { + return; + } + + if (!(f->config[6] & (1 << 6))) { + /* Do nothing unless CSVALID */ return; + } - f->base = base << 24; - f->size = (0x0fffffff & ~(mask << 24)) + 1; + /* TODO: check for overlapping regions and report access errors */ + if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf + && !(s->accept_256 && !mask)) { + fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n", + __func__, mask); + } + + base <<= 24; + size = (0x0fffffff & ~(mask << 24)) + 1; /* TODO: rather than setting the size of the mapping (which should be * constant), the mask should cause wrapping of the address space, so * that the same memory becomes accessible at every <i>size</i> bytes * starting from <i>base</i>. */ - if (f->iomem) { - memory_region_init(&f->container, "omap-gpmc-file", f->size); - memory_region_add_subregion(&f->container, 0, f->iomem); - memory_region_add_subregion(get_system_memory(), f->base, - &f->container); - } - - if (f->base_update) - f->base_update(f->opaque, f->base); + memory_region_init(&f->container, "omap-gpmc-file", size); + memory_region_add_subregion(&f->container, 0, + omap_gpmc_cs_memregion(s, cs)); + memory_region_add_subregion(get_system_memory(), base, + &f->container); } -static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f) +static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs) { - if (f->size) { - if (f->unmap) - f->unmap(f->opaque); - if (f->iomem) { - memory_region_del_subregion(get_system_memory(), &f->container); - memory_region_del_subregion(&f->container, f->iomem); - memory_region_destroy(&f->container); - } - f->base = 0; - f->size = 0; + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + if (!(f->config[6] & (1 << 6))) { + /* Do nothing unless CSVALID */ + return; + } + if (!f->iomem && !f->dev) { + return; } + memory_region_del_subregion(get_system_memory(), &f->container); + memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs)); + memory_region_destroy(&f->container); } void omap_gpmc_reset(struct omap_gpmc_s *s) @@ -115,25 +443,32 @@ void omap_gpmc_reset(struct omap_gpmc_s *s) omap_gpmc_int_update(s); s->timeout = 0; s->config = 0xa00; - s->prefconfig[0] = 0x00004000; - s->prefconfig[1] = 0x00000000; - s->prefcontrol = 0; - s->preffifo = 0; - s->prefcount = 0; + s->prefetch.config1 = 0x00004000; + s->prefetch.transfercount = 0x00000000; + s->prefetch.startengine = 0; + s->prefetch.fifopointer = 0; + s->prefetch.count = 0; for (i = 0; i < 8; i ++) { - if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_unmap(s->cs_file + i); - s->cs_file[i].config[0] = i ? 1 << 12 : 0; + omap_gpmc_cs_unmap(s, i); s->cs_file[i].config[1] = 0x101001; s->cs_file[i].config[2] = 0x020201; s->cs_file[i].config[3] = 0x10031003; s->cs_file[i].config[4] = 0x10f1111; s->cs_file[i].config[5] = 0; s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6); - if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(&s->cs_file[i], - s->cs_file[i].config[6] & 0x1f, /* MASKADDR */ - (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */ + + s->cs_file[i].config[6] = 0xf00; + /* In theory we could probe attached devices for some CFG1 + * bits here, but we just retain them across resets as they + * were set initially by omap_gpmc_attach(). + */ + if (i == 0) { + s->cs_file[i].config[0] &= 0x00433e00; + s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */ + omap_gpmc_cs_map(s, i); + } else { + s->cs_file[i].config[0] &= 0x00403c00; + } } s->ecc_cs = 0; s->ecc_ptr = 0; @@ -142,6 +477,24 @@ void omap_gpmc_reset(struct omap_gpmc_s *s) ecc_reset(&s->ecc[i]); } +static int gpmc_wordaccess_only(target_phys_addr_t addr) +{ + /* Return true if the register offset is to a register that + * only permits word width accesses. + * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND + * for any chipselect. + */ + if (addr >= 0x60 && addr <= 0x1d4) { + int cs = (addr - 0x60) / 0x30; + addr -= cs * 0x30; + if (addr >= 0x7c && addr < 0x88) { + /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */ + return 0; + } + } + return 1; +} + static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr, unsigned size) { @@ -149,13 +502,13 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr, int cs; struct omap_gpmc_cs_file_s *f; - if (size != 4) { + if (size != 4 && gpmc_wordaccess_only(addr)) { return omap_badwidth_read32(opaque, addr); } switch (addr) { case 0x000: /* GPMC_REVISION */ - return 0x20; + return s->revision; case 0x010: /* GPMC_SYSCONFIG */ return s->sysconfig; @@ -187,36 +540,39 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr, addr -= cs * 0x30; f = s->cs_file + cs; switch (addr) { - case 0x60: /* GPMC_CONFIG1 */ - return f->config[0]; - case 0x64: /* GPMC_CONFIG2 */ - return f->config[1]; - case 0x68: /* GPMC_CONFIG3 */ - return f->config[2]; - case 0x6c: /* GPMC_CONFIG4 */ - return f->config[3]; - case 0x70: /* GPMC_CONFIG5 */ - return f->config[4]; - case 0x74: /* GPMC_CONFIG6 */ - return f->config[5]; - case 0x78: /* GPMC_CONFIG7 */ - return f->config[6]; - case 0x84: /* GPMC_NAND_DATA */ - return 0; + case 0x60: /* GPMC_CONFIG1 */ + return f->config[0]; + case 0x64: /* GPMC_CONFIG2 */ + return f->config[1]; + case 0x68: /* GPMC_CONFIG3 */ + return f->config[2]; + case 0x6c: /* GPMC_CONFIG4 */ + return f->config[3]; + case 0x70: /* GPMC_CONFIG5 */ + return f->config[4]; + case 0x74: /* GPMC_CONFIG6 */ + return f->config[5]; + case 0x78: /* GPMC_CONFIG7 */ + return f->config[6]; + case 0x84 ... 0x87: /* GPMC_NAND_DATA */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + return omap_nand_read(f, 0, size); + } + return 0; } break; case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ - return s->prefconfig[0]; + return s->prefetch.config1; case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ - return s->prefconfig[1]; + return s->prefetch.transfercount; case 0x1ec: /* GPMC_PREFETCH_CONTROL */ - return s->prefcontrol; + return s->prefetch.startengine; case 0x1f0: /* GPMC_PREFETCH_STATUS */ - return (s->preffifo << 24) | - ((s->preffifo > - ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) | - s->prefcount; + return (s->prefetch.fifopointer << 24) | + ((s->prefetch.fifopointer >= + ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) | + s->prefetch.count; case 0x1f4: /* GPMC_ECC_CONFIG */ return s->ecc_cs; @@ -251,7 +607,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, int cs; struct omap_gpmc_cs_file_s *f; - if (size != 4) { + if (size != 4 && gpmc_wordaccess_only(addr)) { return omap_badwidth_write32(opaque, addr, value); } @@ -276,7 +632,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, break; case 0x018: /* GPMC_IRQSTATUS */ - s->irqen = ~value; + s->irqen &= ~value; omap_gpmc_int_update(s); break; @@ -302,62 +658,109 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, addr -= cs * 0x30; f = s->cs_file + cs; switch (addr) { - case 0x60: /* GPMC_CONFIG1 */ - f->config[0] = value & 0xffef3e13; - break; - case 0x64: /* GPMC_CONFIG2 */ - f->config[1] = value & 0x001f1f8f; - break; - case 0x68: /* GPMC_CONFIG3 */ - f->config[2] = value & 0x001f1f8f; - break; - case 0x6c: /* GPMC_CONFIG4 */ - f->config[3] = value & 0x1f8f1f8f; - break; - case 0x70: /* GPMC_CONFIG5 */ - f->config[4] = value & 0x0f1f1f1f; - break; - case 0x74: /* GPMC_CONFIG6 */ - f->config[5] = value & 0x00000fcf; - break; - case 0x78: /* GPMC_CONFIG7 */ - if ((f->config[6] ^ value) & 0xf7f) { - if (f->config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_unmap(f); - if (value & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(f, value & 0x1f, /* MASKADDR */ - (value >> 8 & 0xf)); /* BASEADDR */ - } + case 0x60: /* GPMC_CONFIG1 */ + f->config[0] = value & 0xffef3e13; + break; + case 0x64: /* GPMC_CONFIG2 */ + f->config[1] = value & 0x001f1f8f; + break; + case 0x68: /* GPMC_CONFIG3 */ + f->config[2] = value & 0x001f1f8f; + break; + case 0x6c: /* GPMC_CONFIG4 */ + f->config[3] = value & 0x1f8f1f8f; + break; + case 0x70: /* GPMC_CONFIG5 */ + f->config[4] = value & 0x0f1f1f1f; + break; + case 0x74: /* GPMC_CONFIG6 */ + f->config[5] = value & 0x00000fcf; + break; + case 0x78: /* GPMC_CONFIG7 */ + if ((f->config[6] ^ value) & 0xf7f) { + omap_gpmc_cs_unmap(s, cs); f->config[6] = value & 0x00000f7f; - break; - case 0x7c: /* GPMC_NAND_COMMAND */ - case 0x80: /* GPMC_NAND_ADDRESS */ - case 0x84: /* GPMC_NAND_DATA */ - break; - - default: - goto bad_reg; + omap_gpmc_cs_map(s, cs); + } + break; + case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */ + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); + } + break; + case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */ + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); + } + break; + case 0x84 ... 0x87: /* GPMC_NAND_DATA */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + omap_nand_write(f, 0, value, size); + } + break; + default: + goto bad_reg; } break; case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ - s->prefconfig[0] = value & 0x7f8f7fbf; - /* TODO: update interrupts, fifos, dmas */ + if (!s->prefetch.startengine) { + uint32_t oldconfig1 = s->prefetch.config1; + uint32_t changed; + s->prefetch.config1 = value & 0x7f8f7fbf; + changed = oldconfig1 ^ s->prefetch.config1; + if (changed & (0x80 | 0x7000000)) { + /* Turning the engine on or off, or mapping it somewhere else. + * cs_map() and cs_unmap() check the prefetch config and + * overall CSVALID bits, so it is sufficient to unmap-and-map + * both the old cs and the new one. + */ + int oldcs = prefetch_cs(oldconfig1); + int newcs = prefetch_cs(s->prefetch.config1); + omap_gpmc_cs_unmap(s, oldcs); + omap_gpmc_cs_map(s, oldcs); + if (newcs != oldcs) { + omap_gpmc_cs_unmap(s, newcs); + omap_gpmc_cs_map(s, newcs); + } + } + } break; case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ - s->prefconfig[1] = value & 0x3fff; + if (!s->prefetch.startengine) { + s->prefetch.transfercount = value & 0x3fff; + } break; case 0x1ec: /* GPMC_PREFETCH_CONTROL */ - s->prefcontrol = value & 1; - if (s->prefcontrol) { - if (s->prefconfig[0] & 1) - s->preffifo = 0x40; - else - s->preffifo = 0x00; + if (s->prefetch.startengine != (value & 1)) { + s->prefetch.startengine = value & 1; + if (s->prefetch.startengine) { + /* Prefetch engine start */ + s->prefetch.count = s->prefetch.transfercount; + if (s->prefetch.config1 & 1) { + /* Write */ + s->prefetch.fifopointer = 64; + } else { + /* Read */ + s->prefetch.fifopointer = 0; + fill_prefetch_fifo(s); + } + } else { + /* Prefetch engine forcibly stopped. The TRM + * doesn't define the behaviour if you do this. + * We clear the prefetch count, which means that + * we permit no more writes, and don't read any + * more data from NAND. The CPU can still drain + * the FIFO of unread data. + */ + s->prefetch.count = 0; + } + omap_gpmc_int_update(s); } - /* TODO: start */ break; case 0x1f4: /* GPMC_ECC_CONFIG */ @@ -394,24 +797,47 @@ static const MemoryRegionOps omap_gpmc_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq) +struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu, + target_phys_addr_t base, + qemu_irq irq, qemu_irq drq) { + int cs; struct omap_gpmc_s *s = (struct omap_gpmc_s *) g_malloc0(sizeof(struct omap_gpmc_s)); - omap_gpmc_reset(s); - memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000); memory_region_add_subregion(get_system_memory(), base, &s->iomem); + s->irq = irq; + s->drq = drq; + s->accept_256 = cpu_is_omap3630(mpu); + s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20; + s->lastirq = 0; + omap_gpmc_reset(s); + + /* We have to register a different IO memory handler for each + * chip select region in case a NAND device is mapped there. We + * make the region the worst-case size of 256MB and rely on the + * container memory region in cs_map to chop it down to the actual + * guest-requested size. + */ + for (cs = 0; cs < 8; cs++) { + memory_region_init_io(&s->cs_file[cs].nandiomem, + &omap_nand_ops, + &s->cs_file[cs], + "omap-nand", + 256 * 1024 * 1024); + } + + memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s, + "omap-gpmc-prefetch", 256 * 1024 * 1024); return s; } -void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem, - void (*base_upd)(void *opaque, target_phys_addr_t new), - void (*unmap)(void *opaque), void *opaque) +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem) { struct omap_gpmc_cs_file_s *f; + assert(iomem); if (cs < 0 || cs >= 8) { fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs); @@ -419,12 +845,29 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem, } f = &s->cs_file[cs]; + omap_gpmc_cs_unmap(s, cs); + f->config[0] &= ~(0xf << 10); f->iomem = iomem; - f->base_update = base_upd; - f->unmap = unmap; - f->opaque = opaque; + omap_gpmc_cs_map(s, cs); +} - if (f->config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(f, f->config[6] & 0x1f, /* MASKADDR */ - (f->config[6] >> 8 & 0xf)); /* BASEADDR */ +void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand) +{ + struct omap_gpmc_cs_file_s *f; + assert(nand); + + if (cs < 0 || cs >= 8) { + fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs); + exit(-1); + } + f = &s->cs_file[cs]; + + omap_gpmc_cs_unmap(s, cs); + f->config[0] &= ~(0xf << 10); + f->config[0] |= (OMAP_GPMC_NAND << 10); + f->dev = nand; + if (nand_getbuswidth(f->dev) == 16) { + f->config[0] |= OMAP_GPMC_16BIT << 12; + } + omap_gpmc_cs_map(s, cs); } diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c index 70364f4c72..a7b687bc41 100644 --- a/hw/omap_sx1.c +++ b/hw/omap_sx1.c @@ -129,8 +129,7 @@ static void sx1_init(ram_addr_t ram_size, DriveInfo *dinfo; int fl_idx; uint32_t flash_size = flash0_size; - const MemoryRegionOps *flash_ops; - MemoryRegion *flash = g_new(MemoryRegion, 2); + int be; if (version == 2) { flash_size = flash2_size; @@ -156,18 +155,17 @@ static void sx1_init(ram_addr_t ram_size, fl_idx = 0; #ifdef TARGET_WORDS_BIGENDIAN - flash_ops = &pflash_cfi01_ops_be; + be = 1; #else - flash_ops = &pflash_cfi01_ops_le; + be = 0; #endif if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) { - memory_region_init_rom_device(&flash[0], flash_ops, - NULL, "omap_sx1.flash0-1", flash_size); - if (!pflash_cfi01_register(OMAP_CS0_BASE, &flash[0], + if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL, + "omap_sx1.flash0-1", flash_size), dinfo->bdrv, sector_size, flash_size / sector_size, - 4, 0, 0, 0, 0)) { + 4, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory %d.\n", fl_idx); } @@ -184,12 +182,11 @@ static void sx1_init(ram_addr_t ram_size, cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size, OMAP_CS1_SIZE - flash1_size, io); - memory_region_init_rom_device(&flash[1], flash_ops, - NULL, "omap_sx1.flash1-1", flash1_size); - if (!pflash_cfi01_register(OMAP_CS1_BASE, &flash[1], + if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL, + "omap_sx1.flash1-1", flash1_size), dinfo->bdrv, sector_size, flash1_size / sector_size, - 4, 0, 0, 0, 0)) { + 4, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory %d.\n", fl_idx); } diff --git a/hw/onenand.c b/hw/onenand.c index 00276a03cb..6f68f70698 100644 --- a/hw/onenand.c +++ b/hw/onenand.c @@ -25,6 +25,7 @@ #include "blockdev.h" #include "memory.h" #include "exec-memory.h" +#include "sysbus.h" /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */ #define PAGE_SHIFT 11 @@ -33,6 +34,7 @@ #define BLOCK_SHIFT (PAGE_SHIFT + 6) typedef struct { + SysBusDevice busdev; struct { uint16_t man; uint16_t dev; @@ -49,6 +51,7 @@ typedef struct { uint8_t *current; MemoryRegion ram; MemoryRegion mapped_ram; + uint8_t current_direction; uint8_t *boot[2]; uint8_t *data[2][2]; MemoryRegion iomem; @@ -120,27 +123,72 @@ static void onenand_mem_setup(OneNANDState *s) 1); } -void onenand_base_update(void *opaque, target_phys_addr_t new) +static void onenand_intr_update(OneNANDState *s) { - OneNANDState *s = (OneNANDState *) opaque; - - s->base = new; - - memory_region_add_subregion(get_system_memory(), s->base, &s->container); + qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1); } -void onenand_base_unmap(void *opaque) +static void onenand_pre_save(void *opaque) { - OneNANDState *s = (OneNANDState *) opaque; - - memory_region_del_subregion(get_system_memory(), &s->container); + OneNANDState *s = opaque; + if (s->current == s->otp) { + s->current_direction = 1; + } else if (s->current == s->image) { + s->current_direction = 2; + } else { + s->current_direction = 0; + } } -static void onenand_intr_update(OneNANDState *s) +static int onenand_post_load(void *opaque, int version_id) { - qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1); + OneNANDState *s = opaque; + switch (s->current_direction) { + case 0: + break; + case 1: + s->current = s->otp; + break; + case 2: + s->current = s->image; + break; + default: + return -1; + } + onenand_intr_update(s); + return 0; } +static const VMStateDescription vmstate_onenand = { + .name = "onenand", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = onenand_pre_save, + .post_load = onenand_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(current_direction, OneNANDState), + VMSTATE_INT32(cycle, OneNANDState), + VMSTATE_INT32(otpmode, OneNANDState), + VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8), + VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8), + VMSTATE_INT32(bufaddr, OneNANDState), + VMSTATE_INT32(count, OneNANDState), + VMSTATE_UINT16(command, OneNANDState), + VMSTATE_UINT16_ARRAY(config, OneNANDState, 2), + VMSTATE_UINT16(status, OneNANDState), + VMSTATE_UINT16(intstatus, OneNANDState), + VMSTATE_UINT16(wpstatus, OneNANDState), + VMSTATE_INT32(secs_cur, OneNANDState), + VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks), + VMSTATE_UINT8(ecc.cp, OneNANDState), + VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2), + VMSTATE_UINT16(ecc.count, OneNANDState), + VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)), + VMSTATE_END_OF_LIST() + } +}; + /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */ static void onenand_reset(OneNANDState *s, int cold) { @@ -167,11 +215,17 @@ static void onenand_reset(OneNANDState *s, int cold) /* Lock the whole flash */ memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks); - if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0) - hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__); + if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) { + hw_error("%s: Loading the BootRAM failed.\n", __func__); + } } } +static void onenand_system_reset(DeviceState *dev) +{ + onenand_reset(FROM_SYSBUS(OneNANDState, sysbus_from_qdev(dev)), 1); +} + static inline int onenand_load_main(OneNANDState *s, int sec, int secn, void *dest) { @@ -191,8 +245,8 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn, int result = 0; if (secn > 0) { - uint32_t size = (uint32_t) secn * 512; - const uint8_t *sp = (const uint8_t *) src; + uint32_t size = (uint32_t)secn * 512; + const uint8_t *sp = (const uint8_t *)src; uint8_t *dp = 0; if (s->bdrv_cur) { dp = g_malloc(size); @@ -203,7 +257,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn, if (sec + secn > s->secs_cur) { result = 1; } else { - dp = (uint8_t *) s->current + (sec << 9); + dp = (uint8_t *)s->current + (sec << 9); } } if (!result) { @@ -245,13 +299,13 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, { int result = 0; if (secn > 0) { - const uint8_t *sp = (const uint8_t *) src; + const uint8_t *sp = (const uint8_t *)src; uint8_t *dp = 0, *dpp = 0; if (s->bdrv_cur) { dp = g_malloc(512); if (!dp || bdrv_read(s->bdrv_cur, - s->secs_cur + (sec >> 5), - dp, 1) < 0) { + s->secs_cur + (sec >> 5), + dp, 1) < 0) { result = 1; } else { dpp = dp + ((sec & 31) << 4); @@ -270,7 +324,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, } if (s->bdrv_cur) { result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), - dp, 1) < 0; + dp, 1) < 0; } } if (dp) { @@ -326,7 +380,7 @@ fail: return 1; } -static void onenand_command(OneNANDState *s, int cmd) +static void onenand_command(OneNANDState *s) { int b; int sec; @@ -346,7 +400,7 @@ static void onenand_command(OneNANDState *s, int cmd) s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \ buf += (s->bufaddr & 3) << 4; - switch (cmd) { + switch (s->command) { case 0x00: /* Load single/multiple sector data unit into buffer */ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) @@ -527,7 +581,7 @@ static void onenand_command(OneNANDState *s, int cmd) s->status |= ONEN_ERR_CMD; s->intstatus |= ONEN_INT; fprintf(stderr, "%s: unknown OneNAND command %x\n", - __FUNCTION__, cmd); + __func__, s->command); } onenand_intr_update(s); @@ -659,7 +713,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, if (s->intstatus & (1 << 15)) break; s->command = value; - onenand_command(s, s->command); + onenand_command(s); break; case 0xf221: /* System Configuration 1 */ s->config[0] = value; @@ -700,30 +754,25 @@ static const MemoryRegionOps onenand_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -void *onenand_init(BlockDriverState *bdrv, - uint16_t man_id, uint16_t dev_id, uint16_t ver_id, - int regshift, qemu_irq irq) +static int onenand_initfn(SysBusDevice *dev) { - OneNANDState *s = (OneNANDState *) g_malloc0(sizeof(*s)); - uint32_t size = 1 << (24 + ((dev_id >> 4) & 7)); + OneNANDState *s = (OneNANDState *)dev; + uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7)); void *ram; - - s->shift = regshift; - s->intr = irq; + s->base = (target_phys_addr_t)-1; s->rdy = NULL; - s->id.man = man_id; - s->id.dev = dev_id; - s->id.ver = ver_id; s->blocks = size >> BLOCK_SHIFT; s->secs = size >> 9; s->blockwp = g_malloc(s->blocks); - s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0; + s->density_mask = (s->id.dev & 0x08) + ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0; memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand", 0x10000 << s->shift); - s->bdrv = bdrv; if (!s->bdrv) { s->image = memset(g_malloc(size + (size >> 5)), - 0xff, size + (size >> 5)); + 0xff, size + (size >> 5)); + } else { + s->bdrv_cur = s->bdrv; } s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT), 0xff, (64 + 2) << PAGE_SHIFT); @@ -736,15 +785,40 @@ void *onenand_init(BlockDriverState *bdrv, s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift); s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift); onenand_mem_setup(s); + sysbus_init_irq(dev, &s->intr); + sysbus_init_mmio_region(dev, &s->container); + vmstate_register(&dev->qdev, + ((s->shift & 0x7f) << 24) + | ((s->id.man & 0xff) << 16) + | ((s->id.dev & 0xff) << 8) + | (s->id.ver & 0xff), + &vmstate_onenand, s); + return 0; +} - onenand_reset(s, 1); +static SysBusDeviceInfo onenand_info = { + .init = onenand_initfn, + .qdev.name = "onenand", + .qdev.size = sizeof(OneNANDState), + .qdev.reset = onenand_system_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0), + DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0), + DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0), + DEFINE_PROP_INT32("shift", OneNANDState, shift, 0), + DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv), + DEFINE_PROP_END_OF_LIST() + } +}; - return s; +static void onenand_register_device(void) +{ + sysbus_register_withprop(&onenand_info); } -void *onenand_raw_otp(void *opaque) +void *onenand_raw_otp(DeviceState *onenand_device) { - OneNANDState *s = (OneNANDState *) opaque; - - return s->otp; + return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp; } + +device_init(onenand_register_device) diff --git a/hw/pc.c b/hw/pc.c index 263fb1a773..5bc845aaea 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -78,12 +78,12 @@ struct e820_entry { uint64_t address; uint64_t length; uint32_t type; -} __attribute((__packed__, __aligned__(4))); +} QEMU_PACKED __attribute((__aligned__(4))); struct e820_table { uint32_t count; struct e820_entry entry[E820_NR_ENTRIES]; -} __attribute((__packed__, __aligned__(4))); +} QEMU_PACKED __attribute((__aligned__(4))); static struct e820_table e820_table; struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; diff --git a/hw/pci-stub.c b/hw/pci-stub.c index c5a0aa8979..1fb105d51c 100644 --- a/hw/pci-stub.c +++ b/hw/pci-stub.c @@ -1,5 +1,5 @@ /* - * PCI stubs for plathome that doesn't support pci bus. + * PCI stubs for platforms that don't support pci bus. * * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp> * VA Linux Systems Japan K.K. diff --git a/hw/pci.c b/hw/pci.c index 6124790f01..57ff7b1098 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1811,6 +1811,25 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } +static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset) +{ + uint8_t next, prev, found = 0; + + if (!(pdev->used[offset])) { + return 0; + } + + assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST); + + for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]); + prev = next + PCI_CAP_LIST_NEXT) { + if (next <= offset && next > found) { + found = next; + } + } + return found; +} + /* Patch the PCI vendor and device ids in a PCI rom image if necessary. This is needed for an option rom which is used for more than one device. */ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size) @@ -1952,11 +1971,30 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size) { uint8_t *config; + int i, overlapping_cap; + if (!offset) { offset = pci_find_space(pdev, size); if (!offset) { return -ENOSPC; } + } else { + /* Verify that capabilities don't overlap. Note: device assignment + * depends on this check to verify that the device is not broken. + * Should never trigger for emulated devices, but it's helpful + * for debugging these. */ + for (i = offset; i < offset + size; i++) { + overlapping_cap = pci_find_capability_at_offset(pdev, i); + if (overlapping_cap) { + fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " + "Attempt to add PCI capability %x at offset " + "%x overlaps existing capability %x at offset %x\n", + pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + cap_id, offset, overlapping_cap, i); + return -EINVAL; + } + } } config = pdev->config + offset; diff --git a/hw/pci_host.c b/hw/pci_host.c index 44c6c207a9..2e8a29f1e3 100644 --- a/hw/pci_host.c +++ b/hw/pci_host.c @@ -94,72 +94,82 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len) return val; } -static void pci_host_config_write(void *opaque, target_phys_addr_t addr, - uint64_t val, unsigned len) +static void pci_host_config_write(ReadWriteHandler *handler, + pcibus_t addr, uint32_t val, int len) { - PCIHostState *s = opaque; + PCIHostState *s = container_of(handler, PCIHostState, conf_handler); - PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n", + PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n", __func__, addr, len, val); s->config_reg = val; } -static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr, - unsigned len) +static uint32_t pci_host_config_read(ReadWriteHandler *handler, + pcibus_t addr, int len) { - PCIHostState *s = opaque; + PCIHostState *s = container_of(handler, PCIHostState, conf_handler); uint32_t val = s->config_reg; - PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n", + PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n", __func__, addr, len, val); return val; } -static void pci_host_data_write(void *opaque, target_phys_addr_t addr, - uint64_t val, unsigned len) +static void pci_host_data_write(ReadWriteHandler *handler, + pcibus_t addr, uint32_t val, int len) { - PCIHostState *s = opaque; - PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n", - addr, len, (unsigned)val); + PCIHostState *s = container_of(handler, PCIHostState, data_handler); + PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", + addr, len, val); if (s->config_reg & (1u << 31)) pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); } -static uint64_t pci_host_data_read(void *opaque, - target_phys_addr_t addr, unsigned len) +static uint32_t pci_host_data_read(ReadWriteHandler *handler, + pcibus_t addr, int len) { - PCIHostState *s = opaque; + PCIHostState *s = container_of(handler, PCIHostState, data_handler); uint32_t val; if (!(s->config_reg & (1 << 31))) return 0xffffffff; val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); - PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n", + PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); return val; } -const MemoryRegionOps pci_host_conf_le_ops = { - .read = pci_host_config_read, - .write = pci_host_config_write, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -const MemoryRegionOps pci_host_conf_be_ops = { - .read = pci_host_config_read, - .write = pci_host_config_write, - .endianness = DEVICE_BIG_ENDIAN, -}; +static void pci_host_init(PCIHostState *s) +{ + s->conf_handler.write = pci_host_config_write; + s->conf_handler.read = pci_host_config_read; + s->data_handler.write = pci_host_data_write; + s->data_handler.read = pci_host_data_read; +} -const MemoryRegionOps pci_host_data_le_ops = { - .read = pci_host_data_read, - .write = pci_host_data_write, - .endianness = DEVICE_LITTLE_ENDIAN, -}; +int pci_host_conf_register_mmio(PCIHostState *s, int endian) +{ + pci_host_init(s); + return cpu_register_io_memory_simple(&s->conf_handler, endian); +} -const MemoryRegionOps pci_host_data_be_ops = { - .read = pci_host_data_read, - .write = pci_host_data_write, - .endianness = DEVICE_BIG_ENDIAN, -}; +void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s) +{ + pci_host_init(s); + register_ioport_simple(&s->conf_handler, ioport, 4, 4); + sysbus_init_ioports(&s->busdev, ioport, 4); +} +int pci_host_data_register_mmio(PCIHostState *s, int endian) +{ + pci_host_init(s); + return cpu_register_io_memory_simple(&s->data_handler, endian); +} +void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s) +{ + pci_host_init(s); + register_ioport_simple(&s->data_handler, ioport, 4, 1); + register_ioport_simple(&s->data_handler, ioport, 4, 2); + register_ioport_simple(&s->data_handler, ioport, 4, 4); + sysbus_init_ioports(&s->busdev, ioport, 4); +} diff --git a/hw/pci_host.h b/hw/pci_host.h index 0211086d70..7f551143bb 100644 --- a/hw/pci_host.h +++ b/hw/pci_host.h @@ -29,11 +29,12 @@ #define PCI_HOST_H #include "sysbus.h" +#include "rwhandler.h" struct PCIHostState { SysBusDevice busdev; - MemoryRegion conf_mem; - MemoryRegion data_mem; + ReadWriteHandler conf_handler; + ReadWriteHandler data_handler; MemoryRegion *address_space; uint32_t config_reg; PCIBus *bus; @@ -48,9 +49,12 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr, void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len); uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len); -extern const MemoryRegionOps pci_host_conf_le_ops; -extern const MemoryRegionOps pci_host_conf_be_ops; -extern const MemoryRegionOps pci_host_data_le_ops; -extern const MemoryRegionOps pci_host_data_be_ops; +/* for mmio */ +int pci_host_conf_register_mmio(PCIHostState *s, int endian); +int pci_host_data_register_mmio(PCIHostState *s, int endian); + +/* for ioio */ +void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s); +void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s); #endif /* PCI_HOST_H */ diff --git a/hw/pcie.c b/hw/pcie.c index 39607bf31a..5c9eb2f0ac 100644 --- a/hw/pcie.c +++ b/hw/pcie.c @@ -175,6 +175,14 @@ static void hotplug_event_notify(PCIDevice *dev) } } +static void hotplug_event_clear(PCIDevice *dev) +{ + hotplug_event_update_event_status(dev); + if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) { + qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0); + } +} + /* * A PCI Express Hot-Plug Event has occurred, so update slot status register * and notify OS of the event if necessary. @@ -320,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev, uint8_t *exp_cap = dev->config + pos; uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA); + if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) { + hotplug_event_clear(dev); + } + if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) { return; } diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c index 2ae65ec807..62c06eafd6 100644 --- a/hw/pcie_aer.c +++ b/hw/pcie_aer.c @@ -415,7 +415,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err) int i; assert(err->status); - assert(err->status & (err->status - 1)); + assert(!(err->status & (err->status - 1))); errcap &= ~(PCI_ERR_CAP_FEP_MASK | PCI_ERR_CAP_TLP); errcap |= PCI_ERR_CAP_FEP(first_bit); @@ -495,7 +495,7 @@ static int pcie_aer_record_error(PCIDevice *dev, int fep = PCI_ERR_CAP_FEP(errcap); assert(err->status); - assert(err->status & (err->status - 1)); + assert(!(err->status & (err->status - 1))); if (errcap & PCI_ERR_CAP_MHRE && (pci_get_long(aer_cap + PCI_ERR_UNCOR_STATUS) & (1U << fep))) { @@ -979,20 +979,21 @@ int do_pcie_aer_inejct_error(Monitor *mon, if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) { char *e = NULL; error_status = strtoul(error_name, &e, 0); - correctable = !!qdict_get_int(qdict, "correctable"); + correctable = qdict_get_try_bool(qdict, "correctable", 0); if (!e || *e != '\0') { monitor_printf(mon, "invalid error status value. \"%s\"", error_name); return -EINVAL; } } + err.status = error_status; err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn; err.flags = 0; if (correctable) { err.flags |= PCIE_AER_ERR_IS_CORRECTABLE; } - if (qdict_get_int(qdict, "advisory_non_fatal")) { + if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) { err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY; } if (qdict_haskey(qdict, "header0")) { diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c index 257fccaa88..e3ca310efd 100644 --- a/hw/petalogix_ml605_mmu.c +++ b/hw/petalogix_ml605_mmu.c @@ -149,7 +149,7 @@ petalogix_ml605_init(ram_addr_t ram_size, target_phys_addr_t ddr_base = MEMORY_BASEADDR; ram_addr_t phys_lmb_bram; ram_addr_t phys_ram; - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; /* init CPUs */ @@ -169,15 +169,14 @@ petalogix_ml605_init(ram_addr_t ram_size, phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size); cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le, - NULL, "petalogix_ml605.flash", FLASH_SIZE); + phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); /* 5th parameter 2 means bank-width * 10th paremeter 0 means little-endian */ pflash_cfi01_register(FLASH_BASEADDR, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, - 2, 0x89, 0x18, 0x0000, 0x0); + 2, 0x89, 0x18, 0x0000, 0x0, 0); cpu_irq = microblaze_pic_init_cpu(env); diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c index 14817452c6..a43fb4c95c 100644 --- a/hw/petalogix_s3adsp1800_mmu.c +++ b/hw/petalogix_s3adsp1800_mmu.c @@ -127,7 +127,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, target_phys_addr_t ddr_base = 0x90000000; ram_addr_t phys_lmb_bram; ram_addr_t phys_ram; - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; /* init CPUs */ @@ -148,14 +148,12 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size); cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be, - NULL, "petalogix_s3adsp1800.flash", - FLASH_SIZE); + phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(0xa0000000, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, - 1, 0x89, 0x18, 0x0000, 0x0); + 1, 0x89, 0x18, 0x0000, 0x0, 1); cpu_irq = microblaze_pic_init_cpu(env); dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2); diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index 2144c6a3fd..90e1301c5e 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -40,7 +40,6 @@ #include "flash.h" #include "block.h" #include "qemu-timer.h" -#include "exec-memory.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -75,7 +74,8 @@ struct pflash_t { target_phys_addr_t counter; unsigned int writeblock_size; QEMUTimer *timer; - MemoryRegion *mem; + ram_addr_t off; + int fl_mem; void *storage; }; @@ -89,7 +89,8 @@ static void pflash_timer (void *opaque) if (pfl->bypass) { pfl->wcycle = 2; } else { - memory_region_rom_device_set_readable(pfl->mem, true); + cpu_register_physical_memory(pfl->base, pfl->total_len, + pfl->off | IO_MEM_ROMD | pfl->fl_mem); pfl->wcycle = 0; } pfl->cmd = 0; @@ -262,7 +263,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, if (!pfl->wcycle) { /* Set the device in I/O access mode */ - memory_region_rom_device_set_readable(pfl->mem, false); + cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); } switch (pfl->wcycle) { @@ -421,7 +422,8 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, __func__, offset, pfl->wcycle, pfl->cmd, value); reset_flash: - memory_region_rom_device_set_readable(pfl->mem, true); + cpu_register_physical_memory(pfl->base, pfl->total_len, + pfl->off | IO_MEM_ROMD | pfl->fl_mem); pfl->bypass = 0; pfl->wcycle = 0; @@ -512,20 +514,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -const MemoryRegionOps pflash_cfi01_ops_be = { - .old_mmio = { - .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, - .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { + &pflash_writeb_be, + &pflash_writew_be, + &pflash_writel_be, }; -const MemoryRegionOps pflash_cfi01_ops_le = { - .old_mmio = { - .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, - .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUReadMemoryFunc * const pflash_read_ops_be[] = { + &pflash_readb_be, + &pflash_readw_be, + &pflash_readl_be, +}; + +static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { + &pflash_writeb_le, + &pflash_writew_le, + &pflash_writel_le, +}; + +static CPUReadMemoryFunc * const pflash_read_ops_le[] = { + &pflash_readb_le, + &pflash_readw_le, + &pflash_readl_le, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -564,11 +574,12 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3) + uint16_t id2, uint16_t id3, + int be) { pflash_t *pfl; target_phys_addr_t total_len; @@ -586,16 +597,26 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem, pfl = g_malloc0(sizeof(pflash_t)); /* FIXME: Allocate ram ourselves. */ - pfl->storage = memory_region_get_ram_ptr(mem); - pfl->mem = mem; - memory_region_add_subregion(get_system_memory(), base, mem); + pfl->storage = qemu_get_ram_ptr(off); + if (be) { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, + pflash_write_ops_be, pfl, + DEVICE_NATIVE_ENDIAN); + } else { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, + pflash_write_ops_le, pfl, + DEVICE_NATIVE_ENDIAN); + } + pfl->off = off; + cpu_register_physical_memory(base, total_len, + off | pfl->fl_mem | IO_MEM_ROMD); pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9); if (ret < 0) { - memory_region_del_subregion(get_system_memory(), mem); + cpu_unregister_io_memory(pfl->fl_mem); g_free(pfl); return NULL; } diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index e7e0408fc4..ac5115e4c8 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -39,7 +39,6 @@ #include "flash.h" #include "qemu-timer.h" #include "block.h" -#include "exec-memory.h" //#define PFLASH_DEBUG #ifdef PFLASH_DEBUG @@ -70,39 +69,25 @@ struct pflash_t { uint8_t cfi_len; uint8_t cfi_table[0x52]; QEMUTimer *timer; - /* The device replicates the flash memory across its memory space. Emulate - * that by having a container (.mem) filled with an array of aliases - * (.mem_mappings) pointing to the flash memory (.orig_mem). - */ - MemoryRegion mem; - MemoryRegion *mem_mappings; /* array; one per mapping */ - MemoryRegion *orig_mem; + ram_addr_t off; + int fl_mem; int rom_mode; int read_counter; /* used for lazy switch-back to rom mode */ void *storage; }; -/* - * Set up replicated mappings of the same region. - */ -static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem) -{ - unsigned i; - target_phys_addr_t size = memory_region_size(mem); - - pfl->orig_mem = mem; - memory_region_init(&pfl->mem, "pflash", pfl->mappings * size); - pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings); - for (i = 0; i < pfl->mappings; ++i) { - memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", mem, - 0, size); - memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]); - } -} - static void pflash_register_memory(pflash_t *pfl, int rom_mode) { - memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode); + unsigned long phys_offset = pfl->fl_mem; + int i; + + if (rom_mode) + phys_offset |= pfl->off | IO_MEM_ROMD; + pfl->rom_mode = rom_mode; + + for (i = 0; i < pfl->mappings; i++) + cpu_register_physical_memory(pfl->base + i * pfl->chip_len, + pfl->chip_len, phys_offset); } static void pflash_timer (void *opaque) @@ -553,20 +538,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -const MemoryRegionOps pflash_cfi02_ops_be = { - .old_mmio = { - .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, - .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { + &pflash_writeb_be, + &pflash_writew_be, + &pflash_writel_be, +}; + +static CPUReadMemoryFunc * const pflash_read_ops_be[] = { + &pflash_readb_be, + &pflash_readw_be, + &pflash_readl_be, }; -const MemoryRegionOps pflash_cfi02_ops_le = { - .old_mmio = { - .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, - .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { + &pflash_writeb_le, + &pflash_writew_le, + &pflash_writel_le, +}; + +static CPUReadMemoryFunc * const pflash_read_ops_le[] = { + &pflash_readb_le, + &pflash_readw_le, + &pflash_readl_le, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -605,12 +598,13 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, - uint16_t unlock_addr0, uint16_t unlock_addr1) + uint16_t unlock_addr0, uint16_t unlock_addr1, + int be) { pflash_t *pfl; int32_t chip_len; @@ -625,22 +619,31 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem, #endif pfl = g_malloc0(sizeof(pflash_t)); /* FIXME: Allocate ram ourselves. */ - pfl->storage = memory_region_get_ram_ptr(mem); + pfl->storage = qemu_get_ram_ptr(off); + if (be) { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, + pflash_write_ops_be, + pfl, DEVICE_NATIVE_ENDIAN); + } else { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, + pflash_write_ops_le, + pfl, DEVICE_NATIVE_ENDIAN); + } + pfl->off = off; pfl->base = base; pfl->chip_len = chip_len; pfl->mappings = nb_mappings; + pflash_register_memory(pfl, 1); pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9); if (ret < 0) { + cpu_unregister_io_memory(pfl->fl_mem); g_free(pfl); return NULL; } } - pflash_setup_mappings(pfl, mem); - pfl->rom_mode = 1; - memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem); #if 0 /* XXX: there should be a bit to set up read-only, * the same way the hardware does (with WP pin). */ diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 8f6ea42e2c..c563c6e1a3 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -142,7 +142,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d) int i, r; uint32_t smram; - memory_region_transaction_begin(); update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3, &d->pam_regions[0]); for(i = 0; i < 12; i++) { @@ -163,7 +162,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d) d->smram_enabled = false; } } - memory_region_transaction_commit(); } static void i440fx_set_smm(int val, void *arg) @@ -237,16 +235,9 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev) { I440FXState *s = FROM_SYSBUS(I440FXState, dev); - memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, - "pci-conf-idx", 4); - sysbus_add_io(dev, 0xcf8, &s->conf_mem); - sysbus_init_ioports(&s->busdev, 0xcf8, 4); - - memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, - "pci-conf-data", 4); - sysbus_add_io(dev, 0xcfc, &s->data_mem); - sysbus_init_ioports(&s->busdev, 0xcfc, 4); + pci_host_conf_register_ioport(0xcf8, s); + pci_host_data_register_ioport(0xcfc, s); return 0; } diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c index 1eb807c4c1..dec165e40f 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -32,7 +32,6 @@ #include "qemu-log.h" #include "loader.h" #include "blockdev.h" -#include "exec-memory.h" #define BIOS_FILENAME "ppc405_rom.bin" #define BIOS_SIZE (2048 * 1024) @@ -182,9 +181,7 @@ static void ref405ep_init (ram_addr_t ram_size, ppc4xx_bd_info_t bd; CPUPPCState *env; qemu_irq *pic; - ram_addr_t sram_offset, bdloc; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *bios = g_new(MemoryRegion, 1); + ram_addr_t sram_offset, bios_offset, bdloc; MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); target_phys_addr_t ram_bases[2], ram_sizes[2]; target_ulong sram_size; @@ -227,18 +224,18 @@ static void ref405ep_init (ram_addr_t ram_size, dinfo = drive_get(IF_PFLASH, 0, fl_idx); if (dinfo) { bios_size = bdrv_getlength(dinfo->bdrv); - memory_region_init_rom_device(bios, &pflash_cfi02_ops_be, - NULL, "ef405ep.bios", bios_size); + bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size); fl_sectors = (bios_size + 65535) >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at addr %lx '%s' %d\n", - fl_idx, bios_size, -bios_size, + " at offset %08lx addr %lx '%s' %d\n", + fl_idx, bios_size, bios_offset, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios, + pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, dinfo->bdrv, 65536, fl_sectors, 1, - 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA); + 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, + 1); fl_idx++; } else #endif @@ -246,12 +243,12 @@ static void ref405ep_init (ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("Load BIOS from file\n"); #endif - memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE); + bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); + bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); g_free(filename); } else { bios_size = -1; @@ -262,9 +259,8 @@ static void ref405ep_init (ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - memory_region_set_readonly(bios, true); - memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size), - bios); + cpu_register_physical_memory((uint32_t)(-bios_size), + bios_size, bios_offset | IO_MEM_ROM); } /* Register FPGA */ #ifdef DEBUG_BOARD_INIT @@ -511,9 +507,7 @@ static void taihu_405ep_init(ram_addr_t ram_size, { char *filename; qemu_irq *pic; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *bios = g_new(MemoryRegion, 1); - MemoryRegion *flash = g_new(MemoryRegion, 1); + ram_addr_t bios_offset; MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); target_phys_addr_t ram_bases[2], ram_sizes[2]; long bios_size; @@ -550,17 +544,17 @@ static void taihu_405ep_init(ram_addr_t ram_size, /* XXX: should check that size is 2MB */ // bios_size = 2 * 1024 * 1024; fl_sectors = (bios_size + 65535) >> 16; - memory_region_init_rom_device(bios, &pflash_cfi02_ops_be, - NULL, "taihu_405ep.bios", bios_size); + bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size); #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at addr %lx '%s' %d\n", - fl_idx, bios_size, -bios_size, + " at offset %08lx addr %lx '%s' %d\n", + fl_idx, bios_size, bios_offset, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios, + pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, dinfo->bdrv, 65536, fl_sectors, 1, - 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA); + 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, + 1); fl_idx++; } else #endif @@ -570,10 +564,10 @@ static void taihu_405ep_init(ram_addr_t ram_size, #endif if (bios_name == NULL) bios_name = BIOS_FILENAME; - memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE); + bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); + bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); g_free(filename); } else { bios_size = -1; @@ -584,9 +578,8 @@ static void taihu_405ep_init(ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - memory_region_set_readonly(bios, true); - memory_region_add_subregion(address_space_mem, - (uint32_t)(-bios_size), bios); + cpu_register_physical_memory((uint32_t)(-bios_size), + bios_size, bios_offset | IO_MEM_ROM); } /* Register Linux flash */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); @@ -597,15 +590,15 @@ static void taihu_405ep_init(ram_addr_t ram_size, fl_sectors = (bios_size + 65535) >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at addr " TARGET_FMT_lx " '%s'\n", - fl_idx, bios_size, (target_ulong)0xfc000000, + " at offset %08lx addr " TARGET_FMT_lx " '%s'\n", + fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000, bdrv_get_device_name(dinfo->bdrv)); #endif - memory_region_init_rom_device(flash, &pflash_cfi02_ops_be, - NULL, "taihu_405ep.flash", bios_size); - pflash_cfi02_register(0xfc000000, flash, + bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size); + pflash_cfi02_register(0xfc000000, bios_offset, dinfo->bdrv, 65536, fl_sectors, 1, - 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA); + 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, + 1); fl_idx++; } /* Register CLPD & LCD display */ diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index 339b38ec7a..52e2663a01 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -368,12 +368,10 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index); /* CFGDATA */ - memory_region_init_io(&controller->pci_state.data_mem, - &pci_host_data_be_ops, - &controller->pci_state, "pci-conf-data", 4); - memory_region_add_subregion(get_system_memory(), - config_space + PCIC0_CFGDATA, - &controller->pci_state.data_mem); + index = pci_host_data_register_mmio(&controller->pci_state, 1); + if (index < 0) + goto free; + cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index); /* Internal registers */ index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller, diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 2db365d0b6..4390aeb559 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -79,6 +79,8 @@ struct PPCE500PCIState { uint32_t gasket_time; qemu_irq irq[4]; /* mmio maps */ + int cfgaddr; + int cfgdata; int reg; }; @@ -266,18 +268,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base) PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h); - sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem); - sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem); + cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr); + cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata); cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, s->reg); } static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base) { - PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); - - sysbus_del_memory(dev, &h->conf_mem); - sysbus_del_memory(dev, &h->data_mem); + cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, + IO_MEM_UNASSIGNED); + cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, + IO_MEM_UNASSIGNED); cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, IO_MEM_UNASSIGNED); } @@ -307,10 +309,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev) pci_create_simple(b, 0, "e500-host-bridge"); - memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h, - "pci-conf-idx", 4); - memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h, - "pci-conf-data", 4); + s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN); + s->cfgdata = pci_host_data_register_mmio(&s->pci_state, + DEVICE_LITTLE_ENDIAN); s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s, DEVICE_BIG_ENDIAN); sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap); diff --git a/hw/prep_pci.c b/hw/prep_pci.c index 55e4e25099..c36232a808 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -125,15 +125,9 @@ PCIBus *pci_prep_init(qemu_irq *pic, address_space_io, 0, 4); - memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s, - "pci-conf-idx", 1); - memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem); - sysbus_init_ioports(&s->busdev, 0xcf8, 1); - - memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s, - "pci-conf-data", 1); - memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem); - sysbus_init_ioports(&s->busdev, 0xcfc, 1); + pci_host_conf_register_ioport(0xcf8, s); + + pci_host_data_register_ioport(0xcfc, s); PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read, PPC_PCIIO_write, s, diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index 97f90153b7..b73290cb3f 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -70,7 +70,7 @@ struct PXA2xxLCDState { int orientation; }; -typedef struct __attribute__ ((__packed__)) { +typedef struct QEMU_PACKED { uint32_t fdaddr; uint32_t fsaddr; uint32_t fidr; diff --git a/hw/qxl.c b/hw/qxl.c index 1d9077db68..45e24016fc 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1388,11 +1388,7 @@ static void init_pipe_signaling(PCIQXLDevice *d) dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__); return; } -#ifdef CONFIG_IOTHREAD fcntl(d->pipe[0], F_SETFL, O_NONBLOCK); -#else - fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */); -#endif fcntl(d->pipe[1], F_SETFL, O_NONBLOCK); fcntl(d->pipe[0], F_SETOWN, getpid()); diff --git a/hw/r2d.c b/hw/r2d.c index 41aa2c2bd2..771f3d0733 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -209,7 +209,7 @@ static void main_cpu_reset(void *opaque) env->pc = s->vector; } -static struct __attribute__((__packed__)) +static struct QEMU_PACKED { int mount_root_rdonly; int ramdisk_flags; @@ -235,7 +235,6 @@ static void r2d_init(ram_addr_t ram_size, qemu_irq *irq; DriveInfo *dinfo; int i; - MemoryRegion *flash = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "SH7751R"; @@ -268,13 +267,11 @@ static void r2d_init(ram_addr_t ram_size, /* onboard flash memory */ dinfo = drive_get(IF_PFLASH, 0, 0); - memory_region_init_rom_device(flash, &pflash_cfi02_ops_le, - NULL, "r2d.flash", FLASH_SIZE); - pflash_cfi02_register(0x0, flash, + pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE), dinfo ? dinfo->bdrv : NULL, (16 * 1024), FLASH_SIZE >> 16, 1, 4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x555, 0x2aa); + 0x555, 0x2aa, 0); /* NIC: rtl8139 on-board, and 2 slots. */ for (i = 0; i < nb_nics; i++) diff --git a/hw/rc4030.c b/hw/rc4030.c index a2a20996a2..33e10709c6 100644 --- a/hw/rc4030.c +++ b/hw/rc4030.c @@ -50,7 +50,7 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi typedef struct dma_pagetable_entry { int32_t frame; int32_t owner; -} __attribute__((packed)) dma_pagetable_entry; +} QEMU_PACKED dma_pagetable_entry; #define DMA_PAGESIZE 4096 #define DMA_REG_ENABLE 1 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index d94b1eb53c..3cc830ff95 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -57,6 +57,7 @@ typedef struct SCSIDiskReq { struct iovec iov; QEMUIOVector qiov; uint32_t status; + BlockAcctCookie acct; } SCSIDiskReq; struct SCSIDiskState @@ -107,10 +108,13 @@ static void scsi_cancel_io(SCSIRequest *req) static void scsi_read_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); int n; r->req.aiocb = NULL; + bdrv_acct_done(s->bs, &r->acct); + if (ret) { if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) { return; @@ -161,6 +165,8 @@ static void scsi_read_data(SCSIRequest *req) r->iov.iov_len = n * 512; qemu_iovec_init_external(&r->qiov, &r->iov, 1); + + bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, scsi_read_complete, r); if (r->req.aiocb == NULL) { @@ -207,11 +213,14 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) static void scsi_write_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint32_t len; uint32_t n; r->req.aiocb = NULL; + bdrv_acct_done(s->bs, &r->acct); + if (ret) { if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) { return; @@ -252,6 +261,8 @@ static void scsi_write_data(SCSIRequest *req) n = r->iov.iov_len / 512; if (n) { qemu_iovec_init_external(&r->qiov, &r->iov, 1); + + bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, scsi_write_complete, r); if (r->req.aiocb == NULL) { @@ -854,13 +865,19 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) buflen = 8; break; case SYNCHRONIZE_CACHE: + { + BlockAcctCookie acct; + + bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH); ret = bdrv_flush(s->bs); + bdrv_acct_done(s->bs, &acct); if (ret < 0) { if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) { return -1; } } break; + } case GET_CONFIGURATION: memset(outbuf, 0, 8); /* ??? This should probably return much more information. For now diff --git a/hw/sh_pci.c b/hw/sh_pci.c index 76061bb756..36f39300d5 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -150,7 +150,7 @@ static int sh_pci_init_device(SysBusDevice *dev) PCI_DEVFN(0, 0), 4); memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s, "sh_pci", 0x224); - memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7, + memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_p4, 0, 0x224); isa_mmio_setup(&s->isa, 0x40000); sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap); diff --git a/hw/smbios.c b/hw/smbios.c index 8f2e965387..c9ba43e8d0 100644 --- a/hw/smbios.c +++ b/hw/smbios.c @@ -21,19 +21,19 @@ struct smbios_header { uint16_t length; uint8_t type; -} __attribute__((__packed__)); +} QEMU_PACKED; struct smbios_field { struct smbios_header header; uint8_t type; uint16_t offset; uint8_t data[]; -} __attribute__((__packed__)); +} QEMU_PACKED; struct smbios_table { struct smbios_header header; uint8_t data[]; -} __attribute__((__packed__)); +} QEMU_PACKED; #define SMBIOS_FIELD_ENTRY 0 #define SMBIOS_TABLE_ENTRY 1 diff --git a/hw/smbios.h b/hw/smbios.h index 3a5169dbd3..94e3641f9a 100644 --- a/hw/smbios.h +++ b/hw/smbios.h @@ -26,7 +26,7 @@ struct smbios_structure_header { uint8_t type; uint8_t length; uint16_t handle; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 0 - BIOS Information */ struct smbios_type_0 { @@ -42,7 +42,7 @@ struct smbios_type_0 { uint8_t system_bios_minor_release; uint8_t embedded_controller_major_release; uint8_t embedded_controller_minor_release; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 1 - System Information */ struct smbios_type_1 { @@ -55,7 +55,7 @@ struct smbios_type_1 { uint8_t wake_up_type; uint8_t sku_number_str; uint8_t family_str; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 3 - System Enclosure (v2.3) */ struct smbios_type_3 { @@ -74,7 +74,7 @@ struct smbios_type_3 { uint8_t number_of_power_cords; uint8_t contained_element_count; // contained elements follow -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 4 - Processor Information (v2.0) */ struct smbios_type_4 { @@ -94,7 +94,7 @@ struct smbios_type_4 { uint16_t l1_cache_handle; uint16_t l2_cache_handle; uint16_t l3_cache_handle; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 16 - Physical Memory Array * Associated with one type 17 (Memory Device). @@ -107,7 +107,7 @@ struct smbios_type_16 { uint32_t maximum_capacity; uint16_t memory_error_information_handle; uint16_t number_of_memory_devices; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 17 - Memory Device * Associated with one type 19 */ @@ -124,7 +124,7 @@ struct smbios_type_17 { uint8_t bank_locator_str; uint8_t memory_type; uint16_t type_detail; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 19 - Memory Array Mapped Address */ struct smbios_type_19 { @@ -133,7 +133,7 @@ struct smbios_type_19 { uint32_t ending_address; uint16_t memory_array_handle; uint8_t partition_width; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 20 - Memory Device Mapped Address */ struct smbios_type_20 { @@ -145,18 +145,18 @@ struct smbios_type_20 { uint8_t partition_row_position; uint8_t interleave_position; uint8_t interleaved_data_depth; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 32 - System Boot Information */ struct smbios_type_32 { struct smbios_structure_header header; uint8_t reserved[6]; uint8_t boot_status; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 127 -- End-of-table */ struct smbios_type_127 { struct smbios_structure_header header; -} __attribute__((__packed__)); +} QEMU_PACKED; #endif /*QEMU_SMBIOS_H */ diff --git a/hw/srp.h b/hw/srp.h index afcd135c8f..3009bd56ce 100644 --- a/hw/srp.h +++ b/hw/srp.h @@ -106,7 +106,7 @@ struct srp_indirect_buf { struct srp_direct_buf table_desc; uint32_t len; struct srp_direct_buf desc_list[0]; -} __attribute__((packed)); +} QEMU_PACKED; enum { SRP_MULTICHAN_SINGLE = 0, @@ -141,7 +141,7 @@ struct srp_login_rsp { uint16_t buf_fmt; uint8_t rsp_flags; uint8_t reserved2[25]; -} __attribute__((packed)); +} QEMU_PACKED; struct srp_login_rej { uint8_t opcode; @@ -177,7 +177,7 @@ struct srp_tsk_mgmt { uint8_t reserved1[6]; uint64_t tag; uint8_t reserved2[4]; - uint64_t lun __attribute__((packed)); + uint64_t lun QEMU_PACKED; uint8_t reserved3[2]; uint8_t tsk_mgmt_func; uint8_t reserved4; @@ -198,7 +198,7 @@ struct srp_cmd { uint8_t data_in_desc_cnt; uint64_t tag; uint8_t reserved2[4]; - uint64_t lun __attribute__((packed)); + uint64_t lun QEMU_PACKED; uint8_t reserved3; uint8_t task_attr; uint8_t reserved4; @@ -235,6 +235,6 @@ struct srp_rsp { uint32_t sense_data_len; uint32_t resp_data_len; uint8_t data[0]; -} __attribute__((packed)); +} QEMU_PACKED; #endif /* SCSI_SRP_H */ diff --git a/hw/stellaris.c b/hw/stellaris.c index 2bf1c235dc..9b0db7f511 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -15,7 +15,6 @@ #include "i2c.h" #include "net.h" #include "boards.h" -#include "exec-memory.h" #define GPIO_A 0 #define GPIO_B 1 @@ -1261,7 +1260,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000}; static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; - MemoryRegion *address_space_mem = get_system_memory(); qemu_irq *pic; DeviceState *gpio_dev[7]; qemu_irq gpio_in[7][8]; @@ -1276,8 +1274,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, flash_size = ((board->dc0 & 0xffff) + 1) << 1; sram_size = (board->dc0 >> 18) + 1; - pic = armv7m_init(address_space_mem, - flash_size, sram_size, kernel_filename, cpu_model); + pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); if (board->dc1 & (1 << 16)) { dev = sysbus_create_varargs("stellaris-adc", 0x40038000, diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c index d5613ffffd..f9bd3da209 100644 --- a/hw/stellaris_enet.c +++ b/hw/stellaris_enet.c @@ -69,7 +69,7 @@ typedef struct { NICState *nic; NICConf conf; qemu_irq irq; - MemoryRegion mmio; + int mmio_index; } stellaris_enet_state; static void stellaris_enet_update(stellaris_enet_state *s) @@ -130,8 +130,7 @@ static int stellaris_enet_can_receive(VLANClientState *nc) return (s->np < 31); } -static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset, - unsigned size) +static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; uint32_t val; @@ -199,7 +198,7 @@ static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset, } static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, - uint64_t value, unsigned size) + uint32_t value) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; @@ -304,12 +303,17 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, } } -static const MemoryRegionOps stellaris_enet_ops = { - .read = stellaris_enet_read, - .write = stellaris_enet_write, - .endianness = DEVICE_NATIVE_ENDIAN, +static CPUReadMemoryFunc * const stellaris_enet_readfn[] = { + stellaris_enet_read, + stellaris_enet_read, + stellaris_enet_read }; +static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = { + stellaris_enet_write, + stellaris_enet_write, + stellaris_enet_write +}; static void stellaris_enet_reset(stellaris_enet_state *s) { s->mdv = 0x80; @@ -387,7 +391,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc) unregister_savevm(&s->busdev.qdev, "stellaris_enet", s); - memory_region_destroy(&s->mmio); + cpu_unregister_io_memory(s->mmio_index); g_free(s); } @@ -404,9 +408,10 @@ static int stellaris_enet_init(SysBusDevice *dev) { stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev); - memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet", - 0x1000); - sysbus_init_mmio_region(dev, &s->mmio); + s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn, + stellaris_enet_writefn, s, + DEVICE_NATIVE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, s->mmio_index); sysbus_init_irq(dev, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); diff --git a/hw/sun4u.c b/hw/sun4u.c index 1b60e4ef59..32e6ab9beb 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -261,7 +261,9 @@ void cpu_check_irqs(CPUState *env) pil |= 1 << 14; } - if (!pil) { + /* The bit corresponding to psrpil is (1<< psrpil), the next bit + is (2 << psrpil). */ + if (pil < (2 << env->psrpil)){ if (env->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); @@ -293,10 +295,12 @@ void cpu_check_irqs(CPUState *env) break; } } - } else { + } else if (env->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); + env->interrupt_index = 0; + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } } diff --git a/hw/sysbus.c b/hw/sysbus.c index 6e89f065b4..c365d39d24 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -131,6 +131,11 @@ void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory) dev->mmio[n].memory = memory; } +MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n) +{ + return dev->mmio[n].memory; +} + void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) { pio_addr_t i; @@ -256,32 +261,3 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) return strdup(path); } - -void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem) -{ - memory_region_add_subregion(get_system_memory(), addr, mem); -} - -void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem, unsigned priority) -{ - memory_region_add_subregion_overlap(get_system_memory(), addr, mem, - priority); -} - -void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem) -{ - memory_region_del_subregion(get_system_memory(), mem); -} - -void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem) -{ - memory_region_add_subregion(get_system_io(), addr, mem); -} - -void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem) -{ - memory_region_del_subregion(get_system_io(), mem); -} diff --git a/hw/sysbus.h b/hw/sysbus.h index b3e1f99db5..aa3d383277 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -50,6 +50,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, void sysbus_init_mmio_cb2(SysBusDevice *dev, mmio_mapfunc cb, mmio_mapfunc unmap); void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory); +MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n); void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p); void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target); void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); @@ -57,14 +58,6 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq); void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr); -void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem); -void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem, unsigned priority); -void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem); -void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr, - MemoryRegion *mem); -void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem); /* Legacy helper function for creating devices. */ DeviceState *sysbus_create_varargs(const char *name, diff --git a/hw/tusb6010.c b/hw/tusb6010.c index b2bf35934d..de6ffc6133 100644 --- a/hw/tusb6010.c +++ b/hw/tusb6010.c @@ -23,9 +23,11 @@ #include "usb.h" #include "omap.h" #include "irq.h" -#include "tusb6010.h" +#include "devices.h" +#include "sysbus.h" -struct TUSBState { +typedef struct TUSBState { + SysBusDevice busdev; MemoryRegion iomem[2]; qemu_irq irq; MUSBState *musb; @@ -59,7 +61,7 @@ struct TUSBState { uint32_t pullup[2]; uint32_t control_config; uint32_t otg_timer_val; -}; +} TUSBState; #define TUSB_DEVCLOCK 60000000 /* 60 MHz */ @@ -234,16 +236,6 @@ struct TUSBState { #define TUSB_EP_CONFIG_XFR_SIZE(v) ((v) & 0x7fffffff) #define TUSB_PROD_TEST_RESET_VAL 0xa596 -MemoryRegion *tusb6010_sync_io(TUSBState *s) -{ - return &s->iomem[0]; -} - -MemoryRegion *tusb6010_async_io(TUSBState *s) -{ - return &s->iomem[1]; -} - static void tusb_intr_update(TUSBState *s) { if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY) @@ -723,9 +715,33 @@ static void tusb_musb_core_intr(void *opaque, int source, int level) } } -TUSBState *tusb6010_init(qemu_irq intr) +static void tusb6010_power(TUSBState *s, int on) { - TUSBState *s = g_malloc0(sizeof(*s)); + if (!on) { + s->power = 0; + } else if (!s->power && on) { + s->power = 1; + /* Pull the interrupt down after TUSB6010 comes up. */ + s->intr_ok = 0; + tusb_intr_update(s); + qemu_mod_timer(s->pwr_timer, + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2); + } +} + +static void tusb6010_irq(void *opaque, int source, int level) +{ + if (source) { + tusb_musb_core_intr(opaque, source - 1, level); + } else { + tusb6010_power(opaque, level); + } +} + +static void tusb6010_reset(DeviceState *dev) +{ + TUSBState *s = FROM_SYSBUS(TUSBState, sysbus_from_qdev(dev)); + int i; s->test_reset = TUSB_PROD_TEST_RESET_VAL; s->host_mode = 0; @@ -735,28 +751,59 @@ TUSBState *tusb6010_init(qemu_irq intr) s->mask = 0xffffffff; s->intr = 0x00000000; s->otg_timer_val = 0; - memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async", - UINT32_MAX); - s->irq = intr; + s->scratch = 0; + s->prcm_config = 0; + s->prcm_mngmt = 0; + s->intr_ok = 0; + s->usbip_intr = 0; + s->usbip_mask = 0; + s->gpio_intr = 0; + s->gpio_mask = 0; + s->gpio_config = 0; + s->dma_intr = 0; + s->dma_mask = 0; + s->dma_map = 0; + s->dma_config = 0; + s->ep0_config = 0; + s->wkup_mask = 0; + s->pullup[0] = s->pullup[1] = 0; + s->control_config = 0; + for (i = 0; i < 15; i++) { + s->rx_config[i] = s->tx_config[i] = 0; + } +} + +static int tusb6010_init(SysBusDevice *dev) +{ + TUSBState *s = FROM_SYSBUS(TUSBState, dev); + qemu_irq *musb_irqs; + int i; s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s); s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s); - s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s, - __musb_irq_max)); - - return s; + memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async", + UINT32_MAX); + sysbus_init_mmio_region(dev, &s->iomem[0]); + sysbus_init_mmio_region(dev, &s->iomem[1]); + sysbus_init_irq(dev, &s->irq); + qdev_init_gpio_in(&dev->qdev, tusb6010_irq, __musb_irq_max + 1); + musb_irqs = g_new0(qemu_irq, __musb_irq_max); + for (i = 0; i < __musb_irq_max; i++) { + musb_irqs[i] = qdev_get_gpio_in(&dev->qdev, i + 1); + } + s->musb = musb_init(musb_irqs); + return 0; } -void tusb6010_power(TUSBState *s, int on) -{ - if (!on) - s->power = 0; - else if (!s->power && on) { - s->power = 1; +static SysBusDeviceInfo tusb6010_info = { + .init = tusb6010_init, + .qdev.name = "tusb6010", + .qdev.size = sizeof(TUSBState), + .qdev.reset = tusb6010_reset, +}; - /* Pull the interrupt down after TUSB6010 comes up. */ - s->intr_ok = 0; - tusb_intr_update(s); - qemu_mod_timer(s->pwr_timer, - qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2); - } +static void tusb6010_register_device(void) +{ + sysbus_register_withprop(&tusb6010_info); } + +device_init(tusb6010_register_device) diff --git a/hw/tusb6010.h b/hw/tusb6010.h deleted file mode 100644 index b85ee86215..0000000000 --- a/hw/tusb6010.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * tusb6010 interfaces - * - * Copyright 2011 Red Hat, Inc. and/or its affiliates - * - * Authors: - * Avi Kivity <avi@redhat.com> - * - * Derived from hw/devices.h. - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#ifndef TUSB6010_H -#define TUSB6010_H - -#include "targphys.h" -#include "memory.h" - -typedef struct TUSBState TUSBState; -TUSBState *tusb6010_init(qemu_irq intr); -MemoryRegion *tusb6010_sync_io(TUSBState *s); -MemoryRegion *tusb6010_async_io(TUSBState *s); -void tusb6010_power(TUSBState *s, int on); - -#endif diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 600cd1e5bd..f896f8c76b 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -41,6 +41,7 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e }; typedef struct UNINState { SysBusDevice busdev; PCIHostState host_state; + ReadWriteHandler data_handler; } UNINState; static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) @@ -99,70 +100,67 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) return retval; } -static void unin_data_write(void *opaque, target_phys_addr_t addr, - uint64_t val, unsigned len) +static void unin_data_write(ReadWriteHandler *handler, + pcibus_t addr, uint32_t val, int len) { - UNINState *s = opaque; - UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n", - addr, len, val); + UNINState *s = container_of(handler, UNINState, data_handler); + UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); pci_data_write(s->host_state.bus, unin_get_config_reg(s->host_state.config_reg, addr), val, len); } -static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr, - unsigned len) +static uint32_t unin_data_read(ReadWriteHandler *handler, + pcibus_t addr, int len) { - UNINState *s = opaque; + UNINState *s = container_of(handler, UNINState, data_handler); uint32_t val; val = pci_data_read(s->host_state.bus, unin_get_config_reg(s->host_state.config_reg, addr), len); - UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n", - addr, len, val); + UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); return val; } -static const MemoryRegionOps unin_data_ops = { - .read = unin_data_read, - .write = unin_data_write, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - static int pci_unin_main_init_device(SysBusDevice *dev) { UNINState *s; + int pci_mem_config, pci_mem_data; /* Use values found on a real PowerMac */ /* Uninorth main bus */ s = FROM_SYSBUS(UNINState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s, - "pci-conf-data", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + s->data_handler.read = unin_data_read; + s->data_handler.write = unin_data_write; + pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); qemu_register_reset(pci_unin_reset, &s->host_state); return 0; } - static int pci_u3_agp_init_device(SysBusDevice *dev) { UNINState *s; + int pci_mem_config, pci_mem_data; /* Uninorth U3 AGP bus */ s = FROM_SYSBUS(UNINState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s, - "pci-conf-data", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + s->data_handler.read = unin_data_read; + s->data_handler.write = unin_data_write; + pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); qemu_register_reset(pci_unin_reset, &s->host_state); @@ -172,32 +170,34 @@ static int pci_u3_agp_init_device(SysBusDevice *dev) static int pci_unin_agp_init_device(SysBusDevice *dev) { UNINState *s; + int pci_mem_config, pci_mem_data; /* Uninorth AGP bus */ s = FROM_SYSBUS(UNINState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, - &s->host_state, "pci-conf-data", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + pci_mem_data = pci_host_data_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); return 0; } static int pci_unin_internal_init_device(SysBusDevice *dev) { UNINState *s; + int pci_mem_config, pci_mem_data; /* Uninorth internal bus */ s = FROM_SYSBUS(UNINState, dev); - memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, - &s->host_state, "pci-conf-idx", 0x1000); - memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, - &s->host_state, "pci-conf-data", 0x1000); - sysbus_init_mmio_region(dev, &s->host_state.conf_mem); - sysbus_init_mmio_region(dev, &s->host_state.data_mem); + pci_mem_config = pci_host_conf_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + pci_mem_data = pci_host_data_register_mmio(&s->host_state, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x1000, pci_mem_config); + sysbus_init_mmio(dev, 0x1000, pci_mem_data); return 0; } diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 66aeb211af..c2f9241014 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -176,56 +176,56 @@ enum { */ }; -typedef struct __attribute__ ((__packed__)) CCID_Header { +typedef struct QEMU_PACKED CCID_Header { uint8_t bMessageType; uint32_t dwLength; uint8_t bSlot; uint8_t bSeq; } CCID_Header; -typedef struct __attribute__ ((__packed__)) CCID_BULK_IN { +typedef struct QEMU_PACKED CCID_BULK_IN { CCID_Header hdr; uint8_t bStatus; /* Only used in BULK_IN */ uint8_t bError; /* Only used in BULK_IN */ } CCID_BULK_IN; -typedef struct __attribute__ ((__packed__)) CCID_SlotStatus { +typedef struct QEMU_PACKED CCID_SlotStatus { CCID_BULK_IN b; uint8_t bClockStatus; } CCID_SlotStatus; -typedef struct __attribute__ ((__packed__)) CCID_Parameter { +typedef struct QEMU_PACKED CCID_Parameter { CCID_BULK_IN b; uint8_t bProtocolNum; uint8_t abProtocolDataStructure[0]; } CCID_Parameter; -typedef struct __attribute__ ((__packed__)) CCID_DataBlock { +typedef struct QEMU_PACKED CCID_DataBlock { CCID_BULK_IN b; uint8_t bChainParameter; uint8_t abData[0]; } CCID_DataBlock; /* 6.1.4 PC_to_RDR_XfrBlock */ -typedef struct __attribute__ ((__packed__)) CCID_XferBlock { +typedef struct QEMU_PACKED CCID_XferBlock { CCID_Header hdr; uint8_t bBWI; /* Block Waiting Timeout */ uint16_t wLevelParameter; /* XXX currently unused */ uint8_t abData[0]; } CCID_XferBlock; -typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn { +typedef struct QEMU_PACKED CCID_IccPowerOn { CCID_Header hdr; uint8_t bPowerSelect; uint16_t abRFU; } CCID_IccPowerOn; -typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff { +typedef struct QEMU_PACKED CCID_IccPowerOff { CCID_Header hdr; uint16_t abRFU; } CCID_IccPowerOff; -typedef struct __attribute__ ((__packed__)) CCID_SetParameters { +typedef struct QEMU_PACKED CCID_SetParameters { CCID_Header hdr; uint8_t bProtocolNum; uint16_t abRFU; diff --git a/hw/vga.c b/hw/vga.c index 851fd689b3..125fb293f2 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -176,6 +176,7 @@ static void vga_update_memory_access(VGACommonState *s) size = 0x8000; break; case 3: + default: base = 0xb8000; size = 0x8000; break; diff --git a/hw/vhost.c b/hw/vhost.c index 18860678ba..0870cb7d85 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -515,11 +515,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, }; struct VirtQueue *vvq = virtio_get_queue(vdev, idx); - if (!vdev->binding->set_host_notifier) { - fprintf(stderr, "binding does not support host notifiers\n"); - return -ENOSYS; - } - vq->num = state.num = virtio_queue_get_num(vdev, idx); r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); if (r) { @@ -567,12 +562,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, r = -errno; goto fail_alloc; } - r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true); - if (r < 0) { - fprintf(stderr, "Error binding host notifier: %d\n", -r); - goto fail_host_notifier; - } - file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file); if (r) { @@ -591,8 +580,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, fail_call: fail_kick: - vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false); -fail_host_notifier: fail_alloc: cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx), 0, 0); @@ -618,12 +605,6 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev, .index = idx, }; int r; - r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false); - if (r < 0) { - fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r); - fflush(stderr); - } - assert (r >= 0); r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state); if (r < 0) { fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); @@ -697,6 +678,60 @@ bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev) hdev->force; } +/* Stop processing guest IO notifications in qemu. + * Start processing them in vhost in kernel. + */ +int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + int i, r; + if (!vdev->binding->set_host_notifier) { + fprintf(stderr, "binding does not support host notifiers\n"); + r = -ENOSYS; + goto fail; + } + + for (i = 0; i < hdev->nvqs; ++i) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r); + goto fail_vq; + } + } + + return 0; +fail_vq: + while (--i >= 0) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r); + fflush(stderr); + } + assert (r >= 0); + } +fail: + return r; +} + +/* Stop processing guest IO notifications in vhost. + * Start processing them in qemu. + * This might actually run the qemu handlers right away, + * so virtio in qemu must be completely setup when this is called. + */ +void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + int i, r; + + for (i = 0; i < hdev->nvqs; ++i) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r); + fflush(stderr); + } + assert (r >= 0); + } +} + +/* Host notifiers must be enabled at this point. */ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; @@ -762,6 +797,7 @@ fail: return r; } +/* Host notifiers must be enabled at this point. */ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; diff --git a/hw/vhost.h b/hw/vhost.h index c8c595a147..c9452f0732 100644 --- a/hw/vhost.h +++ b/hw/vhost.h @@ -46,5 +46,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev); bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); +int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); +void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); #endif diff --git a/hw/vhost_net.c b/hw/vhost_net.c index a55981200d..950a6b8d99 100644 --- a/hw/vhost_net.c +++ b/hw/vhost_net.c @@ -139,16 +139,22 @@ int vhost_net_start(struct vhost_net *net, { struct vhost_vring_file file = { }; int r; + + net->dev.nvqs = 2; + net->dev.vqs = net->vqs; + + r = vhost_dev_enable_notifiers(&net->dev, dev); + if (r < 0) { + goto fail_notifiers; + } if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr_mrg_rxbuf)); } - net->dev.nvqs = 2; - net->dev.vqs = net->vqs; r = vhost_dev_start(&net->dev, dev); if (r < 0) { - return r; + goto fail_start; } net->vc->info->poll(net->vc, false); @@ -173,6 +179,9 @@ fail: if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } +fail_start: + vhost_dev_disable_notifiers(&net->dev, dev); +fail_notifiers: return r; } @@ -190,6 +199,7 @@ void vhost_net_stop(struct vhost_net *net, if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } + vhost_dev_disable_notifiers(&net->dev, dev); } void vhost_net_cleanup(struct vhost_net *net) diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c index aa9e51222f..333050cdac 100644 --- a/hw/virtex_ml507.c +++ b/hw/virtex_ml507.c @@ -196,7 +196,7 @@ static void virtex_init(ram_addr_t ram_size, target_phys_addr_t ram_base = 0; DriveInfo *dinfo; ram_addr_t phys_ram; - MemoryRegion *phys_flash = g_new(MemoryRegion, 1); + ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; clk_setup_t clk_setup[7]; int kernel_size; @@ -215,13 +215,12 @@ static void virtex_init(ram_addr_t ram_size, phys_ram = qemu_ram_alloc(NULL, "ram", ram_size); cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be, - NULL, "virtex.flash", FLASH_SIZE); + phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(0xfc000000, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, - 1, 0x89, 0x18, 0x0000, 0x0); + 1, 0x89, 0x18, 0x0000, 0x0, 1); cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT]; dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0); diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h index e20cf6bc0d..73300ddc86 100644 --- a/hw/virtio-balloon.h +++ b/hw/virtio-balloon.h @@ -50,6 +50,6 @@ struct virtio_balloon_config typedef struct VirtIOBalloonStat { uint16_t tag; uint64_t val; -} __attribute__((packed)) VirtIOBalloonStat; +} QEMU_PACKED VirtIOBalloonStat; #endif diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index dad8c0a6a2..2a8ccd0aa9 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -47,6 +47,7 @@ typedef struct VirtIOBlockReq struct virtio_scsi_inhdr *scsi; QEMUIOVector qiov; struct VirtIOBlockReq *next; + BlockAcctCookie acct; } VirtIOBlockReq; static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) @@ -58,8 +59,6 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) stb_p(&req->in->status, status); virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in)); virtio_notify(&s->vdev, s->vq); - - g_free(req); } static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, @@ -81,6 +80,8 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, vm_stop(VMSTOP_DISKFULL); } else { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); + bdrv_acct_done(s->bs, &req->acct); + g_free(req); bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); } @@ -100,6 +101,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret) } virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + bdrv_acct_done(req->dev->bs, &req->acct); + g_free(req); } static void virtio_blk_flush_complete(void *opaque, int ret) @@ -113,6 +116,8 @@ static void virtio_blk_flush_complete(void *opaque, int ret) } virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + bdrv_acct_done(req->dev->bs, &req->acct); + g_free(req); } static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s) @@ -155,6 +160,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) */ if (req->elem.out_num < 2 || req->elem.in_num < 3) { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); + g_free(req); return; } @@ -163,6 +169,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) */ if (req->elem.out_num > 2 && req->elem.in_num > 3) { virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); + g_free(req); return; } @@ -229,11 +236,13 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) stl_p(&req->scsi->data_len, hdr.dxfer_len); virtio_blk_req_complete(req, status); + g_free(req); } #else static void virtio_blk_handle_scsi(VirtIOBlockReq *req) { virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); + g_free(req); } #endif /* __linux__ */ @@ -266,6 +275,8 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) { BlockDriverAIOCB *acb; + bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH); + /* * Make sure all outstanding writes are posted to the backing device. */ @@ -284,6 +295,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) sector = ldq_p(&req->out->sector); + bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE); + trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512); if (sector & req->dev->sector_mask) { @@ -317,6 +330,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req) sector = ldq_p(&req->out->sector); + bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ); + if (sector & req->dev->sector_mask) { virtio_blk_rw_complete(req, -EIO); return; @@ -370,6 +385,7 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, s->serial ? s->serial : "", MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES)); virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + g_free(req); } else if (type & VIRTIO_BLK_T_OUT) { qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1], req->elem.out_num - 1); diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h index 5645d2bf3c..244dce45aa 100644 --- a/hw/virtio-blk.h +++ b/hw/virtio-blk.h @@ -49,7 +49,7 @@ struct virtio_blk_config uint8_t alignment_offset; uint16_t min_io_size; uint32_t opt_io_size; -} __attribute__((packed)); +} QEMU_PACKED; /* These two define direction. */ #define VIRTIO_BLK_T_IN 0 diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 8af9a1ce55..44687414c9 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -72,7 +72,7 @@ struct virtio_net_config uint8_t mac[ETH_ALEN]; /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ uint16_t status; -} __attribute__((packed)); +} QEMU_PACKED; /* This is the first element of the scatter-gather list. If you don't * specify GSO or CSUM features, you can simply ignore the header. */ diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h index 36e9d222e5..ab138038c0 100644 --- a/hw/virtio-serial.h +++ b/hw/virtio-serial.h @@ -37,7 +37,7 @@ struct virtio_console_config { uint16_t rows; uint32_t max_nr_ports; -} __attribute__((packed)); +} QEMU_PACKED; struct virtio_console_control { uint32_t id; /* Port number */ diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 52d2d26f1b..aa682376ad 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -70,7 +70,7 @@ struct vmsvga_state_s { union { uint32_t *fifo; - struct __attribute__((__packed__)) { + struct QEMU_PACKED { uint32_t min; uint32_t max; uint32_t next_cmd; diff --git a/hw/xen_disk.c b/hw/xen_disk.c index 31f91514f2..bd5c66916b 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -79,6 +79,7 @@ struct ioreq { struct XenBlkDev *blkdev; QLIST_ENTRY(ioreq) list; + BlockAcctCookie acct; }; struct XenBlkDev { @@ -401,6 +402,7 @@ static void qemu_aio_complete(void *opaque, int ret) ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; ioreq_unmap(ioreq); ioreq_finish(ioreq); + bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct); qemu_bh_schedule(ioreq->blkdev->bh); } @@ -419,6 +421,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) switch (ioreq->req.operation) { case BLKIF_OP_READ: + bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ); ioreq->aio_inflight++; bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE, @@ -429,6 +432,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) if (!ioreq->req.nr_segments) { break; } + + bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE); ioreq->aio_inflight++; bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE, diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c index f35ba8461a..6f44c8466e 100644 --- a/hw/xilinx_ethlite.c +++ b/hw/xilinx_ethlite.c @@ -50,6 +50,7 @@ struct xlx_ethlite { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq irq; NICState *nic; NICConf conf; @@ -70,7 +71,8 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s) } } -static uint32_t eth_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +eth_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_ethlite *s = opaque; uint32_t r = 0; @@ -98,10 +100,12 @@ static uint32_t eth_readl (void *opaque, target_phys_addr_t addr) } static void -eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +eth_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_ethlite *s = opaque; unsigned int base = 0; + uint32_t value = val64; addr >>= 2; switch (addr) @@ -146,12 +150,14 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static CPUReadMemoryFunc * const eth_read[] = { - NULL, NULL, ð_readl, -}; - -static CPUWriteMemoryFunc * const eth_write[] = { - NULL, NULL, ð_writel, +static const MemoryRegionOps eth_ops = { + .read = eth_read, + .write = eth_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static int eth_can_rx(VLANClientState *nc) @@ -206,13 +212,12 @@ static NetClientInfo net_xilinx_ethlite_info = { static int xilinx_ethlite_init(SysBusDevice *dev) { struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev); - int regs; sysbus_init_irq(dev, &s->irq); s->rxbuf = 0; - regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, regs); + memory_region_init_io(&s->mmio, ð_ops, s, "xilinx-ethlite", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c index cb72d5a14e..58b73d95cc 100644 --- a/hw/xilinx_intc.c +++ b/hw/xilinx_intc.c @@ -40,6 +40,7 @@ struct xlx_pic { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq parent_irq; /* Configuration reg chosen at synthesis-time. QEMU populates @@ -72,7 +73,8 @@ static void update_irq(struct xlx_pic *p) } } -static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +pic_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_pic *p = opaque; uint32_t r = 0; @@ -91,9 +93,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) } static void -pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +pic_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_pic *p = opaque; + uint32_t value = val64; addr >>= 2; D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value)); @@ -116,14 +120,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) update_irq(p); } -static CPUReadMemoryFunc * const pic_read[] = { - NULL, NULL, - &pic_readl, -}; - -static CPUWriteMemoryFunc * const pic_write[] = { - NULL, NULL, - &pic_writel, +static const MemoryRegionOps pic_ops = { + .read = pic_read, + .write = pic_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void irq_handler(void *opaque, int irq, int level) @@ -148,13 +152,12 @@ static void irq_handler(void *opaque, int irq, int level) static int xilinx_intc_init(SysBusDevice *dev) { struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev); - int pic_regs; qdev_init_gpio_in(&dev->qdev, irq_handler, 32); sysbus_init_irq(dev, &p->parent_irq); - pic_regs = cpu_register_io_memory(pic_read, pic_write, p, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, pic_regs); + memory_region_init_io(&p->mmio, &pic_ops, p, "xilinx-pic", R_MAX * 4); + sysbus_init_mmio_region(dev, &p->mmio); return 0; } diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c index f1c7abc99e..8779c56f0b 100644 --- a/hw/xilinx_timer.c +++ b/hw/xilinx_timer.c @@ -59,6 +59,7 @@ struct xlx_timer struct timerblock { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq irq; uint32_t nr_timers; uint32_t freq_hz; @@ -85,7 +86,8 @@ static void timer_update_irq(struct timerblock *t) qemu_set_irq(t->irq, !!irq); } -static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +timer_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct timerblock *t = opaque; struct xlx_timer *xt; @@ -134,11 +136,13 @@ static void timer_enable(struct xlx_timer *xt) } static void -timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +timer_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct timerblock *t = opaque; struct xlx_timer *xt; unsigned int timer; + uint32_t value = val64; addr >>= 2; timer = timer_from_addr(addr); @@ -166,14 +170,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) timer_update_irq(t); } -static CPUReadMemoryFunc * const timer_read[] = { - NULL, NULL, - &timer_readl, -}; - -static CPUWriteMemoryFunc * const timer_write[] = { - NULL, NULL, - &timer_writel, +static const MemoryRegionOps timer_ops = { + .read = timer_read, + .write = timer_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void timer_hit(void *opaque) @@ -192,7 +196,6 @@ static int xilinx_timer_init(SysBusDevice *dev) { struct timerblock *t = FROM_SYSBUS(typeof (*t), dev); unsigned int i; - int timer_regs; /* All timers share a single irq line. */ sysbus_init_irq(dev, &t->irq); @@ -209,9 +212,9 @@ static int xilinx_timer_init(SysBusDevice *dev) ptimer_set_freq(xt->ptimer, t->freq_hz); } - timer_regs = cpu_register_io_memory(timer_read, timer_write, t, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs); + memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer", + R_MAX * 4 * t->nr_timers); + sysbus_init_mmio_region(dev, &t->mmio); return 0; } diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c index 467a26cc9e..ceb7b4d9ed 100644 --- a/hw/xilinx_uartlite.c +++ b/hw/xilinx_uartlite.c @@ -49,6 +49,7 @@ struct xlx_uartlite { SysBusDevice busdev; + MemoryRegion mmio; CharDriverState *chr; qemu_irq irq; @@ -82,7 +83,8 @@ static void uart_update_status(struct xlx_uartlite *s) s->regs[R_STATUS] = r; } -static uint32_t uart_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +uart_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_uartlite *s = opaque; uint32_t r = 0; @@ -107,9 +109,11 @@ static uint32_t uart_readl (void *opaque, target_phys_addr_t addr) } static void -uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +uart_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_uartlite *s = opaque; + uint32_t value = val64; unsigned char ch = value; addr >>= 2; @@ -147,16 +151,14 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value) uart_update_irq(s); } -static CPUReadMemoryFunc * const uart_read[] = { - &uart_readl, - &uart_readl, - &uart_readl, -}; - -static CPUWriteMemoryFunc * const uart_write[] = { - &uart_writel, - &uart_writel, - &uart_writel, +static const MemoryRegionOps uart_ops = { + .read = uart_read, + .write = uart_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4 + } }; static void uart_rx(void *opaque, const uint8_t *buf, int size) @@ -196,14 +198,12 @@ static void uart_event(void *opaque, int event) static int xilinx_uartlite_init(SysBusDevice *dev) { struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev); - int uart_regs; sysbus_init_irq(dev, &s->irq); uart_update_status(s); - uart_regs = cpu_register_io_memory(uart_read, uart_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, uart_regs); + memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); s->chr = qdev_init_chardev(&dev->qdev); if (s->chr) diff --git a/hw/z2.c b/hw/z2.c index d7b8d5327b..f93a1bf0fe 100644 --- a/hw/z2.c +++ b/hw/z2.c @@ -280,11 +280,10 @@ static void z2_init(ram_addr_t ram_size, uint32_t sector_len = 0x10000; PXA2xxState *cpu; DriveInfo *dinfo; - const MemoryRegionOps *flash_ops; + int be; void *z2_lcd; i2c_bus *bus; DeviceState *wm; - MemoryRegion *flash = g_new(MemoryRegion, 1); if (!cpu_model) { cpu_model = "pxa270-c5"; @@ -294,9 +293,9 @@ static void z2_init(ram_addr_t ram_size, cpu = pxa270_init(z2_binfo.ram_size, cpu_model); #ifdef TARGET_WORDS_BIGENDIAN - flash_ops = &pflash_cfi01_ops_be; + be = 1; #else - flash_ops = &pflash_cfi01_ops_le; + be = 0; #endif dinfo = drive_get(IF_PFLASH, 0, 0); if (!dinfo) { @@ -305,11 +304,11 @@ static void z2_init(ram_addr_t ram_size, exit(1); } - memory_region_init_rom_device(flash, flash_ops, - NULL, "z2.flash0", Z2_FLASH_SIZE); - if (!pflash_cfi01_register(Z2_FLASH_BASE, flash, + if (!pflash_cfi01_register(Z2_FLASH_BASE, + qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE), dinfo->bdrv, sector_len, - Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) { + Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0, + be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); exit(1); } diff --git a/hw/zaurus.c b/hw/zaurus.c index c24aeb5763..0eeacf7cb3 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -246,7 +246,7 @@ device_init(scoop_register); #define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a) -static struct __attribute__ ((__packed__)) sl_param_info { +static struct QEMU_PACKED sl_param_info { uint32_t comadj_keyword; int32_t comadj; |