[coreboot] Use the constant TSC for AMD Family 10h–15h processors?
Paul Menzel
paulepanter at users.sourceforge.net
Mon May 13 09:04:46 CEST 2013
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20130513/7fad391c/attachment.sig>
More information about the coreboot
mailing list