diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-15 23:15:56 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-15 23:15:56 +0000 |
commit | b7da58fd27bfbe7c14bc8a0332135663f17caecc (patch) | |
tree | ee4cb72849d55a29ccc100dbcdacafcead1cac6c /hw | |
parent | 80e8bd2b0fe8afe3d5f2bd4960ab83514d97b992 (diff) |
target-ppc: create a helper function to allow more flexible RAM allocation for PPC 4xx
The 4xx SDRAM controller supports a small number of banks, and each bank must
be one of a small set of sizes. The number of banks and the supported sizes
varies by SoC.
This function uses the user-specified RAM size to fill in the "ram_bases" and
"ram_sizes" arrays required by ppc4xx_sdram_init().
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6063 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ppc4xx.h | 5 | ||||
-rw-r--r-- | hw/ppc4xx_devs.c | 42 |
2 files changed, 47 insertions, 0 deletions
diff --git a/hw/ppc4xx.h b/hw/ppc4xx.h index 3b986624c5..7832cd9f30 100644 --- a/hw/ppc4xx.h +++ b/hw/ppc4xx.h @@ -48,6 +48,11 @@ enum { 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, + 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, target_phys_addr_t *ram_bases, target_phys_addr_t *ram_sizes, diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c index 2d27e23ca9..939e0669e2 100644 --- a/hw/ppc4xx_devs.c +++ b/hw/ppc4xx_devs.c @@ -873,3 +873,45 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, sdram_map_bcr(sdram); } } + +/* Fill in consecutive SDRAM banks with 'ram_size' bytes of memory. + * + * sdram_bank_sizes[] must be 0-terminated. + * + * The 4xx SDRAM controller supports a small number of banks, and each bank + * 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, + target_phys_addr_t ram_bases[], + target_phys_addr_t ram_sizes[], + const unsigned int sdram_bank_sizes[]) +{ + ram_addr_t ram_end = 0; + int i; + int j; + + for (i = 0; i < nr_banks; i++) { + for (j = 0; sdram_bank_sizes[j] != 0; j++) { + unsigned int bank_size = sdram_bank_sizes[j]; + + if (bank_size <= ram_size) { + ram_bases[i] = ram_end; + ram_sizes[i] = bank_size; + ram_end += bank_size; + ram_size -= bank_size; + break; + } + } + + if (!ram_size) { + /* No need to use the remaining banks. */ + break; + } + } + + if (ram_size) + printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n", + (int)(ram_end >> 20)); + + return ram_end; +} |