Am Sonntag, den 12.05.2013, 15:40 +0200 schrieb Peter Stuge: > Paul Menzel wrote: > > do you know if the timer mentioned in the BIOS and Kernel Developer’s > > Guide (BKGD) for the AMD Family 14h processors [1] > > > > 2.11.4 BIOS Timer > > > > The root complex implements a 32-bit microsecond timer (see > > D0F0xE4_x0130_80F0 and D0F0xE4_x0130_80F1) that the BIOS can use > > to accurately time wait operations between initialization steps. > > To ensure that BIOS waits a minimum number of microseconds > > between steps BIOS should always wait for one microsecond more > > than the required minimum wait time. > > > > could be used for implementing `tsc_freq_mhz()` as done for Intel > > Haswell processors? > > Isn't that quite clear from the text that you quoted?
Probably, yes. As this area is new to me, I prefer to ask and get
confirmation to be sure.
> > Suggestions, if this should be shared and how the files should be
> > named are appreciated.
>
> Yes and no. We can do this for coreboot's own code for AMD platforms,
> but it obviously does not make much sense to hack this into AGESA if
> there are not already provisions for it.
I totally forgot about that. There is coreboot code for the K8 and
Family 10h processors, if I am not mistaken.
AGESA is there for Family 10h to 15h processors.
> Since AGESA is the only thing relevant going forward the question
> is what AGESA needs, timing-wise. Have you checked?
Only a little. Having an ASRock E350M1, I am looking into the Family 14h
family. There seems to be no TSC stuff in `src/cpu/amd`. But the AMD
vendor code seems to have it.
$ git grep -i tsc src/vendorcode/amd/agesa/f14/
`AGESA.h` has a struct `MEM_DATA_STRUCT` where the frequency is put
into.
$ nl -ba src/vendorcode/amd/agesa/f14/AGESA.h | grep -B 40 -A 5
TSC
[…]
1700 ///
1701 /// Contains all data relevant to Memory Initialization.
1702 ///
1703 typedef struct _MEM_DATA_STRUCT {
1704 IN AMD_CONFIG_PARAMS StdHeader; ///< Standard
configuration header
1705
1706 IN MEM_PARAMETER_STRUCT *ParameterListPtr; ///< List of
input Parameters
1707
1708 OUT MEM_FUNCTION_STRUCT FunctionList; ///< List of
function Pointers
1709
1710 IN OUT AGESA_STATUS (*GetPlatformCfg[MAX_PLATFORM_TYPES])
(struct _MEM_DATA_STRUCT *MemData, UINT8 SocketID, CH_DEF_STRUCT
*CurrentChannel); ///< look-up platform info
1711
1712 IN OUT BOOLEAN (*ErrorHandling)(struct _DIE_STRUCT *MCTPtr,
UINT8 DCT, UINT16 ChipSelMask, AMD_CONFIG_PARAMS *StdHeader); ///< Error
Handling
1713
1714
1715 OUT MEM_SOCKET_STRUCT SocketList[MAX_SOCKETS_SUPPORTED];
///< Socket list for memory code.
1716 ///< SocketList is a
shortcut for IBVs to retrieve training
1717 ///< and timing data for
each channel indexed by socket/channel,
1718 ///< eliminating their need
to parse die/dct/channel etc.
1719 ///< It contains pointers to
the populated data structures for
1720 ///< each channel and skips
the channel structures that are
1721 ///< unpopulated. In the
case of channels sharing the same DCT,
1722 ///< the pTimings pointers
will point to the same DCT Timing data.
1723
1724 OUT DIE_STRUCT *DiesPerSystem; ///< Pointed to an array of
DIE_STRUCTs
1725 OUT UINT8 DieCount; ///< Number of MCTs in the
system.
1726
1727 IN SPD_DEF_STRUCT *SpdDataStructure; ///<
Pointer to SPD Data structure
1728
1729 IN OUT struct _PLATFORM_CONFIGURATION *PlatFormConfig;
///< Platform profile/build option config structure
1730
1731 IN OUT BOOLEAN IsFlowControlSupported; ///< Indicates if
flow control is supported
1732
1733 OUT UINT32 TscRate; ///< The rate at which the
TSC increments in megahertz.
1734
1735 } MEM_DATA_STRUCT;
[…]
With
$ git grep -i tsc src/vendorcode/amd/agesa/f14/ | grep -i rate
[…]
src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c: *
@CpuServiceMethod{::F_CPU_GET_TSC_RATE}.
src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c:F14GetTscRate
(
src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.h:F14GetTscRate
(
[…]
I found `F14GetTscRate`.
$ nl -ba
src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/cpuF14Utilities.c
[…]
213
/*---------------------------------------------------------------------------------------*/
214 /**
215 * Determines the rate at which the executing core's time
stamp counter is
216 * incrementing.
217 *
218 * @CpuServiceMethod{::F_CPU_GET_TSC_RATE}.
219 *
220 * @param[in] FamilySpecificServices The current Family
Specific Services.
221 * @param[out] FrequencyInMHz TSC actual frequency.
222 * @param[in] StdHeader Header for library
and services.
223 *
224 * @return The most severe status of all called services
225 */
226 AGESA_STATUS
227 F14GetTscRate (
228 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
229 OUT UINT32 *FrequencyInMHz,
230 IN AMD_CONFIG_PARAMS *StdHeader
231 )
232 {
233 UINT64 MsrReg;
234 PSTATE_CPU_FAMILY_SERVICES *FamilyServices;
235
236 FamilyServices = NULL;
237 GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable,
(const VOID **)&FamilyServices, StdHeader);
238 ASSERT (FamilyServices != NULL);
239
240 LibAmdMsrRead (0xC0010015, &MsrReg, StdHeader);
241 if ((MsrReg & 0x01000000) != 0) {
242 return (FamilyServices->GetPstateFrequency (FamilyServices,
0, FrequencyInMHz, StdHeader));
243 } else {
244 return (FamilySpecificServices->GetCurrentNbFrequency
(FamilySpecificServices, FrequencyInMHz, StdHeader));
245 }
246 }
[…]
So there is the infrastructure already. The only problem is how to hook
this up into coreboot. Create `src/cpu/amd/agesa/tsc_delay.c` and
somehow call the AGESA `F14GetTscRate()` from it?
Thanks,
Paul
signature.asc
Description: This is a digitally signed message part
-- coreboot mailing list: [email protected] http://www.coreboot.org/mailman/listinfo/coreboot

