From cfe5f011042456ad6ebd815f5ce4177befedd79a Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 4 Aug 2011 15:55:30 +0300 Subject: [PATCH] pflash_cfi01/pflash_cfi02: convert to memory API cfi02 is annoying in that is ignores some address bits; we probably want explicit support in the memory API for that. In order to get the correct opaque into the MemoryRegion object, the allocation scheme is changed so that the flash emulation code allocates memory, instead of the caller. This clears a FIXME in the flash code. Signed-off-by: Avi Kivity --- hw/collie.c | 7 +-- hw/flash.h | 13 ++++- hw/gumstix.c | 6 +-- hw/lm32_boards.c | 8 +-- hw/mainstone.c | 7 ++- hw/milkymist.c | 4 +- hw/mips_malta.c | 54 +++++++++++++------- hw/mips_r4k.c | 13 ++--- hw/musicpal.c | 8 +-- hw/omap_sx1.c | 8 +-- hw/petalogix_ml605_mmu.c | 5 +- hw/petalogix_s3adsp1800_mmu.c | 5 +- hw/pflash_cfi01.c | 78 ++++++++++++---------------- hw/pflash_cfi02.c | 95 ++++++++++++++++++----------------- hw/ppc405_boards.c | 49 ++++++++++-------- hw/r2d.c | 2 +- hw/virtex_ml507.c | 4 +- hw/z2.c | 2 +- 18 files changed, 187 insertions(+), 181 deletions(-) diff --git a/hw/collie.c b/hw/collie.c index 156404d9f..a10cc1b90 100644 --- a/hw/collie.c +++ b/hw/collie.c @@ -26,7 +26,6 @@ static void collie_init(ram_addr_t ram_size, { StrongARMState *s; DriveInfo *dinfo; - ram_addr_t phys_flash; if (!cpu_model) { cpu_model = "sa1110"; @@ -34,15 +33,13 @@ static void collie_init(ram_addr_t ram_size, s = sa1110_init(collie_binfo.ram_size, cpu_model); - phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(SA_CS0, phys_flash, + pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); - phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 1); - pflash_cfi01_register(SA_CS1, phys_flash, + pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); diff --git a/hw/flash.h b/hw/flash.h index 270be5e12..9c9e5265b 100644 --- a/hw/flash.h +++ b/hw/flash.h @@ -1,15 +1,22 @@ /* NOR flash devices */ + +#include "memory.h" + typedef struct pflash_t pflash_t; /* pflash_cfi01.c */ -pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, int be); /* pflash_cfi02.c */ -pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, @@ -17,6 +24,8 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, uint16_t unlock_addr0, uint16_t unlock_addr1, int be); +MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl); + /* nand.c */ DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id); void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, diff --git a/hw/gumstix.c b/hw/gumstix.c index 853f7e1ee..b8b76f4b8 100644 --- a/hw/gumstix.c +++ b/hw/gumstix.c @@ -67,8 +67,7 @@ static void connex_init(ram_addr_t ram_size, #else be = 0; #endif - if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom", - connex_rom), + if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom, dinfo->bdrv, sector_len, connex_rom / sector_len, 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); @@ -106,8 +105,7 @@ static void verdex_init(ram_addr_t ram_size, #else be = 0; #endif - if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom", - verdex_rom), + if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom, dinfo->bdrv, sector_len, verdex_rom / sector_len, 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c index d18aad743..e4acac174 100644 --- a/hw/lm32_boards.c +++ b/hw/lm32_boards.c @@ -77,7 +77,6 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used, CPUState *env; DriveInfo *dinfo; ram_addr_t phys_ram; - ram_addr_t phys_flash; qemu_irq *cpu_irq, irq[32]; ResetInfo *reset_info; int i; @@ -108,10 +107,9 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used, phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size); cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - 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, + pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); @@ -165,7 +163,6 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used, CPUState *env; DriveInfo *dinfo; ram_addr_t phys_ram; - ram_addr_t phys_flash; qemu_irq *cpu_irq, irq[32]; HWSetup *hw; ResetInfo *reset_info; @@ -203,10 +200,9 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used, phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size); cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - 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, + pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); diff --git a/hw/mainstone.c b/hw/mainstone.c index 4792f0e3e..c0524d7ba 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -126,10 +126,9 @@ static void mainstone_common_init(ram_addr_t ram_size, exit(1); } - if (!pflash_cfi01_register(mainstone_flash_base[i], - qemu_ram_alloc(NULL, i ? "mainstone.flash1" : - "mainstone.flash0", - MAINSTONE_FLASH), + if (!pflash_cfi01_register(mainstone_flash_base[i], NULL, + i ? "mainstone.flash1" : "mainstone.flash0", + MAINSTONE_FLASH, dinfo->bdrv, sector_len, MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0, be)) { diff --git a/hw/milkymist.c b/hw/milkymist.c index 93288c840..a44b80c61 100644 --- a/hw/milkymist.c +++ b/hw/milkymist.c @@ -82,7 +82,6 @@ milkymist_init(ram_addr_t ram_size_not_used, int kernel_size; DriveInfo *dinfo; ram_addr_t phys_sdram; - ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; int i; char *bios_filename; @@ -113,10 +112,9 @@ milkymist_init(ram_addr_t ram_size_not_used, cpu_register_physical_memory(sdram_base, sdram_size, phys_sdram | IO_MEM_RAM); - 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, + pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1); diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 86a8ba07d..31d443eb2 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -46,6 +46,7 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" //#define DEBUG_BOARD_INIT @@ -761,8 +762,10 @@ void mips_malta_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { char *filename; + pflash_t *fl; ram_addr_t ram_offset; - ram_addr_t bios_offset; + MemoryRegion *system_memory = get_system_memory(); + MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); target_long bios_size; int64_t kernel_entry; PCIBus *pci_bus; @@ -811,17 +814,9 @@ void mips_malta_init (ram_addr_t ram_size, exit(1); } ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_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. */ - 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 @@ -833,12 +828,19 @@ void mips_malta_init (ram_addr_t ram_size, /* Load firmware in flash / BIOS unless we boot directly into a kernel. */ if (kernel_filename) { /* Write a small bootloader to the flash location. */ + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_add_subregion(system_memory, 0x1e000000LL, bios); + memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); - write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry); + write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { dinfo = drive_get(IF_PFLASH, 0, fl_idx); if (dinfo) { @@ -847,15 +849,31 @@ 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 " - "offset %08lx addr %08llx '%s' %x\n", - fl_idx, bios_size, bios_offset, 0x1e000000LL, + "addr %08llx '%s' %x\n", + fl_idx, bios_size, 0x1e000000LL, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi01_register(0x1e000000LL, bios_offset, - dinfo->bdrv, 65536, fl_sectors, - 4, 0x0000, 0x0000, 0x0000, 0x0000, be); - fl_idx++; + fl = pflash_cfi01_register(0x1e000000LL, + NULL, "mips_malta.bios", BIOS_SIZE, + dinfo->bdrv, 65536, fl_sectors, + 4, 0x0000, 0x0000, 0x0000, 0x0000, be); + bios = pflash_cfi01_get_memory(fl); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_init_alias(bios_alias, "bios.1fc", + bios, 0, BIOS_SIZE); + memory_region_add_subregion(system_memory, 0x1fc00000LL, + bios_alias); + fl_idx++; } else { + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_init_alias(bios_alias, "bios.1fc", + bios, 0, BIOS_SIZE); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_add_subregion(system_memory, 0x1e000000LL, bios); + memory_region_add_subregion(system_memory, 0x1fc00000LL, + bios_alias); /* Load a BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; @@ -878,7 +896,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 = qemu_get_ram_ptr(bios_offset);; + uint32_t *addr = memory_region_get_ram_ptr(bios); uint32_t *end = addr + bios_size; while (addr < end) { bswap32s(addr); @@ -890,7 +908,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(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420); + stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420); /* Init internal devices */ cpu_mips_irq_init_cpu(env); diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index 9d90568e4..5d002c5a2 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -23,6 +23,7 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 @@ -163,7 +164,7 @@ void mips_r4k_init (ram_addr_t ram_size, { char *filename; ram_addr_t ram_offset; - ram_addr_t bios_offset; + MemoryRegion *bios; int bios_size; CPUState *env; ResetData *reset_info; @@ -227,15 +228,15 @@ void mips_r4k_init (ram_addr_t ram_size, be = 0; #endif if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { - bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE); - cpu_register_physical_memory(0x1fc00000, BIOS_SIZE, - bios_offset | IO_MEM_ROM); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { uint32_t mips_rom = 0x00400000; - bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom); - if (!pflash_cfi01_register(0x1fc00000, bios_offset, + if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom, dinfo->bdrv, sector_len, mips_rom / sector_len, 4, 0, 0, 0, 0, be)) { diff --git a/hw/musicpal.c b/hw/musicpal.c index 63dd39117..ade5a91fe 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1565,16 +1565,16 @@ static void musicpal_init(ram_addr_t ram_size, * image is smaller than 32 MB. */ #ifdef TARGET_WORDS_BIGENDIAN - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, - "musicpal.flash", flash_size), + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, 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, 1); #else - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, - "musicpal.flash", flash_size), + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL, + "musicpal.flash", flash_size, dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c index a7b687bc4..15cfbb52f 100644 --- a/hw/omap_sx1.c +++ b/hw/omap_sx1.c @@ -161,8 +161,8 @@ static void sx1_init(ram_addr_t ram_size, #endif if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) { - if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL, - "omap_sx1.flash0-1", flash_size), + if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL, + "omap_sx1.flash0-1", flash_size, dinfo->bdrv, sector_size, flash_size / sector_size, 4, 0, 0, 0, 0, be)) { @@ -182,8 +182,8 @@ static void sx1_init(ram_addr_t ram_size, cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size, OMAP_CS1_SIZE - flash1_size, io); - if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL, - "omap_sx1.flash1-1", flash1_size), + if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL, + "omap_sx1.flash1-1", flash1_size, dinfo->bdrv, sector_size, flash1_size / sector_size, 4, 0, 0, 0, 0, be)) { diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c index e3ca310ef..38db521b3 100644 --- a/hw/petalogix_ml605_mmu.c +++ b/hw/petalogix_ml605_mmu.c @@ -149,7 +149,6 @@ 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; - ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; /* init CPUs */ @@ -169,11 +168,11 @@ 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); - 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, + pflash_cfi01_register(FLASH_BASEADDR, + NULL, "petalogix_ml605.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 2, 0x89, 0x18, 0x0000, 0x0, 0); diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c index a43fb4c95..66fb96d8e 100644 --- a/hw/petalogix_s3adsp1800_mmu.c +++ b/hw/petalogix_s3adsp1800_mmu.c @@ -127,7 +127,6 @@ 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; - ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; /* init CPUs */ @@ -148,9 +147,9 @@ 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); - phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(0xa0000000, phys_flash, + pflash_cfi01_register(0xa0000000, + NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index 90e1301c5..ce48fdfae 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -40,6 +40,7 @@ #include "flash.h" #include "block.h" #include "qemu-timer.h" +#include "exec-memory.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -74,8 +75,7 @@ struct pflash_t { target_phys_addr_t counter; unsigned int writeblock_size; QEMUTimer *timer; - ram_addr_t off; - int fl_mem; + MemoryRegion mem; void *storage; }; @@ -89,8 +89,7 @@ static void pflash_timer (void *opaque) if (pfl->bypass) { pfl->wcycle = 2; } else { - cpu_register_physical_memory(pfl->base, pfl->total_len, - pfl->off | IO_MEM_ROMD | pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, true); pfl->wcycle = 0; } pfl->cmd = 0; @@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, if (!pfl->wcycle) { /* Set the device in I/O access mode */ - cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, false); } switch (pfl->wcycle) { @@ -422,8 +421,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, __func__, offset, pfl->wcycle, pfl->cmd, value); reset_flash: - cpu_register_physical_memory(pfl->base, pfl->total_len, - pfl->off | IO_MEM_ROMD | pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, true); pfl->bypass = 0; pfl->wcycle = 0; @@ -514,28 +512,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { - &pflash_writeb_be, - &pflash_writew_be, - &pflash_writel_be, +static 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 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, +static 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, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -574,12 +564,13 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, - int be) + uint16_t id2, uint16_t id3, int be) { pflash_t *pfl; target_phys_addr_t total_len; @@ -596,27 +587,19 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, pfl = g_malloc0(sizeof(pflash_t)); - /* FIXME: Allocate ram ourselves. */ - 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); + memory_region_init_rom_device( + &pfl->mem, be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl, + qdev, name, size); + pfl->storage = memory_region_get_ram_ptr(&pfl->mem); + memory_region_add_subregion(get_system_memory(), base, &pfl->mem); 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) { - cpu_unregister_io_memory(pfl->fl_mem); + memory_region_del_subregion(get_system_memory(), &pfl->mem); + memory_region_destroy(&pfl->mem); g_free(pfl); return NULL; } @@ -724,3 +707,8 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, return pfl; } + +MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl) +{ + return &fl->mem; +} diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index ac5115e4c..4dbec8721 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -39,6 +39,7 @@ #include "flash.h" #include "qemu-timer.h" #include "block.h" +#include "exec-memory.h" //#define PFLASH_DEBUG #ifdef PFLASH_DEBUG @@ -69,25 +70,38 @@ struct pflash_t { uint8_t cfi_len; uint8_t cfi_table[0x52]; QEMUTimer *timer; - ram_addr_t off; - int fl_mem; + /* 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; int rom_mode; int read_counter; /* used for lazy switch-back to rom mode */ void *storage; }; -static void pflash_register_memory(pflash_t *pfl, int rom_mode) +/* + * Set up replicated mappings of the same region. + */ +static void pflash_setup_mappings(pflash_t *pfl) { - unsigned long phys_offset = pfl->fl_mem; - int i; - - if (rom_mode) - phys_offset |= pfl->off | IO_MEM_ROMD; - pfl->rom_mode = rom_mode; + unsigned i; + target_phys_addr_t size = memory_region_size(&pfl->orig_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", + &pfl->orig_mem, 0, size); + memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]); + } +} - 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_register_memory(pflash_t *pfl, int rom_mode) +{ + memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode); } static void pflash_timer (void *opaque) @@ -538,28 +552,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -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, +static 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_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, +static 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, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -598,7 +604,9 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, @@ -618,32 +626,25 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, return NULL; #endif pfl = g_malloc0(sizeof(pflash_t)); - /* FIXME: Allocate ram ourselves. */ - 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; + memory_region_init_rom_device( + &pfl->orig_mem, be ? &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, pfl, + qdev, name, size); + pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem); 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); + 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/ppc405_boards.c b/hw/ppc405_boards.c index dec165e40..e6c8ac67d 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -32,6 +32,7 @@ #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) @@ -181,7 +182,8 @@ static void ref405ep_init (ram_addr_t ram_size, ppc4xx_bd_info_t bd; CPUPPCState *env; qemu_irq *pic; - ram_addr_t sram_offset, bios_offset, bdloc; + MemoryRegion *bios; + ram_addr_t sram_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; @@ -224,15 +226,15 @@ 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); - 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 offset %08lx addr %lx '%s' %d\n", - fl_idx, bios_size, bios_offset, -bios_size, + " at addr %lx '%s' %d\n", + fl_idx, bios_size, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, + pflash_cfi02_register((uint32_t)(-bios_size), + NULL, "ef405ep.bios", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); @@ -243,12 +245,13 @@ static void ref405ep_init (ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("Load BIOS from file\n"); #endif - bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, 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, qemu_get_ram_ptr(bios_offset)); + bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); g_free(filename); } else { bios_size = -1; @@ -259,8 +262,9 @@ static void ref405ep_init (ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(get_system_memory(), + (uint32_t)(-bios_size), bios); } /* Register FPGA */ #ifdef DEBUG_BOARD_INIT @@ -507,7 +511,7 @@ static void taihu_405ep_init(ram_addr_t ram_size, { char *filename; qemu_irq *pic; - ram_addr_t bios_offset; + MemoryRegion *bios; MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); target_phys_addr_t ram_bases[2], ram_sizes[2]; long bios_size; @@ -544,14 +548,14 @@ 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; - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size); #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at offset %08lx addr %lx '%s' %d\n", - fl_idx, bios_size, bios_offset, -bios_size, + " at addr %lx '%s' %d\n", + fl_idx, bios_size, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, + pflash_cfi02_register((uint32_t)(-bios_size), + NULL, "taihu_405ep.bios", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); @@ -564,10 +568,11 @@ static void taihu_405ep_init(ram_addr_t ram_size, #endif if (bios_name == NULL) bios_name = BIOS_FILENAME; - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); + bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); g_free(filename); } else { bios_size = -1; @@ -578,8 +583,9 @@ static void taihu_405ep_init(ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(get_system_memory(), (uint32_t)(-bios_size), + bios); } /* Register Linux flash */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); @@ -590,12 +596,11 @@ 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 offset %08lx addr " TARGET_FMT_lx " '%s'\n", - fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000, + " at addr " TARGET_FMT_lx " '%s'\n", + fl_idx, bios_size, (target_ulong)0xfc000000, bdrv_get_device_name(dinfo->bdrv)); #endif - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size); - pflash_cfi02_register(0xfc000000, bios_offset, + pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); diff --git a/hw/r2d.c b/hw/r2d.c index 771f3d073..b8b0df3bb 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -267,7 +267,7 @@ static void r2d_init(ram_addr_t ram_size, /* onboard flash memory */ dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE), + pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (16 * 1024), FLASH_SIZE >> 16, 1, 4, 0x0000, 0x0000, 0x0000, 0x0000, diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c index 333050cda..7459b0bbe 100644 --- a/hw/virtex_ml507.c +++ b/hw/virtex_ml507.c @@ -196,7 +196,6 @@ static void virtex_init(ram_addr_t ram_size, target_phys_addr_t ram_base = 0; DriveInfo *dinfo; ram_addr_t phys_ram; - ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; clk_setup_t clk_setup[7]; int kernel_size; @@ -215,9 +214,8 @@ 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); - phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(0xfc000000, phys_flash, + pflash_cfi01_register(0xfc000000, NULL, "virtex.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); diff --git a/hw/z2.c b/hw/z2.c index f93a1bf0f..b6ae60865 100644 --- a/hw/z2.c +++ b/hw/z2.c @@ -305,7 +305,7 @@ static void z2_init(ram_addr_t ram_size, } if (!pflash_cfi01_register(Z2_FLASH_BASE, - qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE), + NULL, "z2.flash0", Z2_FLASH_SIZE, dinfo->bdrv, sector_len, Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0, be)) { -- 2.39.5