cb_timestamps.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2013 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/dl.h>
  19. #include <grub/misc.h>
  20. #include <grub/command.h>
  21. #include <grub/i18n.h>
  22. #include <grub/coreboot/lbio.h>
  23. #include <grub/i386/tsc.h>
  24. GRUB_MOD_LICENSE ("GPLv3+");
  25. static grub_uint32_t
  26. tsc2ms (grub_uint64_t tsc)
  27. {
  28. grub_uint64_t ah = tsc >> 32;
  29. grub_uint64_t al = tsc & 0xffffffff;
  30. return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate;
  31. }
  32. static const char *descs[] = {
  33. [1] = "romstage",
  34. [2] = "before RAM init",
  35. [3] = "after RAM init",
  36. [4] = "end of romstage",
  37. [5] = "start of verified boot",
  38. [6] = "end of verified boot",
  39. [8] = "start of RAM copy",
  40. [9] = "end of RAM copy",
  41. [10] = "start of ramstage",
  42. [11] = "start of bootblock",
  43. [12] = "end of bootblock",
  44. [13] = "starting to load romstage",
  45. [14] = "finished loading romstage",
  46. [15] = "starting LZMA decompress (ignore for x86)",
  47. [16] = "finished LZMA decompress (ignore for x86)",
  48. [30] = "device enumerate",
  49. [40] = "device configure",
  50. [50] = "device enable",
  51. [60] = "device initialize",
  52. [70] = "device done",
  53. [75] = "CBMEM POST",
  54. [80] = "writing tables",
  55. [90] = "loading payload",
  56. [98] = "wake jump",
  57. [99] = "selfboot jump",
  58. };
  59. static int
  60. iterate_linuxbios_table (grub_linuxbios_table_item_t table_item,
  61. void *data)
  62. {
  63. int *available = data;
  64. grub_uint64_t last_tsc = 0;
  65. struct grub_linuxbios_timestamp_table *ts_table;
  66. unsigned i;
  67. if (table_item->tag != GRUB_LINUXBIOS_MEMBER_TIMESTAMPS)
  68. return 0;
  69. *available = 1;
  70. ts_table = (struct grub_linuxbios_timestamp_table *) (grub_addr_t)
  71. *(grub_uint64_t *) (table_item + 1);
  72. for (i = 0; i < ts_table->used; i++)
  73. {
  74. grub_uint32_t tmabs = tsc2ms (ts_table->entries[i].tsc);
  75. grub_uint32_t tmrel = tsc2ms (ts_table->entries[i].tsc - last_tsc);
  76. last_tsc = ts_table->entries[i].tsc;
  77. grub_printf ("%3d.%03ds %2d.%03ds %02d %s\n",
  78. tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000,
  79. ts_table->entries[i].id,
  80. (ts_table->entries[i].id < ARRAY_SIZE (descs)
  81. && descs[ts_table->entries[i].id])
  82. ? descs[ts_table->entries[i].id] : "");
  83. }
  84. return 1;
  85. }
  86. static grub_err_t
  87. grub_cmd_coreboot_boottime (struct grub_command *cmd __attribute__ ((unused)),
  88. int argc __attribute__ ((unused)),
  89. char *argv[] __attribute__ ((unused)))
  90. {
  91. int available = 0;
  92. grub_linuxbios_table_iterate (iterate_linuxbios_table, &available);
  93. if (!available)
  94. {
  95. grub_puts_ (N_("No boot time statistics is available\n"));
  96. return 0;
  97. }
  98. return 0;
  99. }
  100. static grub_command_t cmd_boottime;
  101. GRUB_MOD_INIT(cbtime)
  102. {
  103. cmd_boottime =
  104. grub_register_command ("coreboot_boottime", grub_cmd_coreboot_boottime,
  105. 0, N_("Show coreboot boot time statistics."));
  106. }
  107. GRUB_MOD_FINI(cbtime)
  108. {
  109. grub_unregister_command (cmd_boottime);
  110. }