From b6dcbe086c77ec683f5ff0b693593cda1d61f3a1 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Aug 2011 17:17:27 +0300 Subject: [PATCH] ppc4xx_sdram: convert to memory API Clumsy due to the lack of clipping support, needed for changing exposed ram size. Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori --- hw/ppc405.h | 9 ++++++--- hw/ppc405_boards.c | 18 ++++++++++++----- hw/ppc405_uc.c | 12 +++++++---- hw/ppc440.c | 7 +++++-- hw/ppc4xx.h | 2 ++ hw/ppc4xx_devs.c | 50 ++++++++++++++++++++++++++++++++-------------- 6 files changed, 69 insertions(+), 29 deletions(-) diff --git a/hw/ppc405.h b/hw/ppc405.h index e042a05b3b..f0e81a6495 100644 --- a/hw/ppc405.h +++ b/hw/ppc405.h @@ -59,16 +59,19 @@ struct ppc4xx_bd_info_t { ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd, uint32_t flags); -CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], +CPUState *ppc405cr_init (MemoryRegion ram_memories[4], + target_phys_addr_t ram_bases[4], target_phys_addr_t ram_sizes[4], uint32_t sysclk, qemu_irq **picp, int do_init); -CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], +CPUState *ppc405ep_init (MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], target_phys_addr_t ram_sizes[2], uint32_t sysclk, qemu_irq **picp, int do_init); /* IBM STBxxx microcontrollers */ -CPUState *ppc_stb025_init (target_phys_addr_t ram_bases[2], +CPUState *ppc_stb025_init (MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], target_phys_addr_t ram_sizes[2], uint32_t sysclk, qemu_irq **picp, ram_addr_t *offsetp); diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c index 34f9350864..dec165e40f 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -182,6 +182,7 @@ static void ref405ep_init (ram_addr_t ram_size, CPUPPCState *env; qemu_irq *pic; 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; long bios_size; @@ -194,15 +195,17 @@ static void ref405ep_init (ram_addr_t ram_size, DriveInfo *dinfo; /* XXX: fix this */ - ram_bases[0] = qemu_ram_alloc(NULL, "ef405ep.ram", 0x08000000); + memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); + ram_bases[0] = 0; ram_sizes[0] = 0x08000000; + memory_region_init(&ram_memories[1], "ef405ep.ram1", 0); ram_bases[1] = 0x00000000; ram_sizes[1] = 0x00000000; ram_size = 128 * 1024 * 1024; #ifdef DEBUG_BOARD_INIT printf("%s: register cpu\n", __func__); #endif - env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, + env = ppc405ep_init(ram_memories, ram_bases, ram_sizes, 33333333, &pic, kernel_filename == NULL ? 0 : 1); /* allocate SRAM */ sram_size = 512 * 1024; @@ -505,6 +508,7 @@ static void taihu_405ep_init(ram_addr_t ram_size, char *filename; qemu_irq *pic; 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; target_ulong kernel_base, initrd_base; @@ -514,15 +518,19 @@ static void taihu_405ep_init(ram_addr_t ram_size, DriveInfo *dinfo; /* RAM is soldered to the board so the size cannot be changed */ - ram_bases[0] = qemu_ram_alloc(NULL, "taihu_405ep.ram-0", 0x04000000); + memory_region_init_ram(&ram_memories[0], NULL, + "taihu_405ep.ram-0", 0x04000000); + ram_bases[0] = 0; ram_sizes[0] = 0x04000000; - ram_bases[1] = qemu_ram_alloc(NULL, "taihu_405ep.ram-1", 0x04000000); + memory_region_init_ram(&ram_memories[1], NULL, + "taihu_405ep.ram-1", 0x04000000); + ram_bases[1] = 0x04000000; ram_sizes[1] = 0x04000000; ram_size = 0x08000000; #ifdef DEBUG_BOARD_INIT printf("%s: register cpu\n", __func__); #endif - ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, + ppc405ep_init(ram_memories, ram_bases, ram_sizes, 33333333, &pic, kernel_filename == NULL ? 0 : 1); /* allocate and load BIOS */ #ifdef DEBUG_BOARD_INIT diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c index 03b25928f6..9d5d2af5d8 100644 --- a/hw/ppc405_uc.c +++ b/hw/ppc405_uc.c @@ -2107,7 +2107,8 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7], qemu_register_reset(ppc405cr_cpc_reset, cpc); } -CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], +CPUState *ppc405cr_init (MemoryRegion ram_memories[4], + target_phys_addr_t ram_bases[4], target_phys_addr_t ram_sizes[4], uint32_t sysclk, qemu_irq **picp, int do_init) @@ -2136,7 +2137,8 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); *picp = pic; /* SDRAM controller */ - ppc4xx_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[14], 1, ram_memories, + ram_bases, ram_sizes, do_init); /* External bus controller */ ppc405_ebc_init(env); /* DMA controller */ @@ -2451,7 +2453,8 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8], #endif } -CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], +CPUState *ppc405ep_init (MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], target_phys_addr_t ram_sizes[2], uint32_t sysclk, qemu_irq **picp, int do_init) @@ -2485,7 +2488,8 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], *picp = pic; /* SDRAM controller */ /* XXX 405EP has no ECC interrupt */ - ppc4xx_sdram_init(env, pic[17], 2, ram_bases, ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[17], 2, ram_memories, + ram_bases, ram_sizes, do_init); /* External bus controller */ ppc405_ebc_init(env); /* DMA controller */ diff --git a/hw/ppc440.c b/hw/ppc440.c index baf991f2d4..5885ff057c 100644 --- a/hw/ppc440.c +++ b/hw/ppc440.c @@ -38,6 +38,8 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, const unsigned int pci_irq_nrs[4], int do_init, const char *cpu_model) { + MemoryRegion *ram_memories + = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories)); target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; CPUState *env; @@ -66,11 +68,12 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, memset(ram_bases, 0, sizeof(ram_bases)); memset(ram_sizes, 0, sizeof(ram_sizes)); *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS, + ram_memories, ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes); /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ - ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases, - ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories, + ram_bases, ram_sizes, do_init); /* PCI */ pci_irqs = g_malloc(sizeof(qemu_irq) * 4); diff --git a/hw/ppc4xx.h b/hw/ppc4xx.h index bc4ee019a5..f969e44e1b 100644 --- a/hw/ppc4xx.h +++ b/hw/ppc4xx.h @@ -42,11 +42,13 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, uint32_t dcr_base, int has_ssr, int has_vr); ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, + MemoryRegion ram_memories[], target_phys_addr_t ram_bases[], target_phys_addr_t ram_sizes[], const unsigned int sdram_bank_sizes[]); void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, + MemoryRegion ram_memories[], target_phys_addr_t *ram_bases, target_phys_addr_t *ram_sizes, int do_init); diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c index 1af5f2e79f..349f046b2f 100644 --- a/hw/ppc4xx_devs.c +++ b/hw/ppc4xx_devs.c @@ -25,6 +25,7 @@ #include "ppc.h" #include "ppc4xx.h" #include "qemu-log.h" +#include "exec-memory.h" //#define DEBUG_MMIO //#define DEBUG_UNASSIGNED @@ -313,6 +314,8 @@ typedef struct ppc4xx_sdram_t ppc4xx_sdram_t; struct ppc4xx_sdram_t { uint32_t addr; int nbanks; + MemoryRegion containers[4]; /* used for clipping */ + MemoryRegion *ram_memories; target_phys_addr_t ram_bases[4]; target_phys_addr_t ram_sizes[4]; uint32_t besr0; @@ -395,16 +398,22 @@ static target_ulong sdram_size (uint32_t bcr) return size; } -static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled) +static void sdram_set_bcr(ppc4xx_sdram_t *sdram, + uint32_t *bcrp, uint32_t bcr, int enabled) { + unsigned n = bcrp - sdram->bcr; + if (*bcrp & 0x00000001) { /* Unmap RAM */ #ifdef DEBUG_SDRAM printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(*bcrp), sdram_size(*bcrp)); #endif - cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp), - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), + &sdram->containers[n]); + memory_region_del_subregion(&sdram->containers[n], + &sdram->ram_memories[n]); + memory_region_destroy(&sdram->containers[n]); } *bcrp = bcr & 0xFFDEE001; if (enabled && (bcr & 0x00000001)) { @@ -412,8 +421,13 @@ static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled) printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(bcr), sdram_size(bcr)); #endif - cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr), - sdram_base(bcr) | IO_MEM_RAM); + memory_region_init(&sdram->containers[n], "sdram-containers", + sdram_size(bcr)); + memory_region_add_subregion(&sdram->containers[n], 0, + &sdram->ram_memories[n]); + memory_region_add_subregion(get_system_memory(), + sdram_base(bcr), + &sdram->containers[n]); } } @@ -423,11 +437,12 @@ static void sdram_map_bcr (ppc4xx_sdram_t *sdram) for (i = 0; i < sdram->nbanks; i++) { if (sdram->ram_sizes[i] != 0) { - sdram_set_bcr(&sdram->bcr[i], + sdram_set_bcr(sdram, + &sdram->bcr[i], sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]), 1); } else { - sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0); + sdram_set_bcr(sdram, &sdram->bcr[i], 0x00000000, 0); } } } @@ -441,9 +456,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram) printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i])); #endif - cpu_register_physical_memory(sdram_base(sdram->bcr[i]), - sdram_size(sdram->bcr[i]), - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), + &sdram->ram_memories[i]); } } @@ -568,16 +582,16 @@ static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val) sdram->pmit = (val & 0xF8000000) | 0x07C00000; break; case 0x40: /* SDRAM_B0CR */ - sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[0], val, sdram->cfg & 0x80000000); break; case 0x44: /* SDRAM_B1CR */ - sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[1], val, sdram->cfg & 0x80000000); break; case 0x48: /* SDRAM_B2CR */ - sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[2], val, sdram->cfg & 0x80000000); break; case 0x4C: /* SDRAM_B3CR */ - sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[3], val, sdram->cfg & 0x80000000); break; case 0x80: /* SDRAM_TR */ sdram->tr = val & 0x018FC01F; @@ -621,6 +635,7 @@ static void sdram_reset (void *opaque) } void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, + MemoryRegion *ram_memories, target_phys_addr_t *ram_bases, target_phys_addr_t *ram_sizes, int do_init) @@ -630,6 +645,7 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, sdram = g_malloc0(sizeof(ppc4xx_sdram_t)); sdram->irq = irq; sdram->nbanks = nbanks; + sdram->ram_memories = ram_memories; memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t)); memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(target_phys_addr_t)); @@ -653,11 +669,13 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, * must be one of a small set of sizes. The number of banks and the supported * sizes varies by SoC. */ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, + MemoryRegion ram_memories[], target_phys_addr_t ram_bases[], target_phys_addr_t ram_sizes[], const unsigned int sdram_bank_sizes[]) { ram_addr_t size_left = ram_size; + ram_addr_t base = 0; int i; int j; @@ -668,8 +686,10 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, if (bank_size <= size_left) { char name[32]; snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); - ram_bases[i] = qemu_ram_alloc(NULL, name, bank_size); + memory_region_init_ram(&ram_memories[i], NULL, name, bank_size); + ram_bases[i] = base; ram_sizes[i] = bank_size; + base += ram_size; size_left -= bank_size; break; }