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:
parent
9e69c87317
commit
717b6e3151
|
@ -63,26 +63,3 @@ asmlinkage void romstage_after_car(void)
|
||||||
/* Load the ramstage. */
|
/* Load the ramstage. */
|
||||||
run_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 */
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <cbmem.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/x86/bist.h>
|
#include <cpu/x86/bist.h>
|
||||||
#include <cpu/intel/romstage.h>
|
#include <cpu/intel/romstage.h>
|
||||||
|
@ -77,4 +78,6 @@ void mainboard_romstage_entry(unsigned long bist)
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "SDRAM is up.\n");
|
printk(BIOS_DEBUG, "SDRAM is up.\n");
|
||||||
|
|
||||||
|
cbmem_recovery(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ config NORTHBRIDGE_SPECIFIC_OPTIONS # dummy
|
||||||
def_bool y
|
def_bool y
|
||||||
select NO_MMCONF_SUPPORT
|
select NO_MMCONF_SUPPORT
|
||||||
select HAVE_DEBUG_RAM_SETUP
|
select HAVE_DEBUG_RAM_SETUP
|
||||||
select LATE_CBMEM_INIT
|
|
||||||
|
|
||||||
config HW_SCRUBBER
|
config HW_SCRUBBER
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
ifeq ($(CONFIG_NORTHBRIDGE_INTEL_E7505),y)
|
ifeq ($(CONFIG_NORTHBRIDGE_INTEL_E7505),y)
|
||||||
|
|
||||||
ramstage-y += northbridge.c
|
ramstage-y += northbridge.c
|
||||||
|
ramstage-y += memmap.c
|
||||||
|
|
||||||
romstage-y += raminit.c
|
romstage-y += raminit.c
|
||||||
romstage-y += debug.c
|
romstage-y += debug.c
|
||||||
|
romstage-y += memmap.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -31,84 +31,43 @@ unsigned long acpi_fill_mcfg(unsigned long current)
|
||||||
|
|
||||||
static void mch_domain_read_resources(struct device *dev)
|
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;
|
struct device *mc_dev;
|
||||||
uint32_t pci_tolm;
|
|
||||||
|
|
||||||
pci_domain_read_resources(dev);
|
pci_domain_read_resources(dev);
|
||||||
|
|
||||||
pci_tolm = find_pci_tolm(dev->link_list);
|
mc_dev = dev_find_slot(0, PCI_DEVFN(0x0, 0));
|
||||||
mc_dev = dev->link_list->children;
|
if (!mc_dev)
|
||||||
if (mc_dev) {
|
die("Could not find MCH device\n");
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* Get the value of the highest DRB. This tells the end of
|
tolmk = pci_read_config16(mc_dev, TOLM) >> 11;
|
||||||
* the physical memory. The units are ticks of 64MB
|
tolmk <<= 17;
|
||||||
* 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);
|
|
||||||
|
|
||||||
remapbase_r = pci_read_config16(mc_dev, REMAPBASE);
|
tomk = pci_read_config8(mc_dev, DRB_ROW_7);
|
||||||
remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00);
|
tomk <<= 16;
|
||||||
pci_write_config16(mc_dev, REMAPBASE, remapbase_r);
|
|
||||||
|
|
||||||
remaplimit_r = pci_read_config16(mc_dev, REMAPLIMIT);
|
/* Remapped region with a 64 MiB granularity in register
|
||||||
remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00);
|
definition. Limit is inclusive, so add one. */
|
||||||
pci_write_config16(mc_dev, REMAPLIMIT, remaplimit_r);
|
remapbasek = pci_read_config16(mc_dev, REMAPBASE) & 0x3ff;
|
||||||
|
remapbasek <<= 16;
|
||||||
|
|
||||||
|
remaplimitk = pci_read_config16(mc_dev, REMAPLIMIT) & 0x3ff;
|
||||||
|
remaplimitk += 1;
|
||||||
|
remaplimitk <<= 16;
|
||||||
|
|
||||||
/* Report the memory regions */
|
/* Report the memory regions */
|
||||||
idx = 10;
|
idx = 10;
|
||||||
ram_resource(dev, idx++, 0, 640);
|
ram_resource(dev, idx++, 0, 640);
|
||||||
ram_resource(dev, idx++, 768, tolmk - 768);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_late_cbmem_top(tolmk * 1024);
|
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)
|
static void mch_domain_set_resources(struct device *dev)
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <commonlib/helpers.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
|
||||||
#include <cpu/x86/mtrr.h>
|
#include <cpu/x86/mtrr.h>
|
||||||
#include <cpu/x86/cache.h>
|
#include <cpu/x86/cache.h>
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
|
@ -850,6 +850,12 @@ static void configure_e7501_ram_addresses(const struct mem_controller
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t total_dram_64M_multiple = 0;
|
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
|
// Configure the E7501's DRAM row boundaries
|
||||||
// Start by zeroing out the temporary initial configuration
|
// 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_dimm_row_boundaries(sz, total_dram_64M_multiple, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the Top Of Low Memory (TOLM) in the E7501
|
tom = total_dram_64M_multiple * 64ULL * MiB;
|
||||||
// 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.
|
|
||||||
|
|
||||||
// We set TOLM to the smaller of 0xC0000000 (3 GB) or the total DRAM in the system.
|
/* Reserve MMIO space. */
|
||||||
// This reserves addresses from 0xC0000000 - 0xFFFFFFFF for non-DRAM purposes
|
tolm = 4ULL * GiB - 1 * GiB;
|
||||||
// such as flash and memory-mapped I/O.
|
tolm = MIN(tolm, tom);
|
||||||
|
|
||||||
// If there is more than 3 GB of DRAM, we define a remap window which
|
/* The PCI memory hole overlaps memory setup the remap window. */
|
||||||
// makes the DRAM "behind" the reserved region available above the top of physical
|
if (tolm < tom) {
|
||||||
// memory.
|
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) {
|
/* Limit register is inclusive. */
|
||||||
|
remaplimit_r -= 1;
|
||||||
// <= 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,
|
/* Write the RAM configuration registers,
|
||||||
remap_base);
|
preserving the reserved bits. */
|
||||||
pci_write_config16(MCHDEV, REMAPLIMIT,
|
reg = pci_read_config16(MCHDEV, TOLM) & 0x7ff;
|
||||||
remap_limit);
|
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);
|
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.
|
* Scrub and reset error counts for ECC dimms.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue