aopen/dxplplusu intel/e7505: Move to EARLY_CBMEM_INIT

With implementation of LATE_CBMEM_INIT, top-of-low-memory
TOLM was adjusted late in ramstage. We do not allow that with
EARLY_CBMEM_INIT so the previous maximum of 1024 MiB of MMIO
space is now used with statically set TOLM.

Also remove support code for the obsolete LATE_CBMEM_INIT
this northbridge used.

Change-Id: Ib3094903d7614d2212fbe1870248962fbc92e412
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/26585
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Kyösti Mälkki 2018-05-17 14:16:03 +03:00
parent 9e69c87317
commit 717b6e3151
7 changed files with 133 additions and 161 deletions

View File

@ -63,26 +63,3 @@ asmlinkage void romstage_after_car(void)
/* Load the ramstage. */
run_ramstage();
}
#if IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
/* setup_stack_and_mtrrs() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use. */
void *setup_stack_and_mtrrs(void)
{
struct postcar_frame pcf;
postcar_frame_init_lowmem(&pcf);
/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
MTRR_TYPE_WRPROT);
/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
/* Save the number of MTRRs to setup. Return the stack location
* pointing to the number of MTRRs.
*/
return postcar_commit_mtrrs(&pcf);
}
#endif /* CONFIG_LATE_CBMEM_INIT */

View File

@ -18,6 +18,7 @@
#include <arch/io.h>
#include <arch/cpu.h>
#include <stdlib.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/bist.h>
#include <cpu/intel/romstage.h>
@ -77,4 +78,6 @@ void mainboard_romstage_entry(unsigned long bist)
}
printk(BIOS_DEBUG, "SDRAM is up.\n");
cbmem_recovery(0);
}

View File

@ -22,7 +22,6 @@ config NORTHBRIDGE_SPECIFIC_OPTIONS # dummy
def_bool y
select NO_MMCONF_SUPPORT
select HAVE_DEBUG_RAM_SETUP
select LATE_CBMEM_INIT
config HW_SCRUBBER
bool

View File

@ -1,7 +1,9 @@
ifeq ($(CONFIG_NORTHBRIDGE_INTEL_E7505),y)
ramstage-y += northbridge.c
ramstage-y += memmap.c
romstage-y += raminit.c
romstage-y += debug.c
romstage-y += memmap.c
endif

View File

@ -0,0 +1,66 @@
/*
* 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.
*/
// Use simple device model for this file even in ramstage
#define __SIMPLE_DEVICE__
#include <arch/io.h>
#include <arch/cpu.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/intel/romstage.h>
#include <cpu/x86/mtrr.h>
#include <program_loading.h>
#include "e7505.h"
void *cbmem_top(void)
{
pci_devfn_t mch = PCI_DEV(0, 0, 0);
uintptr_t tolm;
/* This is at 128 MiB boundary. */
tolm = pci_read_config16(mch, TOLM) >> 11;
tolm <<= 27;
return (void *)tolm;
}
#define ROMSTAGE_RAM_STACK_SIZE 0x5000
/* setup_stack_and_mtrrs() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use. */
void *setup_stack_and_mtrrs(void)
{
struct postcar_frame pcf;
uintptr_t top_of_ram;
if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE))
die("Unable to initialize postcar frame.\n");
/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
MTRR_TYPE_WRPROT);
/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
/* Cache CBMEM region as WB. */
top_of_ram = (uintptr_t)cbmem_top();
postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 8*MiB,
MTRR_TYPE_WRBACK);
/* Save the number of MTRRs to setup. Return the stack location
* pointing to the number of MTRRs.
*/
return postcar_commit_mtrrs(&pcf);
}

View File

@ -31,84 +31,43 @@ unsigned long acpi_fill_mcfg(unsigned long current)
static void mch_domain_read_resources(struct device *dev)
{
int idx;
unsigned long tomk, tolmk;
unsigned long remapbasek, remaplimitk;
const unsigned long basek_4G = 4 * (GiB / KiB);
struct device *mc_dev;
uint32_t pci_tolm;
pci_domain_read_resources(dev);
pci_tolm = find_pci_tolm(dev->link_list);
mc_dev = dev->link_list->children;
if (mc_dev) {
/* Figure out which areas are/should be occupied by RAM.
* This is all computed in kilobytes and converted to/from
* the memory controller right at the edges.
* Having different variables in different units is
* too confusing to get right. Kilobytes are good up to
* 4 Terabytes of RAM...
*/
uint16_t tolm_r, remapbase_r, remaplimit_r;
unsigned long tomk, tolmk;
unsigned long remapbasek, remaplimitk;
int idx;
mc_dev = dev_find_slot(0, PCI_DEVFN(0x0, 0));
if (!mc_dev)
die("Could not find MCH device\n");
/* Get the value of the highest DRB. This tells the end of
* the physical memory. The units are ticks of 64MB
* i.e. 1 means 64MB.
*/
tomk = ((unsigned long)pci_read_config8(mc_dev, DRB_ROW_7)) << 16;
/* Compute the top of Low memory */
tolmk = pci_tolm >> 10;
if (tolmk >= tomk) {
/* The PCI hole does not overlap memory
* we won't use the remap window.
*/
tolmk = tomk;
remapbasek = 0x3ff << 16;
remaplimitk = 0 << 16;
}
else {
/* The PCI memory hole overlaps memory
* setup the remap window.
*/
/* Find the bottom of the remap window
* is it above 4G?
*/
remapbasek = 4*1024*1024;
if (tomk > remapbasek) {
remapbasek = tomk;
}
/* Find the limit of the remap window */
remaplimitk = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16));
}
/* Write the RAM configuration registers,
* preserving the reserved bits.
*/
tolm_r = pci_read_config16(mc_dev, TOLM);
tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff);
pci_write_config16(mc_dev, TOLM, tolm_r);
tolmk = pci_read_config16(mc_dev, TOLM) >> 11;
tolmk <<= 17;
remapbase_r = pci_read_config16(mc_dev, REMAPBASE);
remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00);
pci_write_config16(mc_dev, REMAPBASE, remapbase_r);
tomk = pci_read_config8(mc_dev, DRB_ROW_7);
tomk <<= 16;
remaplimit_r = pci_read_config16(mc_dev, REMAPLIMIT);
remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00);
pci_write_config16(mc_dev, REMAPLIMIT, remaplimit_r);
/* Remapped region with a 64 MiB granularity in register
definition. Limit is inclusive, so add one. */
remapbasek = pci_read_config16(mc_dev, REMAPBASE) & 0x3ff;
remapbasek <<= 16;
/* Report the memory regions */
idx = 10;
ram_resource(dev, idx++, 0, 640);
ram_resource(dev, idx++, 768, tolmk - 768);
if (tomk > 4*1024*1024) {
ram_resource(dev, idx++, 4096*1024, tomk - 4*1024*1024);
}
if (remaplimitk >= remapbasek) {
ram_resource(dev, idx++, remapbasek,
(remaplimitk + 64*1024) - remapbasek);
}
remaplimitk = pci_read_config16(mc_dev, REMAPLIMIT) & 0x3ff;
remaplimitk += 1;
remaplimitk <<= 16;
set_late_cbmem_top(tolmk * 1024);
}
/* Report the memory regions */
idx = 10;
ram_resource(dev, idx++, 0, 640);
ram_resource(dev, idx++, 768, tolmk - 768);
if (tomk > basek_4G)
ram_resource(dev, idx++, basek_4G, tomk - basek_4G);
if (remaplimitk > remapbasek)
ram_resource(dev, idx++, remapbasek, remaplimitk - remapbasek);
}
static void mch_domain_set_resources(struct device *dev)

View File

@ -30,8 +30,8 @@
#include <arch/cpu.h>
#include <lib.h>
#include <stdlib.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/msr.h>
@ -850,6 +850,12 @@ static void configure_e7501_ram_addresses(const struct mem_controller
{
int i;
uint8_t total_dram_64M_multiple = 0;
uint64_t tolm, tom;
uint16_t reg;
/* Start with disabled remap range. */
uint16_t remapbase_r = 0x3ff;
uint16_t remaplimit_r = 0;
// Configure the E7501's DRAM row boundaries
// Start by zeroing out the temporary initial configuration
@ -879,71 +885,37 @@ static void configure_e7501_ram_addresses(const struct mem_controller
configure_dimm_row_boundaries(sz, total_dram_64M_multiple, i);
}
// Configure the Top Of Low Memory (TOLM) in the E7501
// This address must be a multiple of 128 MB that is less than 4 GB.
// NOTE: 16-bit wide TOLM register stores only the highest 5 bits of a 32-bit address
// in the highest 5 bits.
tom = total_dram_64M_multiple * 64ULL * MiB;
// We set TOLM to the smaller of 0xC0000000 (3 GB) or the total DRAM in the system.
// This reserves addresses from 0xC0000000 - 0xFFFFFFFF for non-DRAM purposes
// such as flash and memory-mapped I/O.
/* Reserve MMIO space. */
tolm = 4ULL * GiB - 1 * GiB;
tolm = MIN(tolm, tom);
// If there is more than 3 GB of DRAM, we define a remap window which
// makes the DRAM "behind" the reserved region available above the top of physical
// memory.
/* The PCI memory hole overlaps memory setup the remap window. */
if (tolm < tom) {
uint64_t remapbase = MAX(tom, 4ULL * GiB);
uint64_t remaplimit = remapbase + (4ULL * GiB - tolm);
// NOTE: 0xC0000000 / (64 MB) == 0x30
remapbase_r = remapbase / (64 * MiB);
remaplimit_r = remaplimit / (64 * MiB);
if (total_dram_64M_multiple <= 0x30) {
// <= 3 GB total RAM
/* I should really adjust all of this in C after I have resources
* to all of the pci devices.
*/
// Round up to 128MB granularity
// SJM: Is "missing" 64 MB of memory a potential issue? Should this round down?
uint8_t total_dram_128M_multiple =
(total_dram_64M_multiple + 1) >> 1;
// Convert to high 16 bits of address
uint16_t top_of_low_memory =
total_dram_128M_multiple << 11;
pci_write_config16(MCHDEV, TOLM,
top_of_low_memory);
} else {
// > 3 GB total RAM
// Set defaults for > 4 GB DRAM, i.e. remap a 1 GB (= 0x10 * 64 MB) range of memory
uint16_t remap_base = total_dram_64M_multiple; // A[25:0] == 0
uint16_t remap_limit = total_dram_64M_multiple + 0x10 - 1; // A[25:0] == 0xF
// Put TOLM at 3 GB
pci_write_config16(MCHDEV, TOLM, 0xc000);
// Define a remap window to make the RAM that would appear from 3 GB - 4 GB
// visible just beyond 4 GB or the end of physical memory, whichever is larger
// NOTE: 16-bit wide REMAP registers store only the highest 10 bits of a 36-bit address,
// (i.e. a multiple of 64 MB) in the lowest 10 bits.
// NOTE: 0x100000000 / (64 MB) == 0x40
if (total_dram_64M_multiple < 0x40) {
remap_base = 0x40; // 0x100000000
remap_limit =
0x40 + (total_dram_64M_multiple - 0x30) - 1;
}
pci_write_config16(MCHDEV, REMAPBASE,
remap_base);
pci_write_config16(MCHDEV, REMAPLIMIT,
remap_limit);
/* Limit register is inclusive. */
remaplimit_r -= 1;
}
/* Write the RAM configuration registers,
preserving the reserved bits. */
reg = pci_read_config16(MCHDEV, TOLM) & 0x7ff;
reg |= (tolm / (128 * MiB)) << 11;
pci_write_config16(MCHDEV, TOLM, reg);
reg = pci_read_config16(MCHDEV, REMAPBASE) & 0xfc00;
reg |= remapbase_r;
pci_write_config16(MCHDEV, REMAPBASE, reg);
reg = pci_read_config16(MCHDEV, REMAPLIMIT) & 0xfc00;
reg |= remaplimit_r;
pci_write_config16(MCHDEV, REMAPLIMIT, reg);
}
/**
@ -1904,12 +1876,6 @@ void e7505_mch_init(const struct mem_controller *memctrl)
sdram_enable(memctrl);
}
uintptr_t restore_top_of_low_cacheable(void)
{
u32 tolm = (pci_read_config16(MCHDEV, TOLM) & ~0x7ff) << 16;
return tolm;
}
/**
* Scrub and reset error counts for ECC dimms.
*