diff options
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/intel/e7505/Kconfig | 1 | ||||
-rw-r--r-- | src/northbridge/intel/e7505/e7505.h | 23 | ||||
-rw-r--r-- | src/northbridge/intel/e7505/memmap.c | 83 | ||||
-rw-r--r-- | src/northbridge/intel/e7505/northbridge.c | 3 | ||||
-rw-r--r-- | src/northbridge/intel/e7505/raminit.c | 6 |
5 files changed, 98 insertions, 18 deletions
diff --git a/src/northbridge/intel/e7505/Kconfig b/src/northbridge/intel/e7505/Kconfig index 4a54bc076d..95e8de7173 100644 --- a/src/northbridge/intel/e7505/Kconfig +++ b/src/northbridge/intel/e7505/Kconfig @@ -10,5 +10,6 @@ config NORTHBRIDGE_SPECIFIC_OPTIONS select NO_ECAM_MMCONF_SUPPORT select HAVE_DEBUG_RAM_SETUP select NO_CBFS_MCACHE + select SMM_TSEG endif diff --git a/src/northbridge/intel/e7505/e7505.h b/src/northbridge/intel/e7505/e7505.h index b429c70ba4..ed596c9875 100644 --- a/src/northbridge/intel/e7505/e7505.h +++ b/src/northbridge/intel/e7505/e7505.h @@ -7,6 +7,11 @@ #ifndef NORTHBRIDGE_INTEL_E7505_E7505_H #define NORTHBRIDGE_INTEL_E7505_E7505_H +#include <types.h> + +size_t northbridge_get_tseg_size(void); +uintptr_t northbridge_get_tseg_base(void); + /************ D0:F0 ************/ // Register offsets #define SMRBASE 0x14 /* System Memory RCOMP Base Address Register, 32 bit? */ @@ -28,8 +33,6 @@ #define DRC 0x7C /* DRAM Controller Mode register, 32 bit */ #define DRDCTL 0x80 /* DRAM Read Timing Control register, 16 bit? (if similar to 855PM) */ #define CKDIS 0x8C /* Clock disable register, 8 bit */ -#define SMRAMC 0x9D -#define ESMRAMC 0x9E #define APSIZE 0xB4 #define TOLM 0xC4 /* Top of Low Memory register, 16 bit */ #define REMAPBASE 0xC6 /* Remap Base Address register, 16 bit */ @@ -38,6 +41,22 @@ #define DVNP 0xE0 /* Device Not Present, 16 bit */ #define MCHTST 0xF4 /* MCH Test Register, 32 bit? (if similar to 855PM) */ +#define SMRAMC 0x9D +#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) +#define G_SMRAME (1 << 3) +#define D_LCK (1 << 4) +#define D_CLS (1 << 5) +#define D_OPEN (1 << 6) + +#define ESMRAMC 0x9E +#define T_EN (1 << 0) +#define TSEG_SZ_128K (0 << 1) +#define TSEG_SZ_256K (1 << 1) +#define TSEG_SZ_512K (2 << 1) +#define TSEG_SZ_1M (3 << 1) +#define TSEG_SZ_MASK TSEG_SZ_1M +#define H_SMRAME (1 << 7) + // CAS# Latency bits in the DRAM Timing (DRT) register #define DRT_CAS_2_5 (0<<4) #define DRT_CAS_2_0 (1<<4) diff --git a/src/northbridge/intel/e7505/memmap.c b/src/northbridge/intel/e7505/memmap.c index 0d90175a5a..47c3b102f5 100644 --- a/src/northbridge/intel/e7505/memmap.c +++ b/src/northbridge/intel/e7505/memmap.c @@ -5,37 +5,93 @@ #include <arch/romstage.h> #include <cbmem.h> +#include <cpu/intel/smm_reloc.h> #include <cpu/x86/mtrr.h> +#include <cpu/x86/smm.h> #include <device/pci_ops.h> #include <program_loading.h> #include <stdint.h> #include "e7505.h" -uintptr_t cbmem_top_chipset(void) +#define HOST_BRIDGE PCI_DEV(0, 0, 0) + +static uintptr_t top_of_low_ram(void) { - const 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 = pci_read_config16(HOST_BRIDGE, TOLM) >> 11; tolm <<= 27; + return tolm; +} + +size_t northbridge_get_tseg_size(void) +{ + const uint8_t esmramc = pci_read_config8(HOST_BRIDGE, ESMRAMC); + + if (!(esmramc & T_EN)) + return 0; + switch ((esmramc & TSEG_SZ_MASK) >> 1) { + case 0: + return 128 * KiB; + case 1: + return 256 * KiB; + case 2: + return 512 * KiB; + case 3: + default: + return 1 * MiB; + } +} + +uintptr_t northbridge_get_tseg_base(void) +{ + uintptr_t tolm = top_of_low_ram(); + + /* subtract TSEG size */ + tolm -= northbridge_get_tseg_size(); return tolm; } -void northbridge_write_smram(u8 smram); +void smm_region(uintptr_t *start, size_t *size) +{ + *start = northbridge_get_tseg_base(); + *size = northbridge_get_tseg_size(); +} + +uintptr_t cbmem_top_chipset(void) +{ + return northbridge_get_tseg_base(); +} -void northbridge_write_smram(u8 smram) +void smm_open(void) { - const pci_devfn_t mch = PCI_DEV(0, 0, 0); - pci_write_config8(mch, SMRAMC, smram); + /* Set D_OPEN */ + pci_write_config8(HOST_BRIDGE, SMRAMC, D_OPEN | G_SMRAME | C_BASE_SEG); } -void fill_postcar_frame(struct postcar_frame *pcf) +void smm_close(void) +{ + /* Clear D_OPEN */ + pci_write_config8(HOST_BRIDGE, SMRAMC, G_SMRAME | C_BASE_SEG); +} + +void smm_lock(void) { - uintptr_t top_of_ram; + /* + * LOCK the SMM memory window and enable normal SMM. + * After running this function, only a full reset can + * make the SMM registers writable again. + */ + printk(BIOS_DEBUG, "Locking SMM.\n"); + + pci_write_config8(HOST_BRIDGE, SMRAMC, D_LCK | G_SMRAME | C_BASE_SEG); +} +void fill_postcar_frame(struct postcar_frame *pcf) +{ /* * Choose to NOT set ROM as WP cacheable here. * Timestamps indicate the CPU this northbridge code is @@ -45,11 +101,6 @@ void fill_postcar_frame(struct postcar_frame *pcf) pcf->skip_common_mtrr = 1; - /* 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); + /* Cache RAM as WB from 0 -> TOLM. */ + postcar_frame_add_mtrr(pcf, top_of_low_ram(), CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK); } diff --git a/src/northbridge/intel/e7505/northbridge.c b/src/northbridge/intel/e7505/northbridge.c index 08ac122243..cc7f85d980 100644 --- a/src/northbridge/intel/e7505/northbridge.c +++ b/src/northbridge/intel/e7505/northbridge.c @@ -42,6 +42,9 @@ static void mch_domain_read_resources(struct device *dev) ram_resource_kb(dev, idx++, 0, tolmk); mmio_resource_kb(dev, idx++, 0xa0000 / KiB, (0xc0000 - 0xa0000) / KiB); + uintptr_t tseg_memory_base = northbridge_get_tseg_base(); + size_t tseg_memory_size = northbridge_get_tseg_size(); + mmio_resource_kb(dev, idx++, tseg_memory_base / KiB, tseg_memory_size / KiB); ASSERT(tom == remapbase); upper_ram_end(dev, idx++, remaplimit); diff --git a/src/northbridge/intel/e7505/raminit.c b/src/northbridge/intel/e7505/raminit.c index 5387d4df04..2b81d37d59 100644 --- a/src/northbridge/intel/e7505/raminit.c +++ b/src/northbridge/intel/e7505/raminit.c @@ -1687,6 +1687,8 @@ static int e7505_mch_is_ready(void) return !!(dword & DRC_DONE); } +#define HOST_BRIDGE PCI_DEV(0, 0, 0) + void sdram_initialize(void) { static const struct mem_controller memctrl[] = { @@ -1714,5 +1716,9 @@ void sdram_initialize(void) timestamp_add_now(TS_INITRAM_END); } + + if (CONFIG(SMM_TSEG)) + pci_write_config8(HOST_BRIDGE, ESMRAMC, TSEG_SZ_1M | T_EN); + printk(BIOS_DEBUG, "SDRAM is up.\n"); } |