QuarkSocPkg: Add new package for Quark SoC X1000

Changes for V4
==============
1) Remove Unicode character from C source file
2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
   from QuarkPlatformPkg commit to QuarkSocPkg commit

Changes for V2
==============
1) Sync with new APIs in SmmCpuFeaturesLib class
2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
3) Remove PCI serial driver from QuarkSocPkg
4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg
5) Convert all UNI files to utf-8
6) Replace tabs with spaces and remove trailing spaces
7) Add License.txt

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Kinney
2015-12-15 19:22:23 +00:00
committed by mdkinney
parent 46ff196fde
commit 9b6bbcdbfd
176 changed files with 54761 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
/** @file
Framework PEIM to initialize memory on a QuarkNcSocId Memory Controller.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
//
// Include common header file for this module.
//
#include "MemoryInit.h"
static PEI_QNC_MEMORY_INIT_PPI mPeiQNCMemoryInitPpi =
{ MrcStart };
static EFI_PEI_PPI_DESCRIPTOR PpiListPeiQNCMemoryInit =
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gQNCMemoryInitPpiGuid,
&mPeiQNCMemoryInitPpi
};
void Mrc( MRCParams_t *MrcData);
/**
Do memory initialization for QuarkNcSocId DDR3 SDRAM Controller
@param FfsHeader Not used.
@param PeiServices General purpose services available to every PEIM.
@return EFI_SUCCESS Memory initialization completed successfully.
All other error conditions encountered result in an ASSERT.
**/
EFI_STATUS
PeimMemoryInit(
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
Status = (**PeiServices).InstallPpi(PeiServices, &PpiListPeiQNCMemoryInit);
return Status;
}
VOID
EFIAPI
MrcStart(
IN OUT MRCParams_t *MrcData
)
{
Mrc(MrcData);
}

View File

@@ -0,0 +1,41 @@
/** @file
Framework PEIM to initialize memory on an DDR2 SDRAM Memory Controller.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _PEI_QNC_MEMORY_INIT_H_
#define _PEI_QNC_MEMORY_INIT_H_
//
// The package level header files this module uses
//
#include <PiPei.h>
#include <IntelQNCPeim.h>
//
// The protocols, PPI and GUID defintions for this module
//
#include <Ppi/QNCMemoryInit.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseMemoryLib.h>
VOID
EFIAPI
MrcStart (
IN OUT MRCParams_t *MrcData
);
#endif

View File

@@ -0,0 +1,76 @@
## @file
# This is the Memory Initialization Driver for Quark
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MemoryInitPei
FILE_GUID = D2C69B26-82E1-4a1b-AD35-ED0261B9F347
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimMemoryInit
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[BuildOptions]
GCC:DEBUG_*_*_CC_FLAGS = -DGCC -Wno-unused-function
GCC:RELEASE_*_*_CC_FLAGS = -DNDEBUG -DGCC -Wno-unused-function
INTEL:RELEASE_*_*_CC_FLAGS = /D NDEBUG
MSFT:RELEASE_*_*_CC_FLAGS = /D NDEBUG
[Sources]
memory_options.h
platform.c
lprint.c
meminit.h
meminit.c
meminit_utils.h
meminit_utils.c
gen5_iosf_sb_definitions.h
general_definitions.h
io.h
core_types.h
prememinit.h
prememinit.c
mrc.h
mrc.c
hte.c
hte.h
MemoryInit.h
MemoryInit.c
[Packages]
QuarkSocPkg/QuarkSocPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
PeimEntryPoint
DebugLib
BaseMemoryLib
[Ppis]
gQNCMemoryInitPpiGuid # PPI ALWAYS_PRODUCED
[Depex]
TRUE

View File

@@ -0,0 +1,49 @@
/** @file
Core types used in Mrc.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __MRC_CORE_TYPES_H
#define __MRC_CORE_TYPES_H
typedef char char_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned char bool;
typedef unsigned int size_t;
#ifdef ASM_INC
// Unfortunately h2inc has issue with long long
typedef struct uint64_s
{
uint32_t lo;
uint32_t hi;
}uint64_t;
#else
typedef unsigned long long uint64_t;
#endif
#ifdef SIM
// Native word length is 64bit in simulation environment
typedef uint64_t uintn_t;
#else
// Quark is 32bit
typedef uint32_t uintn_t;
#endif
#define PTR32(a) ((volatile uint32_t*)(uintn_t)(a))
#endif

View File

@@ -0,0 +1,744 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
* MCU register definition
*
************************************************************************/
#ifndef __IOSF_DEFINITIONS_H
#define __IOSF_DEFINITIONS_H
// Define each of the IOSF-SB register offsets used by MRC.
// MCU registers (DUNIT):
// ====
#define DRP 0x0000
#define DTR0 0x0001
#define DTR1 0x0002
#define DTR2 0x0003
#define DTR3 0x0004
#define DTR4 0x0005
#define DPMC0 0x0006
#define DPMC1 0x0007
#define DRFC 0x0008
#define DSCH 0x0009
#define DCAL 0x000A
#define DRMC 0x000B
#define PMSTS 0x000C
#define DCO 0x000F
#define DSTAT 0x0020
#define DECCCTRL 0x0060
#define DFUSESTAT 0x0070
#define SCRMSEED 0x0080
#define SCRMLO 0x0081
#define SCRMHI 0x0082
#define MCU_CH_OFFSET 0x0040
#define MCU_RK_OFFSET 0x0020
////
//
// BEGIN DUnit register definition
//
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t rank0Enabled :1; /**< BIT [0] Rank 0 Enable */
uint32_t rank1Enabled :1; /**< BIT [1] Rank 1 Enable */
uint32_t reserved0 :2;
uint32_t dimm0DevWidth :2; /**< BIT [5:4] DIMM 0 Device Width (Rank0&1) */
uint32_t dimm0DevDensity :2; /**< BIT [7:6] DIMM 0 Device Density */
uint32_t reserved1 :1;
uint32_t dimm1DevWidth :2; /**< BIT [10:9] DIMM 1 Device Width (Rank2&3) */
uint32_t dimm1DevDensity :2; /**< BIT [12:11] DIMM 1 Device Density */
uint32_t split64 :1; /**< BIT [13] split 64B transactions */
uint32_t addressMap :2; /**< BIT [15:14] Address Map select */
uint32_t reserved3 :14;
uint32_t mode32 :1; /**< BIT [30] Select 32bit data interface*/
uint32_t reserved4 :1;
} field;
} RegDRP; /**< DRAM Rank Population and Interface Register */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t dramFrequency :2; /**< DRAM Frequency (000=800,001=1033,010=1333) */
uint32_t reserved1 :2;
uint32_t tRP :4; /**< bit [7:4] Precharge to Activate Delay */
uint32_t tRCD :4; /**< bit [11:8] Activate to CAS Delay */
uint32_t tCL :3; /**< bit [14:12] CAS Latency */
uint32_t reserved4 :1;
uint32_t tXS :1; /**< SRX Delay */
uint32_t reserved5 :1;
uint32_t tXSDLL :1; /**< SRX To DLL Delay */
uint32_t reserved6 :1;
uint32_t tZQCS :1; /**< bit [20] ZQTS recovery Latncy */
uint32_t reserved7 :1;
uint32_t tZQCL :1; /**< bit [22] ZQCL recovery Latncy */
uint32_t reserved8 :1;
uint32_t pmeDelay :2; /**< bit [25:24] Power mode entry delay */
uint32_t reserved9 :2;
uint32_t CKEDLY :4; /**< bit [31:28] */
} field;
} RegDTR0; /**< DRAM Timing Register 0 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t tWCL :3; /**< bit [2:0] CAS Write Latency */
uint32_t reserved1 :1;
uint32_t tCMD :2; /**< bit [5:4] Command transport duration */
uint32_t reserved2 :2;
uint32_t tWTP :4; /**< Write to Precharge */
uint32_t tCCD :2; /**< CAS to CAS delay */
uint32_t reserved4 :2;
uint32_t tFAW :4; /**< Four bank Activation Window*/
uint32_t tRAS :4; /**< Row Activation Period: */
uint32_t tRRD :2; /**<Row activation to Row activation Delay */
uint32_t reserved5 :2;
uint32_t tRTP :3; /**<Read to Precharge Delay */
uint32_t reserved6 :1;
} field;
} RegDTR1; /**< DRAM Timing Register 1 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t tRRDR :3; /**< RD to RD from different ranks, same DIMM */
uint32_t reserved1 :5;
uint32_t tWWDR :3; /**< WR to WR from different ranks, same DIMM. */
uint32_t reserved3 :5;
uint32_t tRWDR :4; /**< bit [19:16] RD to WR from different ranks, same DIMM. */
uint32_t reserved5 :12;
} field;
} RegDTR2; /**< DRAM Timing Register 2 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t tWRDR :3; /**< WR to RD from different ranks, same DIMM. */
uint32_t reserved1 :1;
uint32_t tWRDD :3; /**< WR to RD from different DIMM. */
uint32_t reserved2 :1;
uint32_t tRWSR :4; /**< RD to WR Same Rank. */
uint32_t reserved3 :1;
uint32_t tWRSR :4; /**< WR to RD Same Rank. */
uint32_t reserved4 :5;
uint32_t tXP :2; /**< Time from CKE set on to any command. */
uint32_t PWD_DLY :4; /**< Extended Power-Down Delay. */
uint32_t EnDeRate :1;
uint32_t DeRateOvr :1;
uint32_t DeRateStat :1;
uint32_t reserved5 :1;
} field;
} RegDTR3; /**< DRAM Timing Register 3 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t WRODTSTRT :2; /**< WR command to ODT assert delay */
uint32_t reserved1 :2;
uint32_t WRODTSTOP :3; /**< Write command to ODT de-assert delay. */
uint32_t reserved2 :1;
uint32_t RDODTSTRT :3; /**< Read command to ODT assert delay */
uint32_t reserved3 :1;
uint32_t RDODTSTOP :3; /**< Read command to ODT de-assert delay */
uint32_t ODTDIS :1; /**< ODT disable */
uint32_t TRGSTRDIS :1; /**< Write target rank is not stretched */
uint32_t RDODTDIS :1; /**< Disable Read ODT */
uint32_t WRBODTDIS :1; /**< Disable Write ODT */
uint32_t reserved5 :13;
} field;
} RegDTR4; /**< DRAM Timing Register 3 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t SREntryDelay :8; /**< Self-Refresh Entry Delay: */
uint32_t powerModeOpCode :5; /**< SPID Power Mode Opcode */
uint32_t reserved1 :3;
uint32_t PCLSTO :3; /**< Page Close Timeout Period */
uint32_t reserved2 :1;
uint32_t PCLSWKOK :1; /**< Wake Allowed For Page Close Timeout */
uint32_t PREAPWDEN :1; /**< Send Precharge All to rank before entering Power-Down mode. */
uint32_t reserved3 :1;
uint32_t DYNSREN :1; /**< Dynamic Self-Refresh */
uint32_t CLKGTDIS :1; /**< Clock Gating Disabled*/
uint32_t DISPWRDN :1; /**< Disable Power Down*/
uint32_t reserved4 :2;
uint32_t REUTCLKGTDIS :1;
uint32_t ENPHYCLKGATE :1;
uint32_t reserved5 :2;
} field;
} RegDPMC0; /**< DRAM Power Management Control Register 0 */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t REFWMLO :4; /**< Refresh Opportunistic Watermark */
uint32_t REFWMHI :4; /**< Refresh High Watermark*/
uint32_t REFWMPNC :4; /**< Refresh Panic Watermark */
uint32_t tREFI :3; /**< bit [14:12] Refresh Period */
uint32_t reserved1 :1;
uint32_t REFCNTMAX :2; /**< Refresh Max tREFI Interval */
uint32_t reserved2 :2;
uint32_t REFSKEWDIS :1; /**< tREFI counters */
uint32_t REFDBTCLR :1;
uint32_t reserved3 :2;
uint32_t CuRefRate :3;
uint32_t DisRefBW :1;
uint32_t reserved4 :4;
} field;
} RegDRCF; /**< DRAM Refresh Control Register*/
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t reserved1 :8;
uint32_t ZQCINT :3; /**< ZQ Calibration Short Interval: */
uint32_t reserved2 :1;
uint32_t SRXZQCL :2; /** < ZQ Calibration Length */
uint32_t ZQCalType :1;
uint32_t ZQCalStart :1;
uint32_t TQPollStart :1;
uint32_t TQPollRS :2;
uint32_t reserved3 :5;
uint32_t MRRData :8; /**< bit[31:24] */
} field;
} RegDCAL; /**< DRAM Calibration Control*/
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t OOOAGETRH :5; /**< Out-of-Order Aging Threshold */
uint32_t reserved1 :3;
uint32_t OOODIS :1; /**< Out-of-Order Disable */
uint32_t OOOST3DIS :1; /**< Out-of-Order Disabled when RequestBD_Status is 3. */
uint32_t reserved2 :2;
uint32_t NEWBYPDIS :1;
uint32_t reserved3 :3;
uint32_t IPREQMAX :3; /** < Max In-Progress Requests stored in MC */
uint32_t reserved4 :13;
} field;
} RegDSCH; /**< DRAM Scheduler Control Register */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t DRPLOCK :1; /**< DRP lock bit */
uint32_t reserved1 :7;
uint32_t REUTLOCK :1; /**< REUT lock bit */
uint32_t reserved2 :19;
uint32_t PMICTL :1; /**< PRI Control Select: 0-memory_manager, 1-hte */
uint32_t PMIDIS :1; /**< PMIDIS Should be set is using IOSF-SB RW */
uint32_t DIOIC :1; /**< DDRIO initialization is complete */
uint32_t IC :1; /**< D-unit Initialization Complete */
} field;
} RegDCO; /**< DRAM Controller Operation Register*/
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t SBEEN :1; /**< Enable Single Bit Error Detection and Correction */
uint32_t DBEEN :1; /**< Enable Double Bit Error Detection */
uint32_t CBOEN :3; /**< Enable ECC Check Bits Override */
uint32_t SYNSEL :2; /**< ECC Syndrome Bits Select for Observation */
uint32_t CLRSBECNT :1; /**< Clear ECC Single Bit Error Count */
uint32_t CBOV :8; /**< ECC Check Bits Override Value */
uint32_t reserved1 :1; /**< */
uint32_t ENCBGEN :1; /**< Enable Generation of ECC Check Bits */
uint32_t ENCBGESWIZ :1; /**< Enable Same Chip ECC Byte Lane Swizzle */
} field;
} RegDECCCTRL; /**< DRAM ECC Control Register */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t FUS_DUN_ECC_DIS :1;
uint32_t FUS_DUN_MAX_SUPPORTED_MEMORY :3;
uint32_t FUS_DUN_MAX_DEVDEN :2;
uint32_t RESERVED1 :1;
uint32_t FUS_DUN_RANK2_DIS :1;
uint32_t FUS_DUN_OOO_DIS :1;
uint32_t FUS_DUN_MEMX8_DIS :1;
uint32_t FUS_DUN_MEMX16_DIS :1;
uint32_t RESERVED2 :1;
uint32_t FUS_DUN_1N_DIS :1;
uint32_t FUS_DUN_DQ_SCRAMBLER_DIS :1;
uint32_t RESERVED3 :1;
uint32_t FUS_DUN_32BIT_DRAM_IFC :1;
} field;
} RegDFUSESTAT;
#pragma pack()
//
// END DUnit register definition
//
////
////
//
// DRAM Initialization Structures used in JEDEC Message Bus Commands
//
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
unsigned command :3; /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
unsigned bankAddress :3; /**< Bank Address (BA[2:0]) */
unsigned BL :2; /**< Burst Length, CDV:1*/
unsigned CL :1; /**< CL Reserved CDV:0 */
unsigned RBT :1; /**< Read Burst Type */
unsigned casLatency :3; /**< cas Latency */
unsigned TM :1; /**< Test mode */
unsigned dllReset :1; /**< DLL Reset */
unsigned writeRecovery :3; /**< Write Recovery for Auto Pre-Charge: 001=2,010=3,011=4,100=5,101=6 */
unsigned PPD :1; /**< DLL Control for Precharge Power-Down CDV:1 */
unsigned reserved1 :3;
unsigned rankSelect :4; /**< Rank Select */
unsigned reserved2 :6;
} field;
} DramInitDDR3MRS0; /**< DDR3 Mode Register Set (MRS) Command */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
unsigned command :3; /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
unsigned bankAddress :3; /**< Bank Address (BA[2:0]) */
unsigned dllEnabled :1; /**< CDV=0 */
unsigned DIC0 :1; /**< Output Driver Impedance Control */
unsigned rttNom0 :1; /**< RTT_nom[0] */
unsigned MRC_AL :2; /**< Additive Latency = 0 */
unsigned DIC1 :1; /**< Reserved */
unsigned rttNom1 :1; /**< RTT_nom[1] */
unsigned wlEnabled :1; /**< Write Leveling Enable */
unsigned reserved1 :1;
unsigned rttNom2 :1; /** < RTT_nom[2] */
unsigned reserved2 :1;
unsigned TDQS :1; /**< TDQS Enable */
unsigned Qoff :1; /**< Output Buffers Disabled */
unsigned reserved3 :3;
unsigned rankSelect :4; /**< Rank Select */
unsigned reserved4 :6;
} field;
} DramInitDDR3EMR1; /**< DDR3 Extended Mode Register 1 Set (EMRS1) Command */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t command :3; /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
uint32_t bankAddress :3; /**< Bank Address (BA[2:0]) */
uint32_t PASR :3; /**< Partial Array Self-Refresh */
uint32_t CWL :3; /**< CAS Write Latency */
uint32_t ASR :1; /**< Auto Self-Refresh */
uint32_t SRT :1; /**< SR Temperature Range = 0*/
uint32_t reserved1 :1;
uint32_t rtt_WR :2; /**< Rtt_WR */
uint32_t reserved2 :5;
uint32_t rankSelect :4; /**< Rank Select */
uint32_t reserved3 :6;
} field;
} DramInitDDR3EMR2; /**< DDR3 Extended Mode Register 2 Set (EMRS2) Command */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t command :3; /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
uint32_t bankAddress :3; /**< Bank Address (BA[2:0]) */
uint32_t MPR_Location :2; /**< MPR Location */
uint32_t MPR :1; /**< MPR: Multi Purpose Register */
uint32_t reserved1 :13;
uint32_t rankSelect :4; /**< Rank Select */
uint32_t reserved2 :6;
} field;
} DramInitDDR3EMR3; /**< DDR3 Extended Mode Register 2 Set (EMRS2) Command */
#pragma pack()
#pragma pack(1)
typedef union {
uint32_t raw;
struct {
uint32_t command :3; /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110 - ZQ Calibration,111-NOP */
uint32_t bankAddress :3; /**< Bank Address (BA[2:0]) */
uint32_t multAddress :16; /**< Multiplexed Address (MA[14:0]) */
uint32_t rankSelect :2; /**< Rank Select */
uint32_t reserved3 :8;
} field;
} DramInitMisc; /**< Miscellaneous DDRx Initialization Command */
#pragma pack()
//
// Construct DRAM init command using DramInitXxxx pattern
//
#define DCMD_MRS1(rnk,dat) (0 | ((rnk)<<22) | (1<<3) | ((dat)<<6))
#define DCMD_REF(rnk) (1 | ((rnk)<<22))
#define DCMD_PRE(rnk) (2 | ((rnk)<<22))
#define DCMD_PREA(rnk) (2 | ((rnk)<<22) | (BIT10<<6))
#define DCMD_ACT(rnk,row) (3 | ((rnk)<<22) | ((row)<<6))
#define DCMD_WR(rnk,col) (4 | ((rnk)<<22) | ((col)<<6))
#define DCMD_RD(rnk,col) (5 | ((rnk)<<22) | ((col)<<6))
#define DCMD_ZQCS(rnk) (6 | ((rnk)<<22))
#define DCMD_ZQCL(rnk) (6 | ((rnk)<<22) | (BIT10<<6))
#define DCMD_NOP(rnk) (7 | ((rnk)<<22))
#define DDR3_EMRS1_DIC_40 (0)
#define DDR3_EMRS1_DIC_34 (1)
#define DDR3_EMRS2_RTTWR_60 (BIT9)
#define DDR3_EMRS2_RTTWR_120 (BIT10)
#define DDR3_EMRS1_RTTNOM_0 (0)
#define DDR3_EMRS1_RTTNOM_60 (BIT2)
#define DDR3_EMRS1_RTTNOM_120 (BIT6)
#define DDR3_EMRS1_RTTNOM_40 (BIT6|BIT2)
#define DDR3_EMRS1_RTTNOM_20 (BIT9)
#define DDR3_EMRS1_RTTNOM_30 (BIT9|BIT2)
//
// END DRAM Init...
//
////
// HOST_BRIDGE registers:
#define HMBOUND 0x0020 //ok
// MEMORY_MANAGER registers:
#define BCTRL 0x0004
#define BWFLUSH 0x0008
#define BDEBUG1 0x00C4
////
//
// BEGIN DDRIO registers
//
// DDR IOs & COMPs:
#define DDRIODQ_BL_OFFSET 0x0800
#define DDRIODQ_CH_OFFSET ((NUM_BYTE_LANES/2) * DDRIODQ_BL_OFFSET)
#define DDRIOCCC_CH_OFFSET 0x0800
#define DDRCOMP_CH_OFFSET 0x0100
// CH0-BL01-DQ
#define DQOBSCKEBBCTL 0x0000
#define DQDLLTXCTL 0x0004
#define DQDLLRXCTL 0x0008
#define DQMDLLCTL 0x000C
#define B0RXIOBUFCTL 0x0010
#define B0VREFCTL 0x0014
#define B0RXOFFSET1 0x0018
#define B0RXOFFSET0 0x001C
#define B1RXIOBUFCTL 0x0020
#define B1VREFCTL 0x0024
#define B1RXOFFSET1 0x0028
#define B1RXOFFSET0 0x002C
#define DQDFTCTL 0x0030
#define DQTRAINSTS 0x0034
#define B1DLLPICODER0 0x0038
#define B0DLLPICODER0 0x003C
#define B1DLLPICODER1 0x0040
#define B0DLLPICODER1 0x0044
#define B1DLLPICODER2 0x0048
#define B0DLLPICODER2 0x004C
#define B1DLLPICODER3 0x0050
#define B0DLLPICODER3 0x0054
#define B1RXDQSPICODE 0x0058
#define B0RXDQSPICODE 0x005C
#define B1RXDQPICODER32 0x0060
#define B1RXDQPICODER10 0x0064
#define B0RXDQPICODER32 0x0068
#define B0RXDQPICODER10 0x006C
#define B01PTRCTL0 0x0070
#define B01PTRCTL1 0x0074
#define B01DBCTL0 0x0078
#define B01DBCTL1 0x007C
#define B0LATCTL0 0x0080
#define B1LATCTL0 0x0084
#define B01LATCTL1 0x0088
#define B0ONDURCTL 0x008C
#define B1ONDURCTL 0x0090
#define B0OVRCTL 0x0094
#define B1OVRCTL 0x0098
#define DQCTL 0x009C
#define B0RK2RKCHGPTRCTRL 0x00A0
#define B1RK2RKCHGPTRCTRL 0x00A4
#define DQRK2RKCTL 0x00A8
#define DQRK2RKPTRCTL 0x00AC
#define B0RK2RKLAT 0x00B0
#define B1RK2RKLAT 0x00B4
#define DQCLKALIGNREG0 0x00B8
#define DQCLKALIGNREG1 0x00BC
#define DQCLKALIGNREG2 0x00C0
#define DQCLKALIGNSTS0 0x00C4
#define DQCLKALIGNSTS1 0x00C8
#define DQCLKGATE 0x00CC
#define B0COMPSLV1 0x00D0
#define B1COMPSLV1 0x00D4
#define B0COMPSLV2 0x00D8
#define B1COMPSLV2 0x00DC
#define B0COMPSLV3 0x00E0
#define B1COMPSLV3 0x00E4
#define DQVISALANECR0TOP 0x00E8
#define DQVISALANECR1TOP 0x00EC
#define DQVISACONTROLCRTOP 0x00F0
#define DQVISALANECR0BL 0x00F4
#define DQVISALANECR1BL 0x00F8
#define DQVISACONTROLCRBL 0x00FC
#define DQTIMINGCTRL 0x010C
// CH0-ECC
#define ECCDLLTXCTL 0x2004
#define ECCDLLRXCTL 0x2008
#define ECCMDLLCTL 0x200C
#define ECCB1DLLPICODER0 0x2038
#define ECCB1DLLPICODER1 0x2040
#define ECCB1DLLPICODER2 0x2048
#define ECCB1DLLPICODER3 0x2050
#define ECCB01DBCTL0 0x2078
#define ECCB01DBCTL1 0x207C
#define ECCCLKALIGNREG0 0x20B8
#define ECCCLKALIGNREG1 0x20BC
#define ECCCLKALIGNREG2 0x20C0
// CH0-CMD
#define CMDOBSCKEBBCTL 0x4800
#define CMDDLLTXCTL 0x4808
#define CMDDLLRXCTL 0x480C
#define CMDMDLLCTL 0x4810
#define CMDRCOMPODT 0x4814
#define CMDDLLPICODER0 0x4820
#define CMDDLLPICODER1 0x4824
#define CMDCFGREG0 0x4840
#define CMDPTRREG 0x4844
#define CMDCLKALIGNREG0 0x4850
#define CMDCLKALIGNREG1 0x4854
#define CMDCLKALIGNREG2 0x4858
#define CMDPMCONFIG0 0x485C
#define CMDPMDLYREG0 0x4860
#define CMDPMDLYREG1 0x4864
#define CMDPMDLYREG2 0x4868
#define CMDPMDLYREG3 0x486C
#define CMDPMDLYREG4 0x4870
#define CMDCLKALIGNSTS0 0x4874
#define CMDCLKALIGNSTS1 0x4878
#define CMDPMSTS0 0x487C
#define CMDPMSTS1 0x4880
#define CMDCOMPSLV 0x4884
#define CMDBONUS0 0x488C
#define CMDBONUS1 0x4890
#define CMDVISALANECR0 0x4894
#define CMDVISALANECR1 0x4898
#define CMDVISACONTROLCR 0x489C
#define CMDCLKGATE 0x48A0
#define CMDTIMINGCTRL 0x48A4
// CH0-CLK-CTL
#define CCOBSCKEBBCTL 0x5800
#define CCRCOMPIO 0x5804
#define CCDLLTXCTL 0x5808
#define CCDLLRXCTL 0x580C
#define CCMDLLCTL 0x5810
#define CCRCOMPODT 0x5814
#define CCDLLPICODER0 0x5820
#define CCDLLPICODER1 0x5824
#define CCDDR3RESETCTL 0x5830
#define CCCFGREG0 0x5838
#define CCCFGREG1 0x5840
#define CCPTRREG 0x5844
#define CCCLKALIGNREG0 0x5850
#define CCCLKALIGNREG1 0x5854
#define CCCLKALIGNREG2 0x5858
#define CCPMCONFIG0 0x585C
#define CCPMDLYREG0 0x5860
#define CCPMDLYREG1 0x5864
#define CCPMDLYREG2 0x5868
#define CCPMDLYREG3 0x586C
#define CCPMDLYREG4 0x5870
#define CCCLKALIGNSTS0 0x5874
#define CCCLKALIGNSTS1 0x5878
#define CCPMSTS0 0x587C
#define CCPMSTS1 0x5880
#define CCCOMPSLV1 0x5884
#define CCCOMPSLV2 0x5888
#define CCCOMPSLV3 0x588C
#define CCBONUS0 0x5894
#define CCBONUS1 0x5898
#define CCVISALANECR0 0x589C
#define CCVISALANECR1 0x58A0
#define CCVISACONTROLCR 0x58A4
#define CCCLKGATE 0x58A8
#define CCTIMINGCTL 0x58AC
// COMP
#define CMPCTRL 0x6800
#define SOFTRSTCNTL 0x6804
#define MSCNTR 0x6808
#define NMSCNTRL 0x680C
#define LATCH1CTL 0x6814
#define COMPVISALANECR0 0x681C
#define COMPVISALANECR1 0x6820
#define COMPVISACONTROLCR 0x6824
#define COMPBONUS0 0x6830
#define TCOCNTCTRL 0x683C
#define DQANAODTPUCTL 0x6840
#define DQANAODTPDCTL 0x6844
#define DQANADRVPUCTL 0x6848
#define DQANADRVPDCTL 0x684C
#define DQANADLYPUCTL 0x6850
#define DQANADLYPDCTL 0x6854
#define DQANATCOPUCTL 0x6858
#define DQANATCOPDCTL 0x685C
#define CMDANADRVPUCTL 0x6868
#define CMDANADRVPDCTL 0x686C
#define CMDANADLYPUCTL 0x6870
#define CMDANADLYPDCTL 0x6874
#define CLKANAODTPUCTL 0x6880
#define CLKANAODTPDCTL 0x6884
#define CLKANADRVPUCTL 0x6888
#define CLKANADRVPDCTL 0x688C
#define CLKANADLYPUCTL 0x6890
#define CLKANADLYPDCTL 0x6894
#define CLKANATCOPUCTL 0x6898
#define CLKANATCOPDCTL 0x689C
#define DQSANAODTPUCTL 0x68A0
#define DQSANAODTPDCTL 0x68A4
#define DQSANADRVPUCTL 0x68A8
#define DQSANADRVPDCTL 0x68AC
#define DQSANADLYPUCTL 0x68B0
#define DQSANADLYPDCTL 0x68B4
#define DQSANATCOPUCTL 0x68B8
#define DQSANATCOPDCTL 0x68BC
#define CTLANADRVPUCTL 0x68C8
#define CTLANADRVPDCTL 0x68CC
#define CTLANADLYPUCTL 0x68D0
#define CTLANADLYPDCTL 0x68D4
#define CHNLBUFSTATIC 0x68F0
#define COMPOBSCNTRL 0x68F4
#define COMPBUFFDBG0 0x68F8
#define COMPBUFFDBG1 0x68FC
#define CFGMISCCH0 0x6900
#define COMPEN0CH0 0x6904
#define COMPEN1CH0 0x6908
#define COMPEN2CH0 0x690C
#define STATLEGEN0CH0 0x6910
#define STATLEGEN1CH0 0x6914
#define DQVREFCH0 0x6918
#define CMDVREFCH0 0x691C
#define CLKVREFCH0 0x6920
#define DQSVREFCH0 0x6924
#define CTLVREFCH0 0x6928
#define TCOVREFCH0 0x692C
#define DLYSELCH0 0x6930
#define TCODRAMBUFODTCH0 0x6934
#define CCBUFODTCH0 0x6938
#define RXOFFSETCH0 0x693C
#define DQODTPUCTLCH0 0x6940
#define DQODTPDCTLCH0 0x6944
#define DQDRVPUCTLCH0 0x6948
#define DQDRVPDCTLCH0 0x694C
#define DQDLYPUCTLCH0 0x6950
#define DQDLYPDCTLCH0 0x6954
#define DQTCOPUCTLCH0 0x6958
#define DQTCOPDCTLCH0 0x695C
#define CMDDRVPUCTLCH0 0x6968
#define CMDDRVPDCTLCH0 0x696C
#define CMDDLYPUCTLCH0 0x6970
#define CMDDLYPDCTLCH0 0x6974
#define CLKODTPUCTLCH0 0x6980
#define CLKODTPDCTLCH0 0x6984
#define CLKDRVPUCTLCH0 0x6988
#define CLKDRVPDCTLCH0 0x698C
#define CLKDLYPUCTLCH0 0x6990
#define CLKDLYPDCTLCH0 0x6994
#define CLKTCOPUCTLCH0 0x6998
#define CLKTCOPDCTLCH0 0x699C
#define DQSODTPUCTLCH0 0x69A0
#define DQSODTPDCTLCH0 0x69A4
#define DQSDRVPUCTLCH0 0x69A8
#define DQSDRVPDCTLCH0 0x69AC
#define DQSDLYPUCTLCH0 0x69B0
#define DQSDLYPDCTLCH0 0x69B4
#define DQSTCOPUCTLCH0 0x69B8
#define DQSTCOPDCTLCH0 0x69BC
#define CTLDRVPUCTLCH0 0x69C8
#define CTLDRVPDCTLCH0 0x69CC
#define CTLDLYPUCTLCH0 0x69D0
#define CTLDLYPDCTLCH0 0x69D4
#define FNLUPDTCTLCH0 0x69F0
// PLL
#define MPLLCTRL0 0x7800
#define MPLLCTRL1 0x7808
#define MPLLCSR0 0x7810
#define MPLLCSR1 0x7814
#define MPLLCSR2 0x7820
#define MPLLDFT 0x7828
#define MPLLMON0CTL 0x7830
#define MPLLMON1CTL 0x7838
#define MPLLMON2CTL 0x783C
#define SFRTRIM 0x7850
#define MPLLDFTOUT0 0x7858
#define MPLLDFTOUT1 0x785C
#define MASTERRSTN 0x7880
#define PLLLOCKDEL 0x7884
#define SFRDEL 0x7888
#define CRUVISALANECR0 0x78F0
#define CRUVISALANECR1 0x78F4
#define CRUVISACONTROLCR 0x78F8
#define IOSFVISALANECR0 0x78FC
#define IOSFVISALANECR1 0x7900
#define IOSFVISACONTROLCR 0x7904
//
// END DDRIO registers
//
////
#endif

View File

@@ -0,0 +1,90 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#ifndef __GENERAL_DEFINITIONS_H
#define __GENERAL_DEFINITIONS_H
#undef BIT0
#undef BIT1
#undef BIT2
#undef BIT3
#undef BIT4
#undef BIT5
#undef BIT6
#undef BIT7
#undef BIT8
#undef BIT9
#undef BIT10
#undef BIT11
#undef BIT12
#undef BIT13
#undef BIT14
#undef BIT15
#undef BIT16
#undef BIT17
#undef BIT18
#undef BIT19
#undef BIT20
#undef BIT21
#undef BIT22
#undef BIT23
#undef BIT24
#undef BIT25
#undef BIT26
#undef BIT27
#undef BIT28
#undef BIT29
#undef BIT30
#undef BIT31
// defines
#define BIT0 0x00000001U
#define BIT1 0x00000002U
#define BIT2 0x00000004U
#define BIT3 0x00000008U
#define BIT4 0x00000010U
#define BIT5 0x00000020U
#define BIT6 0x00000040U
#define BIT7 0x00000080U
#define BIT8 0x00000100U
#define BIT9 0x00000200U
#define BIT10 0x00000400U
#define BIT11 0x00000800U
#define BIT12 0x00001000U
#define BIT13 0x00002000U
#define BIT14 0x00004000U
#define BIT15 0x00008000U
#define BIT16 0x00010000U
#define BIT17 0x00020000U
#define BIT18 0x00040000U
#define BIT19 0x00080000U
#define BIT20 0x00100000U
#define BIT21 0x00200000U
#define BIT22 0x00400000U
#define BIT23 0x00800000U
#define BIT24 0x01000000U
#define BIT25 0x02000000U
#define BIT26 0x04000000U
#define BIT27 0x08000000U
#define BIT28 0x10000000U
#define BIT29 0x20000000U
#define BIT30 0x40000000U
#define BIT31 0x80000000U
#define true 0x01
#define false 0x00
#endif

View File

@@ -0,0 +1,542 @@
/** @file
HTE handling routines for MRC use.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "mrc.h"
#include "memory_options.h"
#include "io.h"
#include "hte.h"
#ifdef SIM
VOID delay_n(UINT32 nanoseconds);
#define MySimStall(a) delay_n(a/1000)
#endif
STATIC VOID EnableAllHteErrors(
UINT8 Mask)
/*++
Routine Description:
This function enables to HTE to detect all possible errors for
the given training parameters (per-bit or full byte lane).
Returns:
None
--*/
{
isbW32m(HTE, 0x000200A2, 0xFFFFFFFF);
isbW32m(HTE, 0x000200A3, 0x000000FF);
isbW32m(HTE, 0x000200A4, 0x00000000);
}
STATIC UINT32 CheckHteErrors(
VOID)
/*++
Routine Description:
This function goes and reads the HTE register in order to find any error
Returns:
The errors detected in the HTE status register
--*/
{
return isbR32m(HTE, 0x000200A7);
}
STATIC VOID WaitForHteComplete(
VOID)
/*++
Routine Description:
This function waits until HTE finishes
Returns:
None
--*/
{
UINT32 Tmp;
ENTERFN();
//
// Is the test done?
//
do
{
#ifdef SIM
MySimStall (35000); // 35 ns delay
#endif
} while (0 != (isbR32m(HTE, 0x00020012) & BIT30));
Tmp = isbR32m(HTE, 0x00020011);
Tmp = Tmp | BIT9;
Tmp = Tmp & ~(BIT13 | BIT12);
isbW32m(HTE, 0x00020011, Tmp);
LEAVEFN();
}
STATIC VOID ClearHteErrorRegisters(
VOID)
/*++
Routine Description:
Clears registers related with errors in the HTE.
Returns:
None
--*/
{
UINT32 Tmp;
//
// Clear all HTE errors and enable error checking
// for burst and chunk.
//
Tmp = isbR32m(HTE, 0x000200A1);
Tmp |= BIT8;
isbW32m(HTE, 0x000200A1, Tmp);
}
UINT32 HteMemInit(
MRC_PARAMS *CurrentMrcData,
UINT8 MemInitFlag,
UINT8 HaltHteEngineOnError)
/*++
Routine Description:
Uses HW HTE engine to initialize or test all memory attached to a given DUNIT.
If MemInitFlag is 1, this routine writes 0s to all memory locations to initialize
ECC.
If MemInitFlag is 0, this routine will send an 5AA55AA5 pattern to all memory
locations on the RankMask and then read it back. Then it sends an A55AA55A
pattern to all memory locations on the RankMask and reads it back.
Arguments:
CurrentMrcData: Host struture for all MRC global data.
MemInitFlag: 0 for memtest, 1 for meminit.
HaltHteEngineOnError: Halt the HTE engine on first error observed, or keep
running to see how many errors are found.
Returns:
Errors register showing HTE failures.
Also prints out which rank failed the HTE test if failure occurs.
For rank detection to work, the address map must be left in its default
state. If MRC changes the address map, this function must be modified
to change it back to default at the beginning, then restore it at the end.
--*/
{
UINT32 Offset;
UINT8 TestNum;
UINT8 i;
//
// Clear out the error registers at the start of each memory
// init or memory test run.
//
ClearHteErrorRegisters();
isbW32m(HTE, 0x00020062, 0x00000015);
for (Offset = 0x80; Offset <= 0x8F; Offset++)
{
isbW32m(HTE, Offset, ((Offset & 1) ? 0xA55A : 0x5AA5));
}
isbW32m(HTE, 0x00020021, 0x00000000);
#ifdef QUICKSIM
// Just do 4 cache lines for simulation memtest to save time.
isbW32m(HTE, 0x00020022, 4-1);
#else
isbW32m(HTE, 0x00020022, (CurrentMrcData->mem_size >> 6) - 1);
#endif
isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
isbW32m(HTE, 0x00020066, 0x03000000);
switch (MemInitFlag)
{
case MrcMemInit:
TestNum = 1; // Only 1 write pass through memory is needed to initialize ECC.
break;
case MrcMemTest:
TestNum = 4; // Write/read then write/read with inverted pattern.
break;
default:
DPF(D_INFO, "Unknown parameter for MemInitFlag: %d\n", MemInitFlag);
return 0xFFFFFFFF;
break;
}
DPF(D_INFO, "HteMemInit");
for (i = 0; i < TestNum; i++)
{
DPF(D_INFO, ".");
if (i == 0)
{
isbW32m(HTE, 0x00020061, 0x00000000);
isbW32m(HTE, 0x00020020, 0x00110010);
}
else if (i == 1)
{
isbW32m(HTE, 0x00020061, 0x00000000);
isbW32m(HTE, 0x00020020, 0x00010010);
}
else if (i == 2)
{
isbW32m(HTE, 0x00020061, 0x00010100);
isbW32m(HTE, 0x00020020, 0x00110010);
}
else
{
isbW32m(HTE, 0x00020061, 0x00010100);
isbW32m(HTE, 0x00020020, 0x00010010);
}
isbW32m(HTE, 0x00020011, 0x00111000);
isbW32m(HTE, 0x00020011, 0x00111100);
WaitForHteComplete();
//
// If this is a READ pass, check for errors at the end.
//
if ((i % 2) == 1)
{
//
// Return immediately if error.
//
if (CheckHteErrors())
{
break;
}
}
}
DPF(D_INFO, "done\n", i);
return CheckHteErrors();
}
STATIC UINT16 BasicDataCompareHte(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 FirstRun,
UINT8 Mode)
/*++
Routine Description:
Execute basic single cache line memory write/read/verify test using simple constant
pattern (different for READ_RAIN and WRITE_TRAIN modes.
See BasicWriteReadHTE which is external visible wrapper.
Arguments:
CurrentMrcData: Host struture for all MRC global data.
Address: memory adress being tested (must hit specific channel/rank)
FirstRun: If set then hte registers are configured, otherwise
it is assumed configuration is done and just re-run the test.
Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
Returns:
Returns byte lane failure on each bit (for Quark only bit0 and bit1)
--*/
{
UINT32 Pattern;
UINT32 Offset;
if (FirstRun)
{
isbW32m(HTE, 0x00020020, 0x01B10021);
isbW32m(HTE, 0x00020021, 0x06000000);
isbW32m(HTE, 0x00020022, Address >> 6);
isbW32m(HTE, 0x00020062, 0x00800015);
isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
isbW32m(HTE, 0x00020061, 0x00030008);
if (Mode == WRITE_TRAIN)
{
Pattern = 0xC33C0000;
}
else // READ_TRAIN
{
Pattern = 0xAA5555AA;
}
for (Offset = 0x80; Offset <= 0x8F; Offset++)
{
isbW32m(HTE, Offset, Pattern);
}
}
isbW32m(HTE, 0x000200A1, 0xFFFF1000);
isbW32m(HTE, 0x00020011, 0x00011000);
isbW32m(HTE, 0x00020011, 0x00011100);
WaitForHteComplete();
//
// Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for any bytelane errors.
//
return ((CheckHteErrors() >> 8) & 0xFF);
}
STATIC UINT16 ReadWriteDataCompareHte(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 LoopCount,
UINT32 LfsrSeedVictim,
UINT32 LfsrSeedAggressor,
UINT8 VictimBit,
UINT8 FirstRun)
/*++
Routine Description:
Examines single cache line memory with write/read/verify test using
multiple data patterns (victim-aggressor algorithm).
See WriteStressBitLanesHTE which is external visible wrapper.
Arguments:
CurrentMrcData: host struture for all MRC global data.
Address: memory adress being tested (must hit specific channel/rank)
LoopCount: number of test iterations
LfsrSeedXxx: victim aggressor data pattern seed
VictimBit: should be 0 as auto rotate feature is in use.
FirstRun: If set then hte registers are configured, otherwise
it is assumed configuration is done and just re-run the test.
Returns:
Returns byte lane failure on each bit (for Quark only bit0 and bit1)
--*/
{
UINT32 Offset;
UINT32 Tmp;
if (FirstRun)
{
isbW32m(HTE, 0x00020020, 0x00910024);
isbW32m(HTE, 0x00020023, 0x00810024);
isbW32m(HTE, 0x00020021, 0x06070000);
isbW32m(HTE, 0x00020024, 0x06070000);
isbW32m(HTE, 0x00020022, Address >> 6);
isbW32m(HTE, 0x00020025, Address >> 6);
isbW32m(HTE, 0x00020062, 0x0000002A);
isbW32m(HTE, 0x00020063, LfsrSeedVictim);
isbW32m(HTE, 0x00020064, LfsrSeedAggressor);
isbW32m(HTE, 0x00020065, LfsrSeedVictim);
//
// Write the pattern buffers to select the victim bit. Start with bit0.
//
for (Offset = 0x80; Offset <= 0x8F; Offset++)
{
if ((Offset % 8) == VictimBit)
{
isbW32m(HTE, Offset, 0x55555555);
}
else
{
isbW32m(HTE, Offset, 0xCCCCCCCC);
}
}
isbW32m(HTE, 0x00020061, 0x00000000);
isbW32m(HTE, 0x00020066, 0x03440000);
isbW32m(HTE, 0x000200A1, 0xFFFF1000);
}
Tmp = 0x10001000 | (LoopCount << 16);
isbW32m(HTE, 0x00020011, Tmp);
isbW32m(HTE, 0x00020011, Tmp | BIT8);
WaitForHteComplete();
return (CheckHteErrors() >> 8) & 0xFF;
}
UINT16 BasicWriteReadHTE(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 FirstRun,
UINT8 Mode)
/*++
Routine Description:
Execute basic single cache line memory write/read/verify test using simple constant
pattern (different for READ_RAIN and WRITE_TRAIN modes.
Arguments:
CurrentMrcData: Host struture for all MRC global data.
Address: memory adress being tested (must hit specific channel/rank)
FirstRun: If set then hte registers are configured, otherwise
it is assumed configuration is done and just re-run the test.
Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
Returns:
Returns byte lane failure on each bit (for Quark only bit0 and bit1)
--*/
{
UINT16 ByteLaneErrors;
ENTERFN();
//
// Enable all error reporting in preparation for HTE test.
//
EnableAllHteErrors(0xFF);
ClearHteErrorRegisters();
ByteLaneErrors = BasicDataCompareHte(CurrentMrcData, Address, FirstRun,
Mode);
LEAVEFN();
return ByteLaneErrors;
}
UINT16 WriteStressBitLanesHTE(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 FirstRun)
/*++
Routine Description:
Examines single cache line memory with write/read/verify test using
multiple data patterns (victim-aggressor algorithm).
Arguments:
CurrentMrcData: host struture for all MRC global data.
Address: memory adress being tested (must hit specific channel/rank)
FirstRun: If set then hte registers are configured, otherwise
it is assumed configuration is done and just re-run the test.
Returns:
Returns byte lane failure on each bit (for Quark only bit0 and bit1)
--*/
{
UINT16 ByteLaneErrors;
UINT8 VictimBit = 0;
ENTERFN();
//
// Enable all error reporting in preparation for HTE test.
//
EnableAllHteErrors(0xFF);
ClearHteErrorRegisters();
//
// Loop through each bit in the bytelane. Each pass creates a victim bit
// while keeping all other bits the same - as aggressors.
// AVN HTE adds an auto-rotate feature which allows us to program the entire victim/aggressor
// sequence in 1 step. The victim bit rotates on each pass so no need to have software implement
// a victim bit loop like on VLV.
//
ByteLaneErrors = ReadWriteDataCompareHte(CurrentMrcData, Address,
HTE_LOOP_CNT, HTE_LFSR_VICTIM_SEED, HTE_LFSR_AGRESSOR_SEED, VictimBit,
FirstRun);
LEAVEFN();
return ByteLaneErrors;
}
VOID HteMemOp(
UINT32 Address,
UINT8 FirstRun,
UINT8 IsWrite)
/*++
Routine Description:
Execute basic single cache line memory write or read.
This is just for receive enable / fine write levelling purpose.
Arguments:
CurrentMrcData: Host structure for all MRC global data.
Address: memory address used (must hit specific channel/rank)
FirstRun: If set then hte registers are configured, otherwise
it is assumed configuration is done and just re-run the test.
IsWrite: When non-zero memory write operation executed, otherwise read
Returns:
None
--*/
{
UINT32 Offset;
UINT32 Tmp;
EnableAllHteErrors(0xFF);
ClearHteErrorRegisters();
if (FirstRun)
{
Tmp = IsWrite ? 0x01110021 : 0x01010021;
isbW32m(HTE, 0x00020020, Tmp);
isbW32m(HTE, 0x00020021, 0x06000000);
isbW32m(HTE, 0x00020022, Address >> 6);
isbW32m(HTE, 0x00020062, 0x00800015);
isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
isbW32m(HTE, 0x00020061, 0x00030008);
for (Offset = 0x80; Offset <= 0x8F; Offset++)
{
isbW32m(HTE, Offset, 0xC33C0000);
}
}
isbW32m(HTE, 0x000200A1, 0xFFFF1000);
isbW32m(HTE, 0x00020011, 0x00011000);
isbW32m(HTE, 0x00020011, 0x00011100);
WaitForHteComplete();
}

View File

@@ -0,0 +1,72 @@
/** @file
HTE handling routines for MRC use.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __HTE_H
#define __HTE_H
#define STATIC static
#define VOID void
#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
typedef uint32_t UINT32;
typedef uint16_t UINT16;
typedef uint8_t UINT8;
#endif
typedef enum
{
MrcNoHaltSystemOnError,
MrcHaltSystemOnError,
MrcHaltHteEngineOnError,
MrcNoHaltHteEngineOnError
} HALT_TYPE;
typedef enum
{
MrcMemInit, MrcMemTest
} MEM_INIT_OR_TEST;
#define READ_TRAIN 1
#define WRITE_TRAIN 2
#define HTE_MEMTEST_NUM 2
#define HTE_LOOP_CNT 5 // EXP_LOOP_CNT field of HTE_CMD_CTL. This CANNOT be less than 4
#define HTE_LFSR_VICTIM_SEED 0xF294BA21 // Random seed for victim.
#define HTE_LFSR_AGRESSOR_SEED 0xEBA7492D // Random seed for aggressor.
UINT32
HteMemInit(
MRC_PARAMS *CurrentMrcData,
UINT8 MemInitFlag,
UINT8 HaltHteEngineOnError);
UINT16
BasicWriteReadHTE(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 FirstRun,
UINT8 Mode);
UINT16
WriteStressBitLanesHTE(
MRC_PARAMS *CurrentMrcData,
UINT32 Address,
UINT8 FirstRun);
VOID
HteMemOp(
UINT32 Address,
UINT8 FirstRun,
UINT8 IsWrite);
#endif

View File

@@ -0,0 +1,138 @@
/** @file
Declaration of IO handling routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __IO_H
#define __IO_H
#include "core_types.h"
#include "general_definitions.h"
#include "gen5_iosf_sb_definitions.h"
// Instruction not present on Quark
#define SFENCE()
#define DEAD_LOOP() for(;;);
////
// Define each of the IOSF_SB ports used by MRC
//
//
// Has to be 0 because of emulation static data
// initialisation:
// Space_t EmuSpace[ SPACE_COUNT] = {0};
//
#define FREE 0x000
// Pseudo side-band ports for access abstraction
// See Wr32/Rd32 functions
#define MEM 0x101
#define MMIO 0x102
#define DCMD 0x0A0
// Real side-band ports
// See Wr32/Rd32 functions
#define MCU 0x001
#define HOST_BRIDGE 0x003
#define MEMORY_MANAGER 0x005
#define HTE 0x011
#define DDRPHY 0x012
#define FUSE 0x033
// End of IOSF_SB ports
////
// Pciexbar address
#define EC_BASE 0xE0000000
#define PCIADDR(bus,dev,fn,reg) ( \
(EC_BASE) + \
((bus) << 20) + \
((dev) << 15) + \
((fn) << 12) + \
(reg))
// Various offsets used in the building sideband commands.
#define SB_OPCODE_OFFSET 24
#define SB_PORT_OFFSET 16
#define SB_REG_OFFEST 8
// Sideband opcodes
#define SB_REG_READ_OPCODE 0x10
#define SB_REG_WRITE_OPCODE 0x11
#define SB_FUSE_REG_READ_OPCODE 0x06
#define SB_FUSE_REG_WRITE_OPCODE 0x07
#define SB_DDRIO_REG_READ_OPCODE 0x06
#define SB_DDRIO_REG_WRITE_OPCODE 0x07
#define SB_DRAM_CMND_OPCODE 0x68
#define SB_WAKE_CMND_OPCODE 0xCA
#define SB_SUSPEND_CMND_OPCODE 0xCC
// Register addresses for sideband command and data.
#define SB_PACKET_REG 0x00D0
#define SB_DATA_REG 0x00D4
#define SB_HADR_REG 0x00D8
// We always flag all 4 bytes in the register reads/writes as required.
#define SB_ALL_BYTES_ENABLED 0xF0
#define SB_COMMAND(Opcode, Port, Reg) \
((Opcode << SB_OPCODE_OFFSET) | \
(Port << SB_PORT_OFFSET) | \
(Reg << SB_REG_OFFEST) | \
SB_ALL_BYTES_ENABLED)
// iosf
#define isbM32m WrMask32
#define isbW32m Wr32
#define isbR32m Rd32
// pci
void pciwrite32(
uint32_t bus,
uint32_t dev,
uint32_t fn,
uint32_t reg,
uint32_t data);
uint32_t pciread32(
uint32_t bus,
uint32_t dev,
uint32_t fn,
uint32_t reg);
// general
uint32_t Rd32(
uint32_t unit,
uint32_t addr);
void Wr32(
uint32_t unit,
uint32_t addr,
uint32_t data);
void WrMask32(
uint32_t unit,
uint32_t addr,
uint32_t data,
uint32_t mask);
#endif

View File

@@ -0,0 +1,388 @@
/** @file
Serial conole output and string formating.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "memory_options.h"
#include "general_definitions.h"
// Resource programmed to PCI bridge, 1MB bound alignment is needed.
// The default value is overwritten by MRC parameter, assuming code
// relocated to eSRAM.
uint32_t UartMmioBase = 0;
// Serial port registers based on SerialPortLib.c
#define R_UART_BAUD_THR 0
#define R_UART_LSR 20
#define B_UART_LSR_RXRDY BIT0
#define B_UART_LSR_TXRDY BIT5
#define B_UART_LSR_TEMT BIT6
// Print mask see DPF and D_Xxxx
#define DPF_MASK DpfPrintMask
// Select class of messages enabled for printing
uint32_t DpfPrintMask =
D_ERROR |
D_INFO |
// D_REGRD |
// D_REGWR |
// D_FCALL |
// D_TRN |
0;
#ifdef NDEBUG
// Don't generate debug code
void dpf( uint32_t mask, char_t* bla, ...)
{
return;
}
uint8_t mgetc(void)
{
return 0;
}
uint8_t mgetch(void)
{
return 0;
}
#else
#ifdef SIM
// Use Vpi console in simulation environment
#include <vpi_user.h>
void dpf( uint32_t mask, char_t* bla, ...)
{
va_list va;
if( 0 == (mask & DPF_MASK)) return;
va_start( va, bla);
vpi_vprintf( bla, va);
va_end(va);
}
#else
#ifdef EMU
// Use standard console in windows environment
#include <stdio.h>
#endif
// Read character from serial port
uint8_t mgetc(void)
{
#ifdef EMU
// Emulation in Windows environment uses console
getchar();
#else
uint8_t c;
while ((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) == 0);
c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);
return c;
#endif
}
uint8_t mgetch(void)
{
#ifdef EMU
return 0;
#else
uint8_t c = 0;
if((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) != 0)
{
c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);
}
return c;
#endif
}
// Print single character
static void printc(
uint8_t c)
{
#ifdef EMU
// Emulation in Windows environment uses console output
putchar(c);
#else
//
// Use MMIO access to serial port on PCI
// while( 0 == (0x20 & inp(0x3f8 + 5)));
// outp(0x3f8 + 0, c);
//
while (0
== (B_UART_LSR_TEMT & *((volatile uint8_t*) (UartMmioBase + R_UART_LSR))))
;
*((volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR)) = c;
#endif
}
// Print 0 terminated string on serial console
static void printstr(
char_t *str)
{
while (*str)
{
printc(*str++);
}
}
// Print 64bit number as hex string on serial console
// the width parameters allows skipping leading zeros
static void printhexx(
uint64_t val,
uint32_t width)
{
uint32_t i;
uint8_t c;
uint8_t empty = 1;
// 64bit number has 16 characters in hex representation
for (i = 16; i > 0; i--)
{
c = *(((uint8_t *)&val) + ((i - 1) >> 1));
if (((i - 1) & 1) != 0)
c = c >> 4;
c = c & 0x0F;
if (c > 9)
c += 'A' - 10;
else
c += '0';
if (c != '0')
{
// end of leading zeros
empty = 0;
}
// don't print leading zero
if (!empty || i <= width)
{
printc(c);
}
}
}
// Print 32bit number as hex string on serial console
// the width parameters allows skipping leading zeros
static void printhex(
uint32_t val,
uint32_t width)
{
uint32_t i;
uint8_t c;
uint8_t empty = 1;
// 32bit number has 8 characters in hex representation
for (i = 8; i > 0; i--)
{
c = (uint8_t) ((val >> 28) & 0x0F);
if (c > 9)
c += 'A' - 10;
else
c += '0';
val = val << 4;
if (c != '0')
{
// end of leading zeros
empty = 0;
}
// don't print leading zero
if (!empty || i <= width)
{
printc(c);
}
}
}
// Print 32bit number as decimal string on serial console
// the width parameters allows skipping leading zeros
static void printdec(
uint32_t val,
uint32_t width)
{
uint32_t i;
uint8_t c = 0;
uint8_t empty = 1;
// Ten digits is enough for 32bit number in decimal
uint8_t buf[10];
for (i = 0; i < sizeof(buf); i++)
{
c = (uint8_t) (val % 10);
buf[i] = c + '0';
val = val / 10;
}
while (i > 0)
{
c = buf[--i];
if (c != '0')
{
// end of leading zeros
empty = 0;
}
// don't print leading zero
if (!empty || i < width)
{
printc(c);
}
}
}
// Consume numeric substring leading the given string
// Return pointer to the first non-numeric character
// Buffer reference by width is updated with number
// converted from the numeric substring.
static char_t *getwidth(
char_t *bla,
uint32_t *width)
{
uint32_t val = 0;
while (*bla >= '0' && *bla <= '9')
{
val = val * 10 + *bla - '0';
bla += 1;
}
if (val > 0)
{
*width = val;
}
return bla;
}
// Consume print format designator from the head of given string
// Return pointer to first character after format designator
// input fmt
// ----- ---
// s -> s
// d -> d
// X -> X
// llX -> L
static char_t *getformat(
char_t *bla,
uint8_t *fmt)
{
if (bla[0] == 's')
{
bla += 1;
*fmt = 's';
}
else if (bla[0] == 'd')
{
bla += 1;
*fmt = 'd';
}
else if (bla[0] == 'X' || bla[0] == 'x')
{
bla += 1;
*fmt = 'X';
}
else if (bla[0] == 'l' && bla[1] == 'l' && bla[2] == 'X')
{
bla += 3;
*fmt = 'L';
}
return bla;
}
// Simplified implementation of standard printf function
// The output is directed to serial console. Only selected
// class of messages is printed (mask has to match DpfPrintMask)
// Supported print formats: %[n]s,%[n]d,%[n]X,,%[n]llX
// The width is ignored for %s format.
void dpf(
uint32_t mask,
char_t* bla,
...)
{
uint32_t* arg = (uint32_t*) (&bla + 1);
// Check UART MMIO base configured
if (0 == UartMmioBase)
return;
// Check event not masked
if (0 == (mask & DPF_MASK))
return;
for (;;)
{
uint8_t x = *bla++;
if (x == 0)
break;
if (x == '\n')
{
printc('\r');
printc('\n');
}
else if (x == '%')
{
uint8_t fmt = 0;
uint32_t width = 1;
bla = getwidth(bla, &width);
bla = getformat(bla, &fmt);
// Print value
if (fmt == 'd')
{
printdec(*arg, width);
arg += 1;
}
else if (fmt == 'X')
{
printhex(*arg, width);
arg += 1;
}
else if (fmt == 'L')
{
printhexx(*(uint64_t*) arg, width);
arg += 2;
}
else if (fmt == 's')
{
printstr(*(char**) arg);
arg += 1;
}
}
else
{
printc(x);
}
}
}
#endif //SIM
#endif //NDEBUG

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#ifndef _MEMINIT_H_
#define _MEMINIT_H_
// function prototypes
void MemInit(MRCParams_t *mrc_params);
typedef void (*MemInitFn_t)(MRCParams_t *mrc_params);
typedef struct MemInit_s {
uint16_t post_code;
uint16_t boot_path;
MemInitFn_t init_fn;
} MemInit_t;
#endif // _MEMINIT_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
***************************************************************************/
#ifndef _MEMINIT_UTILS_H_
#define _MEMINIT_UTILS_H_
// General Definitions:
#ifdef QUICKSIM
#define SAMPLE_SIZE 4 // reduce number of training samples in simulation env
#else
#define SAMPLE_SIZE 6 // must be odd number
#endif
#define EARLY_DB (0x12) // must be less than this number to enable early deadband
#define LATE_DB (0x34) // must be greater than this number to enable late deadband
#define CHX_REGS (11*4)
#define FULL_CLK 128
#define HALF_CLK 64
#define QRTR_CLK 32
#define MCEIL(num,den) ((uint8_t)((num+den-1)/den))
#define MMAX(a,b) ((((int32_t)(a))>((int32_t)(b)))?(a):(b))
#define MCOUNT(a) (sizeof(a)/sizeof(*a))
typedef enum ALGOS_enum {
eRCVN = 0,
eWDQS,
eWDQx,
eRDQS,
eVREF,
eWCMD,
eWCTL,
eWCLK,
eMAX_ALGOS,
} ALGOs_t;
// Prototypes:
void set_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
void set_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
void set_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
void set_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
void set_wcmd(uint8_t channel, uint32_t pi_count);
void set_wclk(uint8_t channel, uint8_t grp, uint32_t pi_count);
void set_wctl(uint8_t channel, uint8_t rank, uint32_t pi_count);
void set_vref(uint8_t channel, uint8_t byte_lane, uint32_t setting);
uint32_t get_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane);
uint32_t get_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane);
uint32_t get_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane);
uint32_t get_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane);
uint32_t get_wcmd(uint8_t channel);
uint32_t get_wclk(uint8_t channel, uint8_t group);
uint32_t get_wctl(uint8_t channel, uint8_t rank);
uint32_t get_vref(uint8_t channel, uint8_t byte_lane);
void clear_pointers(void);
void enable_cache(void);
void disable_cache(void);
void find_rising_edge(MRCParams_t *mrc_params, uint32_t delay[], uint8_t channel, uint8_t rank, bool rcvn);
uint32_t sample_dqs(MRCParams_t *mrc_params, uint8_t channel, uint8_t rank, bool rcvn);
uint32_t get_addr(MRCParams_t *mrc_params, uint8_t channel, uint8_t rank);
uint32_t byte_lane_mask(MRCParams_t *mrc_params);
uint64_t read_tsc(void);
uint32_t get_tsc_freq(void);
void delay_n(uint32_t nanoseconds);
void delay_u(uint32_t microseconds);
void delay_m(uint32_t milliseconds);
void delay_s(uint32_t seconds);
void post_code(uint8_t major, uint8_t minor);
void training_message(uint8_t channel, uint8_t rank, uint8_t byte_lane);
void print_timings(MRCParams_t *mrc_params);
void enable_scrambling(MRCParams_t *mrc_params);
void store_timings(MRCParams_t *mrc_params);
void restore_timings(MRCParams_t *mrc_params);
void default_timings(MRCParams_t *mrc_params);
#ifndef SIM
void *memset(void *d, int c, size_t n);
void *memcpy(void *d, const void *s, size_t n);
#endif
#endif // _MEMINIT_UTILS_H_

View File

@@ -0,0 +1,83 @@
/** @file
Common definitions and compilation switches for MRC
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __MEMORY_OPTIONS_H
#define __MEMORY_OPTIONS_H
#include "core_types.h"
// MRC COMPILE TIME SWITCHES:
// ==========================
//#define MRC_SV // enable some validation opitons
#if defined (SIM) || defined(EMU)
#define QUICKSIM // reduce execution time using shorter rd/wr sequences
#endif
#define CLT // required for Quark project
//#define BACKUP_RCVN // enable STATIC timing settings for RCVN (BACKUP_MODE)
//#define BACKUP_WDQS // enable STATIC timing settings for WDQS (BACKUP_MODE)
//#define BACKUP_RDQS // enable STATIC timing settings for RDQS (BACKUP_MODE)
//#define BACKUP_WDQ // enable STATIC timing settings for WDQ (BACKUP_MODE)
//#define BACKUP_COMPS // enable *COMP overrides (BACKUP_MODE)
//#define RX_EYE_CHECK // enable the RD_TRAIN eye check
#define HMC_TEST // enable Host to Memory Clock Alignment
#define R2R_SHARING // enable multi-rank support via rank2rank sharing
#define FORCE_16BIT_DDRIO // disable signals not used in 16bit mode of DDRIO
//
// Debug support
//
#ifdef NDEBUG
#define DPF if(0) dpf
#else
#define DPF dpf
#endif
void dpf( uint32_t mask, char_t *bla, ...);
uint8_t mgetc(void);
uint8_t mgetch(void);
// Debug print type
#define D_ERROR 0x0001
#define D_INFO 0x0002
#define D_REGRD 0x0004
#define D_REGWR 0x0008
#define D_FCALL 0x0010
#define D_TRN 0x0020
#define D_TIME 0x0040
#define ENTERFN() DPF(D_FCALL, "<%s>\n", __FUNCTION__)
#define LEAVEFN() DPF(D_FCALL, "</%s>\n", __FUNCTION__)
#define REPORTFN() DPF(D_FCALL, "<%s/>\n", __FUNCTION__)
extern uint32_t DpfPrintMask;
#endif

View File

@@ -0,0 +1,46 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#include "mrc.h"
#include "memory_options.h"
#include "meminit.h"
#include "meminit_utils.h"
#include "prememinit.h"
#include "io.h"
// Base address for UART registers
extern uint32_t UartMmioBase;
//
// Memory Reference Code entry point when executing from BIOS
//
void Mrc( MRCParams_t *mrc_params)
{
// configure uart base address assuming code relocated to eSRAM
UartMmioBase = mrc_params->uart_mmio_base;
ENTERFN();
DPF(D_INFO, "MRC Version %04X %s %s\n", MRC_VERSION, __DATE__, __TIME__);
// this will set up the data structures used by MemInit()
PreMemInit(mrc_params);
// this will initialize system memory
MemInit(mrc_params);
LEAVEFN();
return;
}

View File

@@ -0,0 +1,166 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#ifndef _MRC_H_
#define _MRC_H_
#include "core_types.h"
// define the MRC Version
#define MRC_VERSION 0x0112
// architectural definitions
#define NUM_CHANNELS 1 // number of channels
#define NUM_RANKS 2 // number of ranks per channel
#define NUM_BYTE_LANES 4 // number of byte lanes per channel
// software limitations
#define MAX_CHANNELS 1
#define MAX_RANKS 2
#define MAX_BYTE_LANES 4
// only to mock MrcWrapper
#define MAX_SOCKETS 1
#define MAX_SIDES 1
#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS)
// end
// Specify DRAM of nenory channel width
enum {
x8, // DRAM width
x16, // DRAM width & Channel Width
x32 // Channel Width
};
// Specify DRAM speed
enum {
DDRFREQ_800,
DDRFREQ_1066
};
// Specify DRAM type
enum {
DDR3,
DDR3L
};
// Delay configuration for individual signals
// Vref setting
// Scrambler seed
typedef struct MrcTimings_s
{
uint32_t rcvn[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
uint32_t rdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
uint32_t wdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
uint32_t wdq [NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
uint32_t vref[NUM_CHANNELS][NUM_BYTE_LANES];
uint32_t wctl[NUM_CHANNELS][NUM_RANKS];
uint32_t wcmd[NUM_CHANNELS];
uint32_t scrambler_seed;
uint8_t ddr_speed; // need to save for the case of frequency change
} MrcTimings_t;
// DENSITY: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
// tCL is DRAM CAS Latency in clocks.
// All other timings are in picoseconds.
// Refer to JEDEC spec (or DRAM datasheet) when changing these values.
typedef struct DRAMParams_s {
uint8_t DENSITY;
uint8_t tCL; // CAS latency in clocks
uint32_t tRAS; // ACT to PRE command period
uint32_t tWTR; // Delay from start of internal write transaction to internal read command
uint32_t tRRD; // ACT to ACT command period (JESD79 specific to page size 1K/2K)
uint32_t tFAW; // Four activate window (JESD79 specific to page size 1K/2K)
} DRAMParams_t;
// Boot mode defined as bit mask (1<<n)
#define bmCold 1 // full training
#define bmFast 2 // restore timing parameters
#define bmS3 4 // resume from S3
#define bmWarm 8
#define bmUnknown 0
// MRC execution status
#define MRC_SUCCESS 0 // initialization ok
#define MRC_E_MEMTEST 1 // memtest failed
//
// Input/output/context parameters for Memory Reference Code
//
typedef struct MRCParams_s
{
//
// Global settings
//
uint32_t boot_mode; // bmCold, bmFast, bmWarm, bmS3
uint32_t uart_mmio_base; // pcie serial port base address (force 0 to disable debug)
uint8_t dram_width; // x8, x16
uint8_t ddr_speed; // DDRFREQ_800, DDRFREQ_1066
uint8_t ddr_type; // DDR3, DDR3L
uint8_t ecc_enables; // 0, 1 (memory size reduced to 7/8)
uint8_t scrambling_enables; // 0, 1
uint32_t rank_enables; // 1, 3 (1'st rank has to be populated if 2'nd rank present)
uint32_t channel_enables; // 1 only
uint32_t channel_width; // x16 only
uint32_t address_mode; // 0, 1, 2 (mode 2 forced if ecc enabled)
// memConfig_t begin
uint8_t refresh_rate; // REFRESH_RATE : 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED
uint8_t sr_temp_range; // SR_TEMP_RANGE : 0=normal, 1=extended, others=RESERVED
uint8_t ron_value; // RON_VALUE : 0=34ohm, 1=40ohm, others=RESERVED (select MRS1.DIC driver impedance control)
uint8_t rtt_nom_value; // RTT_NOM_VALUE : 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED
uint8_t rd_odt_value; // RD_ODT_VALUE : 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED
// memConfig_t end
DRAMParams_t params;
//
// Internally used
//
uint32_t board_id; // internally used for board layout (use x8 or x16 memory)
uint32_t hte_setup : 1; // when set hte reconfiguration requested
uint32_t menu_after_mrc : 1;
uint32_t power_down_disable :1;
uint32_t tune_rcvn :1;
uint32_t channel_size[NUM_CHANNELS];
uint32_t column_bits[NUM_CHANNELS];
uint32_t row_bits[NUM_CHANNELS];
uint32_t mrs1; // register content saved during training
//
// Output
//
uint32_t status; // initialization result (non zero specifies error code)
uint32_t mem_size; // total memory size in bytes (excludes ECC banks)
MrcTimings_t timings; // training results (also used on input)
} MRCParams_t;
// Alternative type name for consistent naming convention
#define MRC_PARAMS MRCParams_t
#endif // _MRC_H_

View File

@@ -0,0 +1,192 @@
/** @file
The interface layer for memory controller access.
It is supporting both real hardware platform and simulation environment.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "mrc.h"
#include "memory_options.h"
#include "meminit_utils.h"
#include "io.h"
#ifdef SIM
void SimMmio32Write (
uint32_t be,
uint32_t address,
uint32_t data );
void SimMmio32Read (
uint32_t be,
uint32_t address,
uint32_t *data );
void SimDelayClk (
uint32_t x2clk );
// This is a simple delay function.
// It takes "nanoseconds" as a parameter.
void delay_n(uint32_t nanoseconds)
{
SimDelayClk( 800*nanoseconds/1000);
}
#endif
/****
*
***/
uint32_t Rd32(
uint32_t unit,
uint32_t addr)
{
uint32_t data;
switch (unit)
{
case MEM:
case MMIO:
#ifdef SIM
SimMmio32Read( 1, addr, &data);
#else
data = *PTR32(addr);
#endif
break;
case MCU:
case HOST_BRIDGE:
case MEMORY_MANAGER:
case HTE:
// Handle case addr bigger than 8bit
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
addr &= 0x00FF;
pciwrite32(0, 0, 0, SB_PACKET_REG,
SB_COMMAND(SB_REG_READ_OPCODE, unit, addr));
data = pciread32(0, 0, 0, SB_DATA_REG);
break;
case DDRPHY:
// Handle case addr bigger than 8bit
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
addr &= 0x00FF;
pciwrite32(0, 0, 0, SB_PACKET_REG,
SB_COMMAND(SB_DDRIO_REG_READ_OPCODE, unit, addr));
data = pciread32(0, 0, 0, SB_DATA_REG);
break;
default:
DEAD_LOOP()
;
}
if (unit < MEM)
DPF(D_REGRD, "RD32 %03X %08X %08X\n", unit, addr, data);
return data;
}
/****
*
***/
void Wr32(
uint32_t unit,
uint32_t addr,
uint32_t data)
{
if (unit < MEM)
DPF(D_REGWR, "WR32 %03X %08X %08X\n", unit, addr, data);
switch (unit)
{
case MEM:
case MMIO:
#ifdef SIM
SimMmio32Write( 1, addr, data);
#else
*PTR32(addr) = data;
#endif
break;
case MCU:
case HOST_BRIDGE:
case MEMORY_MANAGER:
case HTE:
// Handle case addr bigger than 8bit
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
addr &= 0x00FF;
pciwrite32(0, 0, 0, SB_DATA_REG, data);
pciwrite32(0, 0, 0, SB_PACKET_REG,
SB_COMMAND(SB_REG_WRITE_OPCODE, unit, addr));
break;
case DDRPHY:
// Handle case addr bigger than 8bit
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
addr &= 0x00FF;
pciwrite32(0, 0, 0, SB_DATA_REG, data);
pciwrite32(0, 0, 0, SB_PACKET_REG,
SB_COMMAND(SB_DDRIO_REG_WRITE_OPCODE, unit, addr));
break;
case DCMD:
pciwrite32(0, 0, 0, SB_HADR_REG, 0);
pciwrite32(0, 0, 0, SB_DATA_REG, data);
pciwrite32(0, 0, 0, SB_PACKET_REG,
SB_COMMAND(SB_DRAM_CMND_OPCODE, MCU, 0));
break;
default:
DEAD_LOOP()
;
}
}
/****
*
***/
void WrMask32(
uint32_t unit,
uint32_t addr,
uint32_t data,
uint32_t mask)
{
Wr32(unit, addr, ((Rd32(unit, addr) & ~mask) | (data & mask)));
}
/****
*
***/
void pciwrite32(
uint32_t bus,
uint32_t dev,
uint32_t fn,
uint32_t reg,
uint32_t data)
{
Wr32(MMIO, PCIADDR(bus,dev,fn,reg), data);
}
/****
*
***/
uint32_t pciread32(
uint32_t bus,
uint32_t dev,
uint32_t fn,
uint32_t reg)
{
return Rd32(MMIO, PCIADDR(bus,dev,fn,reg));
}

View File

@@ -0,0 +1,193 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#include "mrc.h"
#include "memory_options.h"
#include "meminit_utils.h"
#include "prememinit.h"
#include "io.h"
// Read character from serial console
uint8_t mgetc(void);
extern uint32_t DpfPrintMask;
// Adjust configuration parameters before initialisation
// sequence.
void PreMemInit(
MRCParams_t *mrc_params)
{
const DRAMParams_t *dram_params;
uint8_t dram_width;
uint32_t dram_cfg_index;
uint32_t channel_i;
ENTERFN();
#ifdef MRC_SV
{
uint8_t ch;
myloop:
DPF(D_INFO, "- c - continue\n");
DPF(D_INFO, "- f - boot mode [%d]\n", mrc_params->boot_mode);
DPF(D_INFO, "- r - rank enable [%d]\n", mrc_params->rank_enables);
DPF(D_INFO, "- e - ecc switch [%d]\n", mrc_params->ecc_enables);
DPF(D_INFO, "- b - scrambling switch [%d]\n", mrc_params->scrambling_enables);
DPF(D_INFO, "- a - adr mode [%d]\n", mrc_params->address_mode);
DPF(D_INFO, "- m - menu after mrc [%d]\n", mrc_params->menu_after_mrc);
DPF(D_INFO, "- t - tune to rcvn [%d]\n", mrc_params->tune_rcvn);
DPF(D_INFO, "- o - odt switch [%d]\n", mrc_params->rd_odt_value);
DPF(D_INFO, "- d - dram density [%d]\n", mrc_params->params.DENSITY);
DPF(D_INFO, "- p - power down disable [%d]\n", mrc_params->power_down_disable);
DPF(D_INFO, "- l - log switch 0x%x\n", DpfPrintMask);
ch = mgetc();
switch (ch)
{
case 'f':
mrc_params->boot_mode >>= 1;
if(mrc_params->boot_mode == bmUnknown)
{
mrc_params->boot_mode = bmWarm;
}
DPF(D_INFO, "Boot mode %d\n", mrc_params->boot_mode);
break;
case 'p':
mrc_params->power_down_disable ^= 1;
DPF(D_INFO, "Power down disable %d\n", mrc_params->power_down_disable);
break;
case 'r':
mrc_params->rank_enables ^= 2;
DPF(D_INFO, "Rank enable %d\n", mrc_params->rank_enables);
break;
case 'e':
mrc_params->ecc_enables ^= 1;
DPF(D_INFO, "Ecc enable %d\n", mrc_params->ecc_enables);
break;
case 'b':
mrc_params->scrambling_enables ^= 1;
DPF(D_INFO, "Scrambler enable %d\n", mrc_params->scrambling_enables);
break;
case 'a':
mrc_params->address_mode = (mrc_params->address_mode + 1) % 3;
DPF(D_INFO, "Adr mode %d\n", mrc_params->address_mode);
break;
case 'm':
mrc_params->menu_after_mrc ^= 1;
DPF(D_INFO, "Menu after mrc %d\n", mrc_params->menu_after_mrc);
break;
case 't':
mrc_params->tune_rcvn ^= 1;
DPF(D_INFO, "Tune to rcvn %d\n", mrc_params->tune_rcvn);
break;
case 'o':
mrc_params->rd_odt_value = (mrc_params->rd_odt_value + 1) % 4;
DPF(D_INFO, "Rd_odt_value %d\n", mrc_params->rd_odt_value);
break;
case 'd':
mrc_params->params.DENSITY = (mrc_params->params.DENSITY + 1) % 4;
DPF(D_INFO, "Dram density %d\n", mrc_params->params.DENSITY);
break;
case 'l':
DpfPrintMask ^= 0x30;
DPF(D_INFO, "Log mask %x\n", DpfPrintMask);
break;
default:
break;
}
if (ch != 'c')
goto myloop;
}
#endif
// initially expect success
mrc_params->status = MRC_SUCCESS;
// todo!!! Setup board layout (must be reviewed as is selecting static timings)
// 0 == R0 (DDR3 x16), 1 == R1 (DDR3 x16), 2 == DV (DDR3 x8), 3 == SV (DDR3 x8)
if (mrc_params->dram_width == x8)
{
mrc_params->board_id = 2; // select x8 layout
}
else
{
mrc_params->board_id = 0; // select x16 layout
}
// initially no memory
mrc_params->mem_size = 0;
channel_i = 0;
// begin of channel settings
dram_width = mrc_params->dram_width;
dram_params = &mrc_params->params;
dram_cfg_index = 0;
// Determine Column & Row Bits:
// Column:
// 11 for 8Gbx8, else 10
mrc_params->column_bits[channel_i] = ((dram_params[dram_cfg_index].DENSITY == 4) && (dram_width == x8)) ? (11) : (10);
// Row:
// 512Mbx16=12 512Mbx8=13
// 1Gbx16=13 1Gbx8=14
// 2Gbx16=14 2Gbx8=15
// 4Gbx16=15 4Gbx8=16
// 8Gbx16=16 8Gbx8=16
mrc_params->row_bits[channel_i] = 12 + (dram_params[dram_cfg_index].DENSITY)
+ (((dram_params[dram_cfg_index].DENSITY < 4) && (dram_width == x8)) ? (1) : (0));
// Determine Per Channel Memory Size:
// (For 2 RANKs, multiply by 2)
// (For 16 bit data bus, divide by 2)
// DENSITY WIDTH MEM_AVAILABLE
// 512Mb x16 0x008000000 ( 128MB)
// 512Mb x8 0x010000000 ( 256MB)
// 1Gb x16 0x010000000 ( 256MB)
// 1Gb x8 0x020000000 ( 512MB)
// 2Gb x16 0x020000000 ( 512MB)
// 2Gb x8 0x040000000 (1024MB)
// 4Gb x16 0x040000000 (1024MB)
// 4Gb x8 0x080000000 (2048MB)
mrc_params->channel_size[channel_i] = (1 << dram_params[dram_cfg_index].DENSITY);
mrc_params->channel_size[channel_i] *= ((dram_width == x8) ? (2) : (1));
mrc_params->channel_size[channel_i] *= (mrc_params->rank_enables == 0x3) ? (2) : (1);
mrc_params->channel_size[channel_i] *= (mrc_params->channel_width == x16) ? (1) : (2);
// Determine memory size (convert number of 64MB/512Mb units)
mrc_params->mem_size += mrc_params->channel_size[channel_i] << 26;
// end of channel settings
LEAVEFN();
return;
}

View File

@@ -0,0 +1,21 @@
/************************************************************************
*
* Copyright (c) 2013-2015 Intel Corporation.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
************************************************************************/
#ifndef __PREMEMINIT_H_
#define __PREMEMINIT_H_
// Function prototypes
void PreMemInit(MRCParams_t *mrc_params);
#endif // _PREMEMINIT_H_