x86: slimbootloader: Set TSC information for tsc_timer
authorPark, Aiden <aiden.park@intel.com>
Sat, 3 Aug 2019 08:30:52 +0000 (08:30 +0000)
committerBin Meng <bmeng.cn@gmail.com>
Fri, 9 Aug 2019 14:24:02 +0000 (22:24 +0800)
Slim Bootloader already calibrated TSC and provides it to U-Boot.
Therefore, U-Boot does not have to re-calibrate TSC.
Configuring tsc_base and clock_rate makes x86 tsc_timer driver bypass
TSC calibration and use the provided TSC frequency.
- Get TSC frequency from performance info hob
- Set tsc_base and clock_rate for tsc_timer driver

Signed-off-by: Aiden Park <aiden.park@intel.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/cpu/slimbootloader/slimbootloader.c
arch/x86/include/asm/arch-slimbootloader/slimbootloader.h

index 9f3a61ec612fc9e083ebde457e708ada9017dffd..e6b174ca88627114e8d0e17b7dfc224e8e953739 100644 (file)
@@ -4,9 +4,46 @@
  */
 
 #include <common.h>
+#include <asm/arch/slimbootloader.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * This sets tsc_base and clock_rate for early_timer and tsc_timer.
+ * The performance info guid hob has all performance timestamp data, but
+ * the only tsc frequency info is used for the timer driver for now.
+ *
+ * Slim Bootloader already calibrated TSC and provides it to U-Boot.
+ * Therefore, U-Boot does not have to re-calibrate TSC.
+ * Configuring tsc_base and clock_rate here makes x86 tsc_timer driver
+ * bypass TSC calibration and use the provided TSC frequency.
+ */
+static void tsc_init(void)
+{
+       struct sbl_performance_info *data;
+       const efi_guid_t guid = SBL_PERFORMANCE_INFO_GUID;
+
+       if (!gd->arch.hob_list)
+               panic("hob list not found!");
+
+       gd->arch.tsc_base = rdtsc();
+       debug("tsc_base=0x%llx\n", gd->arch.tsc_base);
+
+       data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid);
+       if (!data) {
+               debug("performance info hob not found\n");
+               return;
+       }
+
+       /* frequency is in KHz, so to Hz */
+       gd->arch.clock_rate = data->frequency * 1000;
+       debug("freq=0x%lx\n", gd->arch.clock_rate);
+}
 
 int arch_cpu_init(void)
 {
+       tsc_init();
+
        return x86_cpu_init_f();
 }
 
index 174a341d326bb802e13ba98a904ad25d21adbd71..05dd1b2b4471d4ccd480448cc796f1a269692485 100644 (file)
        EFI_GUID(0x6c6872fe, 0x56a9, 0x4403, \
                0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1)
 
+/**
+ * A GUID to get boot performance info hob which is provided by Slim Bootloader
+ */
+#define SBL_PERFORMANCE_INFO_GUID \
+       EFI_GUID(0x868204be, 0x23d0, 0x4ff9, \
+               0xac, 0x34, 0xb9, 0x95, 0xac, 0x04, 0xb1, 0xb9)
+
 /**
  * A single entry of memory map information
  *
@@ -84,4 +91,25 @@ struct sbl_serial_port_info {
        u32     rsvd1;
 };
 
+/**
+ * This includes timestamp data which has been collected in Slim Bootloader
+ * stages from the reset vector. In addition, this has TSC frequency in KHz to
+ * calculate each timestamp.
+ *
+ * @rev   : revision of performance_info structure. currently 1.
+ * @rsvd  : padding for alignment
+ * @count : the number of collected timestamp data
+ * @flags : only used in Slim Bootloader
+ * @frequency: tsc frequency in KHz
+ * @timestamp: the array of timestamp data which has 64-bit tsc value
+ */
+struct sbl_performance_info {
+       u8      rev;
+       u8      rsvd[3];
+       u16     count;
+       u16     flags;
+       u32     frequency;
+       u64     timestamp[0];
+};
+
 #endif /* __SLIMBOOTLOADER_ARCH_H__ */