hpm_parse.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/bin/env python3
  2. import os
  3. import sys
  4. import argparse
  5. from prettytable import *
  6. import json
  7. HPM_EVENTS= [
  8. ["Reserved", "Cycle count", "Retired instruction count", "Integer load instruction (includes LR)",
  9. "Integer store instruction (includes SC)", "Atomic memory operation (do not include LR and SC)",
  10. "System instruction", "Integer computational instruction(excluding multiplication/division/remainder)",
  11. "Conditional branch", "Taken conditional branch", "JAL instruction", "JALR instruction", "Return instruction",
  12. "Control transfer instruction (CBR+JAL+JALR)", "-", "Integer multiplication instruction",
  13. "Integer division/remainder instruction", "Floating-point load instruction", "Floating-point store instruction",
  14. "Floating-point addition/subtraction", "Floating-point multiplication",
  15. "Floating-point fused multiply-add (FMADD, FMSUB, FNMSUB, FNMADD)", "Floating-point division or square-root",
  16. "Other floating-point instruction", "Conditional branch prediction fail", "JAL prediction fail", "JALR prediction fail"],
  17. ["Reserved", "Icache miss", "Dcache miss", "ITLB miss", "DTLB miss", "Main TLB miss"]
  18. ]
  19. HPM_MEVENT_ENABLE = 0x8
  20. HPM_SEVENT_ENABLE = 0x4
  21. HPM_UEVENT_ENABLE = 0x1
  22. def get_hpm_evmode(ena):
  23. evmode = ""
  24. if ena & HPM_MEVENT_ENABLE:
  25. evmode += "M"
  26. if ena & HPM_SEVENT_ENABLE:
  27. evmode += "S"
  28. if ena & HPM_UEVENT_ENABLE:
  29. evmode += "U"
  30. return evmode
  31. def get_hpm_event(sel, idx):
  32. if sel >= len(HPM_EVENTS):
  33. return "INVAILD"
  34. if idx >= len(HPM_EVENTS[sel]):
  35. return "INVAILD"
  36. return HPM_EVENTS[sel][idx]
  37. def parse_hpm(logfile):
  38. if os.path.isfile(logfile) == False:
  39. return dict()
  40. hpmrecords = dict()
  41. with open(logfile, "r") as lf:
  42. for line in lf.readlines():
  43. if line.startswith("HPM"):
  44. hpmkey, proc, hpmcount = line.split(",")
  45. hpmkey = hpmkey.strip()
  46. proc = proc.strip()
  47. hpmcount = hpmcount.strip()
  48. if proc not in hpmrecords:
  49. hpmrecords[proc] = dict()
  50. hpmrecords[proc][hpmkey] = hpmcount
  51. return hpmrecords
  52. def analyze_hpm(records):
  53. x = PrettyTable()
  54. x.set_style(MARKDOWN)
  55. x.field_names = ["Process", "HPM", "Mode", "Event", "Counts"]
  56. parsed_hpm = dict()
  57. csv_hpm = [x.field_names]
  58. for proc in records:
  59. parsed_hpm[proc] = dict()
  60. for hpmkey in records[proc]:
  61. hpmcounter, hpmevent = hpmkey.split(":")
  62. hpmevent = int(hpmevent, 16)
  63. # event_sel: 3:0
  64. event_sel = hpmevent & 0xF
  65. # event_idx: 8:4
  66. event_idx = (hpmevent >> 4) & 0x1F
  67. # event_ena: m/rsv/s/u 31:28
  68. event_ena = (hpmevent >> 28) & 0xF
  69. event_name = get_hpm_event(event_sel, event_idx)
  70. event_mode = get_hpm_evmode(event_ena)
  71. event_count = int(records[proc][hpmkey])
  72. x.add_row([proc, hpmcounter, event_mode, event_name, event_count])
  73. csv_hpm.append([proc, hpmcounter, event_mode, event_name, event_count])
  74. if hpmcounter not in parsed_hpm[proc]:
  75. parsed_hpm[proc][hpmcounter] = list()
  76. parsed_hpm[proc][hpmcounter].append((event_mode, event_name, event_count))
  77. return parsed_hpm, csv_hpm, x
  78. def save_csv(csvlist, csvfile):
  79. with open(csvfile, "w") as cf:
  80. for csvline in csvlist:
  81. line = ",".join(map(str, csvline))
  82. cf.write(line + "\n")
  83. pass
  84. if __name__ == '__main__':
  85. parser = argparse.ArgumentParser(description="Nuclei SDK HPM Log Parsing")
  86. parser.add_argument('--logfile', required=True, help="log file of hpm running")
  87. args = parser.parse_args()
  88. hpmrecords = parse_hpm(args.logfile)
  89. if len(hpmrecords) == 0:
  90. print("None records found in %s!" % (args.logfile))
  91. sys.exit(1)
  92. parsedhpm, csv_hpm, table = analyze_hpm(hpmrecords)
  93. print(table)
  94. hpmresult = {"records": hpmrecords, "parsed": parsedhpm}
  95. hpmrstfile = args.logfile + ".json"
  96. with open(hpmrstfile, "w") as cf:
  97. json.dump(hpmresult, cf, indent=4)
  98. print("\nParsed HPM event saved into %s" %(hpmrstfile))
  99. hpmcsvfile = args.logfile + ".csv"
  100. save_csv(csv_hpm, hpmcsvfile)
  101. print("Save HPM CSV to %s" % (hpmcsvfile))
  102. sys.exit(0)