Index: tools/perf/process_halts.sh
===================================================================
--- tools/perf/process_halts.sh	(revision f2b18d0157ce83fe51957b1e7247726c471d9b76)
+++ tools/perf/process_halts.sh	(revision f2b18d0157ce83fe51957b1e7247726c471d9b76)
@@ -0,0 +1,15 @@
+#!/bin/bash -e
+
+DIR=$( dirname "${BASH_SOURCE[0]}")
+echo $DIR
+tmpfile=$(mktemp)
+function finish {
+  rm -rf "$tmpfile"
+}
+trap finish EXIT
+
+# split the wanted and unwanted output
+awk "/^Processor|^PH:[0-9]+ - [0-9]+ [0-9]+/ {print \$0 > \"$tmpfile\"; next}{print \$0; fflush()}"
+
+# pass the data to the python scirpt
+$DIR/view_halts.py $tmpfile
Index: tools/perf/view_halts.py
===================================================================
--- tools/perf/view_halts.py	(revision f2b18d0157ce83fe51957b1e7247726c471d9b76)
+++ tools/perf/view_halts.py	(revision f2b18d0157ce83fe51957b1e7247726c471d9b76)
@@ -0,0 +1,110 @@
+#!/usr/bin/python3
+import numpy as np
+import re
+import sys, getopt
+import argparse
+
+class Proc:
+	def __init__(self, id, name, address):
+		self.name    = name
+		self.address = address
+		self.id      = id
+
+class Point:
+	def __init__(self, time, on):
+		self.time = time
+		self.on = on
+
+processors = {}
+data = {}
+
+#--------------------------------------------------------------------------------
+# Parse data
+with open(sys.argv[1], "r") as f:
+	for line in f:
+		match = re.match("Processor : ([0-9]+) - (.*) \((0x[0-9a-f]+)\)", line)
+		if match :
+			id = int(match.group(1))
+			processors[id] = Proc(id, match.group(2), match.group(3))
+			continue
+
+		match = re.match("PH:([0-9]+) - ([0-9]+) ([0-9]+)", line)
+		if match :
+			id = int(match.group(1))
+			if not id in data:
+				data[id] = []
+			data[id].append(Point(int(match.group(2)), int(match.group(3))))
+			continue
+
+		print("WARNING : line '%s' filterred not matched" % line, file=sys.stderr)
+
+#--------------------------------------------------------------------------------
+# Check data
+for d in data:
+	if not d in processors:
+		print("WARNING : unkown processor '%s'" % d, file=sys.stderr)
+
+	prevT = data[d][0].time
+	prevO = data[d][0].on
+	for p in data[d][1:]:
+		if prevT > p.time:
+			print("WARNING : Time is inconsistant for Proc '%s'" % d, file=sys.stderr)
+
+		if prevO == p.on:
+			print("WARNING : State is inconsistant for Proc '%s' at %s-%s" % (d, prevT, p.time), file=sys.stderr)
+
+		prevT = p.time
+		prevO = p.on
+
+
+#--------------------------------------------------------------------------------
+# Convert data to series
+offset = min(data)
+print(offset)
+
+series=dict() ## dict of pairs of arrays
+for d in data:
+	series[d] = ([], [], [])
+	for p in data[d]:
+		series[d][0].append( p.time )
+		series[d][1].append(p.on + d - offset)
+		series[d][2].append(d - offset)
+
+#--------------------------------------------------------------------------------
+# setup matplotlib
+import matplotlib as mpl
+mpl.use('Agg')
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+plt.style.use('dark_background')
+
+#--------------------------------------------------------------------------------
+# setup plot
+dots_per_inch = 2000
+height_inches = 5
+width_inches = 12
+fig = plt.figure(figsize=(width_inches, height_inches), dpi=dots_per_inch)
+print('number of series={}'.format(len(series)))
+for s, xy in series.items():
+	print('    plotting series {} with {} points'.format(s, len(xy[0])))
+	plt.fill_between(xy[0], xy[1], xy[2], step="post", alpha=0.4)
+	plt.step(xy[0], xy[1], where='post')
+
+#--------------------------------------------------------------------------------
+# y axis major, minor
+ax = plt.gca()
+ax.grid(which='major', axis='y', linestyle='-', color='lightgray')
+ax.yaxis.set_minor_locator(ticker.AutoMinorLocator())
+ax.grid(which='minor', axis='y', linestyle='dotted', color='gray')
+
+#--------------------------------------------------------------------------------
+# x axis major, minor
+ax.grid(which='major', axis='x', linestyle='-', color='lightgray')
+ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
+ax.grid(which='minor', axis='x', linestyle='dotted', color='gray')
+
+#--------------------------------------------------------------------------------
+# do the plot
+plt.tight_layout()
+print("saving figure image %s\n" % "out.svg")
+plt.savefig("out.svg")
