github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/exp/cbmem/timestamps.go (about)

     1  // Copyright 2021 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // cbmem prints out coreboot mem table information in JSON by default,
     6  // and also implements the basic cbmem -list and -console commands.
     7  // TODO: checksum tables.
     8  package main
     9  
    10  import (
    11  	"fmt"
    12  	"os"
    13  	"sort"
    14  	"unsafe"
    15  )
    16  
    17  const (
    18  	TS_START_ROMSTAGE    uint32 = 1
    19  	TS_BEFORE_INITRAM    uint32 = 2
    20  	TS_AFTER_INITRAM     uint32 = 3
    21  	TS_END_ROMSTAGE      uint32 = 4
    22  	TS_START_VBOOT       uint32 = 5
    23  	TS_END_VBOOT         uint32 = 6
    24  	TS_START_COPYRAM     uint32 = 8
    25  	TS_END_COPYRAM       uint32 = 9
    26  	TS_START_RAMSTAGE    uint32 = 10
    27  	TS_START_BOOTBLOCK   uint32 = 11
    28  	TS_END_BOOTBLOCK     uint32 = 12
    29  	TS_START_COPYROM     uint32 = 13
    30  	TS_END_COPYROM       uint32 = 14
    31  	TS_START_ULZMA       uint32 = 15
    32  	TS_END_ULZMA         uint32 = 16
    33  	TS_START_ULZ4F       uint32 = 17
    34  	TS_END_ULZ4F         uint32 = 18
    35  	TS_DEVICE_ENUMERATE  uint32 = 30
    36  	TS_DEVICE_CONFIGURE  uint32 = 40
    37  	TS_DEVICE_ENABLE     uint32 = 50
    38  	TS_DEVICE_INITIALIZE uint32 = 60
    39  	TS_OPROM_INITIALIZE  uint32 = 65
    40  	TS_OPROM_COPY_END    uint32 = 66
    41  	TS_OPROM_END         uint32 = 67
    42  	TS_DEVICE_DONE       uint32 = 70
    43  	TS_CBMEM_POST        uint32 = 75
    44  	TS_WRITE_TABLES      uint32 = 80
    45  	TS_FINALIZE_CHIPS    uint32 = 85
    46  	TS_LOAD_PAYLOAD      uint32 = 90
    47  	TS_ACPI_WAKE_JUMP    uint32 = 98
    48  	TS_SELFBOOT_JUMP     uint32 = 99
    49  	TS_START_POSTCAR     uint32 = 100
    50  	TS_END_POSTCAR       uint32 = 101
    51  	TS_DELAY_START       uint32 = 110
    52  	TS_DELAY_END         uint32 = 111
    53  
    54  	/* 500+ reserved for vendorcode extensions (500-600: google/chromeos) */
    55  	TS_START_COPYVER       uint32 = 501
    56  	TS_END_COPYVER         uint32 = 502
    57  	TS_START_TPMINIT       uint32 = 503
    58  	TS_END_TPMINIT         uint32 = 504
    59  	TS_START_VERIFY_SLOT   uint32 = 505
    60  	TS_END_VERIFY_SLOT     uint32 = 506
    61  	TS_START_HASH_BODY     uint32 = 507
    62  	TS_DONE_LOADING        uint32 = 508
    63  	TS_DONE_HASHING        uint32 = 509
    64  	TS_END_HASH_BODY       uint32 = 510
    65  	TS_START_TPMPCR        uint32 = 511
    66  	TS_END_TPMPCR          uint32 = 512
    67  	TS_START_TPMLOCK       uint32 = 513
    68  	TS_END_TPMLOCK         uint32 = 514
    69  	TS_START_EC_SYNC       uint32 = 515
    70  	TS_EC_HASH_READY       uint32 = 516
    71  	TS_EC_POWER_LIMIT_WAIT uint32 = 517
    72  	TS_END_EC_SYNC         uint32 = 518
    73  	TS_START_COPYVPD       uint32 = 550
    74  	TS_END_COPYVPD_RO      uint32 = 551
    75  	TS_END_COPYVPD_RW      uint32 = 552
    76  
    77  	/* 900-920 reserved for vendorcode extensions (900-940: AMD AGESA) */
    78  	TS_AGESA_INIT_RESET_START  uint32 = 900
    79  	TS_AGESA_INIT_RESET_DONE   uint32 = 901
    80  	TS_AGESA_INIT_EARLY_START  uint32 = 902
    81  	TS_AGESA_INIT_EARLY_DONE   uint32 = 903
    82  	TS_AGESA_INIT_POST_START   uint32 = 904
    83  	TS_AGESA_INIT_POST_DONE    uint32 = 905
    84  	TS_AGESA_INIT_ENV_START    uint32 = 906
    85  	TS_AGESA_INIT_ENV_DONE     uint32 = 907
    86  	TS_AGESA_INIT_MID_START    uint32 = 908
    87  	TS_AGESA_INIT_MID_DONE     uint32 = 909
    88  	TS_AGESA_INIT_LATE_START   uint32 = 910
    89  	TS_AGESA_INIT_LATE_DONE    uint32 = 911
    90  	TS_AGESA_INIT_RTB_START    uint32 = 912
    91  	TS_AGESA_INIT_RTB_DONE     uint32 = 913
    92  	TS_AGESA_INIT_RESUME_START uint32 = 914
    93  	TS_AGESA_INIT_RESUME_DONE  uint32 = 915
    94  	TS_AGESA_S3_LATE_START     uint32 = 916
    95  	TS_AGESA_S3_LATE_DONE      uint32 = 917
    96  	TS_AGESA_S3_FINAL_START    uint32 = 918
    97  	TS_AGESA_S3_FINAL_DONE     uint32 = 919
    98  
    99  	/* 940-950 reserved for vendorcode extensions (940-950: Intel ME) */
   100  	TS_ME_INFORM_DRAM_WAIT uint32 = 940
   101  	TS_ME_INFORM_DRAM_DONE uint32 = 941
   102  
   103  	/* 950+ reserved for vendorcode extensions (950-999: intel/fsp) */
   104  	TS_FSP_MEMORY_INIT_START         uint32 = 950
   105  	TS_FSP_MEMORY_INIT_END           uint32 = 951
   106  	TS_FSP_TEMP_RAM_EXIT_START       uint32 = 952
   107  	TS_FSP_TEMP_RAM_EXIT_END         uint32 = 953
   108  	TS_FSP_SILICON_INIT_START        uint32 = 954
   109  	TS_FSP_SILICON_INIT_END          uint32 = 955
   110  	TS_FSP_BEFORE_ENUMERATE          uint32 = 956
   111  	TS_FSP_AFTER_ENUMERATE           uint32 = 957
   112  	TS_FSP_BEFORE_FINALIZE           uint32 = 958
   113  	TS_FSP_AFTER_FINALIZE            uint32 = 959
   114  	TS_FSP_BEFORE_END_OF_FIRMWARE    uint32 = 960
   115  	TS_FSP_AFTER_END_OF_FIRMWARE     uint32 = 961
   116  	TS_FSP_MULTI_PHASE_SI_INIT_START uint32 = 962
   117  	TS_FSP_MULTI_PHASE_SI_INIT_END   uint32 = 963
   118  
   119  	/* 1000+ reserved for payloads (1000-1200: ChromeOS depthcharge) */
   120  
   121  	/* Depthcharge entry IDs start at 1000 */
   122  	TS_DC_START uint32 = 1000
   123  
   124  	TS_RO_PARAMS_INIT               uint32 = 1001
   125  	TS_RO_VB_INIT                   uint32 = 1002
   126  	TS_RO_VB_SELECT_FIRMWARE        uint32 = 1003
   127  	TS_RO_VB_SELECT_AND_LOAD_KERNEL uint32 = 1004
   128  
   129  	TS_RW_VB_SELECT_AND_LOAD_KERNEL uint32 = 1010
   130  
   131  	TS_VB_SELECT_AND_LOAD_KERNEL uint32 = 1020
   132  	TS_VB_EC_VBOOT_DONE          uint32 = 1030
   133  	TS_VB_STORAGE_INIT_DONE      uint32 = 1040
   134  	TS_VB_READ_KERNEL_DONE       uint32 = 1050
   135  	TS_VB_VBOOT_DONE             uint32 = 1100
   136  
   137  	TS_START_KERNEL         uint32 = 1101
   138  	TS_KERNEL_DECOMPRESSION uint32 = 1102
   139  )
   140  
   141  // TimeStampNames map timestamp ints to names.
   142  var TimeStampNames = map[uint32]string{
   143  	0:                    "1st timestamp",
   144  	TS_START_ROMSTAGE:    "start of romstage",
   145  	TS_BEFORE_INITRAM:    "before RAM initialization",
   146  	TS_AFTER_INITRAM:     "after RAM initialization",
   147  	TS_END_ROMSTAGE:      "end of romstage",
   148  	TS_START_VBOOT:       "start of verified boot",
   149  	TS_END_VBOOT:         "end of verified boot",
   150  	TS_START_COPYRAM:     "starting to load ramstage",
   151  	TS_END_COPYRAM:       "finished loading ramstage",
   152  	TS_START_RAMSTAGE:    "start of ramstage",
   153  	TS_START_BOOTBLOCK:   "start of bootblock",
   154  	TS_END_BOOTBLOCK:     "end of bootblock",
   155  	TS_START_COPYROM:     "starting to load romstage",
   156  	TS_END_COPYROM:       "finished loading romstage",
   157  	TS_START_ULZMA:       "starting LZMA decompress (ignore for x86)",
   158  	TS_END_ULZMA:         "finished LZMA decompress (ignore for x86)",
   159  	TS_START_ULZ4F:       "starting LZ4 decompress (ignore for x86)",
   160  	TS_END_ULZ4F:         "finished LZ4 decompress (ignore for x86)",
   161  	TS_DEVICE_ENUMERATE:  "device enumeration",
   162  	TS_DEVICE_CONFIGURE:  "device configuration",
   163  	TS_DEVICE_ENABLE:     "device enable",
   164  	TS_DEVICE_INITIALIZE: "device initialization",
   165  	TS_OPROM_INITIALIZE:  "Option ROM initialization",
   166  	TS_OPROM_COPY_END:    "Option ROM copy done",
   167  	TS_OPROM_END:         "Option ROM run done",
   168  	TS_DEVICE_DONE:       "device setup done",
   169  	TS_CBMEM_POST:        "cbmem post",
   170  	TS_WRITE_TABLES:      "write tables",
   171  	TS_FINALIZE_CHIPS:    "finalize chips",
   172  	TS_LOAD_PAYLOAD:      "load payload",
   173  	TS_ACPI_WAKE_JUMP:    "ACPI wake jump",
   174  	TS_SELFBOOT_JUMP:     "selfboot jump",
   175  	TS_DELAY_START:       "Forced delay start",
   176  	TS_DELAY_END:         "Forced delay end",
   177  
   178  	TS_START_COPYVER:     "starting to load verstage",
   179  	TS_END_COPYVER:       "finished loading verstage",
   180  	TS_START_TPMINIT:     "starting to initialize TPM",
   181  	TS_END_TPMINIT:       "finished TPM initialization",
   182  	TS_START_VERIFY_SLOT: "starting to verify keyblock/preamble (RSA)",
   183  	TS_END_VERIFY_SLOT:   "finished verifying keyblock/preamble (RSA)",
   184  	TS_START_HASH_BODY:   "starting to verify body (load+SHA2+RSA) ",
   185  	TS_DONE_LOADING:      "finished loading body",
   186  	TS_DONE_HASHING:      "finished calculating body hash (SHA2)",
   187  	TS_END_HASH_BODY:     "finished verifying body signature (RSA)",
   188  	TS_START_TPMPCR:      "starting TPM PCR extend",
   189  	TS_END_TPMPCR:        "finished TPM PCR extend",
   190  	TS_START_TPMLOCK:     "starting locking TPM",
   191  	TS_END_TPMLOCK:       "finished locking TPM",
   192  
   193  	TS_START_COPYVPD:  "starting to load Chrome OS VPD",
   194  	TS_END_COPYVPD_RO: "finished loading Chrome OS VPD (RO)",
   195  	TS_END_COPYVPD_RW: "finished loading Chrome OS VPD (RW)",
   196  
   197  	TS_START_EC_SYNC:       "starting EC software sync",
   198  	TS_EC_HASH_READY:       "EC vboot hash ready",
   199  	TS_EC_POWER_LIMIT_WAIT: "waiting for EC to allow higher power draw",
   200  	TS_END_EC_SYNC:         "finished EC software sync",
   201  
   202  	TS_DC_START:                     "depthcharge start",
   203  	TS_RO_PARAMS_INIT:               "RO parameter init",
   204  	TS_RO_VB_INIT:                   "RO vboot init",
   205  	TS_RO_VB_SELECT_FIRMWARE:        "RO vboot select firmware",
   206  	TS_RO_VB_SELECT_AND_LOAD_KERNEL: "RO vboot select&load kernel",
   207  	TS_RW_VB_SELECT_AND_LOAD_KERNEL: "RW vboot select&load kernel",
   208  	TS_VB_SELECT_AND_LOAD_KERNEL:    "vboot select&load kernel",
   209  	TS_VB_EC_VBOOT_DONE:             "finished EC verification",
   210  	TS_VB_STORAGE_INIT_DONE:         "finished storage device initialization",
   211  	TS_VB_READ_KERNEL_DONE:          "finished reading kernel from disk",
   212  	TS_VB_VBOOT_DONE:                "finished vboot kernel verification",
   213  	TS_KERNEL_DECOMPRESSION:         "starting kernel decompression/relocation",
   214  	TS_START_KERNEL:                 "jumping to kernel",
   215  
   216  	/* AMD AGESA related timestamps */
   217  	TS_AGESA_INIT_RESET_START:  "calling AmdInitReset",
   218  	TS_AGESA_INIT_RESET_DONE:   "back from AmdInitReset",
   219  	TS_AGESA_INIT_EARLY_START:  "calling AmdInitEarly",
   220  	TS_AGESA_INIT_EARLY_DONE:   "back from AmdInitEarly",
   221  	TS_AGESA_INIT_POST_START:   "calling AmdInitPost",
   222  	TS_AGESA_INIT_POST_DONE:    "back from AmdInitPost",
   223  	TS_AGESA_INIT_ENV_START:    "calling AmdInitEnv",
   224  	TS_AGESA_INIT_ENV_DONE:     "back from AmdInitEnv",
   225  	TS_AGESA_INIT_MID_START:    "calling AmdInitMid",
   226  	TS_AGESA_INIT_MID_DONE:     "back from AmdInitMid",
   227  	TS_AGESA_INIT_LATE_START:   "calling AmdInitLate",
   228  	TS_AGESA_INIT_LATE_DONE:    "back from AmdInitLate",
   229  	TS_AGESA_INIT_RTB_START:    "calling AmdInitRtb/AmdS3Save",
   230  	TS_AGESA_INIT_RTB_DONE:     "back from AmdInitRtb/AmdS3Save",
   231  	TS_AGESA_INIT_RESUME_START: "calling AmdInitResume",
   232  	TS_AGESA_INIT_RESUME_DONE:  "back from AmdInitResume",
   233  	TS_AGESA_S3_LATE_START:     "calling AmdS3LateRestore",
   234  	TS_AGESA_S3_LATE_DONE:      "back from AmdS3LateRestore",
   235  	TS_AGESA_S3_FINAL_START:    "calling AmdS3FinalRestore",
   236  	TS_AGESA_S3_FINAL_DONE:     "back from AmdS3FinalRestore",
   237  
   238  	/* Intel ME related timestamps */
   239  	TS_ME_INFORM_DRAM_WAIT: "waiting for ME acknowledgement of raminit",
   240  	TS_ME_INFORM_DRAM_DONE: "finished waiting for ME response",
   241  
   242  	/* FSP related timestamps */
   243  	TS_FSP_MEMORY_INIT_START:      "calling FspMemoryInit",
   244  	TS_FSP_MEMORY_INIT_END:        "returning from FspMemoryInit",
   245  	TS_FSP_TEMP_RAM_EXIT_START:    "calling FspTempRamExit",
   246  	TS_FSP_TEMP_RAM_EXIT_END:      "returning from FspTempRamExit",
   247  	TS_FSP_SILICON_INIT_START:     "calling FspSiliconInit",
   248  	TS_FSP_SILICON_INIT_END:       "returning from FspSiliconInit",
   249  	TS_FSP_BEFORE_ENUMERATE:       "calling FspNotify(AfterPciEnumeration)",
   250  	TS_FSP_AFTER_ENUMERATE:        "returning from FspNotify(AfterPciEnumeration)",
   251  	TS_FSP_BEFORE_FINALIZE:        "calling FspNotify(ReadyToBoot)",
   252  	TS_FSP_AFTER_FINALIZE:         "returning from FspNotify(ReadyToBoot)",
   253  	TS_FSP_BEFORE_END_OF_FIRMWARE: "calling FspNotify(EndOfFirmware)",
   254  	TS_FSP_AFTER_END_OF_FIRMWARE:  "returning from FspNotify(EndOfFirmware)",
   255  	TS_START_POSTCAR:              "start of postcar",
   256  	TS_END_POSTCAR:                "end of postcar",
   257  }
   258  
   259  // ByTime implements sort.Interface for []TS based on
   260  // the EntryStamp field.
   261  type ByTime []TS
   262  
   263  func (bt ByTime) Len() int           { return len(bt) }
   264  func (bt ByTime) Swap(i, j int)      { bt[i], bt[j] = bt[j], bt[i] }
   265  func (bt ByTime) Less(i, j int) bool { return int64(bt[i].EntryStamp) < int64(bt[j].EntryStamp) }
   266  
   267  func (c *CBmem) readTimeStamps(f *os.File) (*TimeStamps, error) {
   268  	if c.TimeStampsTable.Addr == 0 {
   269  		return nil, fmt.Errorf("no time stamps")
   270  	}
   271  	var t TSHeader
   272  	a := int64(c.TimeStampsTable.Addr)
   273  	r, err := newOffsetReader(f, a, int(unsafe.Sizeof(t)))
   274  	if err != nil {
   275  		return nil, fmt.Errorf("creating TSHeader offsetReader @ %#x: %v", a, err)
   276  	}
   277  	if err := readOne(r, &t, a); err != nil {
   278  		return nil, fmt.Errorf("failed to read TSTable: %v", err)
   279  	}
   280  	a += int64(unsafe.Sizeof(t))
   281  	stamps := make([]TS, t.NumEntries)
   282  	ts := &TimeStamps{TS: []TS{{EntryID: 0, EntryStamp: t.BaseTime}}, TSHeader: t}
   283  	if r, err = newOffsetReader(f, a, len(stamps)*int(unsafe.Sizeof(stamps[0]))); err != nil {
   284  		return nil, fmt.Errorf("newOffsetReader for %d timestamps: %v", t.NumEntries, err)
   285  	}
   286  	if err := readOne(r, stamps, a); err != nil {
   287  		return nil, fmt.Errorf("failed to read %d stamps: %v", t.NumEntries, err)
   288  	}
   289  	// Timestamps are unsigned. But we're seeing on one machine the first several
   290  	// timestamps have the high order 32 bits set (!). To adjust them, it seems the
   291  	// thing that works is take the first one as the base, and treat it as int64, and
   292  	// subtract that base from each value.
   293  	base := int64(stamps[0].EntryStamp)
   294  	for i := range stamps {
   295  		stamps[i].EntryStamp = uint64(int64(stamps[i].EntryStamp)-base) + t.BaseTime
   296  	}
   297  	ts.TS = append(ts.TS, stamps...)
   298  	sort.Sort(ByTime(ts.TS))
   299  	return ts, nil
   300  }