diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2017-04-15 20:07:53 +0300 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2017-05-18 06:50:53 +0200 |
commit | e87564ffe7d0636699467b776a24adffb2f11cca (patch) | |
tree | b4c4aa66031cfd20f29714d044c67217a439aba2 | |
parent | 61be3603f4b9f353e605d7b7c8d0d9f3b90f5636 (diff) | |
download | coreboot-e87564ffe7d0636699467b776a24adffb2f11cca.tar.xz |
binaryPI: Fix UMA calculations
Vendorcode decides already in AMD_INIT_POST the exact location
of UMA memory. To meet alignment requirements, it will extend
uma_memory_size. We cannot calculate base from size and TOP_MEM1,
but need to calculate size from base and TOP_MEM1 instead.
Also allows selection of UmaMode==UMA_SPECIFIED to manually set
amount of memory reserved for framebuffer.
Change-Id: I0c375e5da0dfef6cef0c50272356cd32a87b1ff6
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/19346
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | src/northbridge/amd/pi/00630F01/northbridge.c | 50 | ||||
-rw-r--r-- | src/northbridge/amd/pi/00660F01/northbridge.c | 59 | ||||
-rw-r--r-- | src/northbridge/amd/pi/00670F00/northbridge.c | 59 | ||||
-rw-r--r-- | src/northbridge/amd/pi/00730F01/northbridge.c | 58 | ||||
-rw-r--r-- | src/northbridge/amd/pi/Makefile.inc | 2 | ||||
-rw-r--r-- | src/northbridge/amd/pi/agesawrapper.c | 16 | ||||
-rw-r--r-- | src/northbridge/amd/pi/ramtop.c | 33 |
7 files changed, 52 insertions, 225 deletions
diff --git a/src/northbridge/amd/pi/00630F01/northbridge.c b/src/northbridge/amd/pi/00630F01/northbridge.c index a83ff0e7f5..5ba0e44ff3 100644 --- a/src/northbridge/amd/pi/00630F01/northbridge.c +++ b/src/northbridge/amd/pi/00630F01/northbridge.c @@ -691,46 +691,10 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) } #endif -#define ONE_MB_SHIFT 20 -#define ONE_GB_SHIFT 30 - -static void setup_uma_memory(void) -{ - uint64_t topmem = bsp_topmem(); - uint64_t topmem2 = bsp_topmem2(); - uint32_t sysmem_mb, sysmem_gb; - - sysmem_mb = (topmem + (16ull << ONE_MB_SHIFT)) >> ONE_MB_SHIFT; // Ignore 16MB allocated for C6 when finding UMA size - sysmem_mb += topmem2 ? ((topmem2 >> ONE_MB_SHIFT) - 4096) : 0; - sysmem_gb = sysmem_mb >> (ONE_GB_SHIFT - ONE_MB_SHIFT); - printk(BIOS_SPEW, "%s: system memory size %luGB, topmem2 size %lluMB, topmem size %lluMB\n", __func__, (unsigned long)sysmem_gb, (topmem2 >> ONE_MB_SHIFT), (topmem >> ONE_MB_SHIFT)); - - /* - * Refer to UMA_AUTO size computation in the Family15h BKDG. - * This calculation needs to exactly match the same calculation - * used by AGESA. - */ - - if (sysmem_gb >= 6) { - uma_memory_size = 1024 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 4) { - uma_memory_size = 512 << ONE_MB_SHIFT; - } else { - uma_memory_size = 256 << ONE_MB_SHIFT; - } - uma_memory_base = topmem - uma_memory_size; /* TOP_MEM1 */ - - printk(BIOS_INFO, "%s: uma size %lluMB, memory start 0x%08llx\n", - __func__, uma_memory_size >> ONE_MB_SHIFT, uma_memory_base); - - /* TODO: TOP_MEM2 */ -} - static void domain_set_resources(device_t dev) { unsigned long mmio_basek; u32 pci_tolm; - u64 ramtop = 0; int i, idx; struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 @@ -803,8 +767,6 @@ static void domain_set_resources(device_t dev) ram_resource(dev, (idx | i), basek, pre_sizek); idx += 0x10; sizek -= pre_sizek; - if (!ramtop) - ramtop = mmio_basek * 1024; } basek = mmio_basek; } @@ -822,16 +784,9 @@ static void domain_set_resources(device_t dev) idx += 0x10; printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", i, mmio_basek, basek, limitk); - if (!ramtop) - ramtop = limitk * 1024; } - if (IS_ENABLED(CONFIG_GFXUMA)) { - set_top_of_ram(uma_memory_base); - uma_resource(dev, 7, uma_memory_base >> 10, uma_memory_size >> 10); - } - else - set_top_of_ram(ramtop); + add_uma_resource_below_tolm(dev, 7); for (link = dev->link_list; link; link = link->next) { if (link->children) { @@ -1095,11 +1050,8 @@ static void root_complex_enable_dev(struct device *dev) { static int done = 0; - /* Do not delay UMA setup, as a device on the PCI bus may evaluate - the global uma_memory variables already in its enable function. */ if (!done) { setup_bsp_ramtop(); - setup_uma_memory(); done = 1; } diff --git a/src/northbridge/amd/pi/00660F01/northbridge.c b/src/northbridge/amd/pi/00660F01/northbridge.c index 9fc2dca85a..f085d5c20d 100644 --- a/src/northbridge/amd/pi/00660F01/northbridge.c +++ b/src/northbridge/amd/pi/00660F01/northbridge.c @@ -695,55 +695,10 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) } #endif -#define ONE_MB_SHIFT 20 -#define ONE_GB_SHIFT 30 - -static void setup_uma_memory(void) -{ -#if CONFIG_GFXUMA - uint64_t topmem = bsp_topmem(); - uint64_t topmem2 = bsp_topmem2(); - uint32_t sysmem_mb, sysmem_gb; - - /* refer to UMA_AUTO size computation in Family15h BKDG. */ - /* Please reference MemNGetUmaSizeML() */ - /* - * Total system memory UMASize - * >= 6G 1024M - * >= 4G 512M - * >= 2G 256M - * < 2G 128M - */ - - sysmem_mb = (topmem + (16ull << ONE_MB_SHIFT)) >> ONE_MB_SHIFT; // Ignore 16MB allocated for C6 when finding UMA size - sysmem_mb += topmem2 ? ((topmem2 >> ONE_MB_SHIFT) - 4096) : 0; - sysmem_gb = sysmem_mb >> (ONE_GB_SHIFT - ONE_MB_SHIFT); - printk(BIOS_SPEW, "%s: system memory size %luGB, topmem2 size %lluMB, topmem size %lluMB\n", - __func__, (unsigned long)sysmem_gb, (topmem2 >> ONE_MB_SHIFT), (topmem >> ONE_MB_SHIFT)); - if (sysmem_gb >= 6) { - uma_memory_size = 1024 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 4) { - uma_memory_size = 512 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 2) { - uma_memory_size = 256 << ONE_MB_SHIFT; - } else { - uma_memory_size = 128 << ONE_MB_SHIFT; - } - uma_memory_base = topmem - uma_memory_size; /* TOP_MEM1 */ - - printk(BIOS_INFO, "%s: uma size 0x%08llx, memory start 0x%08llx\n", - __func__, uma_memory_size, uma_memory_base); - - /* TODO: TOP_MEM2 */ -#endif -} - - static void domain_set_resources(device_t dev) { unsigned long mmio_basek; u32 pci_tolm; - u64 ramtop = 0; int i, idx; struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 @@ -814,8 +769,6 @@ static void domain_set_resources(device_t dev) ram_resource(dev, (idx | i), basek, pre_sizek); idx += 0x10; sizek -= pre_sizek; - if (!ramtop) - ramtop = mmio_basek * 1024; } basek = mmio_basek; } @@ -833,16 +786,9 @@ static void domain_set_resources(device_t dev) idx += 0x10; printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", i, mmio_basek, basek, limitk); - if (!ramtop) - ramtop = limitk * 1024; } -#if CONFIG_GFXUMA - set_top_of_ram(uma_memory_base); - uma_resource(dev, 7, uma_memory_base >> 10, uma_memory_size >> 10); -#else - set_top_of_ram(ramtop); -#endif + add_uma_resource_below_tolm(dev, 7); for (link = dev->link_list; link; link = link->next) { if (link->children) { @@ -1100,11 +1046,8 @@ static void root_complex_enable_dev(struct device *dev) { static int done = 0; - /* Do not delay UMA setup, as a device on the PCI bus may evaluate - the global uma_memory variables already in its enable function. */ if (!done) { setup_bsp_ramtop(); - setup_uma_memory(); done = 1; } diff --git a/src/northbridge/amd/pi/00670F00/northbridge.c b/src/northbridge/amd/pi/00670F00/northbridge.c index 3ba0687df1..006bc48a6e 100644 --- a/src/northbridge/amd/pi/00670F00/northbridge.c +++ b/src/northbridge/amd/pi/00670F00/northbridge.c @@ -696,55 +696,10 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) } #endif -#define ONE_MB_SHIFT 20 -#define ONE_GB_SHIFT 30 - -static void setup_uma_memory(void) -{ -#if CONFIG_GFXUMA - uint64_t topmem = bsp_topmem(); - uint64_t topmem2 = bsp_topmem2(); - uint32_t sysmem_mb, sysmem_gb; - - /* refer to UMA_AUTO size computation in Family15h BKDG. */ - /* Please reference MemNGetUmaSizeML() */ - /* - * Total system memory UMASize - * >= 6G 1024M - * >= 4G 512M - * >= 2G 256M - * < 2G 128M - */ - - sysmem_mb = (topmem + (16ull << ONE_MB_SHIFT)) >> ONE_MB_SHIFT; // Ignore 16MB allocated for C6 when finding UMA size - sysmem_mb += topmem2 ? ((topmem2 >> ONE_MB_SHIFT) - 4096) : 0; - sysmem_gb = sysmem_mb >> (ONE_GB_SHIFT - ONE_MB_SHIFT); - printk(BIOS_SPEW, "%s: system memory size %luGB, topmem2 size %lluMB, topmem size %lluMB\n", - __func__, (unsigned long)sysmem_gb, (topmem2 >> ONE_MB_SHIFT), (topmem >> ONE_MB_SHIFT)); - if (sysmem_gb >= 6) { - uma_memory_size = 1024 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 4) { - uma_memory_size = 512 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 2) { - uma_memory_size = 256 << ONE_MB_SHIFT; - } else { - uma_memory_size = 128 << ONE_MB_SHIFT; - } - uma_memory_base = topmem - uma_memory_size; /* TOP_MEM1 */ - - printk(BIOS_INFO, "%s: uma size 0x%08llx, memory start 0x%08llx\n", - __func__, uma_memory_size, uma_memory_base); - - /* TODO: TOP_MEM2 */ -#endif -} - - static void domain_set_resources(device_t dev) { unsigned long mmio_basek; u32 pci_tolm; - u64 ramtop = 0; int i, idx; struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 @@ -815,8 +770,6 @@ static void domain_set_resources(device_t dev) ram_resource(dev, (idx | i), basek, pre_sizek); idx += 0x10; sizek -= pre_sizek; - if (!ramtop) - ramtop = mmio_basek * 1024; } basek = mmio_basek; } @@ -834,16 +787,9 @@ static void domain_set_resources(device_t dev) idx += 0x10; printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", i, mmio_basek, basek, limitk); - if (!ramtop) - ramtop = limitk * 1024; } -#if CONFIG_GFXUMA - set_top_of_ram(uma_memory_base); - uma_resource(dev, 7, uma_memory_base >> 10, uma_memory_size >> 10); -#else - set_top_of_ram(ramtop); -#endif + add_uma_resource_below_tolm(dev, 7); for (link = dev->link_list; link; link = link->next) { if (link->children) { @@ -1109,11 +1055,8 @@ static void root_complex_enable_dev(struct device *dev) { static int done = 0; - /* Do not delay UMA setup, as a device on the PCI bus may evaluate - the global uma_memory variables already in its enable function. */ if (!done) { setup_bsp_ramtop(); - setup_uma_memory(); done = 1; } diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 3a2f730e63..960078e69b 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -707,54 +707,10 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) } #endif -#define ONE_MB_SHIFT 20 -#define ONE_GB_SHIFT 30 - -static void setup_uma_memory(void) -{ -#if CONFIG_GFXUMA - uint64_t topmem = bsp_topmem(); - uint64_t topmem2 = bsp_topmem2(); - uint32_t sysmem_mb, sysmem_gb; - - /* refer to UMA_AUTO size computation in Family16h BKDG. */ - /* Please reference MemNGetUmaSizeML() */ - /* - * Total system memory UMASize - * >= 6G 1024M - * >= 4G 512M - * >= 2G 256M - * < 2G 128M - */ - - sysmem_mb = (topmem + (16ull << ONE_MB_SHIFT)) >> ONE_MB_SHIFT; // Ignore 16MB allocated for C6 when finding UMA size - sysmem_mb += topmem2 ? ((topmem2 >> ONE_MB_SHIFT) - 4096) : 0; - sysmem_gb = sysmem_mb >> (ONE_GB_SHIFT - ONE_MB_SHIFT); - printk(BIOS_SPEW, "%s: system memory size %luGB, topmem2 size %lluMB, topmem size %lluMB\n", __func__, (unsigned long)sysmem_gb, (topmem2 >> ONE_MB_SHIFT), (topmem >> ONE_MB_SHIFT)); - if (sysmem_gb >= 6) { - uma_memory_size = 1024 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 4) { - uma_memory_size = 512 << ONE_MB_SHIFT; - } else if (sysmem_gb >= 2) { - uma_memory_size = 256 << ONE_MB_SHIFT; - } else { - uma_memory_size = 128 << ONE_MB_SHIFT; - } - uma_memory_base = topmem - uma_memory_size; /* TOP_MEM1 */ - - printk(BIOS_INFO, "%s: uma size 0x%08llx, memory start 0x%08llx\n", - __func__, uma_memory_size, uma_memory_base); - - /* TODO: TOP_MEM2 */ -#endif -} - - static void domain_set_resources(device_t dev) { unsigned long mmio_basek; u32 pci_tolm; - u64 ramtop = 0; int i, idx; struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 @@ -827,8 +783,6 @@ static void domain_set_resources(device_t dev) ram_resource(dev, (idx | i), basek, pre_sizek); idx += 0x10; sizek -= pre_sizek; - if (!ramtop) - ramtop = mmio_basek * 1024; } basek = mmio_basek; } @@ -846,16 +800,9 @@ static void domain_set_resources(device_t dev) idx += 0x10; printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", i, mmio_basek, basek, limitk); - if (!ramtop) - ramtop = limitk * 1024; } -#if CONFIG_GFXUMA - set_top_of_ram(uma_memory_base); - uma_resource(dev, 7, uma_memory_base >> 10, uma_memory_size >> 10); -#else - set_top_of_ram(ramtop); -#endif + add_uma_resource_below_tolm(dev, 7); for (link = dev->link_list; link; link = link->next) { if (link->children) { @@ -1129,11 +1076,8 @@ static void root_complex_enable_dev(struct device *dev) { static int done = 0; - /* Do not delay UMA setup, as a device on the PCI bus may evaluate - the global uma_memory variables already in its enable function. */ if (!done) { setup_bsp_ramtop(); - setup_uma_memory(); done = 1; } diff --git a/src/northbridge/amd/pi/Makefile.inc b/src/northbridge/amd/pi/Makefile.inc index 09bc2ad729..1cd0c420ed 100644 --- a/src/northbridge/amd/pi/Makefile.inc +++ b/src/northbridge/amd/pi/Makefile.inc @@ -25,4 +25,6 @@ romstage-y += def_callouts.c ramstage-y += agesawrapper.c ramstage-y += def_callouts.c +romstage-y += ramtop.c +ramstage-y += ramtop.c endif diff --git a/src/northbridge/amd/pi/agesawrapper.c b/src/northbridge/amd/pi/agesawrapper.c index 0afd0ca78a..ec1d0acf9f 100644 --- a/src/northbridge/amd/pi/agesawrapper.c +++ b/src/northbridge/amd/pi/agesawrapper.c @@ -15,6 +15,7 @@ #include <AGESA.h> #include <cbfs.h> +#include <cbmem.h> #include <delay.h> #include <cpu/x86/mtrr.h> #include <cpuRegisters.h> @@ -137,15 +138,25 @@ AGESA_STATUS agesawrapper_amdinitpost(void) AmdCreateStruct (&AmdParamStruct); PostParams = (AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr; - OemPostParams(PostParams); - // Do not use IS_ENABLED here. CONFIG_GFXUMA should always have a value. Allow // the compiler to flag the error if CONFIG_GFXUMA is not set. PostParams->MemConfig.UmaMode = CONFIG_GFXUMA ? UMA_AUTO : UMA_NONE; PostParams->MemConfig.UmaSize = 0; PostParams->MemConfig.BottomIo = (UINT16) (CONFIG_BOTTOMIO_POSITION >> 24); + + OemPostParams(PostParams); + status = AmdInitPost (PostParams); + + /* If UMA is enabled we currently have it below TOP_MEM as well. + * UMA may or may not be cacheable, so Sub4GCacheTop could be + * higher than UmaBase. With UMA_NONE we see UmaBase==0. */ + if (PostParams->MemConfig.UmaBase) + backup_top_of_ram(PostParams->MemConfig.UmaBase << 16); + else + backup_top_of_ram(PostParams->MemConfig.Sub4GCacheTop); + printk( BIOS_SPEW, "setup_uma_memory: umamode %s\n", @@ -166,7 +177,6 @@ AGESA_STATUS agesawrapper_amdinitpost(void) (unsigned long)(PostParams->MemConfig.UmaSize) >> (20 - 16), (unsigned long)(PostParams->MemConfig.UmaBase) << 16 ); - if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(PostParams->StdHeader.HeapStatus); AmdReleaseStruct (&AmdParamStruct); /* Initialize heap space */ diff --git a/src/northbridge/amd/pi/ramtop.c b/src/northbridge/amd/pi/ramtop.c new file mode 100644 index 0000000000..2b501dcf05 --- /dev/null +++ b/src/northbridge/amd/pi/ramtop.c @@ -0,0 +1,33 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define __SIMPLE_DEVICE__ + +#include <stdint.h> +#include <arch/io.h> +#include <cbmem.h> + +#define CBMEM_TOP_SCRATCHPAD 0x78 + +void backup_top_of_ram(uint64_t ramtop) +{ + uint16_t top_cache = ramtop >> 16; + pci_write_config16(PCI_DEV(0,0,0), CBMEM_TOP_SCRATCHPAD, top_cache); +} + +unsigned long get_top_of_ram(void) +{ + uint16_t top_cache; + top_cache = pci_read_config16(PCI_DEV(0,0,0), CBMEM_TOP_SCRATCHPAD); + return (top_cache << 16); +} |