soc/amd/stoneyridge: Add northbridge support
Copy northbridge files from northbridge/amd/pi/00670F00 to soc/amd/stoneyridge and soc/amd/common. Changes: - update chip_ops and device_ops - remove multi-node support - clean up Kconfig and Makefile Change-Id: Ie86b4d744900f23502068517ece5bcea6c128993 Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/19724 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
21cde8b832
commit
1587dc8a2b
|
@ -16,7 +16,6 @@
|
|||
config NORTHBRIDGE_AMD_PI
|
||||
bool
|
||||
default y if CPU_AMD_PI
|
||||
default y if SOC_AMD_PI
|
||||
default n
|
||||
select LATE_CBMEM_INIT
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011,2012 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2013 Sage Electronic Engineering, LLC
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CALLOUTS_AMD_AGESA_H
|
||||
#define CALLOUTS_AMD_AGESA_H
|
||||
|
||||
#include <Porting.h>
|
||||
#include <AGESA.h>
|
||||
|
||||
#define BIOS_HEAP_START_ADDRESS 0x010000000
|
||||
#define BIOS_HEAP_SIZE 0x30000
|
||||
#define BSP_STACK_BASE_ADDR 0x30000
|
||||
|
||||
typedef struct _BIOS_HEAP_MANAGER {
|
||||
UINT32 StartOfAllocatedNodes;
|
||||
UINT32 StartOfFreedNodes;
|
||||
} BIOS_HEAP_MANAGER;
|
||||
|
||||
typedef struct _BIOS_BUFFER_NODE {
|
||||
UINT32 BufferHandle;
|
||||
UINT32 BufferSize;
|
||||
UINT32 NextNodeOffset;
|
||||
} BIOS_BUFFER_NODE;
|
||||
|
||||
UINT32 GetHeapBase(AMD_CONFIG_PARAMS *StdHeader);
|
||||
void EmptyHeap(void);
|
||||
|
||||
AGESA_STATUS agesa_AllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_DeallocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_LocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
|
||||
AGESA_STATUS agesa_NoopUnsupported (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_NoopSuccess (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_EmptyIdsInitData (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_Reset (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_RunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt);
|
||||
|
||||
AGESA_STATUS agesa_ReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
AGESA_STATUS agesa_ReadSpd_from_cbfs(UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
|
||||
AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
|
||||
|
||||
typedef struct {
|
||||
UINT32 CalloutName;
|
||||
CALLOUT_ENTRY CalloutPtr;
|
||||
} BIOS_CALLOUT_STRUCT;
|
||||
|
||||
extern const BIOS_CALLOUT_STRUCT BiosCallouts[];
|
||||
extern const int BiosCalloutsLen;
|
||||
|
||||
#endif /* CALLOUTS_AMD_AGESA_H */
|
|
@ -2,10 +2,14 @@ ifeq ($(CONFIG_SOC_AMD_COMMON),y)
|
|||
|
||||
cpu_incs-y += $(src)/soc/amd/common/cache_as_ram.inc
|
||||
|
||||
romstage-y += agesawrapper.c
|
||||
romstage-y += def_callouts.c
|
||||
romstage-y += heapmanager.c
|
||||
|
||||
ramstage-y += agesawrapper.c
|
||||
ramstage-y += amd_late_init.c
|
||||
ramstage-y += amd_pci_util.c
|
||||
ramstage-y += def_callouts.c
|
||||
ramstage-y += heapmanager.c
|
||||
ramstage-$(CONFIG_SPI_FLASH) += spi.c
|
||||
|
||||
|
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 - 2014 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <AGESA.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <delay.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpuRegisters.h>
|
||||
#include <FchPlatform.h>
|
||||
#include <heapManager.h>
|
||||
#include <agesawrapper.h>
|
||||
#include <BiosCallOuts.h>
|
||||
|
||||
void __attribute__((weak)) OemPostParams(AMD_POST_PARAMS *PostParams) {}
|
||||
|
||||
#define FILECODE UNASSIGNED_FILE_FILECODE
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
/* ACPI table pointers returned by AmdInitLate */
|
||||
static void *DmiTable = NULL;
|
||||
static void *AcpiPstate = NULL;
|
||||
static void *AcpiSrat = NULL;
|
||||
static void *AcpiSlit = NULL;
|
||||
|
||||
static void *AcpiWheaMce = NULL;
|
||||
static void *AcpiWheaCmc = NULL;
|
||||
static void *AcpiAlib = NULL;
|
||||
static void *AcpiIvrs = NULL;
|
||||
static void *AcpiCrat = NULL;
|
||||
#endif /* #ifndef __PRE_RAM__ */
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitreset(void)
|
||||
{
|
||||
AGESA_STATUS status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_RESET_PARAMS AmdResetParams;
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
LibAmdMemFill (&AmdResetParams,
|
||||
0,
|
||||
sizeof(AMD_RESET_PARAMS),
|
||||
&(AmdResetParams.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
|
||||
AmdParamStruct.AllocationMethod = ByHost;
|
||||
AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
|
||||
AmdParamStruct.NewStructPtr = &AmdResetParams;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = 0;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
AmdCreateStruct (&AmdParamStruct);
|
||||
|
||||
AmdResetParams.FchInterface.Xhci0Enable = IS_ENABLED(CONFIG_STONEYRIDGE_XHCI_ENABLE);
|
||||
|
||||
AmdResetParams.FchInterface.SataEnable = !((CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3));
|
||||
AmdResetParams.FchInterface.IdeEnable = (CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3);
|
||||
|
||||
status = AmdInitReset(&AmdResetParams);
|
||||
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(AmdParamStruct.StdHeader.HeapStatus);
|
||||
AmdReleaseStruct (&AmdParamStruct);
|
||||
return status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitearly(void)
|
||||
{
|
||||
AGESA_STATUS status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_EARLY_PARAMS *AmdEarlyParamsPtr;
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
|
||||
AmdParamStruct.AllocationMethod = PreMemHeap;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = 0;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
AmdCreateStruct (&AmdParamStruct);
|
||||
|
||||
AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
|
||||
OemCustomizeInitEarly (AmdEarlyParamsPtr);
|
||||
|
||||
AmdEarlyParamsPtr->GnbConfig.PsppPolicy = PsppDisabled;
|
||||
status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
|
||||
|
||||
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(AmdParamStruct.StdHeader.HeapStatus);
|
||||
AmdReleaseStruct (&AmdParamStruct);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitpost(void)
|
||||
{
|
||||
AGESA_STATUS status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_POST_PARAMS *PostParams;
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
|
||||
AmdParamStruct.AllocationMethod = PreMemHeap;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = NULL;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
|
||||
AmdCreateStruct (&AmdParamStruct);
|
||||
PostParams = (AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr;
|
||||
|
||||
// Do not use IS_ENABLED here. CONFIG_GFXUMA should always have a value. Allow
|
||||
// the compiler to flag the error if CONFIG_GFXUMA is not set.
|
||||
PostParams->MemConfig.UmaMode = CONFIG_GFXUMA ? UMA_AUTO : UMA_NONE;
|
||||
PostParams->MemConfig.UmaSize = 0;
|
||||
PostParams->MemConfig.BottomIo = (UINT16)
|
||||
(CONFIG_BOTTOMIO_POSITION >> 24);
|
||||
|
||||
OemPostParams(PostParams);
|
||||
|
||||
status = AmdInitPost (PostParams);
|
||||
|
||||
/* If UMA is enabled we currently have it below TOP_MEM as well.
|
||||
* UMA may or may not be cacheable, so Sub4GCacheTop could be
|
||||
* higher than UmaBase. With UMA_NONE we see UmaBase==0. */
|
||||
if (PostParams->MemConfig.UmaBase)
|
||||
backup_top_of_low_cacheable(PostParams->MemConfig.UmaBase << 16);
|
||||
else
|
||||
backup_top_of_low_cacheable(PostParams->MemConfig.Sub4GCacheTop);
|
||||
|
||||
|
||||
printk(
|
||||
BIOS_SPEW,
|
||||
"setup_uma_memory: umamode %s\n",
|
||||
(PostParams->MemConfig.UmaMode == UMA_AUTO) ? "UMA_AUTO" :
|
||||
(PostParams->MemConfig.UmaMode == UMA_SPECIFIED) ? "UMA_SPECIFIED" :
|
||||
(PostParams->MemConfig.UmaMode == UMA_NONE) ? "UMA_NONE" :
|
||||
"unknown"
|
||||
);
|
||||
printk(
|
||||
BIOS_SPEW,
|
||||
"setup_uma_memory: syslimit 0x%08llX, bottomio 0x%08lx\n",
|
||||
(unsigned long long)(PostParams->MemConfig.SysLimit) << 16,
|
||||
(unsigned long)(PostParams->MemConfig.BottomIo) << 16
|
||||
);
|
||||
printk(
|
||||
BIOS_SPEW,
|
||||
"setup_uma_memory: uma size %luMB, uma start 0x%08lx\n",
|
||||
(unsigned long)(PostParams->MemConfig.UmaSize) >> (20 - 16),
|
||||
(unsigned long)(PostParams->MemConfig.UmaBase) << 16
|
||||
);
|
||||
|
||||
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(PostParams->StdHeader.HeapStatus);
|
||||
AmdReleaseStruct (&AmdParamStruct);
|
||||
/* Initialize heap space */
|
||||
EmptyHeap();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitenv(void)
|
||||
{
|
||||
AGESA_STATUS status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_ENV_PARAMS *EnvParam;
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
|
||||
AmdParamStruct.AllocationMethod = PostMemDram;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = 0;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
status = AmdCreateStruct (&AmdParamStruct);
|
||||
EnvParam = (AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr;
|
||||
|
||||
EnvParam->FchInterface.AzaliaController = AzEnable;
|
||||
EnvParam->FchInterface.SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
|
||||
EnvParam->FchInterface.SataEnable = !((CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3));
|
||||
EnvParam->FchInterface.IdeEnable = (CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3);
|
||||
EnvParam->FchInterface.SataIdeMode = (CONFIG_STONEYRIDGE_SATA_MODE == 3);
|
||||
EnvParam->GnbEnvConfiguration.IommuSupport = FALSE;
|
||||
|
||||
status = AmdInitEnv (EnvParam);
|
||||
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(EnvParam->StdHeader.HeapStatus);
|
||||
/* Initialize Subordinate Bus Number and Secondary Bus Number
|
||||
* In platform BIOS this address is allocated by PCI enumeration code
|
||||
Modify D1F0x18
|
||||
*/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
VOID* agesawrapper_getlateinitptr (int pick)
|
||||
{
|
||||
switch (pick) {
|
||||
case PICK_DMI:
|
||||
return DmiTable;
|
||||
case PICK_PSTATE:
|
||||
return AcpiPstate;
|
||||
case PICK_SRAT:
|
||||
return AcpiSrat;
|
||||
case PICK_SLIT:
|
||||
return AcpiSlit;
|
||||
case PICK_WHEA_MCE:
|
||||
return AcpiWheaMce;
|
||||
case PICK_WHEA_CMC:
|
||||
return AcpiWheaCmc;
|
||||
case PICK_ALIB:
|
||||
return AcpiAlib;
|
||||
case PICK_IVRS:
|
||||
return AcpiIvrs;
|
||||
case PICK_CRAT:
|
||||
return AcpiCrat;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* #ifndef __PRE_RAM__ */
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitmid(void)
|
||||
{
|
||||
AGESA_STATUS status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_MID_PARAMS *MidParam;
|
||||
|
||||
/* Enable MMIO on AMD CPU Address Map Controller */
|
||||
amd_initcpuio ();
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
|
||||
AmdParamStruct.AllocationMethod = PostMemDram;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = 0;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
|
||||
AmdCreateStruct (&AmdParamStruct);
|
||||
MidParam = (AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr;
|
||||
|
||||
MidParam->GnbMidConfiguration.iGpuVgaMode = 0;/* 0 iGpuVgaAdapter, 1 iGpuVgaNonAdapter; */
|
||||
MidParam->GnbMidConfiguration.GnbIoapicAddress = 0xFEC20000;
|
||||
|
||||
MidParam->FchInterface.AzaliaController = AzEnable;
|
||||
MidParam->FchInterface.SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
|
||||
MidParam->FchInterface.SataEnable = !((CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3));
|
||||
MidParam->FchInterface.IdeEnable = (CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3);
|
||||
MidParam->FchInterface.SataIdeMode = (CONFIG_STONEYRIDGE_SATA_MODE == 3);
|
||||
|
||||
status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
|
||||
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog(AmdParamStruct.StdHeader.HeapStatus);
|
||||
AmdReleaseStruct (&AmdParamStruct);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
AGESA_STATUS agesawrapper_amdinitlate(void)
|
||||
{
|
||||
AGESA_STATUS Status;
|
||||
AMD_INTERFACE_PARAMS AmdParamStruct;
|
||||
AMD_LATE_PARAMS *AmdLateParams;
|
||||
|
||||
LibAmdMemFill (&AmdParamStruct,
|
||||
0,
|
||||
sizeof(AMD_INTERFACE_PARAMS),
|
||||
&(AmdParamStruct.StdHeader));
|
||||
|
||||
AmdParamStruct.AgesaFunctionName = AMD_INIT_LATE;
|
||||
AmdParamStruct.AllocationMethod = PostMemDram;
|
||||
AmdParamStruct.StdHeader.AltImageBasePtr = 0;
|
||||
AmdParamStruct.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdParamStruct.StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
|
||||
AmdParamStruct.StdHeader.Func = 0;
|
||||
AmdParamStruct.StdHeader.ImageBasePtr = 0;
|
||||
|
||||
/* NOTE: if not call amdcreatestruct, the initializer(AmdInitLateInitializer) would not be called */
|
||||
AmdCreateStruct(&AmdParamStruct);
|
||||
AmdLateParams = (AMD_LATE_PARAMS *)AmdParamStruct.NewStructPtr;
|
||||
Status = AmdInitLate(AmdLateParams);
|
||||
if (Status != AGESA_SUCCESS) {
|
||||
agesawrapper_amdreadeventlog(AmdLateParams->StdHeader.HeapStatus);
|
||||
ASSERT(Status == AGESA_SUCCESS);
|
||||
}
|
||||
|
||||
DmiTable = AmdLateParams->DmiTable;
|
||||
AcpiPstate = AmdLateParams->AcpiPState;
|
||||
|
||||
AcpiWheaMce = AmdLateParams->AcpiWheaMce;
|
||||
AcpiWheaCmc = AmdLateParams->AcpiWheaCmc;
|
||||
AcpiAlib = AmdLateParams->AcpiAlib;
|
||||
AcpiIvrs = AmdLateParams->AcpiIvrs;
|
||||
AcpiCrat = AmdLateParams->AcpiCrat;
|
||||
|
||||
printk(BIOS_DEBUG, "DmiTable:%x, AcpiPstatein: %x, AcpiSrat:%x,"
|
||||
"AcpiSlit:%x, Mce:%x, Cmc:%x,"
|
||||
"Alib:%x, AcpiIvrs:%x in %s\n",
|
||||
(unsigned int)DmiTable, (unsigned int)AcpiPstate, (unsigned int)AcpiSrat,
|
||||
(unsigned int)AcpiSlit, (unsigned int)AcpiWheaMce, (unsigned int)AcpiWheaCmc,
|
||||
(unsigned int)AcpiAlib, (unsigned int)AcpiIvrs, __func__);
|
||||
|
||||
/* AmdReleaseStruct (&AmdParamStruct); */
|
||||
return Status;
|
||||
}
|
||||
#endif /* #ifndef __PRE_RAM__ */
|
||||
|
||||
AGESA_STATUS agesawrapper_amdlaterunaptask (
|
||||
UINT32 Func,
|
||||
UINT32 Data,
|
||||
VOID *ConfigPtr
|
||||
)
|
||||
{
|
||||
AGESA_STATUS Status;
|
||||
AP_EXE_PARAMS ApExeParams;
|
||||
|
||||
LibAmdMemFill (&ApExeParams,
|
||||
0,
|
||||
sizeof(AP_EXE_PARAMS),
|
||||
&(ApExeParams.StdHeader));
|
||||
|
||||
ApExeParams.StdHeader.AltImageBasePtr = 0;
|
||||
ApExeParams.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
ApExeParams.StdHeader.Func = 0;
|
||||
ApExeParams.StdHeader.ImageBasePtr = 0;
|
||||
ApExeParams.FunctionNumber = Func;
|
||||
ApExeParams.RelatedDataBlock = ConfigPtr;
|
||||
|
||||
Status = AmdLateRunApTask (&ApExeParams);
|
||||
if (Status != AGESA_SUCCESS) {
|
||||
/* agesawrapper_amdreadeventlog(); */
|
||||
ASSERT(Status == AGESA_SUCCESS);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesawrapper_amdreadeventlog (UINT8 HeapStatus)
|
||||
{
|
||||
AGESA_STATUS Status;
|
||||
EVENT_PARAMS AmdEventParams;
|
||||
|
||||
LibAmdMemFill (&AmdEventParams,
|
||||
0,
|
||||
sizeof(EVENT_PARAMS),
|
||||
&(AmdEventParams.StdHeader));
|
||||
|
||||
AmdEventParams.StdHeader.AltImageBasePtr = 0;
|
||||
AmdEventParams.StdHeader.CalloutPtr = &GetBiosCallout;
|
||||
AmdEventParams.StdHeader.Func = 0;
|
||||
AmdEventParams.StdHeader.ImageBasePtr = 0;
|
||||
AmdEventParams.StdHeader.HeapStatus = HeapStatus;
|
||||
Status = AmdReadEventLog (&AmdEventParams);
|
||||
while (AmdEventParams.EventClass != 0) {
|
||||
printk(BIOS_DEBUG,"\nEventLog: EventClass = %x, EventInfo = %x.\n", (unsigned int)AmdEventParams.EventClass,(unsigned int)AmdEventParams.EventInfo);
|
||||
printk(BIOS_DEBUG," Param1 = %x, Param2 = %x.\n",(unsigned int)AmdEventParams.DataParam1, (unsigned int)AmdEventParams.DataParam2);
|
||||
printk(BIOS_DEBUG," Param3 = %x, Param4 = %x.\n",(unsigned int)AmdEventParams.DataParam3, (unsigned int)AmdEventParams.DataParam4);
|
||||
Status = AmdReadEventLog (&AmdEventParams);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
const void *agesawrapper_locate_module (const CHAR8 name[8])
|
||||
{
|
||||
const void* agesa;
|
||||
const AMD_IMAGE_HEADER* image;
|
||||
const AMD_MODULE_HEADER* module;
|
||||
size_t file_size;
|
||||
|
||||
if (IS_ENABLED(CONFIG_VBOOT)) {
|
||||
/* Use phys. location in flash and prevent vboot from searching cbmem */
|
||||
agesa = (void *)CONFIG_AGESA_BINARY_PI_LOCATION;
|
||||
file_size = 0x100000;
|
||||
} else {
|
||||
agesa = cbfs_boot_map_with_leak((const char *)CONFIG_CBFS_AGESA_NAME,
|
||||
CBFS_TYPE_RAW, &file_size);
|
||||
}
|
||||
|
||||
if (!agesa)
|
||||
return NULL;
|
||||
image = LibAmdLocateImage(agesa, agesa + file_size - 1, 4096, name);
|
||||
module = (AMD_MODULE_HEADER*)image->ModuleInfoOffset;
|
||||
|
||||
return module;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _AGESAWRAPPER_H_
|
||||
#define _AGESAWRAPPER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Porting.h>
|
||||
#include <AGESA.h>
|
||||
|
||||
/* TODO: Add a kconfig option to name the AGESA ROM file in CBFS */
|
||||
#ifndef CONFIG_CBFS_AGESA_NAME
|
||||
#define CONFIG_CBFS_AGESA_NAME "AGESA"
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PICK_DMI, /* DMI Interface */
|
||||
PICK_PSTATE, /* Acpi Pstate SSDT Table */
|
||||
PICK_SRAT, /* SRAT Table */
|
||||
PICK_SLIT, /* SLIT Table */
|
||||
PICK_WHEA_MCE, /* WHEA MCE table */
|
||||
PICK_WHEA_CMC, /* WHEA CMV table */
|
||||
PICK_ALIB, /* SACPI SSDT table with ALIB implementation */
|
||||
PICK_IVRS, /* IOMMU ACPI IVRS(I/O Virtualization Reporting Structure) table */
|
||||
PICK_CRAT,
|
||||
};
|
||||
|
||||
AGESA_STATUS agesawrapper_amdinitreset(void);
|
||||
AGESA_STATUS agesawrapper_amdinitearly(void);
|
||||
AGESA_STATUS agesawrapper_amdinitenv(void);
|
||||
AGESA_STATUS agesawrapper_amdinitlate(void);
|
||||
AGESA_STATUS agesawrapper_amdinitpost(void);
|
||||
AGESA_STATUS agesawrapper_amdinitmid(void);
|
||||
AGESA_STATUS agesawrapper_amdreadeventlog(UINT8 HeapStatus);
|
||||
void *agesawrapper_getlateinitptr(int pick);
|
||||
AGESA_STATUS agesawrapper_amdlaterunaptask(UINT32 Func, UINT32 Data, void *ConfigPtr);
|
||||
AGESA_STATUS agesawrapper_amdS3Save(void);
|
||||
AGESA_STATUS agesawrapper_amdinitresume(void);
|
||||
AGESA_STATUS agesawrapper_amds3laterestore(void);
|
||||
|
||||
AGESA_STATUS agesawrapper_fchs3earlyrestore(void);
|
||||
AGESA_STATUS agesawrapper_fchs3laterestore(void);
|
||||
|
||||
VOID OemCustomizeInitEarly (IN OUT AMD_EARLY_PARAMS *InitEarly);
|
||||
VOID amd_initcpuio(void);
|
||||
VOID amd_initmmio(void);
|
||||
const void *agesawrapper_locate_module (const CHAR8 name[8]);
|
||||
|
||||
void OemPostParams(AMD_POST_PARAMS *PostParams);
|
||||
|
||||
#endif /* _AGESAWRAPPER_H_ */
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _AGESAWRAPPER_CALL_H_
|
||||
#define _AGESAWRAPPER_CALL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <console/console.h>
|
||||
#include <AGESA.h>
|
||||
|
||||
/*
|
||||
* Possible AGESA_STATUS values:
|
||||
*
|
||||
* 0x0 = AGESA_SUCCESS
|
||||
* 0x1 = AGESA_UNSUPPORTED
|
||||
* 0x2 = AGESA_BOUNDS_CHK
|
||||
* 0x3 = AGESA_ALERT
|
||||
* 0x4 = AGESA_WARNING
|
||||
* 0x5 = AGESA_ERROR
|
||||
* 0x6 = AGESA_CRITICAL
|
||||
* 0x7 = AGESA_FATAL
|
||||
*/
|
||||
static const char * decodeAGESA_STATUS(AGESA_STATUS sret)
|
||||
{
|
||||
const char* statusStrings[] = { "AGESA_SUCCESS", "AGESA_UNSUPPORTED",
|
||||
"AGESA_BOUNDS_CHK", "AGESA_ALERT",
|
||||
"AGESA_WARNING", "AGESA_ERROR",
|
||||
"AGESA_CRITICAL", "AGESA_FATAL"
|
||||
};
|
||||
if (sret > 7) return "unknown"; /* Non-AGESA error code */
|
||||
return statusStrings[sret];
|
||||
}
|
||||
|
||||
static inline u32 do_agesawrapper(AGESA_STATUS (*func)(void), const char *name)
|
||||
{
|
||||
AGESA_STATUS ret;
|
||||
printk(BIOS_DEBUG, "agesawrapper_%s() entry\n", name);
|
||||
ret = func();
|
||||
printk(BIOS_DEBUG, "agesawrapper_%s() returned %s\n",
|
||||
name, decodeAGESA_STATUS(ret));
|
||||
return (u32)ret;
|
||||
}
|
||||
|
||||
#define AGESAWRAPPER(func) do_agesawrapper(agesawrapper_ ## func, #func)
|
||||
|
||||
#define AGESAWRAPPER_PRE_CONSOLE(func) agesawrapper_ ## func()
|
||||
|
||||
#endif
|
|
@ -20,8 +20,8 @@
|
|||
#include <device/pci_def.h>
|
||||
#include <device/pci_ops.h>
|
||||
|
||||
#include <northbridge/amd/pi/agesawrapper.h>
|
||||
#include <northbridge/amd/pi/agesawrapper_call.h>
|
||||
#include <agesawrapper.h>
|
||||
#include <agesawrapper_call.h>
|
||||
|
||||
static void agesawrapper_post_device(void *unused)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2013 Sage Electronic Engineering, LLC
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cbfs.h>
|
||||
#include <spd_bin.h>
|
||||
|
||||
#include <AGESA.h>
|
||||
#include <amdlib.h>
|
||||
#include <Ids.h>
|
||||
#include <agesawrapper.h>
|
||||
#include <BiosCallOuts.h>
|
||||
#include <dimmSpd.h>
|
||||
|
||||
AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
UINTN i;
|
||||
|
||||
for (i = 0; i < BiosCalloutsLen; i++) {
|
||||
if (BiosCallouts[i].CalloutName == Func)
|
||||
break;
|
||||
}
|
||||
if (i >= BiosCalloutsLen)
|
||||
return AGESA_UNSUPPORTED;
|
||||
|
||||
return BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_NoopUnsupported (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
return AGESA_UNSUPPORTED;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_NoopSuccess (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
return AGESA_SUCCESS;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_EmptyIdsInitData (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
IDS_NV_ITEM *IdsPtr = ((IDS_CALLOUT_STRUCT *) ConfigPtr)->IdsNvPtr;
|
||||
if (Data == IDS_CALLOUT_INIT)
|
||||
IdsPtr[0].IdsNvValue = IdsPtr[0].IdsNvId = 0xffff;
|
||||
return AGESA_SUCCESS;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_Reset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
AGESA_STATUS Status;
|
||||
UINT8 Value;
|
||||
UINTN ResetType;
|
||||
AMD_CONFIG_PARAMS *StdHeader;
|
||||
|
||||
ResetType = Data;
|
||||
StdHeader = ConfigPtr;
|
||||
|
||||
//
|
||||
// Perform the RESET based upon the ResetType. In case of
|
||||
// WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to
|
||||
// AmdResetManager. During the critical condition, where reset is required
|
||||
// immediately, the reset will be invoked directly by writing 0x04 to port
|
||||
// 0xCF9 (Reset Port).
|
||||
//
|
||||
switch (ResetType) {
|
||||
case WARM_RESET_WHENEVER:
|
||||
case COLD_RESET_WHENEVER:
|
||||
break;
|
||||
|
||||
case WARM_RESET_IMMEDIATELY:
|
||||
case COLD_RESET_IMMEDIATELY:
|
||||
Value = 0x06;
|
||||
LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Status = 0;
|
||||
return Status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_RunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
AGESA_STATUS Status;
|
||||
|
||||
Status = agesawrapper_amdlaterunaptask (Func, Data, ConfigPtr);
|
||||
return Status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt)
|
||||
{
|
||||
GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
|
||||
pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak(
|
||||
"pci"CONFIG_VGA_BIOS_ID".rom",
|
||||
CBFS_TYPE_OPTIONROM, NULL);
|
||||
printk(BIOS_DEBUG, "agesa_GfxGetVbiosImage: IMGptr=%p\n", pVbiosImageInfo->ImagePtr);
|
||||
return (pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING);
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_ReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
AGESA_STATUS Status = AGESA_UNSUPPORTED;
|
||||
#ifdef __PRE_RAM__
|
||||
Status = AmdMemoryReadSPD (Func, Data, ConfigPtr);
|
||||
#endif
|
||||
return Status;
|
||||
}
|
||||
|
||||
AGESA_STATUS agesa_ReadSpd_from_cbfs(UINT32 Func, UINT32 Data, VOID *ConfigPtr)
|
||||
{
|
||||
AGESA_STATUS Status = AGESA_UNSUPPORTED;
|
||||
#ifdef __PRE_RAM__
|
||||
AGESA_READ_SPD_PARAMS *info = ConfigPtr;
|
||||
if (info->MemChannelId > 0)
|
||||
return AGESA_UNSUPPORTED;
|
||||
if (info->SocketId != 0)
|
||||
return AGESA_UNSUPPORTED;
|
||||
if (info->DimmId != 0)
|
||||
return AGESA_UNSUPPORTED;
|
||||
|
||||
/* Read index 0, first SPD_SIZE bytes of spd.bin file. */
|
||||
if (read_ddr3_spd_from_cbfs((u8*)info->Buffer, 0) < 0)
|
||||
die("No SPD data\n");
|
||||
|
||||
Status = AGESA_SUCCESS;
|
||||
#endif
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DIMMSPD_H_
|
||||
#define _DIMMSPD_H_
|
||||
|
||||
AGESA_STATUS
|
||||
AmdMemoryReadSPD (IN UINT32 Func, IN UINT32 Data, IN OUT AGESA_READ_SPD_PARAMS *SpdData);
|
||||
|
||||
int hudson_readSpd(int spdAddress, char *buf, size_t len);
|
||||
int smbus_readSpd(int spdAddress, char *buf, size_t len);
|
||||
|
||||
#endif
|
|
@ -35,10 +35,11 @@ config CPU_SPECIFIC_OPTIONS
|
|||
select HAVE_USBDEBUG_OPTIONS
|
||||
select HAVE_HARD_RESET
|
||||
select LAPIC_MONOTONIC_TIMER
|
||||
select SOC_AMD_COMMON
|
||||
select SOC_AMD_PI
|
||||
select LATE_CBMEM_INIT
|
||||
select SPI_FLASH if HAVE_ACPI_RESUME
|
||||
select TSC_SYNC_LFENCE
|
||||
select SOC_AMD_COMMON
|
||||
select SOC_AMD_PI
|
||||
select UDELAY_LAPIC
|
||||
|
||||
config UDELAY_LAPIC_FIXED_FSB
|
||||
|
@ -69,6 +70,57 @@ config CDB
|
|||
hex
|
||||
default 0x18
|
||||
|
||||
config BOTTOMIO_POSITION
|
||||
hex "Bottom of 32-bit IO space"
|
||||
default 0xD0000000
|
||||
help
|
||||
If PCI peripherals with big BARs are connected to the system
|
||||
the bottom of the IO must be decreased to allocate such
|
||||
devices.
|
||||
|
||||
Declare the beginning of the 128MB-aligned MMIO region. This
|
||||
option is useful when PCI peripherals requesting large address
|
||||
ranges are present.
|
||||
|
||||
config HW_MEM_HOLE_SIZEK
|
||||
hex
|
||||
default 0x200000
|
||||
|
||||
config HW_MEM_HOLE_SIZE_AUTO_INC
|
||||
bool
|
||||
default n
|
||||
|
||||
config MMCONF_BASE_ADDRESS
|
||||
hex
|
||||
default 0xF8000000
|
||||
|
||||
config MMCONF_BUS_NUMBER
|
||||
int
|
||||
default 64
|
||||
|
||||
config VGA_BIOS_ID
|
||||
string
|
||||
default "1002,98e4"
|
||||
help
|
||||
The default VGA BIOS PCI vendor/device ID should be set to the
|
||||
result of the map_oprom_vendev() function in northbridge.c.
|
||||
|
||||
config VGA_BIOS_FILE
|
||||
string
|
||||
default "3rdparty/blobs/northbridge/amd/00670F00/VBIOS.bin"
|
||||
|
||||
config RAMTOP
|
||||
hex
|
||||
default 0x1000000
|
||||
|
||||
config HEAP_SIZE
|
||||
hex
|
||||
default 0xc0000
|
||||
|
||||
config RAMBASE
|
||||
hex
|
||||
default 0x200000
|
||||
|
||||
config BOOTBLOCK_SOUTHBRIDGE_INIT
|
||||
string
|
||||
default "soc/amd/stoneyridge/bootblock/bootblock.c"
|
||||
|
|
|
@ -38,11 +38,13 @@ subdirs-y += ../../../cpu/x86/pae
|
|||
subdirs-y += ../../../cpu/x86/smm
|
||||
|
||||
romstage-y += early_setup.c
|
||||
romstage-y += dimmSpd.c
|
||||
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
|
||||
romstage-y += fixme.c
|
||||
romstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
|
||||
romstage-y += smbus.c
|
||||
romstage-y += smbus_spd.c
|
||||
romstage-y += ramtop.c
|
||||
romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
|
||||
|
||||
ramstage-y += chip.c
|
||||
|
@ -56,6 +58,7 @@ ramstage-y += ide.c
|
|||
ramstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
|
||||
ramstage-y += lpc.c
|
||||
ramstage-y += model_15_init.c
|
||||
ramstage-y += northbridge.c
|
||||
ramstage-y += pci.c
|
||||
ramstage-y += pcie.c
|
||||
ramstage-y += reset.c
|
||||
|
@ -63,6 +66,7 @@ ramstage-y += sata.c
|
|||
ramstage-y += sd.c
|
||||
ramstage-y += sm.c
|
||||
ramstage-y += smbus.c
|
||||
ramstage-y += ramtop.c
|
||||
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
|
||||
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
|
||||
ramstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2013 Sage Electronic Engineering, LLC
|
||||
* Copyright (C) 2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Note: Only need HID on Primary Bus */
|
||||
External (TOM1)
|
||||
External (TOM2)
|
||||
Name(_HID, EISAID("PNP0A08")) /* PCI Express Root Bridge */
|
||||
Name(_CID, EISAID("PNP0A03")) /* PCI Root Bridge */
|
||||
Name(_ADR, 0x00180000) /* Dev# = BSP Dev#, Func# = 0 */
|
||||
|
||||
/* Describe the Northbridge devices */
|
||||
|
||||
Method(_BBN, 0, NotSerialized) /* Bus number = 0 */
|
||||
{
|
||||
Return(Zero)
|
||||
}
|
||||
|
||||
Method(_STA, 0, NotSerialized)
|
||||
{
|
||||
Return(0x0B) /* Status is visible */
|
||||
}
|
||||
|
||||
Method(_PRT,0, NotSerialized)
|
||||
{
|
||||
If(PMOD)
|
||||
{
|
||||
Return(APR0) /* APIC mode */
|
||||
}
|
||||
Return (PR0) /* PIC Mode */
|
||||
}
|
||||
|
||||
Device(AMRT) {
|
||||
Name(_ADR, 0x00000000)
|
||||
} /* end AMRT */
|
||||
|
||||
/* Gpp 0 */
|
||||
Device(PBR4) {
|
||||
Name(_ADR, 0x00020001)
|
||||
Name(_PRW, Package() {0x18, 4})
|
||||
Method(_PRT,0) {
|
||||
If(PMOD){ Return(APS4) } /* APIC mode */
|
||||
Return (PS4) /* PIC Mode */
|
||||
} /* end _PRT */
|
||||
} /* end PBR4 */
|
||||
|
||||
/* Gpp 1 */
|
||||
Device(PBR5) {
|
||||
Name(_ADR, 0x00020002)
|
||||
Name(_PRW, Package() {0x18, 4})
|
||||
Method(_PRT,0) {
|
||||
If(PMOD){ Return(APS5) } /* APIC mode */
|
||||
Return (PS5) /* PIC Mode */
|
||||
} /* end _PRT */
|
||||
} /* end PBR5 */
|
||||
|
||||
/* Gpp 2 */
|
||||
Device(PBR6) {
|
||||
Name(_ADR, 0x00020003)
|
||||
Name(_PRW, Package() {0x18, 4})
|
||||
Method(_PRT,0) {
|
||||
If(PMOD){ Return(APS6) } /* APIC mode */
|
||||
Return (PS6) /* PIC Mode */
|
||||
} /* end _PRT */
|
||||
} /* end PBR6 */
|
||||
|
||||
/* Gpp 3 */
|
||||
Device(PBR7) {
|
||||
Name(_ADR, 0x00020004)
|
||||
Name(_PRW, Package() {0x18, 4})
|
||||
Method(_PRT,0) {
|
||||
If(PMOD){ Return(APS7) } /* APIC mode */
|
||||
Return (PS7) /* PIC Mode */
|
||||
} /* end _PRT */
|
||||
} /* end PBR7 */
|
||||
|
||||
/* Gpp 4 */
|
||||
Device(PBR8) {
|
||||
Name(_ADR, 0x00020005)
|
||||
Name(_PRW, Package() {0x18, 4})
|
||||
Method(_PRT,0) {
|
||||
If(PMOD){ Return(APS8) } /* APIC mode */
|
||||
Return (PS8) /* PIC Mode */
|
||||
} /* end _PRT */
|
||||
} /* end PBR8 */
|
||||
|
||||
Device(AZHD) { /* 0:9.2 - HD Audio */
|
||||
Name(_ADR, 0x00090002)
|
||||
OperationRegion(AZPD, PCI_Config, 0x00, 0x100)
|
||||
Field(AZPD, AnyAcc, NoLock, Preserve) {
|
||||
offset (0x42),
|
||||
NSDI, 1,
|
||||
NSDO, 1,
|
||||
NSEN, 1,
|
||||
offset (0x44),
|
||||
IPCR, 4,
|
||||
offset (0x54),
|
||||
PWST, 2,
|
||||
, 6,
|
||||
PMEB, 1,
|
||||
, 6,
|
||||
PMST, 1,
|
||||
offset (0x62),
|
||||
MMCR, 1,
|
||||
offset (0x64),
|
||||
MMLA, 32,
|
||||
offset (0x68),
|
||||
MMHA, 32,
|
||||
offset (0x6C),
|
||||
MMDT, 16,
|
||||
}
|
||||
|
||||
Method (_INI, 0, NotSerialized)
|
||||
{
|
||||
If (LEqual (OSVR, 0x03))
|
||||
{
|
||||
Store (Zero, NSEN)
|
||||
Store (One, NSDO)
|
||||
Store (One, NSDI)
|
||||
}
|
||||
}
|
||||
} /* end AZHD */
|
|
@ -12,25 +12,46 @@
|
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <chip.h>
|
||||
#include <cpu/amd/mtrr.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <soc/hudson.h>
|
||||
#include <soc/northbridge.h>
|
||||
|
||||
static void pci_domain_set_resources(device_t dev)
|
||||
static void cpu_bus_init(device_t dev)
|
||||
{
|
||||
assign_resources(dev->link_list);
|
||||
initialize_cpus(dev->link_list);
|
||||
}
|
||||
|
||||
static struct device_operations pci_domain_ops = {
|
||||
.set_resources = &pci_domain_set_resources,
|
||||
struct device_operations cpu_bus_ops = {
|
||||
.read_resources = DEVICE_NOOP,
|
||||
.set_resources = DEVICE_NOOP,
|
||||
.enable_resources = DEVICE_NOOP,
|
||||
.init = &cpu_bus_init,
|
||||
.scan_bus = cpu_bus_scan,
|
||||
};
|
||||
|
||||
static struct device_operations cpu_bus_ops = {
|
||||
struct device_operations pci_domain_ops = {
|
||||
.read_resources = domain_read_resources,
|
||||
.set_resources = domain_set_resources,
|
||||
.enable_resources = domain_enable_resources,
|
||||
.init = NULL,
|
||||
.scan_bus = pci_domain_scan_bus,
|
||||
.ops_pci_bus = pci_bus_default_ops,
|
||||
};
|
||||
|
||||
static void enable_dev(device_t dev)
|
||||
{
|
||||
static int done = 0;
|
||||
|
||||
if (!done) {
|
||||
setup_bsp_ramtop();
|
||||
done = 1;
|
||||
}
|
||||
|
||||
/* Set the operations if it is a special bus type */
|
||||
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||
dev->ops = &pci_domain_ops;
|
||||
|
@ -49,6 +70,7 @@ static void soc_init(void *chip_info)
|
|||
static void soc_final(void *chip_info)
|
||||
{
|
||||
hudson_final(chip_info);
|
||||
fam15_finalize(chip_info);
|
||||
}
|
||||
|
||||
struct chip_operations soc_amd_stoneyridge_ops = {
|
||||
|
@ -57,4 +79,3 @@ struct chip_operations soc_amd_stoneyridge_ops = {
|
|||
.init = &soc_init,
|
||||
.final = &soc_final
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2010-2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -20,6 +20,7 @@
|
|||
|
||||
struct soc_amd_stoneyridge_config
|
||||
{
|
||||
u8 spdAddrLookup[1][1][2];
|
||||
u32 ide0_enable : 1;
|
||||
u32 sata0_enable : 1;
|
||||
u32 boot_switch_sata_ide : 1;
|
||||
|
@ -30,4 +31,6 @@ struct soc_amd_stoneyridge_config
|
|||
|
||||
typedef struct soc_amd_stoneyridge_config config_t;
|
||||
|
||||
extern struct device_operations pci_domain_ops;
|
||||
|
||||
#endif /* STONEYRIDGE_CHIP_H */
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2015 - 2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <device/pci_def.h>
|
||||
#include <device/device.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* warning: Porting.h includes an open #pragma pack(1) */
|
||||
#include <Porting.h>
|
||||
#include <AGESA.h>
|
||||
#include <amdlib.h>
|
||||
#include "chip.h"
|
||||
#include <dimmSpd.h>
|
||||
|
||||
AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info)
|
||||
{
|
||||
int spdAddress;
|
||||
DEVTREE_CONST struct device *dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
|
||||
DEVTREE_CONST struct soc_amd_stoneyridge_config *config = dev->chip_info;
|
||||
|
||||
if ((dev == 0) || (config == 0))
|
||||
return AGESA_ERROR;
|
||||
if (info->SocketId >= ARRAY_SIZE(config->spdAddrLookup))
|
||||
return AGESA_ERROR;
|
||||
if (info->MemChannelId >= ARRAY_SIZE(config->spdAddrLookup[0]))
|
||||
return AGESA_ERROR;
|
||||
if (info->DimmId >= ARRAY_SIZE(config->spdAddrLookup[0][0]))
|
||||
return AGESA_ERROR;
|
||||
spdAddress = config->spdAddrLookup
|
||||
[info->SocketId] [info->MemChannelId] [info->DimmId];
|
||||
if (spdAddress == 0)
|
||||
return AGESA_ERROR;
|
||||
int err = hudson_readSpd(spdAddress, (void *) info->Buffer, 128);
|
||||
if (err)
|
||||
return AGESA_ERROR;
|
||||
return AGESA_SUCCESS;
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <northbridge/amd/pi/agesawrapper.h>
|
||||
#include <agesawrapper.h>
|
||||
#include <amdlib.h>
|
||||
|
||||
void amd_initcpuio(void)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef _STONEYRIDGE_GPIO_H_
|
||||
#define _STONEYRIDGE_GPIO_H_
|
||||
|
||||
#include <soc/amd/common/amd_defs.h>
|
||||
#include <amd_defs.h>
|
||||
#include <types.h>
|
||||
|
||||
#define CROS_GPIO_DEVICE_NAME "AmdKern"
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2015 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef NORTHBRIDGE_AMD_AGESA_FAM15H_H
|
||||
#define NORTHBRIDGE_AMD_AGESA_FAM15H_H
|
||||
|
||||
void cpu_bus_scan(device_t dev);
|
||||
void domain_enable_resources(device_t dev);
|
||||
void domain_read_resources(device_t dev);
|
||||
void domain_set_resources(device_t dev);
|
||||
void fam15_finalize(void *chip_info);
|
||||
void setup_uma_memory(void);
|
||||
|
||||
#endif /* NORTHBRIDGE_AMD_AGESA_FAM15H_H */
|
|
@ -0,0 +1,693 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <cbmem.h>
|
||||
#include <chip.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/amdfam15.h>
|
||||
#include <cpu/amd/mtrr.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/hypertransport.h>
|
||||
#include <lib.h>
|
||||
#include <agesawrapper.h>
|
||||
#include <agesawrapper_call.h>
|
||||
#include <soc/northbridge.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* AMD vendorcode files. Place at the end so coreboot defaults and maintained
|
||||
* and not set by vendorcode
|
||||
*/
|
||||
#include <AGESA.h>
|
||||
#include <cpuRegisters.h>
|
||||
#include <FieldAccessors.h>
|
||||
#include <Options.h>
|
||||
#include <Porting.h>
|
||||
#include <Topology.h>
|
||||
|
||||
#define MAX_NODE_NUMS (MAX_NODES * MAX_DIES)
|
||||
|
||||
#if (defined CONFIG_EXT_CONF_SUPPORT) && CONFIG_EXT_CONF_SUPPORT == 1
|
||||
#error CONFIG_EXT_CONF_SUPPORT == 1 not support anymore!
|
||||
#endif
|
||||
|
||||
typedef struct dram_base_mask {
|
||||
u32 base; //[47:27] at [28:8]
|
||||
u32 mask; //[47:27] at [28:8] and enable at bit 0
|
||||
} dram_base_mask_t;
|
||||
|
||||
static unsigned node_nums;
|
||||
static unsigned sblink;
|
||||
static device_t __f0_dev;
|
||||
static device_t __f1_dev;
|
||||
static device_t __f2_dev;
|
||||
static device_t __f4_dev;
|
||||
static unsigned fx_dev = 0;
|
||||
|
||||
static dram_base_mask_t get_dram_base_mask(u32 nodeid)
|
||||
{
|
||||
device_t dev = __f1_dev;
|
||||
dram_base_mask_t d;
|
||||
u32 temp;
|
||||
temp = pci_read_config32(dev, 0x44 + (nodeid << 3)); //[39:24] at [31:16]
|
||||
d.mask = ((temp & 0xfff80000) >> (8 + 3)); // mask out DramMask [26:24] too
|
||||
temp = pci_read_config32(dev, 0x144 + (nodeid << 3)) & 0xff; //[47:40] at [7:0]
|
||||
d.mask |= temp << 21;
|
||||
temp = pci_read_config32(dev, 0x40 + (nodeid << 3)); //[39:24] at [31:16]
|
||||
d.mask |= (temp & 1); // enable bit
|
||||
d.base = ((temp & 0xfff80000) >> (8 + 3)); // mask out DramBase [26:24) too
|
||||
temp = pci_read_config32(dev, 0x140 + (nodeid << 3)) & 0xff; //[47:40] at [7:0]
|
||||
d.base |= temp << 21;
|
||||
return d;
|
||||
}
|
||||
|
||||
static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,
|
||||
u32 io_min, u32 io_max)
|
||||
{
|
||||
u32 tempreg;
|
||||
/* io range allocation */
|
||||
tempreg = (nodeid & 0xf) | ((nodeid & 0x30) << (8 - 4)) | (linkn << 4) | ((io_max & 0xf0) << (12 - 4)); //limit
|
||||
pci_write_config32(__f1_dev, reg + 4, tempreg);
|
||||
tempreg = 3 | ((io_min & 0xf0) << (12 - 4)); //base :ISA and VGA ?
|
||||
pci_write_config32(__f1_dev, reg, tempreg);
|
||||
}
|
||||
|
||||
static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max)
|
||||
{
|
||||
u32 tempreg;
|
||||
/* io range allocation */
|
||||
tempreg = (nodeid & 0xf) | (linkn << 4) | (mmio_max & 0xffffff00); //limit
|
||||
pci_write_config32(__f1_dev, reg + 4, tempreg);
|
||||
tempreg = 3 | (nodeid & 0x30) | (mmio_min & 0xffffff00);
|
||||
pci_write_config32(__f1_dev, reg, tempreg);
|
||||
}
|
||||
|
||||
static device_t get_node_pci(u32 fn)
|
||||
{
|
||||
return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, fn));
|
||||
}
|
||||
|
||||
static void get_fx_dev(void)
|
||||
{
|
||||
__f0_dev = get_node_pci(0);
|
||||
__f1_dev = get_node_pci(1);
|
||||
__f2_dev = get_node_pci(2);
|
||||
__f4_dev = get_node_pci(4);
|
||||
fx_dev = 1;
|
||||
|
||||
if (__f1_dev == NULL || __f0_dev == NULL || fx_dev == 0)
|
||||
die("Cannot find 0:0x18.[0|1]\n");
|
||||
}
|
||||
|
||||
static u32 f1_read_config32(unsigned reg)
|
||||
{
|
||||
if (fx_dev == 0)
|
||||
get_fx_dev();
|
||||
return pci_read_config32(__f1_dev, reg);
|
||||
}
|
||||
|
||||
static void f1_write_config32(unsigned reg, u32 value)
|
||||
{
|
||||
if (fx_dev == 0)
|
||||
get_fx_dev();
|
||||
pci_write_config32(__f1_dev, reg, value);
|
||||
}
|
||||
|
||||
static void set_vga_enable_reg(u32 nodeid, u32 linkn)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = 1 | (nodeid << 4) | (linkn << 12);
|
||||
/* Routes:
|
||||
* mmio 0xa0000:0xbffff
|
||||
* io 0x3b0:0x3bb, 0x3c0:0x3df
|
||||
*/
|
||||
f1_write_config32(0xf4, val);
|
||||
}
|
||||
|
||||
static void read_resources(device_t dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* This MMCONF resource must be reserved in the PCI domain.
|
||||
* It is not honored by the coreboot resource allocator if it is in
|
||||
* the CPU_CLUSTER.
|
||||
*/
|
||||
mmconf_resource(dev, 0xc0010058);
|
||||
}
|
||||
|
||||
static void set_resource(device_t dev, struct resource *resource, u32 nodeid)
|
||||
{
|
||||
resource_t rbase, rend;
|
||||
unsigned reg, link_num;
|
||||
char buf[50];
|
||||
|
||||
/* Make certain the resource has actually been set */
|
||||
if (!(resource->flags & IORESOURCE_ASSIGNED))
|
||||
return;
|
||||
|
||||
/* If I have already stored this resource don't worry about it */
|
||||
if (resource->flags & IORESOURCE_STORED)
|
||||
return;
|
||||
|
||||
/* Only handle PCI memory and IO resources */
|
||||
if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
|
||||
return;
|
||||
|
||||
/* Ensure I am actually looking at a resource of function 1 */
|
||||
if ((resource->index & 0xffff) < 0x1000)
|
||||
return;
|
||||
|
||||
/* Get the base address */
|
||||
rbase = resource->base;
|
||||
|
||||
/* Get the limit (rounded up) */
|
||||
rend = resource_end(resource);
|
||||
|
||||
/* Get the register and link */
|
||||
reg = resource->index & 0xfff; // 4k
|
||||
link_num = IOINDEX_LINK(resource->index);
|
||||
|
||||
if (resource->flags & IORESOURCE_IO) {
|
||||
set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
|
||||
}
|
||||
else if (resource->flags & IORESOURCE_MEM) {
|
||||
set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >> 24), rbase >> 8, rend >> 8); // [39:8]
|
||||
}
|
||||
resource->flags |= IORESOURCE_STORED;
|
||||
snprintf(buf, sizeof(buf), " <node %x link %x>",
|
||||
nodeid, link_num);
|
||||
report_resource_stored(dev, resource, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* I tried to reuse the resource allocation code in set_resource()
|
||||
* but it is too difficult to deal with the resource allocation magic.
|
||||
*/
|
||||
|
||||
static void create_vga_resource(device_t dev)
|
||||
{
|
||||
struct bus *link;
|
||||
|
||||
/* find out which link the VGA card is connected,
|
||||
* we only deal with the 'first' vga card */
|
||||
for (link = dev->link_list; link; link = link->next) {
|
||||
if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
|
||||
break;
|
||||
}
|
||||
|
||||
/* no VGA card installed */
|
||||
if (link == NULL)
|
||||
return;
|
||||
|
||||
printk(BIOS_DEBUG, "VGA: %s link %d has VGA device\n", dev_path(dev), sblink);
|
||||
set_vga_enable_reg(0, sblink);
|
||||
}
|
||||
|
||||
static void set_resources(device_t dev)
|
||||
{
|
||||
struct bus *bus;
|
||||
struct resource *res;
|
||||
|
||||
|
||||
/* do we need this? */
|
||||
create_vga_resource(dev);
|
||||
|
||||
/* Set each resource we have found */
|
||||
for (res = dev->resource_list; res; res = res->next) {
|
||||
set_resource(dev, res, 0);
|
||||
}
|
||||
|
||||
for (bus = dev->link_list; bus; bus = bus->next) {
|
||||
if (bus->children) {
|
||||
assign_resources(bus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void northbridge_init(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned long acpi_fill_hest(acpi_hest_t *hest)
|
||||
{
|
||||
void *addr, *current;
|
||||
|
||||
/* Skip the HEST header. */
|
||||
current = (void *)(hest + 1);
|
||||
|
||||
addr = agesawrapper_getlateinitptr(PICK_WHEA_MCE);
|
||||
if (addr != NULL)
|
||||
current += acpi_create_hest_error_source(hest, current, 0, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
|
||||
|
||||
addr = agesawrapper_getlateinitptr(PICK_WHEA_CMC);
|
||||
if (addr != NULL)
|
||||
current += acpi_create_hest_error_source(hest, current, 1, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
|
||||
|
||||
return (unsigned long)current;
|
||||
}
|
||||
|
||||
static void northbridge_fill_ssdt_generator(device_t device)
|
||||
{
|
||||
msr_t msr;
|
||||
char pscope[] = "\\_SB.PCI0";
|
||||
|
||||
acpigen_write_scope(pscope);
|
||||
msr = rdmsr(TOP_MEM);
|
||||
acpigen_write_name_dword("TOM1", msr.lo);
|
||||
msr = rdmsr(TOP_MEM2);
|
||||
/*
|
||||
* Since XP only implements parts of ACPI 2.0, we can't use a qword
|
||||
* here.
|
||||
* See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
|
||||
* slide 22ff.
|
||||
* Shift value right by 20 bit to make it fit into 32bit,
|
||||
* giving us 1MB granularity and a limit of almost 4Exabyte of memory.
|
||||
*/
|
||||
acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
|
||||
acpigen_pop_len();
|
||||
}
|
||||
|
||||
static unsigned long agesa_write_acpi_tables(device_t device,
|
||||
unsigned long current,
|
||||
acpi_rsdp_t *rsdp)
|
||||
{
|
||||
acpi_srat_t *srat;
|
||||
acpi_slit_t *slit;
|
||||
acpi_header_t *ssdt;
|
||||
acpi_header_t *alib;
|
||||
acpi_header_t *ivrs;
|
||||
acpi_hest_t *hest;
|
||||
|
||||
/* HEST */
|
||||
current = ALIGN(current, 8);
|
||||
hest = (acpi_hest_t *)current;
|
||||
acpi_write_hest((void *)current, acpi_fill_hest);
|
||||
acpi_add_table(rsdp, (void *)current);
|
||||
current += ((acpi_header_t *)current)->length;
|
||||
|
||||
current = ALIGN(current, 8);
|
||||
printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
|
||||
ivrs = agesawrapper_getlateinitptr(PICK_IVRS);
|
||||
if (ivrs != NULL) {
|
||||
memcpy((void *)current, ivrs, ivrs->length);
|
||||
ivrs = (acpi_header_t *) current;
|
||||
current += ivrs->length;
|
||||
acpi_add_table(rsdp, ivrs);
|
||||
} else {
|
||||
printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
|
||||
}
|
||||
|
||||
/* SRAT */
|
||||
current = ALIGN(current, 8);
|
||||
printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
|
||||
srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
|
||||
if (srat != NULL) {
|
||||
memcpy((void *)current, srat, srat->header.length);
|
||||
srat = (acpi_srat_t *) current;
|
||||
current += srat->header.length;
|
||||
acpi_add_table(rsdp, srat);
|
||||
} else {
|
||||
printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
|
||||
}
|
||||
|
||||
/* SLIT */
|
||||
current = ALIGN(current, 8);
|
||||
printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
|
||||
slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
|
||||
if (slit != NULL) {
|
||||
memcpy((void *)current, slit, slit->header.length);
|
||||
slit = (acpi_slit_t *) current;
|
||||
current += slit->header.length;
|
||||
acpi_add_table(rsdp, slit);
|
||||
} else {
|
||||
printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
|
||||
}
|
||||
|
||||
/* ALIB */
|
||||
current = ALIGN(current, 16);
|
||||
printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
|
||||
alib = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_ALIB);
|
||||
if (alib != NULL) {
|
||||
memcpy((void *)current, alib, alib->length);
|
||||
alib = (acpi_header_t *) current;
|
||||
current += alib->length;
|
||||
acpi_add_table(rsdp, (void *)alib);
|
||||
}
|
||||
else {
|
||||
printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
|
||||
}
|
||||
|
||||
/* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
|
||||
/* SSDT */
|
||||
current = ALIGN(current, 16);
|
||||
printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
|
||||
ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
|
||||
if (ssdt != NULL) {
|
||||
memcpy((void *)current, ssdt, ssdt->length);
|
||||
ssdt = (acpi_header_t *) current;
|
||||
current += ssdt->length;
|
||||
}
|
||||
else {
|
||||
printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
|
||||
}
|
||||
acpi_add_table(rsdp,ssdt);
|
||||
|
||||
printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
|
||||
return current;
|
||||
}
|
||||
|
||||
static struct device_operations northbridge_operations = {
|
||||
.read_resources = read_resources,
|
||||
.set_resources = set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = northbridge_init,
|
||||
.acpi_fill_ssdt_generator = northbridge_fill_ssdt_generator,
|
||||
.write_acpi_tables = agesa_write_acpi_tables,
|
||||
.enable = 0,
|
||||
.ops_pci = 0,
|
||||
};
|
||||
|
||||
static const struct pci_driver family15_northbridge __pci_driver = {
|
||||
.ops = &northbridge_operations,
|
||||
.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_15H_MODEL_707F_NB_HT,
|
||||
};
|
||||
|
||||
void fam15_finalize(void *chip_info)
|
||||
{
|
||||
device_t dev;
|
||||
u32 value;
|
||||
dev = dev_find_slot(0, PCI_DEVFN(0, 0)); /* clear IoapicSbFeatureEn */
|
||||
pci_write_config32(dev, 0xF8, 0);
|
||||
pci_write_config32(dev, 0xFC, 5); /* TODO: move it to dsdt.asl */
|
||||
|
||||
/* disable No Snoop */
|
||||
dev = dev_find_slot(0, PCI_DEVFN(1, 1));
|
||||
value = pci_read_config32(dev, 0x60);
|
||||
value &= ~(1 << 11);
|
||||
pci_write_config32(dev, 0x60, value);
|
||||
}
|
||||
|
||||
void domain_read_resources(device_t dev)
|
||||
{
|
||||
unsigned reg;
|
||||
|
||||
/* Find the already assigned resource pairs */
|
||||
get_fx_dev();
|
||||
for (reg = 0x80; reg <= 0xd8; reg += 0x08) {
|
||||
u32 base, limit;
|
||||
base = f1_read_config32(reg);
|
||||
limit = f1_read_config32(reg + 0x04);
|
||||
/* Is this register allocated? */
|
||||
if ((base & 3) != 0) {
|
||||
unsigned nodeid, reg_link;
|
||||
device_t reg_dev;
|
||||
if (reg < 0xc0) { // mmio
|
||||
nodeid = (limit & 0xf) + (base & 0x30);
|
||||
} else { // io
|
||||
nodeid = (limit & 0xf) + ((base >> 4) & 0x30);
|
||||
}
|
||||
reg_link = (limit >> 4) & 7;
|
||||
reg_dev = __f0_dev;
|
||||
if (reg_dev) {
|
||||
/* Reserve the resource */
|
||||
struct resource *res;
|
||||
res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
|
||||
if (res) {
|
||||
res->flags = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: do we need to check extend conf space?
|
||||
I don't believe that much preset value */
|
||||
|
||||
pci_domain_read_resources(dev);
|
||||
}
|
||||
|
||||
void domain_enable_resources(device_t dev)
|
||||
{
|
||||
if (acpi_is_wakeup_s3())
|
||||
AGESAWRAPPER(fchs3laterestore);
|
||||
|
||||
/* Must be called after PCI enumeration and resource allocation */
|
||||
if (!acpi_is_wakeup_s3())
|
||||
AGESAWRAPPER(amdinitmid);
|
||||
|
||||
printk(BIOS_DEBUG, " ader - leaving domain_enable_resources.\n");
|
||||
}
|
||||
|
||||
#if CONFIG_HW_MEM_HOLE_SIZEK != 0
|
||||
struct hw_mem_hole_info {
|
||||
unsigned hole_startk;
|
||||
int node_id;
|
||||
};
|
||||
|
||||
static struct hw_mem_hole_info get_hw_mem_hole_info(void)
|
||||
{
|
||||
struct hw_mem_hole_info mem_hole;
|
||||
mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
|
||||
mem_hole.node_id = -1;
|
||||
dram_base_mask_t d;
|
||||
u32 hole;
|
||||
d = get_dram_base_mask(0);
|
||||
hole = pci_read_config32(__f1_dev, 0xf0);
|
||||
if (hole & 2) {
|
||||
/* We found the hole */
|
||||
mem_hole.hole_startk = (hole & (0xff << 24)) >> 10;
|
||||
mem_hole.node_id = 0; // record the node # with hole
|
||||
}
|
||||
|
||||
return mem_hole;
|
||||
}
|
||||
#endif
|
||||
|
||||
void domain_set_resources(device_t dev)
|
||||
{
|
||||
unsigned long mmio_basek;
|
||||
u32 pci_tolm;
|
||||
int i, idx;
|
||||
struct bus *link;
|
||||
#if CONFIG_HW_MEM_HOLE_SIZEK != 0
|
||||
struct hw_mem_hole_info mem_hole;
|
||||
u32 reset_memhole = 1;
|
||||
#endif
|
||||
|
||||
pci_tolm = 0xffffffffUL;
|
||||
for (link = dev->link_list; link; link = link->next) {
|
||||
pci_tolm = find_pci_tolm(link);
|
||||
}
|
||||
|
||||
mmio_basek = pci_tolm >> 10;
|
||||
/* Round mmio_basek to something the processor can support */
|
||||
mmio_basek &= ~((1 << 6) -1);
|
||||
|
||||
/* FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
|
||||
* MMIO hole. If you fix this here, please fix amdk8, too.
|
||||
*/
|
||||
/* Round the mmio hole to 64M */
|
||||
mmio_basek &= ~((64 * 1024) - 1);
|
||||
|
||||
#if CONFIG_HW_MEM_HOLE_SIZEK != 0
|
||||
/* if the hw mem hole is already set in raminit stage, here we will compare
|
||||
* mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
|
||||
* use hole_basek as mmio_basek and we don't need to reset hole.
|
||||
* otherwise We reset the hole to the mmio_basek
|
||||
*/
|
||||
|
||||
mem_hole = get_hw_mem_hole_info();
|
||||
|
||||
/* Use hole_basek as mmio_basek, and we don't need to reset hole anymore */
|
||||
if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
|
||||
mmio_basek = mem_hole.hole_startk;
|
||||
reset_memhole = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
idx = 0x10;
|
||||
for (i = 0; i < node_nums; i++) {
|
||||
dram_base_mask_t d;
|
||||
resource_t basek, limitk, sizek; // 4 1T
|
||||
|
||||
d = get_dram_base_mask(i);
|
||||
|
||||
if (!(d.mask & 1))
|
||||
continue;
|
||||
basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
|
||||
limitk = ((resource_t)(((d.mask & ~1) + 0x000FF) & 0x1fffff00)) << 9 ;
|
||||
|
||||
sizek = limitk - basek;
|
||||
|
||||
/* see if we need a hole from 0xa0000 to 0xbffff */
|
||||
if ((basek < ((8 * 64) + (8 * 16))) && (sizek > ((8 * 64) + (16 * 16)))) {
|
||||
ram_resource(dev, (idx | i), basek, ((8 * 64) + (8 * 16)) - basek);
|
||||
idx += 0x10;
|
||||
basek = (8 * 64) + (16 * 16);
|
||||
sizek = limitk - ((8 * 64) + (16 * 16));
|
||||
|
||||
}
|
||||
|
||||
/* split the region to accommodate pci memory space */
|
||||
if ((basek < 4 * 1024 * 1024 ) && (limitk > mmio_basek)) {
|
||||
if (basek <= mmio_basek) {
|
||||
unsigned pre_sizek;
|
||||
pre_sizek = mmio_basek - basek;
|
||||
if (pre_sizek>0) {
|
||||
ram_resource(dev, (idx | i), basek, pre_sizek);
|
||||
idx += 0x10;
|
||||
sizek -= pre_sizek;
|
||||
}
|
||||
basek = mmio_basek;
|
||||
}
|
||||
if ((basek + sizek) <= 4 * 1024 * 1024) {
|
||||
sizek = 0;
|
||||
}
|
||||
else {
|
||||
uint64_t topmem2 = bsp_topmem2();
|
||||
basek = 4 * 1024 * 1024;
|
||||
sizek = topmem2 / 1024 - basek;
|
||||
}
|
||||
}
|
||||
|
||||
ram_resource(dev, (idx | i), basek, sizek);
|
||||
idx += 0x10;
|
||||
printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
|
||||
i, mmio_basek, basek, limitk);
|
||||
}
|
||||
|
||||
add_uma_resource_below_tolm(dev, 7);
|
||||
|
||||
for (link = dev->link_list; link; link = link->next) {
|
||||
if (link->children) {
|
||||
assign_resources(link);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Reserve everything between A segment and 1MB:
|
||||
*
|
||||
* 0xa0000 - 0xbffff: legacy VGA
|
||||
* 0xc0000 - 0xfffff: RAM
|
||||
*/
|
||||
mmio_resource(dev, 0xa0000, 0xa0000 / KiB, 0x20000 / KiB);
|
||||
reserved_ram_resource(dev, 0xc0000, 0xc0000 / KiB, 0x40000 / KiB);
|
||||
}
|
||||
|
||||
static void sysconf_init(device_t dev) // first node
|
||||
{
|
||||
sblink = (pci_read_config32(dev, 0x64) >> 8) & 7; // don't forget sublink1
|
||||
node_nums = ((pci_read_config32(dev, 0x60) >> 4) & 7) + 1; // NodeCnt[2:0]
|
||||
}
|
||||
|
||||
|
||||
void cpu_bus_scan(device_t dev)
|
||||
{
|
||||
struct bus *cpu_bus;
|
||||
device_t cpu;
|
||||
device_t cdb_dev;
|
||||
device_t dev_mc;
|
||||
int j;
|
||||
int core_max;
|
||||
int core_nums;
|
||||
int siblings;
|
||||
int family;
|
||||
int enable_node;
|
||||
u32 lapicid_start;
|
||||
u32 apic_id;
|
||||
u32 pccount;
|
||||
|
||||
|
||||
dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
|
||||
if (!dev_mc) {
|
||||
printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB);
|
||||
die("");
|
||||
}
|
||||
sysconf_init(dev_mc); /* sets global node_nums */
|
||||
|
||||
if (node_nums != 1)
|
||||
die("node_nums != 1. This is an SOC. Something is terribly wrong.");
|
||||
|
||||
/* Get max and actual number of cores */
|
||||
pccount = cpuid_ecx(AMD_CPUID_ASIZE_PCCOUNT);
|
||||
core_max = 1 << ((pccount >> 12) & 0xF);
|
||||
core_nums = (pccount & 0xF);
|
||||
|
||||
family = (cpuid_eax(1) >> 20) & 0xFF;
|
||||
|
||||
cdb_dev = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 5));
|
||||
siblings = pci_read_config32(cdb_dev, 0x84) & 0xFF;
|
||||
|
||||
printk(BIOS_SPEW, "%s family%xh, core_max=%d, core_nums=%d, siblings=%d\n",
|
||||
dev_path(cdb_dev), 0x0f + family, core_max, core_nums, siblings);
|
||||
|
||||
/*
|
||||
* APIC ID calucation is tightly coupled with AGESA v5 code.
|
||||
* This calculation MUST match the assignment calculation done
|
||||
* in LocalApicInitializationAtEarly() function.
|
||||
* And reference GetLocalApicIdForCore()
|
||||
*
|
||||
* Apply apic enumeration rules
|
||||
* For systems with >= 16 APICs, put the IO-APICs at 0..n and
|
||||
* put the local-APICs at m..z
|
||||
*
|
||||
* This is needed because many IO-APIC devices only have 4 bits
|
||||
* for their APIC id and therefore must reside at 0..15
|
||||
*/
|
||||
|
||||
/*
|
||||
* While the above statement is true, we know some things about
|
||||
* this silicon. It is an SOC and can't have >= 16 APICs, but
|
||||
* we will start numbering at 0x10. We also know there is only
|
||||
* on physical node (module in AMD speak).
|
||||
*/
|
||||
|
||||
lapicid_start = 0x10; /* Get this from devicetree? see comment above. */
|
||||
enable_node = cdb_dev && cdb_dev->enabled;
|
||||
cpu_bus = dev->link_list;
|
||||
|
||||
for (j = 0; j <= siblings; j++ ) {
|
||||
apic_id = lapicid_start + j;
|
||||
printk(BIOS_SPEW, "lapicid_start 0x%x, node 0x%x, core 0x%x, apicid=0x%x\n",
|
||||
lapicid_start, node_nums, j, apic_id);
|
||||
|
||||
cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
|
||||
if (cpu)
|
||||
amd_cpu_topology(cpu, node_nums, j);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Change the vendor / device IDs to match the generic VBIOS header. *
|
||||
*********************************************************************/
|
||||
u32 map_oprom_vendev(u32 vendev)
|
||||
{
|
||||
u32 new_vendev;
|
||||
new_vendev =
|
||||
((0x100298E0 <= vendev) && (vendev <= 0x100298EF)) ? 0x100298E0 : vendev;
|
||||
|
||||
if (vendev != new_vendev)
|
||||
printk(BIOS_NOTICE, "Mapping PCI device %8x to %8x\n", vendev, new_vendev);
|
||||
|
||||
return new_vendev;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define __SIMPLE_DEVICE__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/io.h>
|
||||
#include <cbmem.h>
|
||||
|
||||
#define CBMEM_TOP_SCRATCHPAD 0x78
|
||||
|
||||
void backup_top_of_low_cacheable(uintptr_t ramtop)
|
||||
{
|
||||
uint16_t top_cache = ramtop >> 16;
|
||||
pci_write_config16(PCI_DEV(0,0,0), CBMEM_TOP_SCRATCHPAD, top_cache);
|
||||
}
|
||||
|
||||
uintptr_t restore_top_of_low_cacheable(void)
|
||||
{
|
||||
uint16_t top_cache;
|
||||
top_cache = pci_read_config16(PCI_DEV(0,0,0), CBMEM_TOP_SCRATCHPAD);
|
||||
return (top_cache << 16);
|
||||
}
|
|
@ -20,8 +20,7 @@
|
|||
#include <Porting.h>
|
||||
#include <AGESA.h>
|
||||
#include <amdlib.h>
|
||||
|
||||
#include <northbridge/amd/pi/dimmSpd.h>
|
||||
#include <dimmSpd.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
@ -61,11 +61,11 @@ ifeq ($(CONFIG_CPU_AMD_PI_00630F01),y)
|
|||
AGESA_INC += -I$(AGESA_ROOT)/Proc/IDS
|
||||
endif
|
||||
|
||||
AGESA_INC += -I$(src)/northbridge/amd/pi
|
||||
|
||||
ifeq ($(CONFIG_SOC_AMD_STONEYRIDGE_FP4)$(CONFIG_SOC_AMD_STONEYRIDGE_FT4),y)
|
||||
AGESA_INC += -I$(src)/soc/amd/stoneyridge/include
|
||||
AGESA_INC += -I$(src)/soc/amd/common
|
||||
else
|
||||
AGESA_INC += -I$(src)/northbridge/amd/pi
|
||||
AGESA_INC += -I$(src)/southbridge/amd/pi/hudson
|
||||
endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue