From patchwork Sun Aug 28 15:43:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 111911 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 198A6B6F7F for ; Mon, 29 Aug 2011 01:44:03 +1000 (EST) Received: from localhost ([::1]:53601 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QxhWd-0003Tl-KK for incoming@patchwork.ozlabs.org; Sun, 28 Aug 2011 11:43:55 -0400 Received: from eggs.gnu.org ([140.186.70.92]:40682) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QxhWU-0003TZ-SC for qemu-devel@nongnu.org; Sun, 28 Aug 2011 11:43:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QxhWR-0006SZ-Uw for qemu-devel@nongnu.org; Sun, 28 Aug 2011 11:43:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48245) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QxhWR-0006ST-Fc for qemu-devel@nongnu.org; Sun, 28 Aug 2011 11:43:43 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p7SFhfNZ031859 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 28 Aug 2011 11:43:41 -0400 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p7SFhc1K015285; Sun, 28 Aug 2011 11:43:39 -0400 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id 3F0B6250B56; Sun, 28 Aug 2011 18:43:38 +0300 (IDT) From: Avi Kivity To: qemu-devel@nongnu.org Date: Sun, 28 Aug 2011 18:43:36 +0300 Message-Id: <1314546216-26613-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: "Edgar E. Iglesias" , Richard Henderson Subject: [Qemu-devel] [PATCH] pflash_cfi01/pflash_cfi02: convert to memory API X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- This is a rework of the pflash conversion to the memory API. It has changed significantly - the change in allocation described above - so please review carefully. The mips_malta change also changes behavious - previously on of the two aliases was mapped as rom/device while the other was mapped as plain rom. Now both aliases are mapped as rom/device. I'm guessing that this is the right behaviour, and the old behaviour was just an implementation limitation, but if someone can check, that would be even better. That file has the most sensitive changes so please review it extra carefully. hw/collie.c | 7 +-- hw/flash.h | 11 ++++- hw/gumstix.c | 6 +-- hw/lm32_boards.c | 8 +--- hw/mainstone.c | 7 +-- hw/milkymist.c | 4 +- hw/mips_malta.c | 44 +++++++++++++------ 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 | 73 ++++++++++++------------------- 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, 174 insertions(+), 177 deletions(-) diff --git a/hw/collie.c b/hw/collie.c index 156404d..a10cc1b 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 140ae39..f92f58a 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, diff --git a/hw/gumstix.c b/hw/gumstix.c index 853f7e1..b8b76f4 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 d18aad7..e4acac1 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 4792f0e..c0524d7 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 93288c8..a44b80c 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 86a8ba0..9762a57 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 @@ -762,7 +763,8 @@ void mips_malta_init (ram_addr_t ram_size, { char *filename; 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 +813,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 +827,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) { @@ -851,11 +852,26 @@ void mips_malta_init (ram_addr_t ram_size, fl_idx, bios_size, bios_offset, 0x1e000000LL, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi01_register(0x1e000000LL, bios_offset, + pflash_cfi01_register(0x1e000000LL, + NULL, "mips_malta.bios", BIOS_SIZE, dinfo->bdrv, 65536, fl_sectors, 4, 0x0000, 0x0000, 0x0000, 0x0000, be); - fl_idx++; + /* 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 +894,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 +906,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 9d90568..5d002c5 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 63dd391..ade5a91 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 a7b687b..15cfbb5 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 e3ca310..38db521 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 a43fb4c..66fb96d 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 90e1301..b597304 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; } diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index ac5115e..4dbec87 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 dec165e..e6c8ac6 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 96a7ff8..ed0c586 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 333050c..7459b0b 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 f93a1bf..b6ae608 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)) {