{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Using plotly\n", "import plotly.graph_objects as go\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define data" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Convert the following into an appropriate data object, which is searchable, from start, to end, to name and label\n", "# - 0x00000000 to 0x00020000: BootROM\n", "# - 0x000002c0: BL1 boot entry point\n", "# - 0x00012848: bootrom authentication function\n", "# - 0x00019310: BL1 boot function\n", "# - 0x02069000: First debugger location\n", "\n", "data = [\n", " {\"start\": 0x00000000, \"end\": 0x00020000, \"name\": \"BootROM\"},\n", " {\"start\": 0x000002c0, \"name\": \"BL1 boot entry point\"},\n", " {\"start\": 0x00012848, \"name\": \"bootrom authentication function\"},\n", " {\"start\": 0x00019310, \"name\": \"BL1 boot function\"},\n", " {\"start\": 0x02069000, \"name\": \"First debugger location\"}\n", "]\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create block diagram" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "mode": "text", "text": "BootROM", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 0.5 ] }, { "mode": "text", "text": "BL1 boot entry point", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 1.5 ] }, { "mode": "text", "text": "Boot USB function", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 2.5 ] }, { "mode": "text", "text": "bootrom authentication function", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 3.5 ] }, { "mode": "text", "text": "BL1 boot function", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 4.5 ] }, { "mode": "text", "text": "Boot USB return address", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 5.5 ] }, { "mode": "text", "text": "Event buffer pointer", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 6.5 ] }, { "mode": "text", "text": "BL1 pointer", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 7.5 ] }, { "mode": "text", "text": "First debugger location", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 8.5 ] }, { "mode": "text", "text": "End of memory stack", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 9.5 ] }, { "mode": "text", "text": "Frederic Destination pointer", "textposition": "middle center", "type": "scatter", "x": [ 0.5 ], "y": [ 10.5 ] } ], "layout": { "autosize": true, "height": 1200, "margin": { "b": 20, "l": 200, "r": 20, "t": 20 }, "shapes": [ { "fillcolor": "#12e884", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 0, "y1": 1 }, { "fillcolor": "#db08ae", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 1, "y1": 2 }, { "fillcolor": "#50034a", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 2, "y1": 3 }, { "fillcolor": "#547ec9", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 3, "y1": 4 }, { "fillcolor": "#daac51", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 4, "y1": 5 }, { "fillcolor": "#8704ee", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 5, "y1": 6 }, { "fillcolor": "#86785f", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 6, "y1": 7 }, { "fillcolor": "#e33d72", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 7, "y1": 8 }, { "fillcolor": "#2f63f4", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 8, "y1": 9 }, { "fillcolor": "#1258f9", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 9, "y1": 10 }, { "fillcolor": "#109cff", "layer": "below", "line": { "width": 2 }, "opacity": 0.5, "type": "rect", "x0": 0, "x1": 1, "y0": 10, "y1": 11 } ], "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "width": 800, "xaxis": { "range": [ 0, 1 ], "tickvals": [ 0, 1 ] }, "yaxis": { "ticktext": [ "0x0", "0x2c0 \n 0x12c0", "0x64e0 \n 0x74e0", "0x12848 \n 0x13848", "0x19310 \n 0x1a310", "0x2020f60 \n 0x2021f60", "0x2021578 \n 0x2022578", "0x2021800 \n 0x2022800", "0x2069000 \n 0x206a000", "0x206f000 \n 0x2070000", "0x20c0000 \n 0x20c1000", "0x20c1000" ], "tickvals": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] } } } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import plotly.graph_objects as go\n", "\n", "# Sample data structure\n", "data = [\n", " {'start': 0x00000000, 'end': 0x00020000, 'name': 'BootROM'},\n", " {'start': 0x000002c0, 'name': 'BL1 boot entry point'},\n", " {'start': 0x000064e0, 'name': 'Boot USB function'},\n", " {'start': 0x00012848, 'name': 'bootrom authentication function'},\n", " {'start': 0x00019310, 'name': 'BL1 boot function'},\n", " {'start': 0x02069000, 'name': 'First debugger location'},\n", " {'end': 0x02070000, 'name': 'End of memory stack'},\n", " {'start': 0x02021578, 'name': 'Event buffer pointer'},\n", " {'start': 0x02020f60, 'name': 'Boot USB return address'},\n", " {'start': 0x02021800, 'name': 'BL1 pointer'},\n", " {'start': 0x020c0000, 'name': 'Frederic Destination pointer'},\n", "]\n", "\n", "# _evtbuf_ptr: .dword 0x02021578\n", "# _boot_usb_ra: .dword 0x02020f60\n", "# _bl1_ptr: .dword 0x02021800\n", "# _original_ra: .dword 0x00007c68\n", "# _boot_usb: .dword 0x000064e0\n", "# _dst_ptr: .dword 0x020c0000\n", "# _auth_bl1: .dword 0x00012848\n", "# _jmp_bl1: .dword 0x000002c0\n", "\n", "# If there is no end, set it to start + 0x1000\n", "for d in data:\n", " if 'end' not in d:\n", " d['end'] = d['start'] + 0x1000\n", "\n", "# If there is no start, set it to end - 0x1000\n", "for d in data:\n", " if 'start' not in d:\n", " d['start'] = d['end'] - 0x1000\n", "\n", "# Sort the data by start\n", "data = sorted(data, key=lambda x: x['start'])\n", "\n", "import random\n", "\n", "def random_color():\n", " return f'#{random.randint(0, 0xFFFFFF):06x}'\n", "\n", "# Create a square for each index\n", "fig = go.Figure()\n", "for i, d in enumerate(data):\n", " fig.add_shape(\n", " type=\"rect\",\n", " x0=0,\n", " y0=i,\n", " x1=0 + 1,\n", " y1=i+1,\n", " line=dict(width=2),\n", " fillcolor=random_color(),\n", " opacity=0.5,\n", " layer=\"below\"\n", " )\n", "\n", " fig.add_trace(go.Scatter\n", " (\n", " x=[0.5],\n", " y=[i+ 0.5],\n", " text=d['name'],\n", " mode=\"text\",\n", " textposition=\"middle center\"\n", " ))\n", "\n", "fig.update_layout(\n", " width=800,\n", " height=1200,\n", " autosize=True,\n", " margin=dict(l=200, r=20, t=20, b=20)\n", ")\n", "\n", "fig.update_xaxes(\n", " range=[0, 1],\n", " tickvals=[0, 1],\n", ")\n", "\n", "labels = [hex(value) for d in data for value in (d.get('start'), d['end']) if 'end' in d]\n", "\n", "# If label is not the first in labels or the last entry, merge the label with the next label\n", "labelset = []\n", "for i in range(0, len(labels), 2):\n", " if i == 0:\n", " labelset.append(labels[i])\n", " elif i == len(labels) - 1:\n", " labelset.append(labels[i])\n", " else:\n", " labelset.append(f\"{labels[i]} \\n {labels[i+1]}\")\n", "labelset.append(labels[-1])\n", "\n", "fig.update_yaxes(\n", " tickvals=[i for i in range(len(data)+1)], \n", " ticktext=labelset\n", ")\n", "\n", "fig.show()" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['0x0',\n", " '0x2c0 - 0x12c0',\n", " '0x12848 - 0x13848',\n", " '0x19310 - 0x1a310',\n", " '0x2069000 - 0x206a000',\n", " '0x206f000 - 0x2070000']" ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'0x2070000'" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "labels[-1]" ] } ], "metadata": { "kernelspec": { "display_name": "venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 2 }