mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-10 17:49:40 +00:00
Compare commits
1069 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf974ffcc2 | ||
|
|
a90513c71d | ||
|
|
27838bf4e0 | ||
|
|
9f113278ee | ||
|
|
5739d0ee4c | ||
|
|
ace4b331e7 | ||
|
|
ee01458bc4 | ||
|
|
16aebb0c5d | ||
|
|
43cea334c2 | ||
|
|
561ce0d559 | ||
|
|
5bccbff58b | ||
|
|
72a8aa325f | ||
|
|
2b0cc18899 | ||
|
|
2b818a5116 | ||
|
|
19e47c804f | ||
|
|
b537e36696 | ||
|
|
e7cef36819 | ||
|
|
a0973894e8 | ||
|
|
edf9f269d4 | ||
|
|
c17ebc09c4 | ||
|
|
7dfe5be985 | ||
|
|
4e086328ee | ||
|
|
aa18675760 | ||
|
|
4bbb62d6fa | ||
|
|
5a0fad4901 | ||
|
|
3a8d8ab2d1 | ||
|
|
83ae005c70 | ||
|
|
81b16de62b | ||
|
|
2d3941a43e | ||
|
|
240feadc0c | ||
|
|
be59d1c9c2 | ||
|
|
01106c82e0 | ||
|
|
e94a86fcfb | ||
|
|
63d509d422 | ||
|
|
e56730ee25 | ||
|
|
0f2a339e0b | ||
|
|
70954f89b4 | ||
|
|
622db82af5 | ||
|
|
10576b064a | ||
|
|
7586303ee8 | ||
|
|
5e074a5cbd | ||
|
|
0b59876919 | ||
|
|
ced1ee94a4 | ||
|
|
b03a1f7ac2 | ||
|
|
47ee830867 | ||
|
|
4db59dc013 | ||
|
|
503988e3a7 | ||
|
|
dabf132d31 | ||
|
|
54b5b5a42f | ||
|
|
60ab87875c | ||
|
|
122a99a6fe | ||
|
|
b11da036d1 | ||
|
|
e04ee4dcc3 | ||
|
|
9ad48d30dc | ||
|
|
8803e6f495 | ||
|
|
df12e9fd79 | ||
|
|
ade6877a7d | ||
|
|
b38b43eef9 | ||
|
|
f9b912d365 | ||
|
|
6c97d86610 | ||
|
|
6299161980 | ||
|
|
31b514f8df | ||
|
|
853ae9d5fe | ||
|
|
5a02c43cc1 | ||
|
|
c2c0030f1b | ||
|
|
e048f5b822 | ||
|
|
9c3e0ed23b | ||
|
|
0e39c24f28 | ||
|
|
25871f4e48 | ||
|
|
014d92dc13 | ||
|
|
5e5f277e21 | ||
|
|
f3c14063c3 | ||
|
|
763ee1b4ed | ||
|
|
cd52174d82 | ||
|
|
bb3b09beb9 | ||
|
|
a6421bec2b | ||
|
|
642933b3d9 | ||
|
|
1100da1a1d | ||
|
|
5cc166254d | ||
|
|
b6f93dbc7d | ||
|
|
6a0782d962 | ||
|
|
f065776565 | ||
|
|
277dbb1b71 | ||
|
|
e05d60be7d | ||
|
|
b0f3fa1ffd | ||
|
|
6b48fec247 | ||
|
|
aa09f9cde3 | ||
|
|
bd30a120ae | ||
|
|
8b725c190b | ||
|
|
0aedc66ed0 | ||
|
|
81c8b88dc3 | ||
|
|
67d8d461bd | ||
|
|
5309211043 | ||
|
|
f274e1aaa0 | ||
|
|
9fd4034855 | ||
|
|
003b63990f | ||
|
|
2cd620b521 | ||
|
|
0841b70dc4 | ||
|
|
986ef9f085 | ||
|
|
d8ee4f1e32 | ||
|
|
3eb1de4055 | ||
|
|
0e4ae4d081 | ||
|
|
95a3305bd4 | ||
|
|
f7d196f36d | ||
|
|
9887fbbdac | ||
|
|
6aca81e534 | ||
|
|
51d5584829 | ||
|
|
2dc1a26f1c | ||
|
|
adfe5f7d14 | ||
|
|
b6b8320518 | ||
|
|
f270605936 | ||
|
|
d2bc99189b | ||
|
|
4774db37bd | ||
|
|
59f9907646 | ||
|
|
ffb0f8ac1d | ||
|
|
a0b305a7e4 | ||
|
|
65bcf4f4c6 | ||
|
|
6001cc3a41 | ||
|
|
0a874d31a9 | ||
|
|
6155304d7f | ||
|
|
ac78efff1b | ||
|
|
f212c8b6b7 | ||
|
|
930378058d | ||
|
|
2ac63b85b9 | ||
|
|
a9d64010e3 | ||
|
|
ab9f508ffc | ||
|
|
757738bf23 | ||
|
|
b56f970e0a | ||
|
|
e923ec451e | ||
|
|
d3fe58bcc7 | ||
|
|
7e002af3a9 | ||
|
|
b19432ee53 | ||
|
|
2d1293ff51 | ||
|
|
3d5ee41bb6 | ||
|
|
453537dc33 | ||
|
|
8711881d3c | ||
|
|
bf2f752116 | ||
|
|
95cd3e7c64 | ||
|
|
dd44025dde | ||
|
|
e8181b4d9b | ||
|
|
83b507e672 | ||
|
|
e16c31517e | ||
|
|
d6f56065d5 | ||
|
|
25371439df | ||
|
|
6b0ebd3e47 | ||
|
|
bca5a245a7 | ||
|
|
7592b12979 | ||
|
|
e0af5afd4f | ||
|
|
3753bcd43d | ||
|
|
0cd11e136b | ||
|
|
5b8076510a | ||
|
|
01e513c876 | ||
|
|
cbb28edde3 | ||
|
|
b7bcbf2f46 | ||
|
|
34dfe5604b | ||
|
|
ef2a482c45 | ||
|
|
1e49d3f05c | ||
|
|
eeeff45f70 | ||
|
|
6bcd4a3b10 | ||
|
|
3bb181fb7d | ||
|
|
5fb4c24fe4 | ||
|
|
ff1f499b9f | ||
|
|
6eca8c6c85 | ||
|
|
e31731cd37 | ||
|
|
d669d93d81 | ||
|
|
cb5a83096d | ||
|
|
468927a30f | ||
|
|
0a279b5dba | ||
|
|
167931fc01 | ||
|
|
81f3d9f3d2 | ||
|
|
37cb28e910 | ||
|
|
b56e34c3d2 | ||
|
|
33c3513184 | ||
|
|
a8f259fbad | ||
|
|
686e445c9b | ||
|
|
02ab868dc7 | ||
|
|
1a63f6e737 | ||
|
|
e5652fbf7f | ||
|
|
434aed98d0 | ||
|
|
59280239e9 | ||
|
|
6871741ee0 | ||
|
|
5fb797c201 | ||
|
|
1369aa777b | ||
|
|
13ccf7c9b0 | ||
|
|
1c5f4f3853 | ||
|
|
ef1ce11154 | ||
|
|
61c30822fb | ||
|
|
64328723c8 | ||
|
|
517872e072 | ||
|
|
4ea5b142f4 | ||
|
|
f6fd116274 | ||
|
|
dfec8d0cb2 | ||
|
|
90337d37f7 | ||
|
|
af3b3e2f71 | ||
|
|
10dd66d416 | ||
|
|
9bf3916909 | ||
|
|
ef1a9cd1f7 | ||
|
|
858434940a | ||
|
|
1a4f02f6df | ||
|
|
10dfa43696 | ||
|
|
90295d7c13 | ||
|
|
de0c56b466 | ||
|
|
e816b93c46 | ||
|
|
77a6a0fb87 | ||
|
|
09416e7fe1 | ||
|
|
ea74b06286 | ||
|
|
c767f40875 | ||
|
|
19b9ebe3fd | ||
|
|
8b593489e7 | ||
|
|
ee72dd5f3f | ||
|
|
4e26d65626 | ||
|
|
0ef8a15ed4 | ||
|
|
02e459d5f6 | ||
|
|
aa80cd9d6b | ||
|
|
6f004f1ffd | ||
|
|
1ad7bac9ce | ||
|
|
469f12c645 | ||
|
|
d3f4e65686 | ||
|
|
c5ba5ccd89 | ||
|
|
b35e0dd43c | ||
|
|
dc085fbe2a | ||
|
|
f1f0e50e08 | ||
|
|
d3cfd7b5d9 | ||
|
|
71fedff180 | ||
|
|
7c6ca98358 | ||
|
|
2f8e7f9029 | ||
|
|
af50093b9b | ||
|
|
f5c45c7ebb | ||
|
|
93ac084d4b | ||
|
|
8a934e93c8 | ||
|
|
84f0fa0ed4 | ||
|
|
76d91901cd | ||
|
|
c6b6a8a3a0 | ||
|
|
e359911d60 | ||
|
|
3cbf328fee | ||
|
|
512e7fe290 | ||
|
|
70f6613953 | ||
|
|
566d38c39a | ||
|
|
03162c06ee | ||
|
|
81869ec715 | ||
|
|
7130daf65d | ||
|
|
8f76929643 | ||
|
|
d930b3341d | ||
|
|
54c2a9923b | ||
|
|
24875bda88 | ||
|
|
54fd52a924 | ||
|
|
774d61782f | ||
|
|
f2ef1c3f3b | ||
|
|
f192c194df | ||
|
|
efded3790b | ||
|
|
4d4045674a | ||
|
|
111bead68d | ||
|
|
6e511c8368 | ||
|
|
43cdab9821 | ||
|
|
a1984fed70 | ||
|
|
01ae55f854 | ||
|
|
2ad4fa56ee | ||
|
|
f36273aba7 | ||
|
|
1b08f14add | ||
|
|
a1d30abdf2 | ||
|
|
65c1a6aef9 | ||
|
|
00f889778c | ||
|
|
13a2bc6368 | ||
|
|
15f8b3cca1 | ||
|
|
6abfc0ec46 | ||
|
|
c266a880c3 | ||
|
|
201820376d | ||
|
|
1dd73675e9 | ||
|
|
2329fd3c19 | ||
|
|
e040a1c711 | ||
|
|
fba6f66e1a | ||
|
|
1337980ec3 | ||
|
|
bff7f7b7c3 | ||
|
|
9b15c762c8 | ||
|
|
3691c5e343 | ||
|
|
815e1b0ef9 | ||
|
|
95c37166e7 | ||
|
|
b0a839222b | ||
|
|
aa0a9ff7ee | ||
|
|
a6f841c380 | ||
|
|
0638660e31 | ||
|
|
bc2779f1c1 | ||
|
|
aafc61457f | ||
|
|
6e0aee6c01 | ||
|
|
4dc64331f6 | ||
|
|
ae8ce290c1 | ||
|
|
0f60d24921 | ||
|
|
f5c54341ac | ||
|
|
9e8dcba265 | ||
|
|
3a21e72f32 | ||
|
|
44f79b6bb9 | ||
|
|
f40f1d8183 | ||
|
|
0ffe8c714c | ||
|
|
5f00c98583 | ||
|
|
b12e3d06a9 | ||
|
|
8f97858987 | ||
|
|
e229d85baa | ||
|
|
85a3a48cd2 | ||
|
|
79f39a35a6 | ||
|
|
a25f81483c | ||
|
|
1eb72d1621 | ||
|
|
91c558e43b | ||
|
|
207772f0e7 | ||
|
|
9b9bdb3af6 | ||
|
|
1924385156 | ||
|
|
20984b36b5 | ||
|
|
5a42d00a1f | ||
|
|
37569a3ae6 | ||
|
|
a0bd050330 | ||
|
|
5e3e0d4081 | ||
|
|
569881c1c1 | ||
|
|
e25209453a | ||
|
|
88b134c50f | ||
|
|
cd5aae1b16 | ||
|
|
ef705fccc7 | ||
|
|
72145109ab | ||
|
|
a7ceabdc33 | ||
|
|
8bd8950514 | ||
|
|
c2e2fe5c4b | ||
|
|
19437cd694 | ||
|
|
338677a0fb | ||
|
|
5462d69dd1 | ||
|
|
2158fc18da | ||
|
|
898ae8cbce | ||
|
|
82540bab5e | ||
|
|
ba2cec3c12 | ||
|
|
43b0245fa1 | ||
|
|
ed2759402a | ||
|
|
8b4178d416 | ||
|
|
4233ade781 | ||
|
|
35f3f3eec8 | ||
|
|
3577876cac | ||
|
|
22096da60e | ||
|
|
2ec5747539 | ||
|
|
e837a4526b | ||
|
|
6fb000ce89 | ||
|
|
228ecd91f1 | ||
|
|
0338f9b301 | ||
|
|
f3b952805b | ||
|
|
8316085e17 | ||
|
|
0d940ee543 | ||
|
|
fe4f2be270 | ||
|
|
cda5029081 | ||
|
|
31fc581135 | ||
|
|
3f6d837a62 | ||
|
|
a869065718 | ||
|
|
85debe2636 | ||
|
|
87f32fb5d0 | ||
|
|
99b807dd6e | ||
|
|
82340d2c7e | ||
|
|
05b27083b2 | ||
|
|
739d143393 | ||
|
|
c37ec6f3c0 | ||
|
|
b2056dfe34 | ||
|
|
1429f2e289 | ||
|
|
13f2b63053 | ||
|
|
8e111d93c6 | ||
|
|
77029f330d | ||
|
|
cb9c61af29 | ||
|
|
91831c0d95 | ||
|
|
66a1b6c6c4 | ||
|
|
972786821f | ||
|
|
8a5f696544 | ||
|
|
e13e6a8f42 | ||
|
|
bc6010d061 | ||
|
|
c655a7705e | ||
|
|
9bd5ffc7b9 | ||
|
|
a949bf66cd | ||
|
|
77422be3dd | ||
|
|
3ce7e7d92b | ||
|
|
613dff02eb | ||
|
|
d2893ab5cc | ||
|
|
16f64afd4f | ||
|
|
61d45c518d | ||
|
|
ece94e748f | ||
|
|
fae3290ec1 | ||
|
|
39920ccfa5 | ||
|
|
360b0e5863 | ||
|
|
cdadcfaded | ||
|
|
57b4b6f4e2 | ||
|
|
4a4b1fab25 | ||
|
|
00c0add449 | ||
|
|
faadc9272d | ||
|
|
82fa6ec316 | ||
|
|
6cb90d80d7 | ||
|
|
38c917e1ec | ||
|
|
da717d0deb | ||
|
|
6ea7989d51 | ||
|
|
4d79ee1f80 | ||
|
|
76adc4ff75 | ||
|
|
7baec5ebed | ||
|
|
af3c228bed | ||
|
|
7b03230a42 | ||
|
|
464e7c6736 | ||
|
|
3f877c36f5 | ||
|
|
853e5c9511 | ||
|
|
cbead678ea | ||
|
|
11f8c2ebed | ||
|
|
3961196112 | ||
|
|
2e4269b5d3 | ||
|
|
5d8d3ca524 | ||
|
|
373158da82 | ||
|
|
2fdf0f59de | ||
|
|
633ea9cb4a | ||
|
|
798f90b311 | ||
|
|
30201f6435 | ||
|
|
9dbfebd5b0 | ||
|
|
0648d875ca | ||
|
|
019162b4ff | ||
|
|
df8b94034f | ||
|
|
945ae55563 | ||
|
|
fdd5dfc55e | ||
|
|
24d9a93531 | ||
|
|
369908f64c | ||
|
|
3c92e09a51 | ||
|
|
0ff9d51301 | ||
|
|
3d73a95b8f | ||
|
|
891382fa50 | ||
|
|
7ae6ad8e37 | ||
|
|
33fbbb4e06 | ||
|
|
d8b5d842d6 | ||
|
|
15061014c7 | ||
|
|
0e5ff45c30 | ||
|
|
beed7ccc34 | ||
|
|
c709e0f04f | ||
|
|
6a89a94496 | ||
|
|
b72c5aec03 | ||
|
|
0c77512609 | ||
|
|
e8e0489a6b | ||
|
|
f01f0d85f8 | ||
|
|
d6f0e22928 | ||
|
|
e5326f895d | ||
|
|
b2b8cf5e63 | ||
|
|
8aa8289236 | ||
|
|
a93b78dfad | ||
|
|
d5f051ad58 | ||
|
|
2637965512 | ||
|
|
fe4dd107cb | ||
|
|
cc8167c089 | ||
|
|
a05cdcdd1c | ||
|
|
4afe2daef2 | ||
|
|
6893c1b19f | ||
|
|
e7a7668325 | ||
|
|
df71d93b2f | ||
|
|
0e649c6107 | ||
|
|
7df82a1b5a | ||
|
|
17914a34c7 | ||
|
|
bba0bd2a4c | ||
|
|
bdfd1f30eb | ||
|
|
664e84a14f | ||
|
|
872947677e | ||
|
|
d74283bf99 | ||
|
|
afd5879bd2 | ||
|
|
29d9dc684e | ||
|
|
1eb9606073 | ||
|
|
d0610661ba | ||
|
|
5011062c95 | ||
|
|
5d33cb7395 | ||
|
|
04e3e1e6f5 | ||
|
|
646e535a2f | ||
|
|
feea1057e2 | ||
|
|
0d5ee6ab60 | ||
|
|
0f0bddea48 | ||
|
|
c70152f916 | ||
|
|
d44e2ff219 | ||
|
|
b86a2e2d64 | ||
|
|
80a434d49d | ||
|
|
3887a2f2bd | ||
|
|
b77a42d761 | ||
|
|
b6e52d6d77 | ||
|
|
269c503863 | ||
|
|
84ad024f9b | ||
|
|
d11f3934cb | ||
|
|
cc8d49cf94 | ||
|
|
0dc676b3d5 | ||
|
|
80820e21d3 | ||
|
|
a443283a71 | ||
|
|
2cc3da3dae | ||
|
|
0512b40ed1 | ||
|
|
8102503c7d | ||
|
|
88b561c05f | ||
|
|
a8e3cf55e1 | ||
|
|
b9433b3b33 | ||
|
|
45da065bf6 | ||
|
|
021af26ded | ||
|
|
be6b055b83 | ||
|
|
6a1da349ef | ||
|
|
8b4103a1ef | ||
|
|
56c2d400fd | ||
|
|
1037583fd4 | ||
|
|
5cac106321 | ||
|
|
1b64969ba9 | ||
|
|
61dc1a115c | ||
|
|
cca2b3e96b | ||
|
|
1a5c316ba6 | ||
|
|
289cd60f23 | ||
|
|
460b982790 | ||
|
|
0f7a167315 | ||
|
|
29cf8e8839 | ||
|
|
551cc452d9 | ||
|
|
480abb916b | ||
|
|
78812c66d3 | ||
|
|
89fc0b996e | ||
|
|
6741855d24 | ||
|
|
603cc6806f | ||
|
|
d4466552b0 | ||
|
|
aca0f7242c | ||
|
|
5247ea3ce1 | ||
|
|
b5702a60bf | ||
|
|
5da7ba0222 | ||
|
|
cbb0832ad6 | ||
|
|
07486f4a96 | ||
|
|
48f8767fe0 | ||
|
|
62e9606db1 | ||
|
|
1a1e620b68 | ||
|
|
5c92dca212 | ||
|
|
4ed399e2d6 | ||
|
|
64d3e8fb3d | ||
|
|
ee17e49bfc | ||
|
|
e0497fc621 | ||
|
|
61a0ae4553 | ||
|
|
8682b3c218 | ||
|
|
d1fe27763d | ||
|
|
7ba93f08da | ||
|
|
ccc8b4dfd7 | ||
|
|
835f4aedb7 | ||
|
|
53af89f2e8 | ||
|
|
dfe38377f6 | ||
|
|
d8c09d38bb | ||
|
|
d24dea8643 | ||
|
|
fe468e27bb | ||
|
|
29d1143258 | ||
|
|
0e823a9b3c | ||
|
|
bdb2583383 | ||
|
|
b7b2b303d8 | ||
|
|
b2b106e456 | ||
|
|
43540dc35d | ||
|
|
36c0302c12 | ||
|
|
bea9ae7a93 | ||
|
|
5a0ad03a0f | ||
|
|
61567d1ab5 | ||
|
|
a32859070f | ||
|
|
bb8db803b6 | ||
|
|
f01fe000f1 | ||
|
|
d81876b91c | ||
|
|
0931ecb47d | ||
|
|
e56ed0ea8b | ||
|
|
0afc582010 | ||
|
|
4ec60c3bed | ||
|
|
74af42897f | ||
|
|
136ba94c29 | ||
|
|
4e226423f1 | ||
|
|
5de9c90a4e | ||
|
|
0bb3398b30 | ||
|
|
46876dd0b9 | ||
|
|
23702ca4f1 | ||
|
|
dc9496749a | ||
|
|
fd79e785ae | ||
|
|
c5ff96beea | ||
|
|
5ed68999e7 | ||
|
|
24969182f7 | ||
|
|
f77e99001b | ||
|
|
a8adba6ea9 | ||
|
|
6497cc7dce | ||
|
|
a93d639a78 | ||
|
|
a86d36b781 | ||
|
|
454a753173 | ||
|
|
76c8cfe2d5 | ||
|
|
f8a3b0d547 | ||
|
|
6360ec407e | ||
|
|
02329af88e | ||
|
|
3a56de4a14 | ||
|
|
0ef4883630 | ||
|
|
104960b69a | ||
|
|
453dff9ac4 | ||
|
|
1ebe1ada38 | ||
|
|
b7043b48ae | ||
|
|
62535c94da | ||
|
|
13befcfa00 | ||
|
|
bb9c4e30d7 | ||
|
|
29071cad41 | ||
|
|
e714e3e6ad | ||
|
|
9fb0360384 | ||
|
|
e9d6b9bf69 | ||
|
|
98d498ced1 | ||
|
|
2b67727bc5 | ||
|
|
14a679a8dc | ||
|
|
f0123c8790 | ||
|
|
f0c917e4d3 | ||
|
|
13d3efa3a4 | ||
|
|
20f3ebd931 | ||
|
|
a6c6c88d05 | ||
|
|
e3d8b6d980 | ||
|
|
851375ec15 | ||
|
|
f09fc83643 | ||
|
|
a73b6d66f2 | ||
|
|
ac87707a0b | ||
|
|
7d1cd99828 | ||
|
|
63f620e00a | ||
|
|
3b88940f4f | ||
|
|
fe03871381 | ||
|
|
8fc23d0936 | ||
|
|
536fd900f7 | ||
|
|
fe97da65b7 | ||
|
|
595a78f776 | ||
|
|
49c18bb118 | ||
|
|
af01f42788 | ||
|
|
3adbd7b57b | ||
|
|
96ba6544fa | ||
|
|
b5097b1893 | ||
|
|
5069b69b0c | ||
|
|
0487556985 | ||
|
|
490b2b4657 | ||
|
|
f848fc0b08 | ||
|
|
0ef0c5e451 | ||
|
|
f051c778dc | ||
|
|
35ca575bfd | ||
|
|
a336ad80e0 | ||
|
|
1df3163ba7 | ||
|
|
8799c84345 | ||
|
|
f49f92f872 | ||
|
|
1de311647c | ||
|
|
dcb3f50bae | ||
|
|
f3321dc62d | ||
|
|
34561c8d36 | ||
|
|
2ed0918c97 | ||
|
|
e5f9e31f8c | ||
|
|
c6e5d638c0 | ||
|
|
5466d182e1 | ||
|
|
1dfe98603d | ||
|
|
27a108873b | ||
|
|
eb3ba5de6b | ||
|
|
1ae683af48 | ||
|
|
814bb78ff6 | ||
|
|
8f546c4374 | ||
|
|
308cf3967d | ||
|
|
38f7e747d6 | ||
|
|
636ef473ee | ||
|
|
a9c25ad7a2 | ||
|
|
6949a85e3b | ||
|
|
e926e3edb1 | ||
|
|
153fd64ef9 | ||
|
|
418f375ba0 | ||
|
|
37c463b23e | ||
|
|
e61b9abbde | ||
|
|
886537ef87 | ||
|
|
9cd1330e14 | ||
|
|
cce5dd33bb | ||
|
|
6ec8754db4 | ||
|
|
6af7adfd21 | ||
|
|
0915c09419 | ||
|
|
cb575a6624 | ||
|
|
b5d6551165 | ||
|
|
7f248d3067 | ||
|
|
211295bf81 | ||
|
|
d517b1bb48 | ||
|
|
8edd118a40 | ||
|
|
0b404c61ae | ||
|
|
e686276cdc | ||
|
|
ba0f017dc2 | ||
|
|
16c60bbe7e | ||
|
|
b5383aa0d7 | ||
|
|
4b41b42d6c | ||
|
|
c35df1f06c | ||
|
|
c0bc6a93bb | ||
|
|
498df5c38b | ||
|
|
9a7db27357 | ||
|
|
49877c680a | ||
|
|
deb49b86fb | ||
|
|
bba0914d77 | ||
|
|
8435ca4e7f | ||
|
|
b05414a171 | ||
|
|
a1ef3e8808 | ||
|
|
6d91391d68 | ||
|
|
2ec1af86ac | ||
|
|
03401a7fbd | ||
|
|
27359df8fa | ||
|
|
c07377e1ee | ||
|
|
ac10080690 | ||
|
|
98ce42da79 | ||
|
|
56fa031cdd | ||
|
|
b9a8f755e3 | ||
|
|
1422c5f8dc | ||
|
|
e7627aca9c | ||
|
|
83583bf56c | ||
|
|
555ced3cd3 | ||
|
|
ad28eca220 | ||
|
|
7671884c62 | ||
|
|
56bff45026 | ||
|
|
249e2468fd | ||
|
|
e23178b6d9 | ||
|
|
f9997fcb70 | ||
|
|
fc323db3d9 | ||
|
|
7ce9991a4a | ||
|
|
31ff2bb714 | ||
|
|
7b91f3ca3e | ||
|
|
16203a41a0 | ||
|
|
0e25c5b617 | ||
|
|
04bb555318 | ||
|
|
1860612659 | ||
|
|
0841b63862 | ||
|
|
a998f0ab91 | ||
|
|
95ffeef9bf | ||
|
|
c30b8a42aa | ||
|
|
85b0bdb221 | ||
|
|
6dcfcad875 | ||
|
|
9deeecfeea | ||
|
|
f3cc9dbdfe | ||
|
|
ce9f83ad5c | ||
|
|
e35635f0e0 | ||
|
|
00fd5391fe | ||
|
|
8caea1fb77 | ||
|
|
22e8d82452 | ||
|
|
a747d56751 | ||
|
|
cf20290ab3 | ||
|
|
02c9b97505 | ||
|
|
8c45148271 | ||
|
|
0fe90f5a7b | ||
|
|
c84408924c | ||
|
|
acae1d3a41 | ||
|
|
b7725a769e | ||
|
|
ceb12f842f | ||
|
|
c3e4596d01 | ||
|
|
417eaeaf3c | ||
|
|
91a480c12b | ||
|
|
2b32b4d771 | ||
|
|
2a2283de1d | ||
|
|
d5a0e1238b | ||
|
|
a6fb5625cc | ||
|
|
37e3221980 | ||
|
|
c07fa0acb0 | ||
|
|
787e79d713 | ||
|
|
2843332a1c | ||
|
|
a6b26c7e93 | ||
|
|
dcb9f44584 | ||
|
|
4fc7d9d441 | ||
|
|
5d9959cdf6 | ||
|
|
e1e4a13cf0 | ||
|
|
c878957cbb | ||
|
|
33b1ad5be5 | ||
|
|
000a9241fb | ||
|
|
760908f5e3 | ||
|
|
4c54c0c20b | ||
|
|
865111dd6a | ||
|
|
13c4355a16 | ||
|
|
cef8b27816 | ||
|
|
8099424b89 | ||
|
|
328b906e31 | ||
|
|
302c812b45 | ||
|
|
a9ba979abc | ||
|
|
5e26626f91 | ||
|
|
1e3f8f385c | ||
|
|
6005722cc9 | ||
|
|
f587313425 | ||
|
|
602dd5d049 | ||
|
|
1e4e8fd6f0 | ||
|
|
4e5c44d679 | ||
|
|
f9ca713601 | ||
|
|
0aba9b5a1b | ||
|
|
ceca0ae762 | ||
|
|
ed081861a2 | ||
|
|
a19e4b521c | ||
|
|
fab806d62f | ||
|
|
4d6a242a59 | ||
|
|
ff4fe10ffd | ||
|
|
90da764d7e | ||
|
|
647a7297ba | ||
|
|
699e911a25 | ||
|
|
dfa8fa3dc6 | ||
|
|
0001a09190 | ||
|
|
5106e440d1 | ||
|
|
13b1d2f57a | ||
|
|
6ef4c4b58a | ||
|
|
847466a2a5 | ||
|
|
11d3031c99 | ||
|
|
0c34aab9a8 | ||
|
|
481f103035 | ||
|
|
4b16deae60 | ||
|
|
9291420cf8 | ||
|
|
87ddbe1ba1 | ||
|
|
37d6fc208b | ||
|
|
36b648eac6 | ||
|
|
a0abb047a8 | ||
|
|
8cdb4036b1 | ||
|
|
9a8a6fef4b | ||
|
|
98ebfaeb1e | ||
|
|
8bb2b6ae0c | ||
|
|
5ebce54a2f | ||
|
|
4f35e6e2c0 | ||
|
|
5e595f3418 | ||
|
|
bcaa6bd282 | ||
|
|
8e2491751e | ||
|
|
e8fe1bce74 | ||
|
|
33f44f25d0 | ||
|
|
25a912fbdb | ||
|
|
25aca15604 | ||
|
|
901e906f54 | ||
|
|
3eb34a91ed | ||
|
|
d4b3640fd9 | ||
|
|
9c0d233d73 | ||
|
|
9a5a393b18 | ||
|
|
68217e932a | ||
|
|
fe2e86abcb | ||
|
|
3304751e9b | ||
|
|
0bfb36f195 | ||
|
|
c5a10922f3 | ||
|
|
cd6311b9e8 | ||
|
|
2143c0a2f3 | ||
|
|
0192fd0222 | ||
|
|
22ffc4fab5 | ||
|
|
15c94d0b0e | ||
|
|
9030ed96a3 | ||
|
|
0df5c1b78f | ||
|
|
c55dd4a2c1 | ||
|
|
8f1f0f2e74 | ||
|
|
0d8f62a3fc | ||
|
|
a549ba6ef1 | ||
|
|
865a506570 | ||
|
|
139be97b81 | ||
|
|
25290cf2d7 | ||
|
|
e30a5d6ce0 | ||
|
|
6197407eb6 | ||
|
|
386b3e9a10 | ||
|
|
c8113aa796 | ||
|
|
547415a9be | ||
|
|
8c34277247 | ||
|
|
5af1f2b653 | ||
|
|
df50e0d866 | ||
|
|
7c3b7a68f9 | ||
|
|
2d6f657d87 | ||
|
|
7f4d400f3f | ||
|
|
5e298a853a | ||
|
|
fb50598525 | ||
|
|
556efd2bd3 | ||
|
|
bfd6843211 | ||
|
|
9332cefea6 | ||
|
|
800f59bb29 | ||
|
|
9a68be32c9 | ||
|
|
a1d110b64a | ||
|
|
14f463e6eb | ||
|
|
29c88e6266 | ||
|
|
63d09b12f8 | ||
|
|
39ee2740df | ||
|
|
86ef7491d4 | ||
|
|
fbb04c4754 | ||
|
|
94f22f37e5 | ||
|
|
2e2f848377 | ||
|
|
6ee313aeb6 | ||
|
|
6d6b4388ed | ||
|
|
7516873f11 | ||
|
|
5d93a90cdf | ||
|
|
d3a2583719 | ||
|
|
af9ffa6363 | ||
|
|
aaa712eb7d | ||
|
|
2b63cfafc6 | ||
|
|
d336d66a80 | ||
|
|
7d3c21ff0b | ||
|
|
04424aa77c | ||
|
|
d5eae3df63 | ||
|
|
4a83786eaf | ||
|
|
a691c1df3b | ||
|
|
a61a2c44fc | ||
|
|
b165f56a7b | ||
|
|
a8d907eef4 | ||
|
|
9ec9608845 | ||
|
|
b1ee8f8c12 | ||
|
|
61daca066a | ||
|
|
482cf5bfe1 | ||
|
|
aed17a3acd | ||
|
|
dd7835eeae | ||
|
|
6263d10b81 | ||
|
|
a398ca936b | ||
|
|
1e609c3b5e | ||
|
|
ee9583a839 | ||
|
|
0ca7362ceb | ||
|
|
13b575efdf | ||
|
|
79f5c3d1d1 | ||
|
|
aab38e8123 | ||
|
|
fcf8698ef2 | ||
|
|
1ea90c119b | ||
|
|
bbf5e72000 | ||
|
|
cd44c1467a | ||
|
|
7fbb243e01 | ||
|
|
b29248e937 | ||
|
|
9620ffb854 | ||
|
|
4d430f3680 | ||
|
|
c5a2d74be6 | ||
|
|
4f6273990f | ||
|
|
b8d9960a48 | ||
|
|
3ef3d59f3d | ||
|
|
f849bdf862 | ||
|
|
52670172df | ||
|
|
49ed125e72 | ||
|
|
e8680081a1 | ||
|
|
4412f5b2d6 | ||
|
|
d0045bb3b2 | ||
|
|
e3372e8810 | ||
|
|
c4cd890f85 | ||
|
|
0dad558ef0 | ||
|
|
9b4fbaeb61 | ||
|
|
f73d847c7d | ||
|
|
48c362255e | ||
|
|
c0180f6f26 | ||
|
|
3057707d48 | ||
|
|
a6234e494a | ||
|
|
92e6e81bba | ||
|
|
6df5d360a7 | ||
|
|
91c244b0ec | ||
|
|
aa094bd7ae | ||
|
|
543b40cb64 | ||
|
|
4e63f828e1 | ||
|
|
5ad3ee1320 | ||
|
|
885a052f33 | ||
|
|
7ed7972554 | ||
|
|
a4e7807d3c | ||
|
|
8ddd2134fc | ||
|
|
8c92c92118 | ||
|
|
9c229eec12 | ||
|
|
5fb31083a4 | ||
|
|
f1111c34a1 | ||
|
|
64cfb00df0 | ||
|
|
096381941e | ||
|
|
16cc1e14b6 | ||
|
|
b6b7596637 | ||
|
|
2ac50ae90e | ||
|
|
f6c6a39061 | ||
|
|
2aeaa391ad | ||
|
|
c7c9b34e6d | ||
|
|
c4fbc1e4f6 | ||
|
|
c8a32ed779 | ||
|
|
303a7d4586 | ||
|
|
3ae7f01de6 | ||
|
|
b27e51d6f7 | ||
|
|
cbbcdec157 | ||
|
|
99cb883fa9 | ||
|
|
a7fe90de78 | ||
|
|
38e2467985 | ||
|
|
ea93c2f496 | ||
|
|
b169851ed9 | ||
|
|
45b88f652d | ||
|
|
bc205b3df2 | ||
|
|
1574a717a3 | ||
|
|
061de3a180 | ||
|
|
519e0ed3a5 | ||
|
|
a71a8c9f63 | ||
|
|
13bf89b16d | ||
|
|
11073f334a | ||
|
|
a3be51214f | ||
|
|
00aa73e1f2 | ||
|
|
0fa85827ce | ||
|
|
5df4d2a526 | ||
|
|
a60f6fb22a | ||
|
|
e13283a619 | ||
|
|
29e1a06926 | ||
|
|
83db63dcb9 | ||
|
|
0e8bccba96 | ||
|
|
e0fa562975 | ||
|
|
1968999a61 | ||
|
|
06bda24517 | ||
|
|
d9260f51c7 | ||
|
|
9f67917da1 | ||
|
|
dd377551f6 | ||
|
|
254a8dfe38 | ||
|
|
b930f57f80 | ||
|
|
4636be8061 | ||
|
|
4d2f458752 | ||
|
|
f2174968fa | ||
|
|
92c6fb0dcc | ||
|
|
a572616c02 | ||
|
|
85921e4443 | ||
|
|
b92ff764ed | ||
|
|
2ec94ea3da | ||
|
|
2d793e79b6 | ||
|
|
f5d7332a19 | ||
|
|
b83f66f539 | ||
|
|
d799e0b9a4 | ||
|
|
9cbcef61f9 | ||
|
|
a7e6c124ab | ||
|
|
f13f6770b7 | ||
|
|
e8ff6bd821 | ||
|
|
2ed63f73b4 | ||
|
|
e3cc9a27ad | ||
|
|
e212884cd0 | ||
|
|
d524edabed | ||
|
|
189ff9cfa0 | ||
|
|
0357c5c4e9 | ||
|
|
338b511994 | ||
|
|
792fe4e967 | ||
|
|
975fcf889f | ||
|
|
3367784030 | ||
|
|
ca4fe55111 | ||
|
|
0e54da1a87 | ||
|
|
08fcd5f887 | ||
|
|
f448127670 | ||
|
|
3961bb604e | ||
|
|
1e46f1df25 | ||
|
|
91db4eacd1 | ||
|
|
41ad0c1b68 | ||
|
|
6ad860d65e | ||
|
|
70addf4036 | ||
|
|
af541f9662 | ||
|
|
5897065f15 | ||
|
|
820d9ce2c9 | ||
|
|
fcaafaae53 | ||
|
|
d6c775a852 | ||
|
|
5d1d3ad56b | ||
|
|
77a4fc83e0 | ||
|
|
a515f7b878 | ||
|
|
9948494c11 | ||
|
|
1b409a1123 | ||
|
|
ff2b51ed13 | ||
|
|
c733e71950 | ||
|
|
834b43ece9 | ||
|
|
fb2866e92b | ||
|
|
f9c1cbf19d | ||
|
|
b964e2cfa0 | ||
|
|
62fbb739a5 | ||
|
|
a655cb7c71 | ||
|
|
4a671c70d1 | ||
|
|
8bf6d592a9 | ||
|
|
f610bd1f60 | ||
|
|
487ff41031 | ||
|
|
d6fece1f2f | ||
|
|
135a3fb8df | ||
|
|
acc7116bc4 | ||
|
|
f650644922 | ||
|
|
af8de1f0db | ||
|
|
18814a5adb | ||
|
|
204d2dd908 | ||
|
|
e24d1da7b5 | ||
|
|
985a4bcf9c | ||
|
|
224fc66dd3 | ||
|
|
783462d483 | ||
|
|
40fc283501 | ||
|
|
f55f664923 | ||
|
|
1f356bccbb | ||
|
|
75c1d6ae71 | ||
|
|
11b3c5cbf7 | ||
|
|
09dca8266d | ||
|
|
ba3e0a7b90 | ||
|
|
833d26b740 | ||
|
|
e1abffab5e | ||
|
|
f73175714d | ||
|
|
2b666aed88 | ||
|
|
3890408b6c | ||
|
|
4fa5fe3539 | ||
|
|
f77b16b752 | ||
|
|
f447156456 | ||
|
|
bc34dcde89 | ||
|
|
310df381c2 | ||
|
|
c52edfaad4 | ||
|
|
18fd4ed691 | ||
|
|
9fd5c39300 | ||
|
|
e1e1debb3c | ||
|
|
296d2fe345 | ||
|
|
0218975986 | ||
|
|
8db7cc7192 | ||
|
|
22ef15abda | ||
|
|
f1247d1b74 | ||
|
|
53059bbac0 | ||
|
|
20307ecdcb | ||
|
|
3ea7973810 | ||
|
|
02faf1de5a | ||
|
|
85da245a4d | ||
|
|
48c8c6e6e6 | ||
|
|
8bbb5955e3 | ||
|
|
a55263e171 | ||
|
|
6fbca3b7dc | ||
|
|
c6f03de4e0 |
833 changed files with 108942 additions and 25428 deletions
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -7,6 +7,13 @@ assignees: ''
|
|||
|
||||
---
|
||||
|
||||
**Note**
|
||||
We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
|
||||
|
||||
Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address issues created by users, we greatly appreciate your efforts to resolve issues independently and submit PRs. If you're unable to create a PR, please feel free to create an issue, and we'll do our best to address it.
|
||||
|
||||
Thank you for reporting issues and for your contributions! ❤️
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
|
|
|||
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -7,6 +7,13 @@ assignees: ''
|
|||
|
||||
---
|
||||
|
||||
**Note**
|
||||
We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
|
||||
|
||||
Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address requests for new features created by users, we greatly appreciate your efforts to add them independently and submit PRs. If you're unable to create a PR, please feel free to create your request, and we'll do our best to address it. You can also create issues or discussions to discuss the possible features that you want to add to HyperDbg.
|
||||
|
||||
Thank you for requesting new features and for your contributions! ❤️
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
|
|
|
|||
26
.github/git/git-help.md
vendored
26
.github/git/git-help.md
vendored
|
|
@ -44,6 +44,32 @@ To remove the effects of `git add .` and `git commit -m "test"` or just `git add
|
|||
git reset --soft HEAD~1
|
||||
```
|
||||
|
||||
To remove **all uncommitted and untracked changes** in Git and reset your working tree to the last commit:
|
||||
|
||||
```bash
|
||||
git reset --hard
|
||||
git clean -fd
|
||||
```
|
||||
|
||||
To modify the last pushed commit:
|
||||
|
||||
```bash
|
||||
# Undo the last commit but keep the changes in your working tree
|
||||
git reset --soft HEAD~1
|
||||
|
||||
# Make your additional modifications
|
||||
# edit files...
|
||||
|
||||
# Stage everything
|
||||
git add .
|
||||
|
||||
# Create a new commit
|
||||
git commit -m "Updated commit message"
|
||||
|
||||
# Force-push to replace the remote commit
|
||||
git push --force-with-lease
|
||||
```
|
||||
|
||||
---------------
|
||||
|
||||
## Releasing instructions
|
||||
|
|
|
|||
53
.github/workflows/vs2022.yml
vendored
53
.github/workflows/vs2022.yml
vendored
|
|
@ -1,26 +1,31 @@
|
|||
name: vs2022-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
tags:
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- '**.cmd'
|
||||
- '**.bat'
|
||||
- '**.md'
|
||||
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- '**.cmd'
|
||||
- '**.bat'
|
||||
- '**.md'
|
||||
workflow_dispatch:
|
||||
|
||||
# Disabled, uncomment the below line and remove the above lines to activate
|
||||
# on:
|
||||
# push:
|
||||
# branches:
|
||||
# - master
|
||||
# - dev
|
||||
# tags:
|
||||
# - 'v*'
|
||||
# paths-ignore:
|
||||
# - '.gitignore'
|
||||
# - '.gitattributes'
|
||||
# - '**.cmd'
|
||||
# - '**.bat'
|
||||
# - '**.md'
|
||||
#
|
||||
# pull_request:
|
||||
# paths-ignore:
|
||||
# - '.gitignore'
|
||||
# - '.gitattributes'
|
||||
# - '**.cmd'
|
||||
# - '**.bat'
|
||||
# - '**.md'
|
||||
|
||||
env:
|
||||
# WDK for Windows 11, version 22H2
|
||||
WDK_URL: https://go.microsoft.com/fwlink/?linkid=2196230
|
||||
|
|
@ -73,12 +78,12 @@ jobs:
|
|||
# working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
# run: msbuild /m /p:Configuration="Release MT" /p:Platform=${{matrix.PLATFORM}} /target:zydis /target:zycore /p:OutDir=${{ github.workspace }}/hyperdbg/libraries/zydis/ ${{ github.workspace }}/hyperdbg/dependencies/zydis/msvc/Zydis.sln
|
||||
|
||||
- name: Build Hyperdbg solution
|
||||
- name: Build HyperDbg solution
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
|
||||
|
||||
- name: Upload build directory
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4.4.0
|
||||
with:
|
||||
name: build_files_${{matrix.BUILD_CONFIGURATION}}
|
||||
path: ${{ env.BUILD_BIN_DIR }}
|
||||
|
|
@ -86,12 +91,12 @@ jobs:
|
|||
deploy-release:
|
||||
name: Deploy release
|
||||
needs: win-amd64-build
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2022
|
||||
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Download build files from "build" job
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
with:
|
||||
name: build_files_release
|
||||
path: ${{ env.BUILD_BIN_DIR }}
|
||||
|
|
|
|||
99
.github/workflows/vs2026.yml
vendored
Normal file
99
.github/workflows/vs2026.yml
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
name: vs2026-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**' # matches all branch names, including ones with slashes
|
||||
tags:
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- '**.cmd'
|
||||
- '**.bat'
|
||||
- '**.md'
|
||||
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- '**.cmd'
|
||||
- '**.bat'
|
||||
- '**.md'
|
||||
|
||||
env:
|
||||
SOLUTION_FILE_PATH: ./hyperdbg/hyperdbg.sln
|
||||
RELEASE_ZIP_FILE_NAME: hyperdbg
|
||||
BUILD_BIN_DIR: ./hyperdbg/build/bin/
|
||||
|
||||
jobs:
|
||||
win-amd64-build:
|
||||
runs-on: windows-2025-vs2026
|
||||
strategy:
|
||||
matrix:
|
||||
BUILD_CONFIGURATION: [release, debug]
|
||||
PLATFORM: [x64]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Checkout submodules recursively
|
||||
run: git submodule update --init --recursive --remote
|
||||
|
||||
- name: Add MSBuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: NuGet/setup-nuget@v2
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Update vcxproj files
|
||||
run: python utils/replace-sdk-wdk.py
|
||||
|
||||
- name: Build HyperDbg solution
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
|
||||
|
||||
- name: Upload build directory
|
||||
uses: actions/upload-artifact@v4.4.0
|
||||
with:
|
||||
name: build_files_${{matrix.BUILD_CONFIGURATION}}
|
||||
path: ${{ env.BUILD_BIN_DIR }}
|
||||
|
||||
deploy-release:
|
||||
name: Deploy release
|
||||
needs: win-amd64-build
|
||||
runs-on: windows-2025-vs2026
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Download build files from "build" job
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
with:
|
||||
name: build_files_release
|
||||
path: ${{ env.BUILD_BIN_DIR }}
|
||||
|
||||
- name: Archive release
|
||||
uses: thedoctor0/zip-release@master
|
||||
with:
|
||||
path: ${{ env.BUILD_BIN_DIR }}release/
|
||||
type: 'zip'
|
||||
filename: ${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: |
|
||||
${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -377,16 +377,26 @@ MigrationBackup/
|
|||
!/hyperdbg/libraries/DIA/x84/*
|
||||
!/hyperdbg/libraries/DIA/x64/*
|
||||
|
||||
# KdSerial Libraries
|
||||
# kdserial libraries
|
||||
!/hyperdbg/libraries/kdserial/*
|
||||
!/hyperdbg/libraries/kdserial/x86/*
|
||||
!/hyperdbg/libraries/kdserial/x64/*
|
||||
!/hyperdbg/libraries/kdserial/arm/*
|
||||
!/hyperdbg/libraries/kdserial/arm64/*
|
||||
|
||||
# Ignore keystone libraries
|
||||
!/hyperdbg/libraries/keystone/release/
|
||||
!/hyperdbg/libraries/keystone/debug/
|
||||
!/hyperdbg/libraries/keystone/release/*
|
||||
!/hyperdbg/libraries/keystone/debug/*
|
||||
|
||||
# Code review tools
|
||||
|
||||
compile_commands.json
|
||||
StructLayoutSettings.json
|
||||
*.metaproj
|
||||
*.metaproj
|
||||
|
||||
#ignore clion config files
|
||||
.idea
|
||||
cmake-build-debug
|
||||
/hyperdbg/hyperhv/zydis/
|
||||
|
|
|
|||
12
.gitmodules
vendored
12
.gitmodules
vendored
|
|
@ -1,12 +1,12 @@
|
|||
[submodule "hyperdbg/tests/script-engine-test"]
|
||||
path = hyperdbg/tests/script-engine-test
|
||||
url = https://github.com/HyperDbg/script-engine-test.git
|
||||
[submodule "hyperdbg/miscellaneous/constants/pciid"]
|
||||
path = hyperdbg/miscellaneous/constants/pciid
|
||||
url = https://github.com/HyperDbg/pciids
|
||||
[submodule "hyperdbg/dependencies/ia32-doc"]
|
||||
path = hyperdbg/dependencies/ia32-doc
|
||||
url = https://github.com/HyperDbg/ia32-doc.git
|
||||
[submodule "hyperdbg/dependencies/phnt"]
|
||||
path = hyperdbg/dependencies/phnt
|
||||
url = https://github.com/HyperDbg/phnt.git
|
||||
[submodule "hyperdbg/script-engine/modules/script-engine-test"]
|
||||
path = hyperdbg/script-engine/modules/script-engine-test
|
||||
url = https://github.com/HyperDbg/script-engine-test
|
||||
[submodule "hyperdbg/dependencies/pdbex"]
|
||||
path = hyperdbg/dependencies/pdbex
|
||||
url = https://github.com/HyperDbg/pdbex.git
|
||||
|
|
|
|||
406
CHANGELOG.md
406
CHANGELOG.md
|
|
@ -4,6 +4,412 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.21.0.0] - 2026-07-05
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added structure for the hyperperf (Hardware Performance Counter) project ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- The 'unload' command checks whether any module is loaded or not ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
|
||||
- Exported SDK API for checking whether any module is loaded or not ([link](https://github.com/HyperDbg/HyperDbg/commit/19e47c804f50f5dbb698f314e66b7d685a87ac1f))
|
||||
- Added user mode and kernel mode PT parameter parser ([link](https://github.com/HyperDbg/HyperDbg/pull/631))
|
||||
- Added thread (TID) and process (PID) helper functions for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/pull/633))
|
||||
|
||||
### Changed
|
||||
- Separated SDK libraries for user mode and kernel mode modules ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- Fix pool manager uninitialize list corruption ([link](https://github.com/HyperDbg/HyperDbg/pull/629))
|
||||
- Fix 'access denied' error on loading all modules using 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))([link](https://github.com/HyperDbg/HyperDbg/commit/2b818a5116d80d466aab7b343d4aa9d1d640f082))
|
||||
- Fix the concatenation error for the "hyperkd" string on the hypertrace project (https://github.com/HyperDbg/HyperDbg/commit/2b0cc18899ff532d9d590a71bf880fee5456c15f))
|
||||
- Organized header files for the libhyperdbg project ([link](https://github.com/HyperDbg/HyperDbg/pull/632))
|
||||
|
||||
## [0.20.0.0-beta] - 2026-06-21
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added the libipt library to the project and the SDK
|
||||
- Added Intel Processor Trace (PT) example app
|
||||
- Added Linux distinction and pragmas together with new platform functions ([link](https://github.com/HyperDbg/HyperDbg/commit/9c3e0ed23b5f4bb64bd305e546dd0e86ee1910d9))
|
||||
- Added interfaces to Linux port for the serial devices ([link](https://github.com/HyperDbg/HyperDbg/commit/31b514f8df40d81d44ae07a2328c02360ce488c3))
|
||||
- Added platform IOCTL interface ([link](https://github.com/HyperDbg/HyperDbg/pull/619))
|
||||
- Added typecast for wchar, mismatch on Linux and Windows ([link](https://github.com/HyperDbg/HyperDbg/commit/10576b064a9824ab655e7bea0e35e9556ee68ca4))
|
||||
- Added missing IOCTLs for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/commit/df12e9fd79851c8f378ec82a45066da510da507a))
|
||||
- Added NuGet packages for Windows SDK and WDK
|
||||
- Added Signal handler platform API for Linux ([link](https://github.com/HyperDbg/HyperDbg/pull/627))
|
||||
- Added contribution guidelines for Linux ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/linux#readme))
|
||||
|
||||
### Changed
|
||||
- Moved to Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/pull/626))
|
||||
- Zydis and pdbex submodules are updated to VS2026
|
||||
- Fix the new form of loading and unloading in the example app and PT app ([link](https://github.com/HyperDbg/HyperDbg/commit/9ad48d30dcf6b409ae86b2d08262584cd06f606e))
|
||||
- Check whether the top-level hypervisor is Hyper-V and disable/enable VPIDs based on that, thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/625))
|
||||
- Fix PT operation IOCTL buffer size ([link](https://github.com/HyperDbg/HyperDbg/commit/dabf132d31503843f90949f35f8dce4601d43126))
|
||||
- CI/CD updated with NuGet packages for Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/commit/5a0fad490124268550f955f594d1211d5c74f03d))
|
||||
|
||||
## [0.19.0.0-beta] - 2026-06-10
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- First release of the HyperTrace module ([link](https://url.hyperdbg.org/hypertrace))
|
||||
- HyperTrace now enables/disables VM-entry/VM-exit controls for Load and Save IA32_DEBUGCTL MSR
|
||||
- Added Legacy LBR support to the HyperTrace module
|
||||
- Added Architectural LBR support to the HyperTrace module
|
||||
- Added the '!lbr' command for performing different Last Branch Record (LBR) operations ([link](https://docs.hyperdbg.org/commands/extension-commands/lbr))
|
||||
- Added the '!lbrdump' command for dumping saved Last Branch Record (LBR) entries ([link](https://docs.hyperdbg.org/commands/extension-commands/lbrdump))
|
||||
- Added **lbr_save()** and **lbr_print()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print))
|
||||
- Added mock application for compiling SDK for Linux
|
||||
- Added '!help' alias for the '.help' command
|
||||
- Added 'vm' alias for the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Added **lbr_check()** and **lbr_restore()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore))
|
||||
- Added **lbr_restore_by_filter(filter)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter))
|
||||
- Added the 'kd' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Added the 'trace' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Exported SDK API for detecting CPU vendors
|
||||
- Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589))
|
||||
- Exported SDK APIs for loading and unloading the 'kd' and the 'trace' modules
|
||||
- Exported SDK APIs for starting (installing) the 'kd' driver
|
||||
- Exported SDK APIs for loading/unloading all modules
|
||||
- Added tests for checking PE parser in 'hyperdbg-test' project
|
||||
- Added example for loading HyperDbg in VMI mode directly from libhyperdbg
|
||||
- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601))
|
||||
- Added transparent-mode evade mask selection thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/602))
|
||||
- Added synthetic MSR handling thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/605))
|
||||
- Added use of relative RSDS fixture paths when loading PDB symbols, thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/607))
|
||||
|
||||
### Changed
|
||||
- Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters))
|
||||
- Refactoring the IOCTL parameter checks and status routines
|
||||
- All basic types are now defined for Linux
|
||||
- VMX instructions are ported to platform-independent files to support Linux
|
||||
- All CPU-related intrinsic instructions are ported to platform-independent files to support Linux
|
||||
- HyperDbg SDK now compiles on Linux (GCC) for both user-mode and kernel-mode
|
||||
- Fix the 'wrmsr' command IOCTL checks by receiving output in the buffer ([link](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr))
|
||||
- Extensive refactoring of code base (doxygen, variables, function names)
|
||||
- Building certain modules on Linux and fixing CMake files thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/592))
|
||||
- Fix the '!hide' command's HyperEvade activation guard thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/593))
|
||||
- Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595))
|
||||
- PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe))
|
||||
- Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596))
|
||||
- The pool manager moved from 'hyperhv' to 'hyperkd'
|
||||
- The 'load' command could load all modules using a new alias 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- The 'unload' command could remove all modules using two new aliases 'unload all' and 'unload remove all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
|
||||
- Change device handle checks with module loading status checks for IOCTLs ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
|
||||
- Fix standard callbacks for the VMM module ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
|
||||
- Fix race condition bug within the pool manager
|
||||
|
||||
## [0.18.1.0] - 2026-04-09
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- HyperTrace now works with HyperDbg VMM ([link](https://github.com/HyperDbg/HyperDbg/pull/568))
|
||||
- Progress on implementing Last Branch Recode (LBR) ([link](https://github.com/HyperDbg/HyperDbg/commit/1dd73675e9cd78737e013ffb35bc712f385f387e))
|
||||
- Applying LBR registers on the VMCS instead of the DEBUGCTL MSR ([link](https://github.com/HyperDbg/HyperDbg/commit/15f8b3cca15448acd18d7e198740464a19ce4fe2))
|
||||
|
||||
### Changed
|
||||
- Fix the problem of the '!epthook' not finding the PML1 entry ([link](https://docs.hyperdbg.org/commands/extension-commands/epthook))
|
||||
- Fix the problem of getting the PML1 entry of the target address on Intel Core Ultra processors (#567) ([link](https://github.com/HyperDbg/HyperDbg/issues/567))
|
||||
- Fix the '.clang-format' formatting error
|
||||
- Restructure of the HyperTrace project
|
||||
- Add starting structure for supporting Intel Processor Trace (PT)
|
||||
|
||||
## [0.18.0.0] - 2026-02-16
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Script engine now supports writing libraries using the '#include' keyword thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion))([link](https://github.com/HyperDbg/HyperDbg/issues/557))([link](https://github.com/HyperDbg/HyperDbg/pull/561))
|
||||
- Initial codes for the HyperTrace project by using Intel Last Branch Record (LBR) and Branch Trace Store (BTS) thanks to [@harimishal1](https://github.com/harimishal1) ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/hypertrace))
|
||||
- The HyperTrace project is now linked to the hyperkd
|
||||
- Initial efforts to port HyperDbg to Linux have started thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/563))
|
||||
|
||||
### Changed
|
||||
- Fix compilation error in Zydis with the new Windows WDK ([link](https://github.com/HyperDbg/zydis/commit/e61f59332ce49f8853006573ca853e404fafdd08))
|
||||
|
||||
## [0.17.0.0] - 2025-11-10
|
||||
New release of the HyperDbg Debugger. All credit for this release goes to [@xmaple555](https://github.com/xmaple555).
|
||||
|
||||
### Added
|
||||
- Added 1D and 2D arrays (multidimensional arrays) in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multidimensional-array))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
- Added compound assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#compound-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
- Added multiple assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multiple-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
|
||||
### Changed
|
||||
- Fix bugs for interpreting 'db_pa, 'dd_pa', 'eb_pa', and 'ed_pa' keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))([link](https://github.com/HyperDbg/HyperDbg/pull/507))
|
||||
- Fix variable types in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/43b0245fa11b5c73ce4cd21d8b8787b86a05f89d))
|
||||
- Fix and update array index for boolean expressions in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/ba2cec3c12c3ff45ddc0004051884983ff62a0b3))
|
||||
|
||||
## [0.16.0.0] - 2025-09-08
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- The **!xsetbv** event command was added for handling the execution of the XSETBV instruction, thanks to HyperDbg group members ([link](https://docs.hyperdbg.org/commands/extension-commands/xsetbv))
|
||||
- Display of the number of blocked context switches in the '.switch' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.switch))
|
||||
- Added support for step-in (the 't' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/t))
|
||||
- Added support for step-over (the 'p' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/p))
|
||||
- Added support to show all registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
|
||||
- Exported SDK API for running scripts in either the kernel debugger or the user debugger
|
||||
- Added support to modify registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
|
||||
- Added support to evaluate (run) scripts on the target thread in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/eval))
|
||||
- Added an indication of a thread's running or paused state to the HyperDbg signature in the user debugger ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/signatures))
|
||||
- Added support for the '.formats' command in the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.formats))
|
||||
- Added support for interpreting parameters based on script engine expressions in the user debugger
|
||||
- Exported SDK API for evaluating expressions based on the context of the kernel debugger or the user debugger
|
||||
- Added a new mechanism for showing the 'printf' and the 'print' function messages in the user debugger ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/printf))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/print))
|
||||
|
||||
### Changed
|
||||
- Non-volatile XMM registers are no longer saved/restored on VM-exit handler ([link](https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170))
|
||||
- Fix grammar and spelling errors throughout HyperDbg codebase ([link](https://github.com/HyperDbg/HyperDbg/pull/546))
|
||||
- Relocate extension command files into their corresponding VS directory
|
||||
- Fix infinite VM-exit bug for the '!monitor x' command thanks to [@unlockable](https://github.com/unlockable) ([link](https://github.com/HyperDbg/HyperDbg/pull/545))
|
||||
|
||||
## [0.15.0.0] - 2025-08-18
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added the '!smi' command for performing operations related to System Management Interrupt (SMI) ([link](https://docs.hyperdbg.org/commands/extension-commands/smi))
|
||||
- Export the SDK functions for SMI operations ([link](https://docs.hyperdbg.org/commands/extension-commands/smi#sdk))
|
||||
- Check for Intel CET IBT (indirect branch tracking) support
|
||||
- Check for Intel CET shadow stack support
|
||||
- Added support to Intel CET for SYSCALL/SYSRET emulation ([link](https://docs.hyperdbg.org/commands/extension-commands/syscall))([link](https://docs.hyperdbg.org/commands/extension-commands/sysret))
|
||||
|
||||
### Changed
|
||||
- The 'hyperhv' project now has build optimizations enabled
|
||||
- Reformat VMXOFF restoring routines to restore general-purpose and XMM registers correctly before moving to the previous stack
|
||||
- Fix unloading (VMXOFF) crash when restoring XMM registers
|
||||
- Fix the problem with restoring XMM registers (#468) ([link](https://github.com/HyperDbg/HyperDbg/issues/468))
|
||||
- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
|
||||
- Updated ia32-doc to fix VMCS PL3 SSP fields ([link](https://github.com/HyperDbg/ia32-doc))
|
||||
- Fix the terminating process issue of the '!syscall/!sysret' commands on 11 generation (Rocket Lake/Tiger Lake) and newer Intel processors ([link](https://github.com/HyperDbg/HyperDbg/issues/392))
|
||||
- Re-enable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- The '!mode' event command is now compatible with different EPT hook commands (e.g., !epthook, !epthook2, !monitor, .start, and .restart) ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
|
||||
- The '!mode' command doesn't need allocating extra EPTPs ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
|
||||
|
||||
## [0.14.1.0] - 2025-07-27
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Changed
|
||||
- Restored the previous optimization on the release builds
|
||||
- Fixed the issue of not properly restoring registers after the 'CPUID' instruction
|
||||
- Fixed the building issues of the user debugger with the 'bp' and the '.start' commands
|
||||
|
||||
## [0.14.0.0] - 2025-07-23
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- **microsleep(microseconds)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/microsleep))
|
||||
- **rdtsc()** and **rdtscp()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtsc))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtscp))
|
||||
- Added functions to get system-call number from the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
|
||||
- Added the support for the '.start' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- Added a new mechanism for finding the system-call number based on the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
|
||||
- Added hyperevade transparency project ([link](https://url.hyperdbg.org/hyperevade))
|
||||
- Added support to the '.attach' and '.detach' in the debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.attach))([link](https://docs.hyperdbg.org/commands/meta-commands/.detach))
|
||||
- Added support to the '.start' command in the VMI mode for the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- Added support to setting the breakpoint using the 'bp' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/debugging-commands/bp))
|
||||
- Added EPT page table support for MMIO addresses above 512 GB
|
||||
|
||||
### Changed
|
||||
- Redesigned the '!mode' extension command without extra EPTP ([link](https://github.com/HyperDbg/HyperDbg/commit/a93b78dfadbf94d2d69f24413170c983ec379f48))
|
||||
- The user mode debugger now uses MBEC for preventing user-mode code execution ([link](https://github.com/HyperDbg/HyperDbg/commit/6893c1b19f1edaf57d0074bd60abcd518bf77338))
|
||||
- Apply transparent-mode based on dynamic system-calls ([link](https://github.com/HyperDbg/HyperDbg/commit/1eb960607331fc0c2622804d7aff65702c155649))
|
||||
- Breakpoint initialization is changed from kernel debugger to the regular debugger ([link](https://github.com/HyperDbg/HyperDbg/commit/e5326f895dcddb1adbc873a9fecede7af7eb7651))
|
||||
- Fixed the build issue on new Windows SDK for Token structures ([link](https://github.com/HyperDbg/HyperDbg/pull/530))
|
||||
- Fixed retrieving valid watching process IDs for the execution trap and user-mode execution prevention
|
||||
- Fixed crashing the driver if the hyperlog memory was not properly allocated
|
||||
- The target runner image for deploying HyperDbg (CI/CD) changed from Windows Server 2019 to 2022
|
||||
- Restored the pid and the process name parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
|
||||
- Fixed crashing Windows when using 'TPAUSE' instruction on bare metal Windows 11 24h2
|
||||
- Check to avoid putting EPT hooks on physical addresses greater than 512 GB
|
||||
|
||||
## [0.13.2.0] - 2025-05-26
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Intercepting system-call return results using the TRAP flag for the transparent-mode
|
||||
- Added optional parameters and context for the transparent-mode system-call return interceptions
|
||||
|
||||
### Changed
|
||||
- Set variable length (stack frames) for showing the callstack ([link](https://docs.hyperdbg.org/commands/debugging-commands/k))
|
||||
- Fixed VMCS layout corruption due to NMI injection (VMRESUME 0x7 error) in nested-virtualization on Meteor Lake processors
|
||||
- Restore RDMSR handler for VM-exits
|
||||
|
||||
## [0.13.1.0] - 2025-04-14
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added new transparency methods for hiding nested virtualization environments thanks to [@CokeTree3](https://github.com/CokeTree3) ([link](https://github.com/HyperDbg/HyperDbg/pull/515))
|
||||
|
||||
### Changed
|
||||
- Fix '.thread' command crash ([link](https://github.com/HyperDbg/HyperDbg/pull/510))
|
||||
- Update .clang-format format file based on the new version of LLVM
|
||||
- Update the list of required contributions
|
||||
|
||||
## [0.13.0.0] - 2025-02-25
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added mitigation for the anti-hypervisor method in handling the trap flag for emulated instructions ([link](https://github.com/HyperDbg/HyperDbg/pull/497))
|
||||
- Export the SDK functions for enabling and disabling transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/hide#sdk))([link](https://docs.hyperdbg.org/commands/extension-commands/unhide#sdk))
|
||||
- New description of changing script engine constants ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations))
|
||||
- Added the command for interpreting PCI CAM (PCI configuration space) fields ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
|
||||
- Added the command for dumping PCI CAM (PCI configuration space) memory ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
|
||||
- Checking for and unloading the older version of the driver (if it exists) ([link](https://github.com/HyperDbg/HyperDbg/pull/503))
|
||||
- **memcpy_pa()** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/memcpy_pa))
|
||||
- **poi_pa**, **hi_pa**, **low_pa**, **db_pa**, **dd_pa**, **dw_pa**, and **dq_pa** keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))
|
||||
- **eb_pa**, **ed_pa**, and **eq_pa** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/eb_pa-ed_pa-eq_pa))
|
||||
|
||||
### Changed
|
||||
- Fix the 'lm' command issue of not showing kernel module addresses (KASLR leak mitigation) introduced in Windows 11 24h2 ([link](https://docs.hyperdbg.org/commands/debugging-commands/lm))
|
||||
- Deprecated TSC mitigation for the transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/measure))
|
||||
- Changed the parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
|
||||
- Changed the parameters of the '!unhide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/unhide))
|
||||
- Fix containing backslash escape character in script strings ([link](https://github.com/HyperDbg/HyperDbg/pull/499))
|
||||
- Fix reading/writing into devices' physical memory (MMIO region) in VMI Mode ([link](https://github.com/HyperDbg/HyperDbg/pull/500))
|
||||
- All test cases for command parsing are now passed ([link](https://github.com/HyperDbg/HyperDbg/pull/504))
|
||||
- The '.sympath' command now requires the symbol server path to be within quotes, although it is not mandatory ([link](https://docs.hyperdbg.org/commands/meta-commands/.sympath))
|
||||
|
||||
## [0.12.0.0] - 2025-01-02
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added the PCI tree command ([link](https://docs.hyperdbg.org/commands/extension-commands/pcitree))
|
||||
- Added the proper handling for the xsetbv VM exits thanks to [@Shtan7](https://github.com/Shtan7) ([link](https://github.com/HyperDbg/HyperDbg/pull/491))
|
||||
- Added the IDT command for interpreting Interrupt Descriptor Table (IDT) ([link](https://docs.hyperdbg.org/commands/extension-commands/idt))
|
||||
- Export SDK APIs for getting Interrupt Descriptor Table (IDT) entries
|
||||
|
||||
### Changed
|
||||
- Fix buffer overflow in the symbols path converter thanks to [@binophism](https://github.com/binophism) ([link](https://github.com/HyperDbg/HyperDbg/pull/490))
|
||||
- Fix script engine's "printf" function to improve safety thanks to [@Reodus](https://github.com/Reodus) ([link](https://github.com/HyperDbg/HyperDbg/pull/489))
|
||||
|
||||
## [0.11.0.0] - 2024-12-03
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added the local APIC command (xAPIC and x2APIC modes) ([link](https://docs.hyperdbg.org/commands/extension-commands/apic))
|
||||
- Added the I/O APIC command ([link](https://docs.hyperdbg.org/commands/extension-commands/ioapic))
|
||||
- The new link is added to help increase the number of EPT hook breakpoints in a single page ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/number-of-ept-hooks-in-one-page))
|
||||
- Export SDK APIs for Local APIC and X2APIC
|
||||
|
||||
### Changed
|
||||
- The link for changing the communication buffer size is updated ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size))
|
||||
- Update Microsoft's DIA SDK and symsrv
|
||||
|
||||
## [0.10.2.0] - 2024-10-11
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Automated test case parsing and test case compilation (generation) for the hwdbg debugger
|
||||
- Export hwdbg testing functions
|
||||
- Automated test case interpretation and emulation of hwdbg hardware scripts
|
||||
- Create JSON representation of hwdbg configs
|
||||
|
||||
### Changed
|
||||
- Fix main command parser bugs according to test cases
|
||||
- Improvements in symbol structure, token structure, and stack buffer in the script engine
|
||||
- Fix compatibility mode program crash when terminating 32-bit process (#479) ([link](https://github.com/HyperDbg/HyperDbg/pull/479))
|
||||
- Extensive refactor of chip instance info interpretation codes of hwdbg debugger
|
||||
- Separating functions of hwdbg interpreter and script manager
|
||||
- Fix synthesize inconsistencies between Icarus iVerilog and Xilinx ISim
|
||||
- Fix runtime error for deallocating memory from separate DLLs
|
||||
- Exporting standard functions (import/export) for the script engine
|
||||
- Exporting standard functions (import/export) for the symbol parser
|
||||
- Avoid passing signals once the stage is not configured
|
||||
|
||||
## [0.10.1.0] - 2024-09-08
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added feature to pause the debuggee immediately upon connection
|
||||
- The '.debug' command now supports pausing the debuggee at startup ([link](https://docs.hyperdbg.org/commands/meta-commands/.debug))
|
||||
- Export SDK API for assembling instructions
|
||||
- The 'struct' command now supports a path as output ([link](https://docs.hyperdbg.org/commands/debugging-commands/struct))
|
||||
- Export SDK API closing connection to the remote debuggee
|
||||
- Automated tests for the main command parser
|
||||
- Export SDK APIs for stepping and tracing instructions
|
||||
- Export SDK APIs for tracking execution
|
||||
|
||||
### Changed
|
||||
- HyperDbg command-line comment sign is changed from '#' to C-like comments ('//' and '/**/')
|
||||
- Integrating a new command parser for the regular HyperDbg commands
|
||||
- Fix showing a list of active outputs using the 'output' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/output))
|
||||
- Fix the issue of passing arguments to the '.start' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- Fix the problem with parsing multiple spaces within the events (#420) ([link](https://github.com/HyperDbg/HyperDbg/issues/420))
|
||||
- Fix the problem with escaping '{' in the command parser (#421) ([link](https://github.com/HyperDbg/HyperDbg/issues/421))
|
||||
- Fix nested brackets issues in the main command parser
|
||||
- Fix script engine bugs on order of passing arguments to functions (#453) ([link](https://github.com/HyperDbg/HyperDbg/issues/453))
|
||||
- Fix the script test case for factorial computation ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
|
||||
- Fix the script test case for computation iterative Fibonacci ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
|
||||
- Fix miscomputation of physical address width for physical address validity checks (#469) ([link](https://github.com/HyperDbg/HyperDbg/issues/469))
|
||||
|
||||
## [0.10.0.0] - 2024-07-22
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Support using assembly conditions and codes in all events ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition))([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action))
|
||||
- Added support for forwarding events to binary (DLL) modules ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding))([link](https://docs.hyperdbg.org/commands/debugging-commands/output))([link](https://github.com/HyperDbg/event-forwarding-examples))
|
||||
- Added the assembler command 'a' for virtual memory ([link](https://docs.hyperdbg.org/commands/debugging-commands/a))
|
||||
- Added the assembler command '!a' for physical memory ([link](https://docs.hyperdbg.org/commands/extension-commands/a))
|
||||
- Providing a unified SDK API for reading memory in the VMI Mode and the Debugger Mode
|
||||
- Export SDK APIs for reading/writing into registers in the Debugger Mode
|
||||
- Export SDK API for writing memory in the VMI Mode and the Debugger Mode
|
||||
- Export SDK API for getting kernel base address
|
||||
- Export SDK API for connecting to the debugger and from debuggee in the Debugger Mode
|
||||
- Export SDK API for starting a new process
|
||||
- Add and export SDK API for unsetting message callback
|
||||
- Event commands are coming with more examples regarding scripts and assembly codes
|
||||
- Add message callback using shared memory
|
||||
- Add maximum execution limitation to the script IRs (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
|
||||
|
||||
### Changed
|
||||
- Fix clearing '!monitor' hooks on a different process or if the process is closed (#409) ([link](https://github.com/HyperDbg/HyperDbg/issues/409))
|
||||
- Fix triggering multiple '!monitor' hooks with different contexts (#415) ([link](https://github.com/HyperDbg/HyperDbg/issues/415))
|
||||
- Fix the problem of repeating commands once kHyperDbg is disconnected
|
||||
- Fix step-over hangs if the process terminates/excepts within call instruction (#406) ([link](https://github.com/HyperDbg/HyperDbg/issues/406))
|
||||
- Fix crash on editing invalid physical addresses (#424) ([link](https://github.com/HyperDbg/HyperDbg/issues/424))
|
||||
- Fix exporting VMM module load and install it in the SDK
|
||||
- Fix function interpretation issues and update the parser and the code execution (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
|
||||
|
||||
## [0.9.1.0] - 2024-06-30
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Regular port/pin value read and modification in hwdbg
|
||||
- Conditional statement evaluation in hwdbg
|
||||
- Added automatic script buffer packet generator for hwdbg
|
||||
- Added support for @hw_pinX and @hw_portX registers
|
||||
- Added hwdbg instance information interpreter
|
||||
- Added stack buffer in vmx-root ([link](https://github.com/HyperDbg/HyperDbg/commit/5df4d2a5268a6b190dc126bf6cfe0527703296eb))
|
||||
- Exporting functions to support loading drivers with different names
|
||||
- Exporting function to connect and load HyperDbg drivers
|
||||
- Exporting function to connect and load HyperDbg drivers
|
||||
- **$date** and **$time** pseudo-registers are added ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#pseudo-registers))([link](https://github.com/HyperDbg/HyperDbg/issues/397))
|
||||
|
||||
### Changed
|
||||
- Fix using constant WSTRINGs in the **wcsncmp** function ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
|
||||
- Fix `phnt` build error with 24H2 SDK
|
||||
- `hprdbgctrl.dll` changed to `libhyperdbg.dll`
|
||||
- `hprdbgkd.sys` changed to `hyperkd.sys`
|
||||
- `hprdbghv.dll` changed to `hyperhv.dll`
|
||||
- Dividing user/kernel exported headers in the SDK
|
||||
|
||||
## [0.9.0.0] - 2024-06-09
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- The **!monitor** command now physical address hooking ([link](https://docs.hyperdbg.org/commands/extension-commands/monitor))
|
||||
- **hwdbg** is merged to HyperDbg codebase ([link](https://hwdbg.hyperdbg.org))
|
||||
- **strncmp(Str1, Str2, Num)**, and **wcsncmp(WStr1, WStr2, Num)** functions in script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/strncmp))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
|
||||
|
||||
### Changed
|
||||
- Using a separate HOST IDT in VMCS (not OS IDT) (fix to this [VM escape](https://www.unknowncheats.me/forum/c-and-c-/390593-vm-escape-via-nmi.html) issues)
|
||||
- Using a dedicated HOST GDT and TSS Stack
|
||||
- Checking for race-condition of not locked cores before applying instant-events and switching cores
|
||||
- The error message for invalid address is changed ([more information](https://docs.hyperdbg.org/tips-and-tricks/considerations/accessing-invalid-address))
|
||||
- Fix the problem of not locking all cores after running the '.pagein' command
|
||||
|
||||
## [0.8.4.0] - 2024-05-10
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Changed
|
||||
- Fixed the signedness overflow of the command parser
|
||||
|
||||
## [0.8.3.0] - 2024-05-03
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,21 +2,19 @@
|
|||
|
||||
First off, thanks for taking the time to contribute! ❤️
|
||||
|
||||
HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list, or if you want to implement one of the below items, or if you'd like to discuss a question you might have.
|
||||
HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list.
|
||||
|
||||
## Things to Work on
|
||||
|
||||
- Writing blog posts about use-cases of HyperDbg
|
||||
- Troubleshooting problems with running on Hyper-V's nested virtualization
|
||||
- Troubleshooting problems with running on VirtualBox's nested virtualization
|
||||
- Supporting kdnet (sending data over the net)
|
||||
- Adding an assembler to the project
|
||||
- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode), especially anti-hypervisor methods
|
||||
- Making a SoftICE-style GUI
|
||||
- Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command
|
||||
- Anything else you might find interesting ;)
|
||||
Please make sure to create a [discussion](https://github.com/orgs/HyperDbg/discussions) or an [issue](https://github.com/HyperDbg/HyperDbg/issues), or even better, join the HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) on social media. Discuss the way you want to implement your changes and inform developers, because we often see people simultaneously working on the same issue. To avoid this collision, make sure to inform us before you start developing.
|
||||
|
||||
This list will be updated frequently.
|
||||
### Working on an Idea or a Task
|
||||
- We have a [wide range of ideas and tasks](https://github.com/orgs/HyperDbg/projects/2) that you might be interested in working on. You can choose a task and start working on it, and if you have any questions or need clarification, feel free to ask. This list will be updated frequently.
|
||||
|
||||
### Other Things to Work on
|
||||
- Writing blog posts and creating videos about use-cases of HyperDbg (make sure to add it to the [awesome](https://github.com/HyperDbg/awesome) repository).
|
||||
- Fixing unresolved GitHub [issues](https://github.com/HyperDbg/HyperDbg/issues).
|
||||
- Any other interesting ideas you might find! (Let's have a discussion before working on them.)
|
||||
|
||||
## Fixing Bugs
|
||||
|
||||
|
|
|
|||
10
CREDITS.md
10
CREDITS.md
|
|
@ -4,7 +4,7 @@ The list provided comprises individuals who have made significant contributions
|
|||
|
||||
## Credits:
|
||||
|
||||
The attributions listed on this credits page are acknowledged without any particular order.
|
||||
Just so you know – the attributions listed on this credits page are acknowledged without any particular order.
|
||||
|
||||
- All of the [contributors](https://github.com/HyperDbg/HyperDbg/graphs/contributors)
|
||||
- Sina Karvandi ([@Intel80x86](https://twitter.com/Intel80x86))
|
||||
|
|
@ -21,4 +21,10 @@ The attributions listed on this credits page are acknowledged without any partic
|
|||
- Ddkwork ([@ddkwork](https://github.com/ddkwork)) for making GUI
|
||||
- Mohammad K. Fallah ([@mkfallah11](https://github.com/mkfallah11)) for implementing the optimization algorithms
|
||||
- Xandora Team ([xandora.io](https://www.xandora.io)) for [Keystone](https://github.com/keystone-engine/keystone) engine
|
||||
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
|
||||
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
|
||||
- Abbas Masoumi Gorji ([@AbbasMasoumiG](https://twitter.com/AbbasMasoumiG))
|
||||
- Björn Ruytenberg ([@0Xiphorus](https://twitter.com/0Xiphorus))
|
||||
- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3)) for his works on enhancing HyperEvade project
|
||||
- Artem Shishkin ([@honorary_bot](https://twitter.com/honorary_bot)) for always answering our hypervisor questions
|
||||
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
|
||||
- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)
|
||||
136
README.md
136
README.md
|
|
@ -6,25 +6,40 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/License-GPLv3-blue.svg" alt="License"></a>
|
||||
</p>
|
||||
|
||||
|
||||
# HyperDbg Debugger
|
||||
|
||||
<a href="https://hyperdbg.org/"><img align="right" width="150" height="150" src="https://github.com/HyperDbg/graphics/raw/master/Art%20Board/HyperDbg-Cat.Circle.Compressed.png" alt="HyperDbg Debugger"></a></br>
|
||||
HyperDbg Debugger is an open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
|
||||
**HyperDbg Debugger** is a free (as in free beer), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
|
||||
|
||||
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** to get notified about new releases, or join the HyperDbg **[Telegram](https://t.me/HyperDbg)** group, where you can ask developers and open-source reversing enthusiasts for help with setting up and running HyperDbg.
|
||||
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **[Mastodon](https://infosec.exchange/@hyperdbg)** to get notified about new releases, or join any of the HyperDbg groups, where you can ask developers and open-source reversing enthusiasts for help setting up and using HyperDbg.
|
||||
|
||||
- **[Telegram](https://t.me/HyperDbg)**
|
||||
- **[Discord](https://discord.gg/anSPsGUtzN)**
|
||||
- **[Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)**
|
||||
|
||||
## Description
|
||||
|
||||
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and Intel PT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
|
||||
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and EPT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
|
||||
<p align="center"><a href="https://hyperdbg.org/"><img align="center" width="600" height="500" src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Art%20Board/Artboard%201.png" alt="HyperDbg Debugger"></a></br>
|
||||
</p>
|
||||
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time entirely invisible for both Windows kernel and the programs, and of course, without any limitation in size or count!
|
||||
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time invisible for both the Windows kernel and the programs, and of course, without any limitation in size or count!
|
||||
|
||||
Using TLB-splitting, and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
|
||||
Using TLB-splitting and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
|
||||
|
||||
Although it has novel features, HyperDbg tries to be as stealthy as possible. It doesn’t use any debugging APIs to debug Windows or any application, so classic anti-debugging methods won’t detect it. Also, it resists the exploitation of time delta methods (e.g., RDTSC/RDTSCP) to detect the presence of hypervisors, therefore making it much harder for applications, packers, protectors, malware, anti-cheat engines, etc. to discover the debugger.
|
||||
|
||||
## Why HyperDbg?
|
||||
|
||||
HyperDbg is harder to set up and use, and also requires deeper low-level system knowledge compared to traditional debuggers. However, it provides two major advantages:
|
||||
|
||||
1. **Full System & OS Control**
|
||||
HyperDbg operates at the hypervisor level, giving you powerful capabilities that are simply not possible with classic debuggers. This allows you to leverage hardware-assisted [features](https://github.com/HyperDbg/HyperDbg?tab=readme-ov-file#unique-features) for advanced reverse engineering and debugging scenarios.
|
||||
|
||||
2. **Stealth & Detection Resistance**
|
||||
Since HyperDbg doesn't rely on standard OS debugging APIs, it is generally much harder (though not impossible) to detect. This makes it a strong choice when working against anti-debugging protections.
|
||||
|
||||
These advantages open up entirely new debugging and reverse engineering techniques that go beyond what conventional debuggers can offer.
|
||||
|
||||
## Build & Installation
|
||||
|
||||
You can download the latest compiled binary files from **[releases](https://github.com/HyperDbg/HyperDbg/releases)**; otherwise, if you want to build HyperDbg, you should clone HyperDbg with the `--recursive` flag.
|
||||
|
|
@ -35,7 +50,7 @@ Please visit **[Build & Install](https://docs.hyperdbg.org/getting-started/build
|
|||
|
||||
## Tutorials
|
||||
|
||||
The **[OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)"](https://ost2.fyi/Dbg3301)** tutorial is the recommended way to get started with and learn HyperDbg, guiding you through the initial steps of using HyperDbg, covering essential concepts, principles, debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
|
||||
The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (_preferred_) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
|
||||
|
||||
If you're interested in understanding the internal design and architecture of hypervisors and HyperDbg, you can read the [**Hypervisor From Scratch**](https://rayanfam.com/tutorials) tutorials.
|
||||
|
||||
|
|
@ -54,26 +69,71 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
|
|||
year={2022}
|
||||
}
|
||||
```
|
||||
<details>
|
||||
|
||||
**2. [The Reversing Machine: Reconstructing Memory Assumptions](https://arxiv.org/pdf/2405.00298)** [[arXiv](https://arxiv.org/abs/2405.00298)]
|
||||
<summary><b>Other paper built upon HyperDbg...</b></summary>
|
||||
|
||||
**2. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
|
||||
|
||||
```
|
||||
@misc{karvandi2024reversing,
|
||||
Author = {Mohammad Sina Karvandi and Soroush Meghdadizanjani and Sima Arasteh and Saleh Khalaj Monfared and Mohammad K. Fallah and Saeid Gorgin and Jeong-A Lee and Erik van der Kouwe},
|
||||
Title = {The Reversing Machine: Reconstructing Memory Assumptions},
|
||||
Year = {2024},
|
||||
Eprint = {arXiv:2405.00298},
|
||||
@inproceedings{karvandi2025hwdbg,
|
||||
title={hwdbg: Debugging Hardware Like Software},
|
||||
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
|
||||
booktitle={Proceedings of the 18th European Workshop on Systems Security},
|
||||
pages={56--62},
|
||||
year={2025}
|
||||
}
|
||||
```
|
||||
|
||||
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design.html) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/debugger/transparency.html) about our efforts on vm-exit transparency, and [this article](https://research.hyperdbg.org/debugger/chasing-bugs.html) about chasing bugs within hypervisors. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
|
||||
**3. [HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg (DEBT'25)](https://www.jot.fm/contents/issue_2026_01/a8.html)** [[PDF](https://www.jot.fm/issues/issue_2026_01/a8.pdf)]
|
||||
|
||||
```
|
||||
@article{ruytenberg2026hyperevade,
|
||||
title={HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg},
|
||||
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina},
|
||||
journal={Journal of Object Technology},
|
||||
volume={25},
|
||||
number={1},
|
||||
pages={1--3},
|
||||
year={2026},
|
||||
publisher={Association Internationale pour les Technologies Objets}
|
||||
}
|
||||
```
|
||||
|
||||
**4. [Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher (EuroSys'26)](https://dl.acm.org/doi/abs/10.1145/3767295.3803583)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3767295.3803583)]
|
||||
|
||||
```
|
||||
@inproceedings{ruytenberg2026digital,
|
||||
title={Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher},
|
||||
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina and Bos, Herbert and van der Kouwe, Erik and Slowinska, Asia},
|
||||
booktitle={Proceedings of the 21st European Conference on Computer Systems},
|
||||
pages={484--496},
|
||||
year={2026}
|
||||
}
|
||||
```
|
||||
|
||||
**5. [TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction (AsiaCCS'26)](https://dl.acm.org/doi/10.1145/3779208.3785293)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3779208.3785293)]
|
||||
|
||||
```
|
||||
@inproceedings{karvandi2026trm,
|
||||
title={TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction},
|
||||
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and Slowinska, Asia and van der Kouwe, Erik},
|
||||
booktitle={Proceedings of the ACM Asia Conference on Computer and Communications Security},
|
||||
pages={68--82},
|
||||
year={2026}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design/) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/vmm/transparency/) about our efforts on vm-exit transparency, [this article](https://research.hyperdbg.org/debugger/chasing-bugs/) about chasing bugs within hypervisors, and [this article](https://research.hyperdbg.org/debugger/gaining-insights/) about new reverse engineering techniques introduced in HyperDbg. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
|
||||
|
||||
## Unique Features
|
||||
### First Release (v0.1.0.0)
|
||||
|
||||
* Advanced Hypervisor-based Kernel Mode Debugger [<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging" target="_blank">link</a>]
|
||||
* Classic EPT Hook (Hidden Breakpoint) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/hooking-any-function" target="_blank">link</a>]
|
||||
* Inline EPT Hook (Inline Hook) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook2" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook2" target="_blank">link</a>]
|
||||
* Monitor Memory For R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
|
||||
* Monitor Memory for R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
|
||||
* SYSCALL Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/syscall" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/intercepting-all-syscalls" target="_blank">link</a>]
|
||||
* SYSRET Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>]
|
||||
* CPUID Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/cpuid" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
|
||||
|
|
@ -83,15 +143,15 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
|
|||
* RDPMC Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/pmc" target="_blank">link</a>]
|
||||
* VMCALL Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/vmcall" target="_blank">link</a>]
|
||||
* Debug Registers Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/dr" target="_blank">link</a>]
|
||||
* I/O Port (In Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
|
||||
* I/O Port (Out Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
|
||||
* I/O Port (IN Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
|
||||
* I/O Port (OUT Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
|
||||
* MMIO Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
|
||||
* Exception (IDT < 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/exception" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
|
||||
* External-Interrupt (IDT > 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
|
||||
* Running Automated Scripts [<a href="https://docs.hyperdbg.org/commands/scripting-language/debugger-script" target="_blank">link</a>]
|
||||
* Transparent-mode (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/misc/defeating-anti-debug-and-anti-hypervisor-methods" target="_blank">link</a>]
|
||||
* Running Custom Assembly In Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
|
||||
* Checking For Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
|
||||
* Transparent-mode and Hyperevade Project (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/hide" target="_blank">link</a>][<a href="https://www.vusec.net/projects/hyperevade/" target="_blank">link</a>]
|
||||
* Running Custom Assembly in Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
|
||||
* Checking for Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
|
||||
* Process-specific & Thread-specific Debugging [<a href="https://docs.hyperdbg.org/commands/meta-commands/.process" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/meta-commands/.thread" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/user-mode-debugging/examples/basics/switching-to-a-specific-process-or-thread" target="_blank">link</a>]
|
||||
* VMX-root Compatible Message Tracing [<a href="https://docs.hyperdbg.org/design/features/vmm-module/vmx-root-mode-compatible-message-tracing" target="_blank">link</a>]
|
||||
* Powerful Kernel Side Scripting Engine [<a href="https://docs.hyperdbg.org/commands/scripting-language" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/script-engine" target="_blank">link</a>]
|
||||
|
|
@ -100,30 +160,26 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
|
|||
* Event Forwarding (#DFIR) [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/debugging-commands/output" target="_blank">link</a>]
|
||||
* Transparent Breakpoint Handler [<a href="https://docs.hyperdbg.org/commands/debugging-commands/bp" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/basics/setting-breakpoints-and-stepping-instructions" target="_blank">link</a>]
|
||||
* Various Custom Scripts [<a href="https://github.com/HyperDbg/scripts" target="_blank">link</a>]
|
||||
|
||||
### Second Release (v0.2.0.0)
|
||||
* HyperDbg Software Development Kit (SDK) [<a href="https://docs.hyperdbg.org/using-hyperdbg/sdk" target="_blank">link</a>]
|
||||
|
||||
### Third Release (v0.3.0.0)
|
||||
* Event Short-circuiting [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_sc" target="_blank">link</a>]
|
||||
* Tracking records of function calls and return addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
|
||||
* Tracking Records of Function Calls and Return Addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
|
||||
* Kernel-level Length Disassembler Engine (LDE) [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len32" target="_blank">link</a>]
|
||||
|
||||
### Fourth Release (v0.4.0.0)
|
||||
* Memory Execution Monitor & Execution Blocking [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
|
||||
* Custom Page-fault Injection [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pagein" target="_blank">link</a>]
|
||||
|
||||
### Fifth Release (v0.5.0.0)
|
||||
* Different Event Calling Stages [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-calling-stage" target="_blank">link</a>]
|
||||
|
||||
### Sixth Release (v0.6.0.0)
|
||||
* Injecting Custom Interrupts/Exceptions/Faults [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject_error_code" target="_blank">link</a>]
|
||||
|
||||
### Seventh Release (v0.7.0.0)
|
||||
* Instant events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
|
||||
|
||||
### Eighth Release (v0.8.0.0)
|
||||
* Detect kernel-to-user and user-to-kernel transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
|
||||
* Instant Events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
|
||||
* Detecting Kernel-to-user and User-to-kernel Transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
|
||||
* Physical Memory Monitoring Hooks [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
|
||||
* Enumerating PCI/PCI-e Devices [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcitree" target="_blank">link</a>]
|
||||
* Interpreting and Dumping PCI/PCI-e Configuration Space (CAM) [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcicam" target="_blank">link</a>]
|
||||
* Dumping IDT Entries, I/O APIC, and Local APIC in XAPIC and X2APIC Modes [<a href="https://docs.hyperdbg.org/commands/extension-commands/idt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/ioapic" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/apic" target="_blank">link</a>]
|
||||
* Triggering and Counting System Management Mode (SMM) Interrupts (SMIs) [<a href="https://docs.hyperdbg.org/commands/extension-commands/smi" target="_blank">link</a>]
|
||||
* Attaching to the User-mode Process and Preventing Execution [<a href="https://docs.hyperdbg.org/commands/meta-commands/.attach" target="_blank">link</a>]
|
||||
* Intercepting Execution of XSETBV Instructions [<a href="https://docs.hyperdbg.org/commands/extension-commands/xsetbv" target="_blank">link</a>]
|
||||
* Writing Library Script Files [<a href="https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion" target="_blank">link</a>]
|
||||
* Enhanced Portable Executable (PE) Parser [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pe" target="_blank">link</a>]
|
||||
* Tracing Branches using Last Branch Record (LBR) [<a href="https://docs.hyperdbg.org/commands/extension-commands/lbr" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/lbrdump" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter" target="_blank">link</a>]
|
||||
|
||||
## How does it work?
|
||||
|
||||
|
|
@ -135,15 +191,17 @@ You can read about the internal design of HyperDbg and its features in the [docu
|
|||
</br>
|
||||
|
||||
## Scripts
|
||||
|
||||
You can write your **[scripts](https://github.com/HyperDbg/scripts)** to automate your debugging journey. **HyperDbg** has a powerful, fast, and entirely kernel-side implemented [script engine](https://docs.hyperdbg.org/commands/scripting-language).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributing to HyperDbg is super appreciated. We have made a list of potential [tasks](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md#things-to-work-on) that you might be interested in contributing towards.
|
||||
|
||||
If you want to contribute to HyperDbg, please read the [Contribution Guide](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
**HyperDbg**, and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
|
||||
|
||||
Dependencies are licensed by their own.
|
||||
|
|
|
|||
3
examples/README.md
Normal file
3
examples/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# User-Mode and Kernel-Mode Examples
|
||||
|
||||
Examples for user-mode and kernel-mode are **NOT** yet completed and are currently **under construction**!
|
||||
3
examples/kernel/README.md
Normal file
3
examples/kernel/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
NOTE
|
||||
============
|
||||
Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.
|
||||
20
examples/kernel/hyperdbg_driver/CMakeLists.txt
Normal file
20
examples/kernel/hyperdbg_driver/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Code generated by Visual Studio kit, DO NOT EDIT.
|
||||
set(SourceFiles
|
||||
"header/core/Core.h"
|
||||
"header/driver/Driver.h"
|
||||
"header/driver/Loader.h"
|
||||
"header/misc/Global.h"
|
||||
"header/pch.h"
|
||||
"code/core/Core.c"
|
||||
"code/driver/Driver.c"
|
||||
"code/driver/Ioctl.c"
|
||||
"code/driver/Loader.c"
|
||||
)
|
||||
include_directories(
|
||||
"../../../hyperdbg/include"
|
||||
"header"
|
||||
)
|
||||
wdk_add_driver(hyperdbg_driver
|
||||
KMDF 1.15
|
||||
${SourceFiles}
|
||||
)
|
||||
|
|
@ -83,6 +83,7 @@ DriverEntry(
|
|||
//
|
||||
DbgPrint("HyperDbg's device and major functions are loaded");
|
||||
|
||||
|
||||
ASSERT(NT_SUCCESS(Ntstatus));
|
||||
return Ntstatus;
|
||||
}
|
||||
|
|
@ -105,7 +106,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
|
|||
//
|
||||
// Unloading VMM and Debugger
|
||||
//
|
||||
LoaderUninitializeLogTracer();
|
||||
LoaderUninitLogTracer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -26,15 +26,17 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
PREGISTER_NOTIFY_BUFFER RegisterEventRequest;
|
||||
NTSTATUS Status;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
//
|
||||
// Here's the best place to see if there is any allocation pending
|
||||
// to be allcated as we're in PASSIVE_LEVEL
|
||||
//
|
||||
// DO NOT CHANGE CALLING OF THE FOLLOWING FUNCTION
|
||||
//
|
||||
PoolManagerCheckAndPerformAllocationAndDeallocation();
|
||||
// PoolManagerCheckAndPerformAllocationAndDeallocation();
|
||||
|
||||
if (g_AllowIOCTLFromUsermode)
|
||||
if (g_VmmInitialized)
|
||||
{
|
||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
|
@ -62,10 +64,21 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
switch (RegisterEventRequest->Type)
|
||||
{
|
||||
case IRP_BASED:
|
||||
Status = LogRegisterIrpBasedNotification(DeviceObject, Irp);
|
||||
|
||||
LogRegisterIrpBasedNotification((PVOID)Irp, &Status);
|
||||
|
||||
break;
|
||||
case EVENT_BASED:
|
||||
Status = LogRegisterEventBasedNotification(DeviceObject, Irp);
|
||||
|
||||
if (LogRegisterEventBasedNotification((PVOID)Irp))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
LogError("Err, unknown notification type from user-mode");
|
||||
|
|
@ -24,7 +24,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
//
|
||||
// Allow to server IOCTL
|
||||
//
|
||||
g_AllowIOCTLFromUsermode = TRUE;
|
||||
g_VmmInitialized = TRUE;
|
||||
|
||||
//
|
||||
// Fill the callbacks for the message tracer
|
||||
|
|
@ -90,7 +90,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
//
|
||||
// Not loaded
|
||||
//
|
||||
g_AllowIOCTLFromUsermode = FALSE;
|
||||
g_VmmInitialized = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LoaderUninitializeLogTracer()
|
||||
LoaderUninitLogTracer()
|
||||
{
|
||||
LogDebugInfo("Unloading HyperDbg's debugger...\n");
|
||||
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
//////////////////////////////////////////////////
|
||||
|
||||
VOID
|
||||
LoaderUninitializeLogTracer();
|
||||
LoaderUninitLogTracer();
|
||||
|
||||
BOOLEAN
|
||||
LoaderInitVmmAndReversingMachine();
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
BOOLEAN g_HandleInUse;
|
||||
|
||||
/**
|
||||
* @brief Determines whether the clients are allowed to send IOCTL to the drive or not
|
||||
* @brief Shows whether the VMM is initialized or not
|
||||
*
|
||||
*/
|
||||
BOOLEAN g_AllowIOCTLFromUsermode;
|
||||
BOOLEAN g_VmmInitialized;
|
||||
|
|
@ -9,12 +9,6 @@
|
|||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h>
|
||||
#include <wdf.h>
|
||||
#include <wdm.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <Windef.h>
|
||||
|
||||
//
|
||||
// Scope definitions
|
||||
|
|
@ -23,14 +17,15 @@
|
|||
#define HYPERDBG_RM
|
||||
|
||||
//
|
||||
// Definition of Intel primitives (External header)
|
||||
// General WDK headers
|
||||
//
|
||||
// #include "ia32-doc/out/ia32.h"
|
||||
#include <ntifs.h>
|
||||
#include <Windef.h>
|
||||
|
||||
//
|
||||
// Import Configuration and Definitions
|
||||
//
|
||||
#include "Configuration.h"
|
||||
#include "config/Configuration.h"
|
||||
|
||||
//
|
||||
// Macros
|
||||
|
|
@ -45,15 +40,15 @@
|
|||
//
|
||||
// Import HyperLog Module
|
||||
//
|
||||
#include "SDK/Modules/HyperLog.h"
|
||||
#include "SDK/Imports/HyperDbgHyperLogImports.h"
|
||||
#include "SDK/Imports/HyperDbgHyperLogIntrinsics.h"
|
||||
#include "SDK/modules/HyperLog.h"
|
||||
#include "SDK/imports/kernel/HyperDbgHyperLogImports.h"
|
||||
#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
|
||||
|
||||
//
|
||||
// Import VMM Module
|
||||
//
|
||||
#include "SDK/Modules/VMM.h"
|
||||
#include "SDK/Imports/HyperDbgVmmImports.h"
|
||||
#include "SDK/modules/VMM.h"
|
||||
#include "SDK/imports/kernel/HyperDbgVmmImports.h"
|
||||
|
||||
//
|
||||
// Local Driver headers
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
|
||||
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
|
||||
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="debug|x64">
|
||||
<Configuration>debug</Configuration>
|
||||
|
|
@ -9,14 +12,6 @@
|
|||
<Configuration>release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="debug|ARM64">
|
||||
<Configuration>debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="release|ARM64">
|
||||
<Configuration>release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}</ProjectGuid>
|
||||
|
|
@ -47,22 +42,6 @@
|
|||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
|
@ -81,18 +60,12 @@
|
|||
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
|
|
@ -101,7 +74,7 @@
|
|||
</ClCompile>
|
||||
<Link>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
|
@ -110,29 +83,20 @@
|
|||
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<Optimization>Full</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM64'">
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM64'">
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
|
|
@ -149,7 +113,20 @@
|
|||
<ClCompile Include="code\driver\Ioctl.c" />
|
||||
<ClCompile Include="code\driver\Loader.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -56,4 +56,7 @@
|
|||
<Filter>code\driver</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
examples/kernel/hyperdbg_driver/packages.config
Normal file
6
examples/kernel/hyperdbg_driver/packages.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
|
||||
</packages>
|
||||
3
examples/user/README.md
Normal file
3
examples/user/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
NOTE
|
||||
============
|
||||
Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.
|
||||
11
examples/user/hyperdbg_app/CMakeLists.txt
Normal file
11
examples/user/hyperdbg_app/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Code generated by Visual Studio kit, DO NOT EDIT.
|
||||
set(SourceFiles
|
||||
"../../../platform/user/header/Environment.h"
|
||||
"header/pch.h"
|
||||
"code/hyperdbg-app.cpp"
|
||||
)
|
||||
include_directories(
|
||||
"../../../hyperdbg/include"
|
||||
"header"
|
||||
)
|
||||
add_executable(hyperdbg_app ${SourceFiles})
|
||||
58
examples/user/hyperdbg_app/code/hyperdbg-app.cpp
Normal file
58
examples/user/hyperdbg_app/code/hyperdbg-app.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include "pch.h"
|
||||
|
||||
static int
|
||||
ShowMessages(const char * Text)
|
||||
{
|
||||
printf("%s", Text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
LoadVmm()
|
||||
{
|
||||
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
|
||||
|
||||
if (!hyperdbg_u_detect_vmx_support())
|
||||
{
|
||||
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[*] loading HyperDbg VMM...\n");
|
||||
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
|
||||
{
|
||||
printf("[-] cannot load the HyperDbg VMM\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[+] HyperDbg VMM is running\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
return main2(argc, argv);
|
||||
|
||||
if (LoadVmm() != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
hyperdbg_u_run_command((CHAR*)"lm");
|
||||
|
||||
printf("[*] unloading HyperDbg VMM...\n");
|
||||
|
||||
//
|
||||
// Unload the driver
|
||||
//
|
||||
hyperdbg_u_unload_vmm();
|
||||
hyperdbg_u_unload_kd();
|
||||
hyperdbg_u_stop_kd_driver();
|
||||
hyperdbg_u_uninstall_kd_driver();
|
||||
|
||||
printf("[+] done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
583
examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
Normal file
583
examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dbghelp.h>
|
||||
#include "../dependencies/libipt/intel-pt.h"
|
||||
#include <Zydis/Zydis.h>
|
||||
|
||||
#pragma comment(lib, "dbghelp.lib")
|
||||
|
||||
static UINT64 g_ImageBase = 0;
|
||||
static UINT64 g_CodeBase = 0;
|
||||
static UINT64 g_CodeSize = 0;
|
||||
static UINT8 * g_Code = NULL;
|
||||
|
||||
static int
|
||||
ShowMessages(const char * Text)
|
||||
{
|
||||
printf("%s", Text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ReadImage(uint8_t * Buffer, size_t Size, const struct pt_asid * Asid, uint64_t Ip, void * Context)
|
||||
{
|
||||
(void)Asid;
|
||||
(void)Context;
|
||||
|
||||
if (g_Code == NULL || Ip < g_CodeBase || Ip >= g_CodeBase + g_CodeSize)
|
||||
return -pte_nomap;
|
||||
|
||||
uint64_t Available = g_CodeBase + g_CodeSize - Ip;
|
||||
size_t Count = (Size < Available) ? Size : (size_t)Available;
|
||||
|
||||
memcpy(Buffer, g_Code + (Ip - g_CodeBase), Count);
|
||||
return (int)Count;
|
||||
}
|
||||
|
||||
typedef struct _PROC_BASIC_INFO
|
||||
{
|
||||
LONG ExitStatus;
|
||||
PVOID PebBaseAddress;
|
||||
ULONG_PTR Reserved[4];
|
||||
} PROC_BASIC_INFO;
|
||||
|
||||
typedef LONG(NTAPI * PFN_NT_QIP)(HANDLE, ULONG, PVOID, ULONG, PULONG);
|
||||
|
||||
static BOOLEAN
|
||||
CaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd)
|
||||
{
|
||||
HMODULE Ntdll = GetModuleHandleA("ntdll.dll");
|
||||
PFN_NT_QIP NtQip = Ntdll ? (PFN_NT_QIP)GetProcAddress(Ntdll, "NtQueryInformationProcess") : NULL;
|
||||
PROC_BASIC_INFO Pbi = {0};
|
||||
ULONG Ret = 0;
|
||||
SIZE_T Got = 0;
|
||||
UINT64 Base = 0;
|
||||
IMAGE_DOS_HEADER Dos;
|
||||
IMAGE_NT_HEADERS64 Nt;
|
||||
UINT64 SectionBase;
|
||||
|
||||
if (NtQip == NULL || NtQip(Process, 0, &Pbi, sizeof(Pbi), &Ret) < 0 || Pbi.PebBaseAddress == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!ReadProcessMemory(Process, (PBYTE)Pbi.PebBaseAddress + 0x10, &Base, sizeof(Base), &Got) || Base == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!ReadProcessMemory(Process, (PVOID)Base, &Dos, sizeof(Dos), &Got) || Dos.e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return FALSE;
|
||||
|
||||
if (!ReadProcessMemory(Process, (PBYTE)Base + Dos.e_lfanew, &Nt, sizeof(Nt), &Got) || Nt.Signature != IMAGE_NT_SIGNATURE)
|
||||
return FALSE;
|
||||
|
||||
g_ImageBase = Base;
|
||||
SectionBase = Base + Dos.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader) + Nt.FileHeader.SizeOfOptionalHeader;
|
||||
|
||||
for (WORD i = 0; i < Nt.FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
IMAGE_SECTION_HEADER Section;
|
||||
|
||||
if (!ReadProcessMemory(Process, (PBYTE)SectionBase + (UINT64)i * sizeof(Section), &Section, sizeof(Section), &Got))
|
||||
return FALSE;
|
||||
|
||||
if (memcmp(Section.Name, ".text", 6) != 0)
|
||||
continue;
|
||||
|
||||
UINT64 Start = Base + Section.VirtualAddress;
|
||||
UINT64 Size = Section.Misc.VirtualSize ? Section.Misc.VirtualSize : Section.SizeOfRawData;
|
||||
|
||||
if (Size == 0)
|
||||
return FALSE;
|
||||
|
||||
g_Code = (UINT8 *)malloc((size_t)Size);
|
||||
if (g_Code == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!ReadProcessMemory(Process, (PVOID)Start, g_Code, (SIZE_T)Size, &Got) || Got != Size)
|
||||
{
|
||||
free(g_Code);
|
||||
g_Code = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_CodeBase = Start;
|
||||
g_CodeSize = Size;
|
||||
*TextStart = Start;
|
||||
*TextEnd = Start + Size - 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
ResolveFunction(HANDLE Process, const char * Path, const char * Name, UINT64 * Start, UINT64 * End)
|
||||
{
|
||||
union
|
||||
{
|
||||
SYMBOL_INFO Info;
|
||||
BYTE Buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
|
||||
} Symbol = {0};
|
||||
BOOLEAN Ok = FALSE;
|
||||
|
||||
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
||||
if (!SymInitialize(Process, NULL, FALSE))
|
||||
return FALSE;
|
||||
|
||||
if (SymLoadModuleEx(Process, NULL, Path, NULL, (DWORD64)g_ImageBase, 0, NULL, 0) != 0)
|
||||
{
|
||||
Symbol.Info.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
Symbol.Info.MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
if (SymFromName(Process, Name, &Symbol.Info) && Symbol.Info.Address != 0)
|
||||
{
|
||||
*Start = Symbol.Info.Address;
|
||||
*End = Symbol.Info.Address + (Symbol.Info.Size ? Symbol.Info.Size : 0x200) - 1;
|
||||
Ok = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SymCleanup(Process);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE Type)
|
||||
{
|
||||
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
|
||||
Op.PtOperationType = Type;
|
||||
return hyperdbg_u_pt_operation(&Op);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
PtFilter(UINT32 ProcessId, UINT64 Start, UINT64 End)
|
||||
{
|
||||
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
|
||||
|
||||
Op.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
|
||||
Op.FilterOptions.TraceUser = 1;
|
||||
Op.EnableOptions.Pid = ProcessId;
|
||||
|
||||
if (End > Start)
|
||||
{
|
||||
Op.FilterOptions.NumAddrRanges = 1;
|
||||
Op.FilterOptions.AddrRanges[0].Start = Start;
|
||||
Op.FilterOptions.AddrRanges[0].End = End;
|
||||
}
|
||||
|
||||
if (!hyperdbg_u_pt_operation(&Op))
|
||||
return FALSE;
|
||||
|
||||
printf("[+] PT filter: cr3=0x%llx traceuser=%u ranges=%u buffer=0x%llx\n",
|
||||
(unsigned long long)Op.EnableOptions.Cr3,
|
||||
Op.FilterOptions.TraceUser,
|
||||
Op.FilterOptions.NumAddrRanges,
|
||||
(unsigned long long)Op.BufferSize);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
PacketName(enum pt_packet_type Type)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case ppt_psb: return "PSB"; case ppt_psbend: return "PSBEND"; case ppt_pad: return "PAD";
|
||||
case ppt_fup: return "FUP"; case ppt_tip: return "TIP"; case ppt_tip_pge: return "TIP.PGE";
|
||||
case ppt_tip_pgd: return "TIP.PGD"; case ppt_tnt_8: return "TNT8"; case ppt_tnt_64: return "TNT64";
|
||||
case ppt_mode: return "MODE"; case ppt_pip: return "PIP"; case ppt_vmcs: return "VMCS";
|
||||
case ppt_cbr: return "CBR"; case ppt_tsc: return "TSC"; case ppt_tma: return "TMA";
|
||||
case ppt_mtc: return "MTC"; case ppt_cyc: return "CYC"; case ppt_ovf: return "OVF";
|
||||
case ppt_stop: return "STOP"; case ppt_exstop: return "EXSTOP"; case ppt_mnt: return "MNT";
|
||||
case ppt_ptw: return "PTW"; default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
ReconstructIp(const struct pt_packet_ip * Packet, uint64_t * LastIp)
|
||||
{
|
||||
uint64_t Value = *LastIp;
|
||||
|
||||
switch (Packet->ipc)
|
||||
{
|
||||
case pt_ipc_update_16: Value = (Value & ~0xffffull) | (Packet->ip & 0xffffull); break;
|
||||
case pt_ipc_update_32: Value = (Value & ~0xffffffffull) | (Packet->ip & 0xffffffffull); break;
|
||||
case pt_ipc_update_48: Value = (Value & ~0xffffffffffffull) | (Packet->ip & 0xffffffffffffull); break;
|
||||
case pt_ipc_sext_48:
|
||||
Value = Packet->ip & 0xffffffffffffull;
|
||||
if (Value & 0x800000000000ull)
|
||||
Value |= 0xffff000000000000ull;
|
||||
break;
|
||||
default: Value = Packet->ip; break;
|
||||
}
|
||||
|
||||
*LastIp = Value;
|
||||
return Value;
|
||||
}
|
||||
|
||||
static UINT64
|
||||
DecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
|
||||
{
|
||||
struct pt_config Config;
|
||||
struct pt_packet_decoder * Decoder;
|
||||
UINT64 Count = 0;
|
||||
uint64_t LastIp = 0;
|
||||
int Status;
|
||||
|
||||
pt_config_init(&Config);
|
||||
Config.begin = (uint8_t *)Buffer;
|
||||
Config.end = (uint8_t *)Buffer + Size;
|
||||
|
||||
Decoder = pt_pkt_alloc_decoder(&Config);
|
||||
if (Decoder == NULL)
|
||||
{
|
||||
printf("[-] core %u: cannot allocate packet decoder\n", Cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Status = pt_pkt_sync_forward(Decoder);
|
||||
if (Status < 0)
|
||||
break;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct pt_packet Packet;
|
||||
|
||||
Status = pt_pkt_next(Decoder, &Packet, sizeof(Packet));
|
||||
if (Status < 0)
|
||||
break;
|
||||
|
||||
Count++;
|
||||
|
||||
switch (Packet.type)
|
||||
{
|
||||
case ppt_tnt_8:
|
||||
case ppt_tnt_64:
|
||||
printf(" %-8s %2u ", PacketName(Packet.type), Packet.payload.tnt.bit_size);
|
||||
for (uint8_t Bit = 0; Bit < Packet.payload.tnt.bit_size && Bit < 64; Bit++)
|
||||
putchar(((Packet.payload.tnt.payload >> (Packet.payload.tnt.bit_size - 1 - Bit)) & 1) ? 'T' : 'N');
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case ppt_tip:
|
||||
case ppt_fup:
|
||||
case ppt_tip_pge:
|
||||
case ppt_tip_pgd:
|
||||
if (Packet.payload.ip.ipc == pt_ipc_suppressed)
|
||||
printf(" %-8s (ip suppressed)\n", PacketName(Packet.type));
|
||||
else
|
||||
{
|
||||
uint64_t Ip = ReconstructIp(&Packet.payload.ip, &LastIp);
|
||||
printf(" %-8s 0x%016llx exe+0x%llx\n",
|
||||
PacketName(Packet.type), (unsigned long long)Ip, (unsigned long long)(Ip - g_ImageBase));
|
||||
}
|
||||
break;
|
||||
|
||||
case ppt_pip:
|
||||
printf(" %-8s cr3=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.pip.cr3);
|
||||
break;
|
||||
|
||||
case ppt_cbr:
|
||||
//printf(" %-8s ratio=%u\n", PacketName(Packet.type), Packet.payload.cbr.ratio);
|
||||
break;
|
||||
|
||||
case ppt_tsc:
|
||||
printf(" %-8s tsc=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.tsc.tsc);
|
||||
break;
|
||||
|
||||
default:
|
||||
//printf(" %-8s\n", PacketName(Packet.type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pt_pkt_free_decoder(Decoder);
|
||||
return Count;
|
||||
}
|
||||
|
||||
static UINT64
|
||||
DecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
|
||||
{
|
||||
struct pt_config Config;
|
||||
struct pt_insn_decoder * Decoder;
|
||||
struct pt_image * Image;
|
||||
UINT64 Count = 0;
|
||||
int Status;
|
||||
|
||||
pt_config_init(&Config);
|
||||
Config.begin = (uint8_t *)Buffer;
|
||||
Config.end = (uint8_t *)Buffer + Size;
|
||||
|
||||
Decoder = pt_insn_alloc_decoder(&Config);
|
||||
if (Decoder == NULL)
|
||||
{
|
||||
printf("[-] core %u: cannot allocate instruction decoder\n", Cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Image = pt_insn_get_image(Decoder);
|
||||
pt_image_set_callback(Image, ReadImage, NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Status = pt_insn_sync_forward(Decoder);
|
||||
if (Status < 0)
|
||||
break;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct pt_insn Insn;
|
||||
|
||||
while (Status & pts_event_pending)
|
||||
{
|
||||
struct pt_event Event;
|
||||
Status = pt_insn_event(Decoder, &Event, sizeof(Event));
|
||||
if (Status < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status < 0 || (Status & pts_eos))
|
||||
break;
|
||||
|
||||
Status = pt_insn_next(Decoder, &Insn, sizeof(Insn));
|
||||
if (Status < 0)
|
||||
break;
|
||||
|
||||
ZydisDisassembledInstruction Disasm;
|
||||
ZydisMachineMode Mode = (Insn.mode == ptem_32bit) ? ZYDIS_MACHINE_MODE_LEGACY_32 : ZYDIS_MACHINE_MODE_LONG_64;
|
||||
|
||||
if (ZYAN_SUCCESS(ZydisDisassembleIntel(Mode, Insn.ip, Insn.raw, Insn.size, &Disasm)))
|
||||
printf(" 0x%016llx exe+0x%-6llx %s\n",
|
||||
(unsigned long long)Insn.ip,
|
||||
(unsigned long long)(Insn.ip - g_ImageBase),
|
||||
Disasm.text);
|
||||
else
|
||||
printf(" 0x%016llx (undecodable)\n", (unsigned long long)Insn.ip);
|
||||
|
||||
Count++;
|
||||
}
|
||||
|
||||
if (Status >= 0 && (Status & pts_eos))
|
||||
break;
|
||||
}
|
||||
|
||||
pt_insn_free_decoder(Decoder);
|
||||
return Count;
|
||||
}
|
||||
|
||||
static void
|
||||
RunAndTrace(const char * Path, const char * Function, BOOLEAN Packets, int PinCore)
|
||||
{
|
||||
STARTUPINFOA Startup = {0};
|
||||
PROCESS_INFORMATION Process = {0};
|
||||
HYPERTRACE_PT_MMAP_PACKETS Mmap = {0};
|
||||
HYPERTRACE_PT_OPERATION_PACKETS Sizes = {0};
|
||||
UINT64 TextStart = 0;
|
||||
UINT64 TextEnd = 0;
|
||||
UINT64 FilterStart = 0;
|
||||
UINT64 FilterEnd = 0;
|
||||
UINT64 Total = 0;
|
||||
|
||||
Startup.cb = sizeof(Startup);
|
||||
|
||||
if (!CreateProcessA(Path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &Startup, &Process))
|
||||
{
|
||||
printf("[-] cannot launch '%s' (error 0x%x)\n", Path, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
printf("[+] launched '%s' (pid %u, suspended)\n", Path, Process.dwProcessId);
|
||||
|
||||
if (PinCore >= 0)
|
||||
{
|
||||
DWORD_PTR Mask = (DWORD_PTR)1 << PinCore;
|
||||
if (SetProcessAffinityMask(Process.hProcess, Mask))
|
||||
printf("[+] pinned target to core %d (all trace should land on this core)\n", PinCore);
|
||||
else
|
||||
printf("[!] could not pin to core %d (error 0x%x); running unpinned\n", PinCore, GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[*] target unpinned (scheduler may migrate it across cores)\n");
|
||||
}
|
||||
|
||||
if (!CaptureImage(Process.hProcess, &TextStart, &TextEnd))
|
||||
{
|
||||
printf("[-] cannot read target image / .text section\n");
|
||||
TerminateProcess(Process.hProcess, 1);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
printf("[+] image base 0x%llx, .text 0x%llx-0x%llx (%llu bytes)\n",
|
||||
(unsigned long long)g_ImageBase,
|
||||
(unsigned long long)TextStart,
|
||||
(unsigned long long)TextEnd,
|
||||
(unsigned long long)g_CodeSize);
|
||||
|
||||
FilterStart = TextStart;
|
||||
FilterEnd = TextEnd;
|
||||
|
||||
if (Function != NULL && ResolveFunction(Process.hProcess, Path, Function, &FilterStart, &FilterEnd)) {
|
||||
printf("[+] IP filter narrowed to '%s' 0x%llx-0x%llx (%llu bytes)\n",
|
||||
Function,
|
||||
(unsigned long long)FilterStart,
|
||||
(unsigned long long)FilterEnd,
|
||||
(unsigned long long)(FilterEnd - FilterStart + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[!] IP filter: whole .text (symbol '%s' not found - build the target with a PDB)\n",
|
||||
Function ? Function : "(none)");
|
||||
}
|
||||
|
||||
if (!PtFilter(Process.dwProcessId, FilterStart, FilterEnd) ||
|
||||
!PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE))
|
||||
{
|
||||
printf("[-] cannot enable Intel PT\n");
|
||||
TerminateProcess(Process.hProcess, 1);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!hyperdbg_u_pt_mmap(&Mmap))
|
||||
{
|
||||
printf("[-] pt_mmap failed\n");
|
||||
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
|
||||
TerminateProcess(Process.hProcess, 1);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
printf("[+] PT enabled, %u per-core buffers mapped\n", Mmap.NumCpus);
|
||||
printf("[*] resuming target and waiting for it to exit...\n");
|
||||
|
||||
ResumeThread(Process.hThread);
|
||||
WaitForSingleObject(Process.hProcess, INFINITE);
|
||||
printf("[+] target exited, decoding trace\n");
|
||||
|
||||
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE);
|
||||
|
||||
Sizes.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE;
|
||||
if (!hyperdbg_u_pt_operation(&Sizes))
|
||||
{
|
||||
printf("[-] cannot query PT sizes\n");
|
||||
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
for (UINT32 i = 0; i < Mmap.NumCpus; i++)
|
||||
{
|
||||
UINT32 Cpu = Mmap.Cpus[i].CpuId;
|
||||
UINT64 Bytes = (Cpu < Sizes.NumCpus) ? Sizes.BytesPerCpu[Cpu] : 0;
|
||||
|
||||
if (Bytes == 0)
|
||||
continue;
|
||||
|
||||
if (Bytes > Mmap.Cpus[i].Size)
|
||||
Bytes = Mmap.Cpus[i].Size;
|
||||
|
||||
printf("\n[*] core %u: %llu bytes of trace\n", Cpu, (unsigned long long)Bytes);
|
||||
Total += Packets
|
||||
? DecodeCorePackets(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes)
|
||||
: DecodeCore(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes);
|
||||
}
|
||||
|
||||
printf("\n[+] decoded %llu %s total\n", (unsigned long long)Total, Packets ? "packet(s)" : "instruction(s)");
|
||||
|
||||
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
|
||||
|
||||
Cleanup:
|
||||
if (g_Code != NULL)
|
||||
{
|
||||
free(g_Code);
|
||||
g_Code = NULL;
|
||||
}
|
||||
if (Process.hThread != NULL)
|
||||
CloseHandle(Process.hThread);
|
||||
if (Process.hProcess != NULL)
|
||||
CloseHandle(Process.hProcess);
|
||||
}
|
||||
|
||||
static int
|
||||
LoadVmmAndTrace()
|
||||
{
|
||||
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
|
||||
|
||||
if (!hyperdbg_u_detect_vmx_support())
|
||||
{
|
||||
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[*] loading HyperDbg VMM...\n");
|
||||
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
|
||||
{
|
||||
printf("[-] cannot load the HyperDbg VMM\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[+] HyperDbg VMM is running\n");
|
||||
|
||||
printf("[*] loading HyperTrace...\n");
|
||||
|
||||
if ( hyperdbg_u_load_hypertrace_module() == 1)
|
||||
{
|
||||
printf("[-] cannot load the HyperDbg HyperTrace\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[+] HyperDbg HyperTrace is running\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main2(int argc, char ** argv)
|
||||
{
|
||||
const char * function = "main";
|
||||
BOOLEAN packets = FALSE;
|
||||
int pinCore = 0;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("HyperDbg Intel PT tracer\n");
|
||||
printf("usage: %s <path-to-exe-that-exits> [function] [-p] [-c core]\n", argv[0]);
|
||||
printf(" [function] symbol to IP-filter (default 'main'; pass '*' for whole .text)\n");
|
||||
printf(" -p dump raw PT packets (TNT/TIP/FUP/PSB/...) instead of instructions\n");
|
||||
printf(" -c core pin the target to this logical core (default 0; -1 = unpinned)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 2; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--packets") == 0)
|
||||
packets = TRUE;
|
||||
else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc)
|
||||
pinCore = atoi(argv[++i]);
|
||||
else if (strcmp(argv[i], "*") == 0)
|
||||
function = NULL;
|
||||
else
|
||||
function = argv[i];
|
||||
}
|
||||
|
||||
if (LoadVmmAndTrace() != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
RunAndTrace(argv[1], function, packets, pinCore);
|
||||
|
||||
printf("[*] unloading HyperDbg VMM...\n");
|
||||
|
||||
//
|
||||
// Unload the driver
|
||||
//
|
||||
hyperdbg_u_unload_vmm();
|
||||
hyperdbg_u_unload_kd();
|
||||
hyperdbg_u_stop_kd_driver();
|
||||
hyperdbg_u_uninstall_kd_driver();
|
||||
|
||||
printf("[+] done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
16
examples/user/hyperdbg_app/header/example-ipt.h
Normal file
16
examples/user/hyperdbg_app/header/example-ipt.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* @file example-ipt.h
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Headers for Intel PT example
|
||||
* @details
|
||||
*
|
||||
* @version 0.20
|
||||
* @date 2026-06-13
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
int
|
||||
main2(int argc, char** argv);
|
||||
|
|
@ -12,14 +12,14 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// add headers that you want to pre-compile here
|
||||
//
|
||||
//
|
||||
// Environment headers
|
||||
//
|
||||
#include "platform/general/header/Environment.h"
|
||||
|
||||
//
|
||||
// Windows SDK headers
|
||||
//
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
//
|
||||
|
|
@ -36,6 +36,10 @@
|
|||
//
|
||||
// HyperDbg SDK headers
|
||||
//
|
||||
#include "Definition.h"
|
||||
#include "SDK/HyperDbgSdk.h"
|
||||
#include "SDK/Imports/HyperDbgCtrlImports.h"
|
||||
#include "SDK/imports/user/HyperDbgLibImports.h"
|
||||
|
||||
//
|
||||
// Other internal headers
|
||||
//
|
||||
#include "example-ipt.h"
|
||||
|
|
@ -1,14 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="debug|Win32">
|
||||
<Configuration>debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="release|Win32">
|
||||
<Configuration>release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="debug|x64">
|
||||
<Configuration>debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
|
|
@ -19,9 +11,11 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="header\example-ipt.h" />
|
||||
<ClInclude Include="header\pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="code\hyperdbg-ipt.cpp" />
|
||||
<ClCompile Include="code\hyperdbg-app.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
|
@ -33,29 +27,16 @@
|
|||
<ProjectName>hyperdbg_app</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
|
@ -64,73 +45,55 @@
|
|||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<!--
|
||||
libipt (Intel Processor Trace decoder) install root.
|
||||
Set this to the folder that contains 'include\intel-pt.h' and
|
||||
'lib\libipt.lib'. 'libipt.dll' must be reachable at run time.
|
||||
-->
|
||||
<LibIptDir>C:\Users\masra\Desktop\libipt</LibIptDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
|
||||
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
|
||||
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)\header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hprdbgctrl.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<AdditionalLibraryDirectories>$(LibIptDir)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib</AdditionalDependencies>
|
||||
<TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Message>
|
||||
</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -138,22 +101,30 @@
|
|||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)\header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\hprdbgctrl.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(LibIptDir)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib</AdditionalDependencies>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Message>
|
||||
</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
@ -7,13 +7,22 @@
|
|||
<Filter Include="code">
|
||||
<UniqueIdentifier>{c40916c8-414b-486b-bfd1-13bcbafd8fa1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\platform">
|
||||
<UniqueIdentifier>{14cb7f22-aa90-410e-a333-f05e0ec7981f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="header\pch.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\example-ipt.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="code\hyperdbg-ipt.cpp">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\hyperdbg-app.cpp">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
59
hwdbg/.github/workflows/test.yml
vendored
Normal file
59
hwdbg/.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ['*']
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
verilator-version: v5.012
|
||||
verilator-install-dir: verilator-install
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: ci
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Cleanup
|
||||
run: sed -i "s/%NAME%/test/g" build.sc
|
||||
- name: Cache Scala
|
||||
uses: coursier/cache-action@v6
|
||||
- name: Setup Scala
|
||||
uses: coursier/setup-action@v1
|
||||
with:
|
||||
jvm: adopt:11
|
||||
apps: sbt mill
|
||||
- name: Setup Dependencies
|
||||
run: |
|
||||
sudo apt-get install ccache
|
||||
- name: Get Cached Verilator
|
||||
id: get-cached-verilator
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.verilator-install-dir }}
|
||||
key: verilator-${{ env.verilator-version }}
|
||||
- name: Install Verilator
|
||||
if: steps.get-cached-verilator.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
sudo apt-get install git help2man perl python3 make autoconf g++ flex bison numactl perl-doc libfl-dev
|
||||
git clone https://github.com/verilator/verilator
|
||||
unset VERILATOR_ROOT
|
||||
cd verilator
|
||||
git checkout ${{ env.verilator-version }}
|
||||
autoconf
|
||||
./configure --prefix=$(pwd)/../${{ env.verilator-install-dir }}
|
||||
make
|
||||
make install
|
||||
- name: Set PATH
|
||||
run: |
|
||||
echo "$(pwd)/${{ env.verilator-install-dir }}/bin" >> $GITHUB_PATH
|
||||
echo VERILATOR_ROOT="$(pwd)/${{ env.verilator-install-dir }}/share/verilator" >> $GITHUB_ENV
|
||||
ln -sf $(pwd)/${{ env.verilator-install-dir }}/bin/verilator_bin $(pwd)/${{ env.verilator-install-dir }}/share/verilator/verilator_bin
|
||||
- name: SBT Test
|
||||
run: sbt test
|
||||
- name: mill Test
|
||||
run: mill _.test
|
||||
366
hwdbg/.gitignore
vendored
Normal file
366
hwdbg/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
### Project Specific stuff
|
||||
test_run_dir/*
|
||||
### XilinxISE template
|
||||
# intermediate build files
|
||||
*.bgn
|
||||
*.bit
|
||||
*.bld
|
||||
*.cmd_log
|
||||
*.drc
|
||||
*.ll
|
||||
*.lso
|
||||
*.msd
|
||||
*.msk
|
||||
*.ncd
|
||||
*.ngc
|
||||
*.ngd
|
||||
*.ngr
|
||||
*.pad
|
||||
*.par
|
||||
*.pcf
|
||||
*.prj
|
||||
*.ptwx
|
||||
*.rbb
|
||||
*.rbd
|
||||
*.stx
|
||||
*.syr
|
||||
*.twr
|
||||
*.twx
|
||||
*.unroutes
|
||||
*.ut
|
||||
*.xpi
|
||||
*.xst
|
||||
*_bitgen.xwbt
|
||||
*_envsettings.html
|
||||
*_map.map
|
||||
*_map.mrp
|
||||
*_map.ngm
|
||||
*_map.xrpt
|
||||
*_ngdbuild.xrpt
|
||||
*_pad.csv
|
||||
*_pad.txt
|
||||
*_par.xrpt
|
||||
*_summary.html
|
||||
*_summary.xml
|
||||
*_usage.xml
|
||||
*_xst.xrpt
|
||||
|
||||
# project-wide generated files
|
||||
*.gise
|
||||
par_usage_statistics.html
|
||||
usage_statistics_webtalk.html
|
||||
webtalk.log
|
||||
webtalk_pn.xml
|
||||
|
||||
# generated folders
|
||||
iseconfig/
|
||||
xlnx_auto_0_xdb/
|
||||
xst/
|
||||
_ngo/
|
||||
_xmsgs/
|
||||
### Eclipse template
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
### C template
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
### SBT template
|
||||
# Simple Build Tool
|
||||
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
|
||||
|
||||
target/
|
||||
lib_managed/
|
||||
src_managed/
|
||||
project/boot/
|
||||
.history
|
||||
.cache
|
||||
### Emacs template
|
||||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
### Vim template
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
### C++ template
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
### OSX template
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
### Xcode template
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
|
||||
## Other
|
||||
*.xccheckout
|
||||
*.moved-aside
|
||||
*.xcuserstate
|
||||
### Scala template
|
||||
*.class
|
||||
*.log
|
||||
/.bsp
|
||||
|
||||
# sbt specific
|
||||
.cache
|
||||
.history
|
||||
.lib/
|
||||
dist/*
|
||||
target/
|
||||
lib_managed/
|
||||
src_managed/
|
||||
project/boot/
|
||||
project/plugins/project/
|
||||
|
||||
# Scala-IDE specific
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
### Java template
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Scala metals
|
||||
.metals/*
|
||||
|
||||
# Scala metals
|
||||
.bloop/
|
||||
|
||||
# Temporary disable the generated verilog files
|
||||
generated/
|
||||
|
||||
# BRAM emulation content
|
||||
# bram_instance_info.txt
|
||||
1
hwdbg/.mill-version
Normal file
1
hwdbg/.mill-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
0.11.5
|
||||
5
hwdbg/.scalafmt.conf
Normal file
5
hwdbg/.scalafmt.conf
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
version = "3.8.1"
|
||||
runner.dialect = scala213
|
||||
maxColumn = 150
|
||||
docstrings.style = Asterisk
|
||||
docstrings.oneline = unfold
|
||||
76
hwdbg/CODE_OF_CONDUCT.md
Normal file
76
hwdbg/CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at sina@rayanfam.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
674
hwdbg/LICENSE
Normal file
674
hwdbg/LICENSE
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
121
hwdbg/README.md
Normal file
121
hwdbg/README.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<p align="center">
|
||||
<img alt="hwdbg" title="hwdbg" src="https://github.com/HyperDbg/graphics/blob/master/Logos/hwdbg/hwdbg-high-resolution-logo-transparent.png?raw=true" width="300">
|
||||
</p>
|
||||
|
||||
<p align="left">
|
||||
<a href="https://hwdbg.hyperdbg.org"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Website-orange.svg" alt="Website"></a>
|
||||
<a href="https://hwdbg.hyperdbg.org/docs"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Docs-yellow.svg" alt="Docs"></a>
|
||||
<a href="https://hwdbg.hyperdbg.org/api"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-API-green.svg" alt="API"></a>
|
||||
<a href="https://research.hyperdbg.org"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/Link-Research-pink.svg" alt="Published Researches"></a>
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/License-GPLv3-blue.svg" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## Description
|
||||
The **hwdbg** debugger chip generator is a gate-level debugging tool designed to make configurable and synthesizable hardware debuggers for white-box and black-box chip fuzzing, testing, and reverse engineering. The primary goal of **hwdbg** is to provide control over hardware, enabling monitoring and modification of signals down to the granular level of a single clock cycle. It is written in Chisel and Verilog.
|
||||
|
||||
- ⚠️ This project is a work in progress and is not yet ready for testing.
|
||||
|
||||
**hwdbg** is a highly customizable debugger designed to ease hardware debugging by bringing software debugging concepts into the hardware debugging domain. **hwdbg** aims to help with the complexities associated with debugging hardware, including chips and IP cores. Key features of **hwdbg** include the ability to step through the hardware design at the clock-cycle level, visualize waveforms, inspect values (e.g., like a logical analyzer), and modify signals. Moreover, it is synthesizable into [FPGAs](https://github.com/HyperDbg/hwdbg-fpga) and has the potential for fabrication into physical chips.
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
_ _ _ ┃
|
||||
| |_ _ _ _ _| || |_ ___ ┃
|
||||
| . || | | |/ . || . \/ . | ┃
|
||||
|_|_||__/_/ \___||___/\_. | ┃
|
||||
<___' ┃
|
||||
┃ ╱|、
|
||||
HyperDbg's chip-level debugger ┃ (˚ˎ 。7
|
||||
┃ |、 ˜〵
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━┛ じしˍ,)ノ
|
||||
```
|
||||
## Publications
|
||||
|
||||
In case you use **hwdbg** in your work, please consider citing our paper.
|
||||
|
||||
**[hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
|
||||
|
||||
```
|
||||
@inproceedings{karvandi2025hwdbg,
|
||||
title={hwdbg: Debugging Hardware Like Software},
|
||||
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
|
||||
booktitle={Proceedings of the 18th European Workshop on Systems Security},
|
||||
pages={56--62},
|
||||
year={2025}
|
||||
}
|
||||
```
|
||||
|
||||
## Deployment Board
|
||||
|
||||
[This repository](https://github.com/HyperDbg/hwdbg-fpga) contains pre-built TCL files to facilitate project creation for running **hwdbg** on various FPGA development boards.
|
||||
|
||||
## Output
|
||||
|
||||
For generating SystemVerilog files, you need to install [Chisel](https://www.chisel-lang.org/docs/installation). Once installed, use the following commands:
|
||||
|
||||
```sh
|
||||
$ sbt run
|
||||
```
|
||||
|
||||
This command prompts you to select a component. The `hwdbg.Main` class contains the debugger for synthesis purposes, while the `hwdbg.MainWithInitializedBRAM` class includes a pre-initialized Block RAM (BRAM), primarily for simulation and testing.
|
||||
|
||||
After selecting the appropriate class for synthesis (option `1`) or simulation (option `2`), the output should look like this:
|
||||
|
||||
```sh
|
||||
$ sbt run
|
||||
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.10)
|
||||
[info] loading settings for project -build-build-build from metals.sbt ...
|
||||
[info] loading project definition from /home/sina/HyperDbg//project/project/project
|
||||
[info] loading settings for project -build-build from metals.sbt ...
|
||||
[info] loading project definition from /home/sina/HyperDbg//project/project
|
||||
[success] Generated .bloop/-build-build.json
|
||||
[success] Total time: 1 s, completed Apr 16, 2024, 1:49:05 PM
|
||||
[info] loading settings for project -build from metals.sbt,plugins.sbt ...
|
||||
[info] loading project definition from /home/sina/HyperDbg//project
|
||||
[success] Total time: 0 s, completed Apr 16, 2024, 1:49:05 PM
|
||||
[info] loading settings for project root from build.sbt ...
|
||||
[info] set current project to hwdbg (in build file:/home/sina/HyperDbg/hwdbg/)
|
||||
|
||||
Multiple main classes detected. Select one to run:
|
||||
[1] hwdbg.Main
|
||||
[2] hwdbg.MainWithInitializedBRAM
|
||||
|
||||
Enter number: 2
|
||||
[info] running hwdbg.MainWithInitializedBRAM
|
||||
```
|
||||
|
||||
The generated code for the debugger can be found in the `generated` directory.
|
||||
|
||||
## Testbenches
|
||||
|
||||
To test **hwdbg**, [cocotb](https://www.cocotb.org/) should be installed. After that, first, run the debugger (generated SystemVerilog files) and then run the following commands:
|
||||
|
||||
```sh
|
||||
cd sim/hwdbg/DebuggerModuleTestingBRAM
|
||||
./test.sh
|
||||
```
|
||||
|
||||
The above command generates a waves file at `./sim/hwdbg/DebuggerModuleTestingBRAM/sim_build/DebuggerModuleTestingBRAM.fst` which can be read using [GTKWave](https://gtkwave.sourceforge.net/).
|
||||
|
||||
```sh
|
||||
cd sim/hwdbg/DebuggerModuleTestingBRAM
|
||||
gtkwave ./sim_build/DebuggerModuleTestingBRAM.fst
|
||||
```
|
||||
|
||||
### ModelSim
|
||||
|
||||
If you prefer to use ModelSim instead of GTKWave, you can configure the `modelsim.config` file. Please visit <a href="https://github.com/HyperDbg/hwdbg/blob/main/sim/modelsim/README.md">here</a> for more information.
|
||||
|
||||
## API
|
||||
|
||||
If you want to create the latest version of API documentation, you can run the following command:
|
||||
|
||||
```sh
|
||||
$ sbt doc
|
||||
```
|
||||
|
||||
This will generate documentation at `./target/scala-{version}/api/index.html`.
|
||||
|
||||
## License
|
||||
|
||||
**hwdbg** and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
|
||||
29
hwdbg/build.sbt
Normal file
29
hwdbg/build.sbt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// See README.md for license details.
|
||||
|
||||
ThisBuild / scalaVersion := "2.13.12"
|
||||
ThisBuild / version := "0.1.0"
|
||||
ThisBuild / organization := "org.hyperdbg"
|
||||
|
||||
val chiselVersion = "6.2.0"
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
name := "hwdbg",
|
||||
libraryDependencies ++= Seq(
|
||||
"org.chipsalliance" %% "chisel" % chiselVersion,
|
||||
"org.scalatest" %% "scalatest" % "3.2.16" % "test",
|
||||
"io.circe" %% "circe-core" % "0.14.3",
|
||||
"io.circe" %% "circe-generic" % "0.14.3",
|
||||
"io.circe" %% "circe-parser" % "0.14.3"
|
||||
),
|
||||
scalacOptions ++= Seq(
|
||||
"-language:reflectiveCalls",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-Xcheckinit",
|
||||
"-Ymacro-annotations"
|
||||
),
|
||||
addCompilerPlugin(
|
||||
"org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full
|
||||
)
|
||||
)
|
||||
30
hwdbg/build.sc
Normal file
30
hwdbg/build.sc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// import Mill dependency
|
||||
import mill._
|
||||
import mill.define.Sources
|
||||
import mill.modules.Util
|
||||
import mill.scalalib.TestModule.ScalaTest
|
||||
import scalalib._
|
||||
// support BSP
|
||||
import mill.bsp._
|
||||
|
||||
object hwdbg extends SbtModule { m =>
|
||||
override def millSourcePath = os.pwd
|
||||
override def scalaVersion = "2.13.12"
|
||||
override def scalacOptions = Seq(
|
||||
"-language:reflectiveCalls",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-Xcheckinit",
|
||||
)
|
||||
override def ivyDeps = Agg(
|
||||
ivy"org.chipsalliance::chisel:6.0.0",
|
||||
)
|
||||
override def scalacPluginIvyDeps = Agg(
|
||||
ivy"org.chipsalliance:::chisel-plugin:6.0.0",
|
||||
)
|
||||
object test extends SbtModuleTests with TestModule.ScalaTest {
|
||||
override def ivyDeps = m.ivyDeps() ++ Agg(
|
||||
ivy"org.scalatest::scalatest::3.2.16"
|
||||
)
|
||||
}
|
||||
}
|
||||
1
hwdbg/project/build.properties
Normal file
1
hwdbg/project/build.properties
Normal file
|
|
@ -0,0 +1 @@
|
|||
sbt.version = 1.9.7
|
||||
8
hwdbg/project/metals.sbt
Normal file
8
hwdbg/project/metals.sbt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// format: off
|
||||
// DO NOT EDIT! This file is auto-generated.
|
||||
|
||||
// This file enables sbt-bloop to create bloop config files.
|
||||
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
|
||||
|
||||
// format: on
|
||||
1
hwdbg/project/plugins.sbt
Normal file
1
hwdbg/project/plugins.sbt
Normal file
|
|
@ -0,0 +1 @@
|
|||
logLevel := Level.Warn
|
||||
8
hwdbg/project/project/metals.sbt
Normal file
8
hwdbg/project/project/metals.sbt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// format: off
|
||||
// DO NOT EDIT! This file is auto-generated.
|
||||
|
||||
// This file enables sbt-bloop to create bloop config files.
|
||||
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
|
||||
|
||||
// format: on
|
||||
8
hwdbg/project/project/project/metals.sbt
Normal file
8
hwdbg/project/project/project/metals.sbt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// format: off
|
||||
// DO NOT EDIT! This file is auto-generated.
|
||||
|
||||
// This file enables sbt-bloop to create bloop config files.
|
||||
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
|
||||
|
||||
// format: on
|
||||
164
hwdbg/sim/.gitignore
vendored
Normal file
164
hwdbg/sim/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# cocotb folders and files
|
||||
sim_build/
|
||||
results.xml
|
||||
23
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile
Normal file
23
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Makefile
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerModuleTestingBRAM.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/InitRegMemFromFile.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerMain.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/SendReceiveSynchronizer.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketReceiver.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketSender.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketInterpreter.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterInstanceInfo.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterSendSuccessOrError.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptExecutionEngine.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterScriptBufferHandler.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineGetValue.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineSetValue.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineEval.sv
|
||||
|
||||
TOPLEVEL = DebuggerModuleTestingBRAM
|
||||
MODULE = test_DebuggerModuleTestingBRAM
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
261
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/bram_instance_info.txt
Normal file
261
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/bram_instance_info.txt
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
Content of BRAM after emulation:
|
||||
|
||||
PS to PL area:
|
||||
mem_0: 0000005a | Checksum
|
||||
mem_1: 00000000 | Checksum
|
||||
mem_2: 52444247 | Indicator
|
||||
mem_3: 48595045 | Indicator
|
||||
mem_4: 00000004 | TypeOfThePacket
|
||||
mem_5: 00000001 | RequestedActionOfThePacket
|
||||
mem_6: 00000000 | Start of Optional Data
|
||||
mem_7: 00000000
|
||||
mem_8: 00000000
|
||||
mem_9: 00000000
|
||||
mem_10: 00000000
|
||||
mem_11: 00000000
|
||||
mem_12: 00000000
|
||||
mem_13: 00000000
|
||||
mem_14: 00000000
|
||||
mem_15: 00000000
|
||||
mem_16: 00000000
|
||||
mem_17: 00000000
|
||||
mem_18: 00000000
|
||||
mem_19: 00000000
|
||||
mem_20: 00000000
|
||||
mem_21: 00000000
|
||||
mem_22: 00000000
|
||||
mem_23: 00000000
|
||||
mem_24: 00000000
|
||||
mem_25: 00000000
|
||||
mem_26: 00000000
|
||||
mem_27: 00000000
|
||||
mem_28: 00000000
|
||||
mem_29: 00000000
|
||||
mem_30: 00000000
|
||||
mem_31: 00000000
|
||||
mem_32: 00000000
|
||||
mem_33: 00000000
|
||||
mem_34: 00000000
|
||||
mem_35: 00000000
|
||||
mem_36: 00000000
|
||||
mem_37: 00000000
|
||||
mem_38: 00000000
|
||||
mem_39: 00000000
|
||||
mem_40: 00000000
|
||||
mem_41: 00000000
|
||||
mem_42: 00000000
|
||||
mem_43: 00000000
|
||||
mem_44: 00000000
|
||||
mem_45: 00000000
|
||||
mem_46: 00000000
|
||||
mem_47: 00000000
|
||||
mem_48: 00000000
|
||||
mem_49: 00000000
|
||||
mem_50: 00000000
|
||||
mem_51: 00000000
|
||||
mem_52: 00000000
|
||||
mem_53: 00000000
|
||||
mem_54: 00000000
|
||||
mem_55: 00000000
|
||||
mem_56: 00000000
|
||||
mem_57: 00000000
|
||||
mem_58: 00000000
|
||||
mem_59: 00000000
|
||||
mem_60: 00000000
|
||||
mem_61: 00000000
|
||||
mem_62: 00000000
|
||||
mem_63: 00000000
|
||||
mem_64: 00000000
|
||||
mem_65: 00000000
|
||||
mem_66: 00000000
|
||||
mem_67: 00000000
|
||||
mem_68: 00000000
|
||||
mem_69: 00000000
|
||||
mem_70: 00000000
|
||||
mem_71: 00000000
|
||||
mem_72: 00000000
|
||||
mem_73: 00000000
|
||||
mem_74: 00000000
|
||||
mem_75: 00000000
|
||||
mem_76: 00000000
|
||||
mem_77: 00000000
|
||||
mem_78: 00000000
|
||||
mem_79: 00000000
|
||||
mem_80: 00000000
|
||||
mem_81: 00000000
|
||||
mem_82: 00000000
|
||||
mem_83: 00000000
|
||||
mem_84: 00000000
|
||||
mem_85: 00000000
|
||||
mem_86: 00000000
|
||||
mem_87: 00000000
|
||||
mem_88: 00000000
|
||||
mem_89: 00000000
|
||||
mem_90: 00000000
|
||||
mem_91: 00000000
|
||||
mem_92: 00000000
|
||||
mem_93: 00000000
|
||||
mem_94: 00000000
|
||||
mem_95: 00000000
|
||||
mem_96: 00000000
|
||||
mem_97: 00000000
|
||||
mem_98: 00000000
|
||||
mem_99: 00000000
|
||||
mem_100: 00000000
|
||||
mem_101: 00000000
|
||||
mem_102: 00000000
|
||||
mem_103: 00000000
|
||||
mem_104: 00000000
|
||||
mem_105: 00000000
|
||||
mem_106: 00000000
|
||||
mem_107: 00000000
|
||||
mem_108: 00000000
|
||||
mem_109: 00000000
|
||||
mem_110: 00000000
|
||||
mem_111: 00000000
|
||||
mem_112: 00000000
|
||||
mem_113: 00000000
|
||||
mem_114: 00000000
|
||||
mem_115: 00000000
|
||||
mem_116: 00000000
|
||||
mem_117: 00000000
|
||||
mem_118: 00000000
|
||||
mem_119: 00000000
|
||||
mem_120: 00000000
|
||||
mem_121: 00000000
|
||||
mem_122: 00000000
|
||||
mem_123: 00000000
|
||||
mem_124: 00000000
|
||||
mem_125: 00000000
|
||||
mem_126: 00000000
|
||||
mem_127: 00000000
|
||||
|
||||
PL to PS area:
|
||||
mem_128: 00000000 | Checksum
|
||||
mem_129: 00000000 | Checksum
|
||||
mem_130: 52444247 | Indicator
|
||||
mem_131: 48595045 | Indicator
|
||||
mem_132: 00000005 | TypeOfThePacket
|
||||
mem_133: 00000002 | RequestedActionOfThePacket
|
||||
mem_134: 00000100 | Start of Optional Data
|
||||
mem_135: 00000020
|
||||
mem_136: 00000008
|
||||
mem_137: 00000002
|
||||
mem_138: 00000002
|
||||
mem_139: 00000002
|
||||
mem_140: 00000001
|
||||
mem_141: 00000400
|
||||
mem_142: 00000000
|
||||
mem_143: 00000200
|
||||
mem_144: 00000020
|
||||
mem_145: 00000002
|
||||
mem_146: 01ff9efb
|
||||
mem_147: 00000000
|
||||
mem_148: 0000000d
|
||||
mem_149: 00000020
|
||||
mem_150: 0000000c
|
||||
mem_151: 00000014
|
||||
mem_152: 00000000
|
||||
mem_153: 00000000
|
||||
mem_154: 00000000
|
||||
mem_155: 00000000
|
||||
mem_156: 00000000
|
||||
mem_157: 00000000
|
||||
mem_158: 00000000
|
||||
mem_159: 00000000
|
||||
mem_160: 00000000
|
||||
mem_161: 00000000
|
||||
mem_162: 00000000
|
||||
mem_163: 00000000
|
||||
mem_164: 00000000
|
||||
mem_165: 00000000
|
||||
mem_166: 00000000
|
||||
mem_167: 00000000
|
||||
mem_168: 00000000
|
||||
mem_169: 00000000
|
||||
mem_170: 00000000
|
||||
mem_171: 00000000
|
||||
mem_172: 00000000
|
||||
mem_173: 00000000
|
||||
mem_174: 00000000
|
||||
mem_175: 00000000
|
||||
mem_176: 00000000
|
||||
mem_177: 00000000
|
||||
mem_178: 00000000
|
||||
mem_179: 00000000
|
||||
mem_180: 00000000
|
||||
mem_181: 00000000
|
||||
mem_182: 00000000
|
||||
mem_183: 00000000
|
||||
mem_184: 00000000
|
||||
mem_185: 00000000
|
||||
mem_186: 00000000
|
||||
mem_187: 00000000
|
||||
mem_188: 00000000
|
||||
mem_189: 00000000
|
||||
mem_190: 00000000
|
||||
mem_191: 00000000
|
||||
mem_192: 00000000
|
||||
mem_193: 00000000
|
||||
mem_194: 00000000
|
||||
mem_195: 00000000
|
||||
mem_196: 00000000
|
||||
mem_197: 00000000
|
||||
mem_198: 00000000
|
||||
mem_199: 00000000
|
||||
mem_200: 00000000
|
||||
mem_201: 00000000
|
||||
mem_202: 00000000
|
||||
mem_203: 00000000
|
||||
mem_204: 00000000
|
||||
mem_205: 00000000
|
||||
mem_206: 00000000
|
||||
mem_207: 00000000
|
||||
mem_208: 00000000
|
||||
mem_209: 00000000
|
||||
mem_210: 00000000
|
||||
mem_211: 00000000
|
||||
mem_212: 00000000
|
||||
mem_213: 00000000
|
||||
mem_214: 00000000
|
||||
mem_215: 00000000
|
||||
mem_216: 00000000
|
||||
mem_217: 00000000
|
||||
mem_218: 00000000
|
||||
mem_219: 00000000
|
||||
mem_220: 00000000
|
||||
mem_221: 00000000
|
||||
mem_222: 00000000
|
||||
mem_223: 00000000
|
||||
mem_224: 00000000
|
||||
mem_225: 00000000
|
||||
mem_226: 00000000
|
||||
mem_227: 00000000
|
||||
mem_228: 00000000
|
||||
mem_229: 00000000
|
||||
mem_230: 00000000
|
||||
mem_231: 00000000
|
||||
mem_232: 00000000
|
||||
mem_233: 00000000
|
||||
mem_234: 00000000
|
||||
mem_235: 00000000
|
||||
mem_236: 00000000
|
||||
mem_237: 00000000
|
||||
mem_238: 00000000
|
||||
mem_239: 00000000
|
||||
mem_240: 00000000
|
||||
mem_241: 00000000
|
||||
mem_242: 00000000
|
||||
mem_243: 00000000
|
||||
mem_244: 00000000
|
||||
mem_245: 00000000
|
||||
mem_246: 00000000
|
||||
mem_247: 00000000
|
||||
mem_248: 00000000
|
||||
mem_249: 00000000
|
||||
mem_250: 00000000
|
||||
mem_251: 00000000
|
||||
mem_252: 00000000
|
||||
mem_253: 00000000
|
||||
mem_254: 00000000
|
||||
mem_255: 00000000
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
Content of BRAM after emulation:
|
||||
|
||||
PS to PL area:
|
||||
mem_0: 00000017 | Checksum
|
||||
mem_1: 00000000 | Checksum
|
||||
mem_2: 52444247 | Indicator
|
||||
mem_3: 48595045 | Indicator
|
||||
mem_4: 00000004 | TypeOfThePacket
|
||||
mem_5: 00000002 | RequestedActionOfThePacket
|
||||
mem_6: 00000033 | Start of Optional Data
|
||||
mem_7: 00000006
|
||||
mem_8: 0000000a
|
||||
mem_9: 00000003
|
||||
mem_10: 00000001
|
||||
mem_11: 0000000f
|
||||
mem_12: 00000000
|
||||
mem_13: 0000000f
|
||||
mem_14: 00000000
|
||||
mem_15: 00000006
|
||||
mem_16: 00000013
|
||||
mem_17: 00000003
|
||||
mem_18: 00000001
|
||||
mem_19: 00000004
|
||||
mem_20: 00000000
|
||||
mem_21: 00000007
|
||||
mem_22: 00000000
|
||||
mem_23: 00000006
|
||||
mem_24: 00000016
|
||||
mem_25: 00000003
|
||||
mem_26: 00000013
|
||||
mem_27: 00000007
|
||||
mem_28: 00000000
|
||||
mem_29: 00000000
|
||||
mem_30: 00000000
|
||||
mem_31: 00000006
|
||||
mem_32: 00000018
|
||||
mem_33: 00000003
|
||||
mem_34: 00000000
|
||||
mem_35: 00000000
|
||||
mem_36: 00000000
|
||||
mem_37: 00000004
|
||||
mem_38: 00000002
|
||||
mem_39: 00000006
|
||||
mem_40: 00000018
|
||||
mem_41: 00000003
|
||||
mem_42: 00000000
|
||||
mem_43: 00000000
|
||||
mem_44: 00000000
|
||||
mem_45: 00000004
|
||||
mem_46: 00000003
|
||||
mem_47: 00000006
|
||||
mem_48: 00000015
|
||||
mem_49: 00000003
|
||||
mem_50: 00000028
|
||||
mem_51: 00000000
|
||||
mem_52: 00000000
|
||||
mem_53: 00000000
|
||||
mem_54: 00000000
|
||||
mem_55: 00000006
|
||||
mem_56: 00000013
|
||||
mem_57: 00000003
|
||||
mem_58: 00000001
|
||||
mem_59: 00000004
|
||||
mem_60: 00000001
|
||||
mem_61: 00000007
|
||||
mem_62: 00000000
|
||||
mem_63: 00000006
|
||||
mem_64: 00000016
|
||||
mem_65: 00000003
|
||||
mem_66: 00000022
|
||||
mem_67: 00000007
|
||||
mem_68: 00000000
|
||||
mem_69: 00000000
|
||||
mem_70: 00000000
|
||||
mem_71: 00000006
|
||||
mem_72: 00000018
|
||||
mem_73: 00000003
|
||||
mem_74: 00000000
|
||||
mem_75: 00000000
|
||||
mem_76: 00000000
|
||||
mem_77: 00000004
|
||||
mem_78: 00000004
|
||||
mem_79: 00000006
|
||||
mem_80: 00000018
|
||||
mem_81: 00000003
|
||||
mem_82: 00000000
|
||||
mem_83: 00000000
|
||||
mem_84: 00000000
|
||||
mem_85: 00000004
|
||||
mem_86: 00000005
|
||||
mem_87: 00000006
|
||||
mem_88: 00000015
|
||||
mem_89: 00000003
|
||||
mem_90: 00000028
|
||||
mem_91: 00000000
|
||||
mem_92: 00000000
|
||||
mem_93: 00000000
|
||||
mem_94: 00000000
|
||||
mem_95: 00000006
|
||||
mem_96: 00000018
|
||||
mem_97: 00000003
|
||||
mem_98: 00000000
|
||||
mem_99: 00000000
|
||||
mem_100: 00000000
|
||||
mem_101: 00000004
|
||||
mem_102: 00000006
|
||||
mem_103: 00000006
|
||||
mem_104: 00000018
|
||||
mem_105: 00000003
|
||||
mem_106: 00000000
|
||||
mem_107: 00000000
|
||||
mem_108: 00000000
|
||||
mem_109: 00000004
|
||||
mem_110: 00000007
|
||||
mem_111: 00000000
|
||||
mem_112: 00000000
|
||||
mem_113: 00000000
|
||||
mem_114: 00000000
|
||||
mem_115: 00000000
|
||||
mem_116: 00000000
|
||||
mem_117: 00000000
|
||||
mem_118: 00000000
|
||||
mem_119: 00000000
|
||||
mem_120: 00000000
|
||||
mem_121: 00000000
|
||||
mem_122: 00000000
|
||||
mem_123: 00000000
|
||||
mem_124: 00000000
|
||||
mem_125: 00000000
|
||||
mem_126: 00000000
|
||||
mem_127: 00000000
|
||||
|
||||
PL to PS area:
|
||||
mem_128: 00000000 | Checksum
|
||||
mem_129: 00000000 | Checksum
|
||||
mem_130: 52444247 | Indicator
|
||||
mem_131: 48595045 | Indicator
|
||||
mem_132: 00000005 | TypeOfThePacket
|
||||
mem_133: 00000001 | RequestedActionOfThePacket
|
||||
mem_134: 7fffffff | Start of Optional Data
|
||||
mem_135: 00000000
|
||||
mem_136: 00000000
|
||||
mem_137: 00000000
|
||||
mem_138: 00000000
|
||||
mem_139: 00000000
|
||||
mem_140: 00000000
|
||||
mem_141: 00000000
|
||||
mem_142: 00000000
|
||||
mem_143: 00000000
|
||||
mem_144: 00000000
|
||||
mem_145: 00000000
|
||||
mem_146: 00000000
|
||||
mem_147: 00000000
|
||||
mem_148: 00000000
|
||||
mem_149: 00000000
|
||||
mem_150: 00000000
|
||||
mem_151: 00000000
|
||||
mem_152: 00000000
|
||||
mem_153: 00000000
|
||||
mem_154: 00000000
|
||||
mem_155: 00000000
|
||||
mem_156: 00000000
|
||||
mem_157: 00000000
|
||||
mem_158: 00000000
|
||||
mem_159: 00000000
|
||||
mem_160: 00000000
|
||||
mem_161: 00000000
|
||||
mem_162: 00000000
|
||||
mem_163: 00000000
|
||||
mem_164: 00000000
|
||||
mem_165: 00000000
|
||||
mem_166: 00000000
|
||||
mem_167: 00000000
|
||||
mem_168: 00000000
|
||||
mem_169: 00000000
|
||||
mem_170: 00000000
|
||||
mem_171: 00000000
|
||||
mem_172: 00000000
|
||||
mem_173: 00000000
|
||||
mem_174: 00000000
|
||||
mem_175: 00000000
|
||||
mem_176: 00000000
|
||||
mem_177: 00000000
|
||||
mem_178: 00000000
|
||||
mem_179: 00000000
|
||||
mem_180: 00000000
|
||||
mem_181: 00000000
|
||||
mem_182: 00000000
|
||||
mem_183: 00000000
|
||||
mem_184: 00000000
|
||||
mem_185: 00000000
|
||||
mem_186: 00000000
|
||||
mem_187: 00000000
|
||||
mem_188: 00000000
|
||||
mem_189: 00000000
|
||||
mem_190: 00000000
|
||||
mem_191: 00000000
|
||||
mem_192: 00000000
|
||||
mem_193: 00000000
|
||||
mem_194: 00000000
|
||||
mem_195: 00000000
|
||||
mem_196: 00000000
|
||||
mem_197: 00000000
|
||||
mem_198: 00000000
|
||||
mem_199: 00000000
|
||||
mem_200: 00000000
|
||||
mem_201: 00000000
|
||||
mem_202: 00000000
|
||||
mem_203: 00000000
|
||||
mem_204: 00000000
|
||||
mem_205: 00000000
|
||||
mem_206: 00000000
|
||||
mem_207: 00000000
|
||||
mem_208: 00000000
|
||||
mem_209: 00000000
|
||||
mem_210: 00000000
|
||||
mem_211: 00000000
|
||||
mem_212: 00000000
|
||||
mem_213: 00000000
|
||||
mem_214: 00000000
|
||||
mem_215: 00000000
|
||||
mem_216: 00000000
|
||||
mem_217: 00000000
|
||||
mem_218: 00000000
|
||||
mem_219: 00000000
|
||||
mem_220: 00000000
|
||||
mem_221: 00000000
|
||||
mem_222: 00000000
|
||||
mem_223: 00000000
|
||||
mem_224: 00000000
|
||||
mem_225: 00000000
|
||||
mem_226: 00000000
|
||||
mem_227: 00000000
|
||||
mem_228: 00000000
|
||||
mem_229: 00000000
|
||||
mem_230: 00000000
|
||||
mem_231: 00000000
|
||||
mem_232: 00000000
|
||||
mem_233: 00000000
|
||||
mem_234: 00000000
|
||||
mem_235: 00000000
|
||||
mem_236: 00000000
|
||||
mem_237: 00000000
|
||||
mem_238: 00000000
|
||||
mem_239: 00000000
|
||||
mem_240: 00000000
|
||||
mem_241: 00000000
|
||||
mem_242: 00000000
|
||||
mem_243: 00000000
|
||||
mem_244: 00000000
|
||||
mem_245: 00000000
|
||||
mem_246: 00000000
|
||||
mem_247: 00000000
|
||||
mem_248: 00000000
|
||||
mem_249: 00000000
|
||||
mem_250: 00000000
|
||||
mem_251: 00000000
|
||||
mem_252: 00000000
|
||||
mem_253: 00000000
|
||||
mem_254: 00000000
|
||||
mem_255: 00000000
|
||||
1
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test.sh
Executable file
1
hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test.sh
Executable file
|
|
@ -0,0 +1 @@
|
|||
make SIM=icarus WAVES=1
|
||||
|
|
@ -0,0 +1,570 @@
|
|||
##
|
||||
# @file test_DebuggerModuleTestingBRAM.py
|
||||
#
|
||||
# @author Sina Karvandi (sina@hyperdbg.org)
|
||||
#
|
||||
# @brief Testing module for DebuggerModuleTestingBRAM
|
||||
#
|
||||
# @details
|
||||
#
|
||||
# @version 0.1
|
||||
#
|
||||
# @date 2024-04-21
|
||||
#
|
||||
# @copyright This project is released under the GNU Public License v3.
|
||||
#
|
||||
|
||||
import random
|
||||
import re
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer
|
||||
from cocotb.types import LogicArray
|
||||
|
||||
maximum_number_of_clock_cycles = 1000
|
||||
|
||||
'''
|
||||
input clock,
|
||||
reset,
|
||||
io_en,
|
||||
io_inputPin_0,
|
||||
io_inputPin_1,
|
||||
io_inputPin_2,
|
||||
io_inputPin_3,
|
||||
io_inputPin_4,
|
||||
io_inputPin_5,
|
||||
io_inputPin_6,
|
||||
io_inputPin_7,
|
||||
io_inputPin_8,
|
||||
io_inputPin_9,
|
||||
io_inputPin_10,
|
||||
io_inputPin_11,
|
||||
io_inputPin_12,
|
||||
io_inputPin_13,
|
||||
io_inputPin_14,
|
||||
io_inputPin_15,
|
||||
io_inputPin_16,
|
||||
io_inputPin_17,
|
||||
io_inputPin_18,
|
||||
io_inputPin_19,
|
||||
io_inputPin_20,
|
||||
io_inputPin_21,
|
||||
io_inputPin_22,
|
||||
io_inputPin_23,
|
||||
io_inputPin_24,
|
||||
io_inputPin_25,
|
||||
io_inputPin_26,
|
||||
io_inputPin_27,
|
||||
io_inputPin_28,
|
||||
io_inputPin_29,
|
||||
io_inputPin_30,
|
||||
io_inputPin_31,
|
||||
output io_outputPin_0,
|
||||
io_outputPin_1,
|
||||
io_outputPin_2,
|
||||
io_outputPin_3,
|
||||
io_outputPin_4,
|
||||
io_outputPin_5,
|
||||
io_outputPin_6,
|
||||
io_outputPin_7,
|
||||
io_outputPin_8,
|
||||
io_outputPin_9,
|
||||
io_outputPin_10,
|
||||
io_outputPin_11,
|
||||
io_outputPin_12,
|
||||
io_outputPin_13,
|
||||
io_outputPin_14,
|
||||
io_outputPin_15,
|
||||
io_outputPin_16,
|
||||
io_outputPin_17,
|
||||
io_outputPin_18,
|
||||
io_outputPin_19,
|
||||
io_outputPin_20,
|
||||
io_outputPin_21,
|
||||
io_outputPin_22,
|
||||
io_outputPin_23,
|
||||
io_outputPin_24,
|
||||
io_outputPin_25,
|
||||
io_outputPin_26,
|
||||
io_outputPin_27,
|
||||
io_outputPin_28,
|
||||
io_outputPin_29,
|
||||
io_outputPin_30,
|
||||
io_outputPin_31,
|
||||
input io_plInSignal,
|
||||
output io_psOutInterrupt
|
||||
'''
|
||||
|
||||
#
|
||||
# Define a function to extract the numeric part of the string
|
||||
#
|
||||
def extract_number(s):
|
||||
return int(s.split('_')[1])
|
||||
|
||||
def print_bram_content(dut):
|
||||
"""Printing contents of Block RAM and saving them to a file"""
|
||||
|
||||
#
|
||||
# Print the instances and signals (which includes the ports) of the design's toplevel
|
||||
#
|
||||
print("===================================================================")
|
||||
# print("Onstances and signals (which includes the ports) of the design's toplevel:")
|
||||
# print(dir(dut))
|
||||
# print("===================================================================")
|
||||
|
||||
#
|
||||
# Print the instances and signals of "inst_sub_block" under the toplevel
|
||||
# which is the instance name of a Verilog module or VHDL entity/component
|
||||
#
|
||||
# print("Onstances and signals of 'dataOut_initRegMemFromFileModule' under the toplevel:")
|
||||
# print(dir(dut.dataOut_initRegMemFromFileModule))
|
||||
|
||||
items_inside_bram_emulator = dir(dut.dataOut_initRegMemFromFileModule)
|
||||
mem_items = []
|
||||
|
||||
for item in items_inside_bram_emulator:
|
||||
if item.startswith("mem_"):
|
||||
mem_items.append(item)
|
||||
|
||||
#
|
||||
# Sort the list using the custom key function
|
||||
#
|
||||
sorted_list = sorted(mem_items, key=extract_number)
|
||||
|
||||
with open("script_buffer_response.txt", "w") as file:
|
||||
# with open("bram_instance_info.txt", "w") as file:
|
||||
file.write("Content of BRAM after emulation:\n")
|
||||
print("Content of BRAM after emulation:")
|
||||
|
||||
#
|
||||
# The second half of the BRAM is used for PL to PS communication
|
||||
#
|
||||
address_of_ps_to_pl_communication = "mem_0"
|
||||
address_of_ps_to_pl_communication_checksum1 = "mem_0"
|
||||
address_of_ps_to_pl_communication_checksum2 = "mem_1"
|
||||
address_of_ps_to_pl_communication_indicator1 = "mem_2"
|
||||
address_of_ps_to_pl_communication_indicator2 = "mem_3"
|
||||
address_of_ps_to_pl_communication_type_of_packet = "mem_4"
|
||||
address_of_ps_to_pl_communication_requested_action_of_the_packet = "mem_5"
|
||||
address_of_ps_to_pl_communication_start_of_data = "mem_6"
|
||||
|
||||
len_of_sorted_list_div_by_2 = int(len(sorted_list) / 2)
|
||||
address_of_pl_to_ps_communication = "mem_" + str(len_of_sorted_list_div_by_2)
|
||||
address_of_pl_to_ps_communication_checksum1 = "mem_" + str(len_of_sorted_list_div_by_2 + 0)
|
||||
address_of_pl_to_ps_communication_checksum2 = "mem_" + str(len_of_sorted_list_div_by_2 + 1)
|
||||
address_of_pl_to_ps_communication_indicator1 = "mem_" + str(len_of_sorted_list_div_by_2 + 2)
|
||||
address_of_pl_to_ps_communication_indicator2 = "mem_" + str(len_of_sorted_list_div_by_2 + 3)
|
||||
address_of_pl_to_ps_communication_type_of_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 4)
|
||||
address_of_pl_to_ps_communication_requested_action_of_the_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 5)
|
||||
address_of_pl_to_ps_communication_start_of_data = "mem_" + str(len_of_sorted_list_div_by_2 + 6)
|
||||
|
||||
print("Address of PL to PS communication: " + address_of_pl_to_ps_communication)
|
||||
|
||||
for item in sorted_list:
|
||||
element = getattr(dut.dataOut_initRegMemFromFileModule, item)
|
||||
|
||||
#
|
||||
# Print the target register in binary format
|
||||
#
|
||||
# print(str(element))
|
||||
|
||||
#
|
||||
# Convert binary to int
|
||||
#
|
||||
int_content = int(str(element.value), 2)
|
||||
|
||||
#
|
||||
# Convert integer to hexadecimal string with at least 8 characters
|
||||
#
|
||||
hex_string = f'{int_content:08x}'
|
||||
|
||||
final_string = ""
|
||||
if len(item) == 5:
|
||||
final_string = item + ": " + hex_string
|
||||
elif len(item) == 6:
|
||||
final_string = item + ": " + hex_string
|
||||
else:
|
||||
final_string = item + ": " + hex_string
|
||||
|
||||
#
|
||||
# Make a separation between PS and PL area
|
||||
#
|
||||
if item == address_of_ps_to_pl_communication:
|
||||
file.write("\nPS to PL area:\n")
|
||||
print("\nPS to PL area:")
|
||||
elif item == address_of_pl_to_ps_communication:
|
||||
file.write("\nPL to PS area:\n")
|
||||
print("\nPL to PS area:")
|
||||
|
||||
if item == address_of_ps_to_pl_communication_checksum1 or \
|
||||
item == address_of_ps_to_pl_communication_checksum2 or \
|
||||
item == address_of_pl_to_ps_communication_checksum1 or \
|
||||
item == address_of_pl_to_ps_communication_checksum2:
|
||||
final_string = final_string + " | Checksum"
|
||||
elif item == address_of_ps_to_pl_communication_indicator1 or \
|
||||
item == address_of_ps_to_pl_communication_indicator2 or \
|
||||
item == address_of_pl_to_ps_communication_indicator1 or \
|
||||
item == address_of_pl_to_ps_communication_indicator2:
|
||||
final_string = final_string + " | Indicator"
|
||||
elif item == address_of_ps_to_pl_communication_type_of_packet or \
|
||||
item == address_of_pl_to_ps_communication_type_of_packet:
|
||||
final_string = final_string + " | TypeOfThePacket"
|
||||
elif item == address_of_ps_to_pl_communication_requested_action_of_the_packet or \
|
||||
item == address_of_pl_to_ps_communication_requested_action_of_the_packet:
|
||||
final_string = final_string + " | RequestedActionOfThePacket"
|
||||
elif item == address_of_ps_to_pl_communication_start_of_data or \
|
||||
item == address_of_pl_to_ps_communication_start_of_data:
|
||||
final_string = final_string + " | Start of Optional Data"
|
||||
|
||||
#
|
||||
# Print contents of BRAM
|
||||
#
|
||||
file.write(final_string + "\n")
|
||||
print(final_string)
|
||||
|
||||
print("\n===================================================================\n")
|
||||
|
||||
|
||||
#
|
||||
# Define a function to extract value of symbol
|
||||
#
|
||||
def get_symbol_value(dut, value):
|
||||
element_value = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, value)
|
||||
hex_string_value = ""
|
||||
try:
|
||||
int_content_value = int(str(element_value.value), 2)
|
||||
hex_string_value = f'{int_content_value:x}'
|
||||
except:
|
||||
hex_string_value = str(element_value.value)
|
||||
|
||||
final_string_value = f'{value}: 0x{hex_string_value}' + " (bin: " + str(element_value.value) + ")"
|
||||
return final_string_value
|
||||
|
||||
#
|
||||
# Define a function to extract type of symbol
|
||||
#
|
||||
def get_symbol_type(dut, type):
|
||||
element_type = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, type)
|
||||
hex_string_type = ""
|
||||
try:
|
||||
int_content_type = int(str(element_type.value), 2)
|
||||
hex_string_type = f'{int_content_type:x}'
|
||||
except:
|
||||
hex_string_type = str(element_type.value)
|
||||
|
||||
final_string_type = f'{type} : 0x{hex_string_type}' + " (bin: " + str(element_type.value) + ")"
|
||||
return final_string_type
|
||||
|
||||
#
|
||||
# Define a function to extract stage index
|
||||
#
|
||||
def get_stage_index(dut, stage_index):
|
||||
stage_index_str = "stageRegs_" + str(stage_index) + "_stageIndex"
|
||||
element_stage_index = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_index_str)
|
||||
hex_string_stage_index = ""
|
||||
try:
|
||||
int_content_stage_index = int(str(element_stage_index.value), 2)
|
||||
hex_string_stage_index = f'{int_content_stage_index:x}'
|
||||
except:
|
||||
hex_string_stage_index = str(element_stage_index.value)
|
||||
|
||||
final_string_stage_index = f'{stage_index}: 0x{hex_string_stage_index}' + " (bin: " + str(element_stage_index.value) + ")"
|
||||
return final_string_stage_index
|
||||
|
||||
#
|
||||
# Define a function to extract content of stages
|
||||
#
|
||||
def extract_stage_details(dut):
|
||||
|
||||
print("Script Stage Registers Configuration:\n")
|
||||
all_elements = dir(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule)
|
||||
|
||||
#
|
||||
# Define the pattern to match
|
||||
#
|
||||
pattern_value = re.compile(r'stageRegs_\d+_stageSymbol_Value')
|
||||
pattern_type = re.compile(r'stageRegs_\d+_stageSymbol_Type')
|
||||
pattern_stage_index = re.compile(r'stageRegs_\d+_stageIndex')
|
||||
|
||||
#
|
||||
# Filter the list using the patterns
|
||||
#
|
||||
filtered_strings_values = [s for s in all_elements if pattern_value.match(s)]
|
||||
filtered_strings_types = [s for s in all_elements if pattern_type.match(s)]
|
||||
filtered_strings_stage_index = [s for s in all_elements if pattern_stage_index.match(s)]
|
||||
|
||||
#
|
||||
# Sort the lists
|
||||
#
|
||||
sorted_values = sorted(filtered_strings_values, key=extract_number)
|
||||
sorted_types = sorted(filtered_strings_types, key=extract_number)
|
||||
sorted_stage_index = sorted(filtered_strings_stage_index, key=extract_number)
|
||||
|
||||
#
|
||||
# Print the filtered strings
|
||||
#
|
||||
# print(sorted_values)
|
||||
# print(sorted_types)
|
||||
# print(sorted_stage_index)
|
||||
|
||||
for index, element in enumerate(sorted_values):
|
||||
|
||||
try:
|
||||
final_string_type = get_symbol_type(dut, sorted_types[index])
|
||||
|
||||
#
|
||||
# Print the type
|
||||
#
|
||||
print(final_string_type)
|
||||
except:
|
||||
print("This stage does not contain a 'type'")
|
||||
|
||||
try:
|
||||
final_string_value = get_symbol_value(dut, sorted_values[index])
|
||||
|
||||
#
|
||||
# Print the value
|
||||
#
|
||||
print(final_string_value)
|
||||
except:
|
||||
print("Unable to get stage 'value' configuration details")
|
||||
|
||||
try:
|
||||
final_string_stage_index = get_stage_index(dut, index)
|
||||
|
||||
#
|
||||
# Print the stage index
|
||||
#
|
||||
print("index: " + final_string_stage_index)
|
||||
|
||||
except:
|
||||
print("index: " + str(index) +": This stage does not contain a 'stage index'")
|
||||
|
||||
print("\n")
|
||||
|
||||
|
||||
#
|
||||
# Check stage enable bit
|
||||
#
|
||||
try:
|
||||
stage_enabled = "stageRegs_" + str(index) + "_stageEnable"
|
||||
is_stage_enabled = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_enabled)
|
||||
print("\t Stage enabled bit: " + str(is_stage_enabled))
|
||||
except:
|
||||
print("\t Stage enabled bit: (unavailable)")
|
||||
|
||||
try:
|
||||
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Value")
|
||||
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Type")
|
||||
|
||||
print("\t Get (0) | " + final_string_type)
|
||||
print("\t Get (0) | " + final_string_value)
|
||||
except:
|
||||
print("\t stage at:" + str(index) + " does not contain a Get (0) buffer")
|
||||
|
||||
print("\n")
|
||||
|
||||
try:
|
||||
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Value")
|
||||
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Type")
|
||||
|
||||
print("\t Get (1) | " + final_string_type)
|
||||
print("\t Get (1) | " + final_string_value)
|
||||
except:
|
||||
print("\t stage at:" + str(index) + " does not contain a Get (1) buffer")
|
||||
|
||||
print("\n")
|
||||
|
||||
try:
|
||||
final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Value")
|
||||
final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Type")
|
||||
|
||||
print("\t Set (0) | " + final_string_type)
|
||||
print("\t Set (0) | " + final_string_value)
|
||||
except:
|
||||
print("\t stage at:" + str(index) + " does not contain a Set (0) buffer")
|
||||
|
||||
print("\n\n")
|
||||
|
||||
def set_input_pins(dut):
|
||||
dut.io_inputPin_0.value = 1
|
||||
dut.io_inputPin_1.value = 1
|
||||
dut.io_inputPin_2.value = 1
|
||||
dut.io_inputPin_3.value = 1
|
||||
dut.io_inputPin_4.value = 1
|
||||
dut.io_inputPin_5.value = 1
|
||||
dut.io_inputPin_6.value = 1
|
||||
dut.io_inputPin_7.value = 1
|
||||
dut.io_inputPin_8.value = 1
|
||||
dut.io_inputPin_9.value = 1
|
||||
dut.io_inputPin_10.value = 1
|
||||
dut.io_inputPin_11.value = 1
|
||||
dut.io_inputPin_12.value = 1
|
||||
dut.io_inputPin_13.value = 1
|
||||
dut.io_inputPin_14.value = 1
|
||||
dut.io_inputPin_15.value = 1
|
||||
dut.io_inputPin_16.value = 1
|
||||
dut.io_inputPin_17.value = 1
|
||||
dut.io_inputPin_18.value = 1
|
||||
dut.io_inputPin_19.value = 1
|
||||
dut.io_inputPin_20.value = 1
|
||||
dut.io_inputPin_21.value = 1
|
||||
dut.io_inputPin_22.value = 1
|
||||
dut.io_inputPin_23.value = 1
|
||||
dut.io_inputPin_24.value = 1
|
||||
dut.io_inputPin_25.value = 1
|
||||
dut.io_inputPin_26.value = 1
|
||||
dut.io_inputPin_27.value = 1
|
||||
dut.io_inputPin_28.value = 1
|
||||
dut.io_inputPin_29.value = 1
|
||||
dut.io_inputPin_30.value = 1
|
||||
dut.io_inputPin_31.value = 1
|
||||
|
||||
@cocotb.test()
|
||||
async def DebuggerModuleTestingBRAM_test(dut):
|
||||
"""Test hwdbg module (with pre-defined BRAM)"""
|
||||
|
||||
#
|
||||
# Assert initial output is unknown
|
||||
#
|
||||
assert LogicArray(dut.io_outputPin_0.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_1.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_2.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_3.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_4.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_5.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_6.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_7.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_8.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_9.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_10.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_11.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_12.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_13.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_14.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_15.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_16.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_17.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_18.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_19.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_20.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_21.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_22.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_23.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_24.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_25.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_26.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_27.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_28.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_29.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_30.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_outputPin_31.value) == LogicArray("X")
|
||||
|
||||
#
|
||||
# Create a 10ns period clock on port clock
|
||||
#
|
||||
clock = Clock(dut.clock, 10, units="ns")
|
||||
|
||||
#
|
||||
# Start the clock. Start it low to avoid issues on the first RisingEdge
|
||||
#
|
||||
cocotb.start_soon(clock.start(start_high=False))
|
||||
|
||||
dut._log.info("Initialize and reset module")
|
||||
|
||||
#
|
||||
# Initial values
|
||||
#
|
||||
dut.io_en.value = 0
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# Reset DUT
|
||||
#
|
||||
dut.reset.value = 1
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
dut.reset.value = 0
|
||||
|
||||
|
||||
dut._log.info("Enabling an interrupting chip to receive commands from BRAM")
|
||||
|
||||
#
|
||||
# Enable chip
|
||||
#
|
||||
dut.io_en.value = 1
|
||||
|
||||
#
|
||||
# Set initial input value to prevent it from floating
|
||||
#
|
||||
dut._log.info("Initializing input pins")
|
||||
# set_input_pins(dut)
|
||||
|
||||
#
|
||||
# Tell the hwdbg to receive BRAM results
|
||||
#
|
||||
dut.io_plInSignal.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# Synchronize with the clock. This will regisiter the initial `inputPinX` value
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Wait until the debuggee sends an interrupt to debugger
|
||||
#
|
||||
clock_counter = 0
|
||||
interrupt_not_delivered = False
|
||||
|
||||
while str(dut.io_psOutInterrupt) != "1":
|
||||
|
||||
# print("State of interrupt: '" + str(dut.io_psOutInterrupt) + "'")
|
||||
|
||||
if clock_counter % 10 == 0:
|
||||
print("Number of clock cycles spent in debuggee (PL): " + str(clock_counter))
|
||||
|
||||
clock_counter = clock_counter + 1
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Apply a limitation to the number of clock cycles that
|
||||
# can be executed to avoid infinite time
|
||||
#
|
||||
if (clock_counter >= maximum_number_of_clock_cycles):
|
||||
interrupt_not_delivered = True
|
||||
break
|
||||
|
||||
#
|
||||
# Being here means either the debuggee sent an interrupt to the PS
|
||||
# or the maximum clock cycles reached
|
||||
#
|
||||
if interrupt_not_delivered:
|
||||
print("Maximum clock cycles reached")
|
||||
else:
|
||||
print("Debuggee (PL) interrupted Debugger (PS)")
|
||||
|
||||
#
|
||||
# Run one more clock cycle to apply the latest BRAM modifications
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Print contents of BRAM
|
||||
#
|
||||
print_bram_content(dut)
|
||||
|
||||
#
|
||||
# Print the script stage configuration
|
||||
#
|
||||
extract_stage_details(dut)
|
||||
|
||||
#
|
||||
# Check the final input on the next clock and run the circuit for a couple
|
||||
# of more clock cycles
|
||||
#
|
||||
for _ in range(100):
|
||||
set_input_pins(dut)
|
||||
await Timer(10, units="ns")
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Makefile
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
|
||||
TOPLEVEL = DebuggerPacketReceiver
|
||||
MODULE = test_DebuggerPacketReceiver
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
|
|
@ -0,0 +1 @@
|
|||
make SIM=icarus WAVES=1
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
##
|
||||
# @file test_DebuggerPacketReceiver.py
|
||||
#
|
||||
# @author Sina Karvandi (sina@hyperdbg.org)
|
||||
#
|
||||
# @brief Testing module for DebuggerPacketReceiver
|
||||
#
|
||||
# @details
|
||||
#
|
||||
# @version 0.1
|
||||
#
|
||||
# @date 2024-04-22
|
||||
#
|
||||
# @copyright This project is released under the GNU Public License v3.
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer
|
||||
from cocotb.types import LogicArray
|
||||
|
||||
'''
|
||||
input clock,
|
||||
reset,
|
||||
io_en,
|
||||
io_plInSignal,
|
||||
output [12:0] io_rdWrAddr,
|
||||
input [31:0] io_rdData,
|
||||
output [31:0] io_requestedActionOfThePacketOutput,
|
||||
output io_requestedActionOfThePacketOutputValid,
|
||||
input io_noNewDataReceiver,
|
||||
io_readNextData,
|
||||
output io_dataValidOutput,
|
||||
output [31:0] io_receivingData,
|
||||
output io_finishedReceivingBuffer
|
||||
'''
|
||||
|
||||
@cocotb.test()
|
||||
async def DebuggerPacketReceiver_test(dut):
|
||||
"""Test DebuggerPacketReceiver module"""
|
||||
|
||||
#
|
||||
# Assert initial output is unknown
|
||||
#
|
||||
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_finishedReceivingBuffer.value) == LogicArray("X")
|
||||
|
||||
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
|
||||
|
||||
#
|
||||
# Start the clock. Start it low to avoid issues on the first RisingEdge
|
||||
#
|
||||
cocotb.start_soon(clock.start(start_high=False))
|
||||
|
||||
dut._log.info("Initialize and reset module")
|
||||
|
||||
#
|
||||
# Initial values
|
||||
#
|
||||
dut.io_en.value = 0
|
||||
dut.io_readNextData.value = 0
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# Reset DUT
|
||||
#
|
||||
dut.reset.value = 1
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
dut.reset.value = 0
|
||||
|
||||
dut._log.info("Enabling chip")
|
||||
|
||||
#
|
||||
# Enable chip
|
||||
#
|
||||
dut.io_en.value = 1
|
||||
|
||||
for test_number in range(10):
|
||||
|
||||
dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
|
||||
|
||||
#
|
||||
# Tell the receiver to start receiving data (This mainly operates based on
|
||||
# a rising-edge detector, so we'll need to make it low)
|
||||
#
|
||||
dut.io_plInSignal.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# Wait until the receive operation is done (finished)
|
||||
#
|
||||
for i in range(30):
|
||||
|
||||
if (dut.io_finishedReceivingBuffer.value == 1):
|
||||
break
|
||||
else:
|
||||
match dut.io_rdWrAddr.value:
|
||||
case 0x0: # checksum
|
||||
dut.io_rdData.value = 0x00001234
|
||||
case 0x8: # indicator
|
||||
dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
|
||||
case 0x10: # type
|
||||
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
|
||||
case 0x14: # requested action
|
||||
dut.io_rdData.value = 0x14141414
|
||||
case 0x18: # General output
|
||||
dut.io_rdData.value = 0x18181818
|
||||
case 0x1c: # General output
|
||||
dut.io_rdData.value = 0x1c1c1c1c
|
||||
case 0x20: # General output
|
||||
dut.io_rdData.value = 0x20202020
|
||||
case 0x24: # General output
|
||||
dut.io_rdData.value = 0x24242424
|
||||
case 0x28: # General output
|
||||
dut.io_rdData.value = 0x28282828
|
||||
case 0x2c: # General output
|
||||
dut.io_rdData.value = 0x2c2c2c2c
|
||||
case 0x30: # General output
|
||||
dut.io_rdData.value = 0x30303030
|
||||
case 0x34: # General output
|
||||
dut.io_rdData.value = 0x34343434
|
||||
case 0x38: # General output
|
||||
dut.io_rdData.value = 0x38383838
|
||||
case 0x3c: # General output
|
||||
dut.io_rdData.value = 0x3c3c3c3c
|
||||
case 0x40: # General output
|
||||
dut.io_rdData.value = 0x40404040
|
||||
case 0x44: # General output
|
||||
dut.io_rdData.value = 0x44444444
|
||||
case 0x48: # General output
|
||||
dut.io_rdData.value = 0x48484848
|
||||
case 0x4c: # General output
|
||||
dut.io_rdData.value = 0x4c4c4c4c
|
||||
case 0x50: # General output
|
||||
dut.io_rdData.value = 0x50505050
|
||||
case _:
|
||||
assert "invalid address in the address line"
|
||||
|
||||
if dut.io_requestedActionOfThePacketOutputValid.value == 1:
|
||||
|
||||
#
|
||||
# No new data needed to be received
|
||||
#
|
||||
if test_number % 3 == 0:
|
||||
dut.io_noNewDataReceiver.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
else:
|
||||
#
|
||||
# Make change to the io_readNextData signal as it operates mainly
|
||||
# based on a rising-edge detector
|
||||
#
|
||||
if dut.io_readNextData.value == 0:
|
||||
dut.io_readNextData.value = 1
|
||||
else:
|
||||
dut.io_readNextData.value = 0
|
||||
|
||||
|
||||
#
|
||||
# Go to the next clock cycle
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
if test_number % 3 != 0:
|
||||
dut.io_noNewDataReceiver.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
|
||||
#
|
||||
# Run extra waiting clocks
|
||||
#
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Check the final input on the next clock
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Makefile
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
|
||||
TOPLEVEL = DebuggerPacketSender
|
||||
MODULE = test_DebuggerPacketSender
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
|
|
@ -0,0 +1 @@
|
|||
make SIM=icarus WAVES=1
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
##
|
||||
# @file test_DebuggerPacketSender.py
|
||||
#
|
||||
# @author Sina Karvandi (sina@hyperdbg.org)
|
||||
#
|
||||
# @brief Testing module for DebuggerPacketSender
|
||||
#
|
||||
# @details
|
||||
#
|
||||
# @version 0.1
|
||||
#
|
||||
# @date 2024-04-21
|
||||
#
|
||||
# @copyright This project is released under the GNU Public License v3.
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer
|
||||
from cocotb.types import LogicArray
|
||||
|
||||
'''
|
||||
input clock,
|
||||
reset,
|
||||
io_en,
|
||||
output io_psOutInterrupt,
|
||||
output [12:0] io_rdWrAddr,
|
||||
output io_wrEna,
|
||||
output [31:0] io_wrData,
|
||||
input io_beginSendingBuffer,
|
||||
io_noNewDataSender,
|
||||
io_dataValidInput,
|
||||
output io_sendWaitForBuffer,
|
||||
io_finishedSendingBuffer,
|
||||
input [31:0] io_requestedActionOfThePacketInput,
|
||||
io_sendingData
|
||||
'''
|
||||
|
||||
@cocotb.test()
|
||||
async def DebuggerPacketSender_test(dut):
|
||||
"""Test DebuggerPacketSender module"""
|
||||
|
||||
#
|
||||
# Assert initial output is unknown
|
||||
#
|
||||
assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_finishedSendingBuffer.value) == LogicArray("X")
|
||||
|
||||
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
|
||||
|
||||
#
|
||||
# Start the clock. Start it low to avoid issues on the first RisingEdge
|
||||
#
|
||||
cocotb.start_soon(clock.start(start_high=False))
|
||||
|
||||
dut._log.info("Initialize and reset module")
|
||||
|
||||
#
|
||||
# Initial values
|
||||
#
|
||||
dut.io_en.value = 0
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
|
||||
#
|
||||
# Reset DUT
|
||||
#
|
||||
dut.reset.value = 1
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
dut.reset.value = 0
|
||||
|
||||
dut._log.info("Enabling chip")
|
||||
|
||||
#
|
||||
# Enable chip
|
||||
#
|
||||
dut.io_en.value = 1
|
||||
|
||||
for test_number in range(10):
|
||||
|
||||
dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
|
||||
|
||||
#
|
||||
# Still there is data to send
|
||||
#
|
||||
dut.io_noNewDataSender.value = 0
|
||||
|
||||
#
|
||||
# Tell the sender to start sending data (This mainly operates based on
|
||||
# a rising-edge detector, so we'll need to make it low)
|
||||
#
|
||||
dut.io_beginSendingBuffer.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
|
||||
#
|
||||
# No new data at this stage
|
||||
#
|
||||
dut.io_dataValidInput.value = 0
|
||||
dut.io_sendingData.value = 0
|
||||
|
||||
#
|
||||
# Adjust the requested action of the packet
|
||||
#
|
||||
dut.io_requestedActionOfThePacketInput.value = 0x55859555
|
||||
|
||||
#
|
||||
# Synchronize with the clock. This will apply the initial values
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# This will change the behavior of the data producer to only
|
||||
# generate extra data for 2 of the test case rounds, the third
|
||||
# test case doesn't have any extra data
|
||||
#
|
||||
if test_number % 3 != 0 :
|
||||
#
|
||||
# Run until the module asks for further buffers
|
||||
#
|
||||
for i in range(100):
|
||||
if dut.io_sendWaitForBuffer.value == 1:
|
||||
val = random.randint(0, 0xffffffff)
|
||||
|
||||
#
|
||||
# Indicate that the data is valid
|
||||
#
|
||||
dut.io_dataValidInput.value = 1
|
||||
|
||||
#
|
||||
# Assign the random value to send as the data
|
||||
#
|
||||
dut.io_sendingData.value = val
|
||||
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Now, tell the sender module that there is no longer needed to send data
|
||||
#
|
||||
for i in range(100):
|
||||
if dut.io_sendWaitForBuffer.value == 1:
|
||||
dut.io_noNewDataSender.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataSender.value = 0
|
||||
break
|
||||
|
||||
await Timer(10, units="ns")
|
||||
|
||||
|
||||
#
|
||||
# Run extra waiting clocks
|
||||
#
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Check the final input on the next clock
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Makefile
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../../generated/SendReceiveSynchronizer.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
|
||||
VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
|
||||
TOPLEVEL = SendReceiveSynchronizer
|
||||
MODULE = test_SendReceiveSynchronizer
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
|
|
@ -0,0 +1 @@
|
|||
make SIM=icarus WAVES=1
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
##
|
||||
# @file test_SendReceiveSynchronizer.py
|
||||
#
|
||||
# @author Sina Karvandi (sina@hyperdbg.org)
|
||||
#
|
||||
# @brief Testing module for SendReceiveSynchronizer
|
||||
#
|
||||
# @details
|
||||
#
|
||||
# @version 0.1
|
||||
#
|
||||
# @date 2024-04-23
|
||||
#
|
||||
# @copyright This project is released under the GNU Public License v3.
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer
|
||||
from cocotb.types import LogicArray
|
||||
|
||||
'''
|
||||
input clock,
|
||||
reset,
|
||||
io_en,
|
||||
io_plInSignal,
|
||||
output io_psOutInterrupt,
|
||||
output [12:0] io_rdWrAddr,
|
||||
input [31:0] io_rdData,
|
||||
output io_wrEna,
|
||||
output [31:0] io_wrData,
|
||||
io_requestedActionOfThePacketOutput,
|
||||
output io_requestedActionOfThePacketOutputValid,
|
||||
input io_noNewDataReceiver,
|
||||
io_readNextData,
|
||||
output io_dataValidOutput,
|
||||
output [31:0] io_receivingData,
|
||||
input io_beginSendingBuffer,
|
||||
io_noNewDataSender,
|
||||
io_dataValidInput,
|
||||
output io_sendWaitForBuffer,
|
||||
input [31:0] io_requestedActionOfThePacketInput,
|
||||
io_sendingData
|
||||
'''
|
||||
|
||||
@cocotb.test()
|
||||
async def SendReceiveSynchronizer_test(dut):
|
||||
"""Test SendReceiveSynchronizer module"""
|
||||
|
||||
global DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
|
||||
|
||||
#
|
||||
# Assert initial output is unknown
|
||||
#
|
||||
assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
|
||||
assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
||||
assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
|
||||
|
||||
clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
|
||||
|
||||
#
|
||||
# Start the clock. Start it low to avoid issues on the first RisingEdge
|
||||
#
|
||||
cocotb.start_soon(clock.start(start_high=False))
|
||||
|
||||
dut._log.info("Initialize and reset module")
|
||||
|
||||
#
|
||||
# Initial values
|
||||
#
|
||||
dut.io_en.value = 0
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
dut.io_noNewDataSender.value = 0
|
||||
dut.io_dataValidInput.value = 0
|
||||
dut.io_readNextData.value = 0
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
dut.io_plInSignal.value = 0
|
||||
dut.io_requestedActionOfThePacketInput.value = 0
|
||||
dut.io_requestedActionOfThePacketInput.value = 0
|
||||
|
||||
#
|
||||
# Reset DUT
|
||||
#
|
||||
dut.reset.value = 1
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
dut.reset.value = 0
|
||||
|
||||
dut._log.info("Enabling chip")
|
||||
|
||||
#
|
||||
# Enable chip
|
||||
#
|
||||
dut.io_en.value = 1
|
||||
|
||||
for test_number in range(10):
|
||||
|
||||
###############################################################
|
||||
# #
|
||||
# Receiving Logic #
|
||||
# #
|
||||
###############################################################
|
||||
|
||||
dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
|
||||
|
||||
#
|
||||
# Tell the receiver to start receiving data (This mainly operates based on
|
||||
# a rising-edge detector, so we'll need to make it low)
|
||||
#
|
||||
dut.io_plInSignal.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# Activate sending logic to test whether the chip fails synchronizing signals or not
|
||||
#
|
||||
dut.io_beginSendingBuffer.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
|
||||
#
|
||||
# Wait until the receive operation is done (finished)
|
||||
#
|
||||
for i in range(30):
|
||||
|
||||
match dut.io_rdWrAddr.value:
|
||||
|
||||
#
|
||||
# For the PS data range
|
||||
#
|
||||
case 0x0: # checksum
|
||||
dut.io_rdData.value = 0x00001234
|
||||
case 0x8: # indicator
|
||||
dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
|
||||
case 0x10: # type
|
||||
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
|
||||
case 0x14: # requested action
|
||||
dut.io_rdData.value = 0x14141414
|
||||
case 0x18: # General output
|
||||
dut.io_rdData.value = 0x18181818
|
||||
case 0x1c: # General output
|
||||
dut.io_rdData.value = 0x1c1c1c1c
|
||||
case 0x20: # General output
|
||||
dut.io_rdData.value = 0x20202020
|
||||
case 0x24: # General output
|
||||
dut.io_rdData.value = 0x24242424
|
||||
case 0x28: # General output
|
||||
dut.io_rdData.value = 0x28282828
|
||||
case 0x2c: # General output
|
||||
dut.io_rdData.value = 0x2c2c2c2c
|
||||
case 0x30: # General output
|
||||
dut.io_rdData.value = 0x30303030
|
||||
case 0x34: # General output
|
||||
dut.io_rdData.value = 0x34343434
|
||||
case 0x38: # General output
|
||||
dut.io_rdData.value = 0x38383838
|
||||
case 0x3c: # General output
|
||||
dut.io_rdData.value = 0x3c3c3c3c
|
||||
case 0x40: # General output
|
||||
dut.io_rdData.value = 0x40404040
|
||||
case 0x44: # General output
|
||||
dut.io_rdData.value = 0x44444444
|
||||
case 0x48: # General output
|
||||
dut.io_rdData.value = 0x48484848
|
||||
case 0x4c: # General output
|
||||
dut.io_rdData.value = 0x4c4c4c4c
|
||||
case 0x50: # General output
|
||||
dut.io_rdData.value = 0x50505050
|
||||
|
||||
#
|
||||
# For the PL data range
|
||||
#
|
||||
case 0x1000: # checksum
|
||||
dut.io_rdData.value = 0x10001000
|
||||
case 0x1008: # indicator 1
|
||||
dut.io_rdData.value = 0x48595045 # The first 32 bits of the indicator
|
||||
case 0x100c: # indicator 2
|
||||
dut.io_rdData.value = 0x100c100c # The second 32 bits of the indicator
|
||||
case 0x1010: # type
|
||||
dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
|
||||
case 0x1014: # requested action
|
||||
dut.io_rdData.value = 0x10141014
|
||||
case 0x1018: # General output
|
||||
dut.io_rdData.value = 0x10181018
|
||||
case 0x101c: # General output
|
||||
dut.io_rdData.value = 0x101c101c
|
||||
case 0x1020: # General output
|
||||
dut.io_rdData.value = 0x10201020
|
||||
case 0x1024: # General output
|
||||
dut.io_rdData.value = 0x10241024
|
||||
case 0x1028: # General output
|
||||
dut.io_rdData.value = 0x10281028
|
||||
case 0x102c: # General output
|
||||
dut.io_rdData.value = 0x102c102c
|
||||
case 0x1030: # General output
|
||||
dut.io_rdData.value = 0x10301030
|
||||
case 0x1034: # General output
|
||||
dut.io_rdData.value = 0x10341034
|
||||
case 0x1038: # General output
|
||||
dut.io_rdData.value = 0x10381038
|
||||
case 0x103c: # General output
|
||||
dut.io_rdData.value = 0x103c103c
|
||||
case 0x1040: # General output
|
||||
dut.io_rdData.value = 0x10401040
|
||||
case 0x1044: # General output
|
||||
dut.io_rdData.value = 0x10441044
|
||||
case 0x1048: # General output
|
||||
dut.io_rdData.value = 0x10481048
|
||||
case 0x104c: # General output
|
||||
dut.io_rdData.value = 0x104c104c
|
||||
case 0x1050: # General output
|
||||
dut.io_rdData.value = 0x10501050
|
||||
case _:
|
||||
assert 1 == 2, "invalid address in the address line"
|
||||
|
||||
if dut.io_requestedActionOfThePacketOutputValid.value == 1:
|
||||
|
||||
#
|
||||
# No new data needed to be received
|
||||
#
|
||||
if test_number % 3 == 0:
|
||||
dut.io_noNewDataReceiver.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
else:
|
||||
#
|
||||
# Make change to the io_readNextData signal as it operates mainly
|
||||
# based on a rising-edge detector
|
||||
#
|
||||
if dut.io_readNextData.value == 0:
|
||||
dut.io_readNextData.value = 1
|
||||
else:
|
||||
dut.io_readNextData.value = 0
|
||||
|
||||
#
|
||||
# Go to the next clock cycle
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
|
||||
if test_number % 3 != 0:
|
||||
dut.io_noNewDataReceiver.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataReceiver.value = 0
|
||||
|
||||
#
|
||||
# Run extra waiting clocks
|
||||
#
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
|
||||
###############################################################
|
||||
# #
|
||||
# Sending Logic #
|
||||
# #
|
||||
###############################################################
|
||||
|
||||
dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
|
||||
|
||||
#
|
||||
# There is data to send
|
||||
#
|
||||
dut.io_noNewDataSender.value = 0
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
|
||||
#
|
||||
# Tell the sender to start sending data (This mainly operates based on
|
||||
# a rising-edge detector, so we'll need to make it low)
|
||||
#
|
||||
dut.io_beginSendingBuffer.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_beginSendingBuffer.value = 0
|
||||
|
||||
#
|
||||
# Activate receiving logic to test whether the chip fails synchronizing signals or not
|
||||
#
|
||||
dut.io_plInSignal.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_plInSignal.value = 0
|
||||
|
||||
#
|
||||
# No new data at this stage
|
||||
#
|
||||
dut.io_dataValidInput.value = 0
|
||||
dut.io_sendingData.value = 0
|
||||
|
||||
#
|
||||
# Adjust the requested action of the packet
|
||||
#
|
||||
dut.io_requestedActionOfThePacketInput.value = 0x55859555
|
||||
|
||||
#
|
||||
# Synchronize with the clock. This will apply the initial values
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# This will change the behavior of the data producer to only
|
||||
# generate extra data for 2 of the test case rounds, the third
|
||||
# test case doesn't have any extra data
|
||||
#
|
||||
if test_number % 3 != 0 :
|
||||
#
|
||||
# Run until the module asks for further buffers
|
||||
#
|
||||
for i in range(100):
|
||||
if dut.io_sendWaitForBuffer.value == 1:
|
||||
val = random.randint(0, 0xffffffff)
|
||||
|
||||
#
|
||||
# Indicate that the data is valid
|
||||
#
|
||||
dut.io_dataValidInput.value = 1
|
||||
|
||||
#
|
||||
# Assign the random value to send as the data
|
||||
#
|
||||
dut.io_sendingData.value = val
|
||||
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Now, tell the sender module that there is no longer needed to send data
|
||||
#
|
||||
for i in range(100):
|
||||
if dut.io_sendWaitForBuffer.value == 1:
|
||||
dut.io_noNewDataSender.value = 1
|
||||
await Timer(10, units="ns")
|
||||
dut.io_noNewDataSender.value = 0
|
||||
break
|
||||
|
||||
await Timer(10, units="ns")
|
||||
|
||||
|
||||
#
|
||||
# Run extra waiting clocks
|
||||
#
|
||||
for _ in range(10):
|
||||
await Timer(10, units="ns")
|
||||
|
||||
#
|
||||
# Check the final input on the next clock
|
||||
#
|
||||
await Timer(10, units="ns")
|
||||
32
hwdbg/sim/modelsim/README.md
Normal file
32
hwdbg/sim/modelsim/README.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Automated ModelSim Viewer
|
||||
|
||||
First of all, make sure to edit the address of the "ModelSim" directory in **modelsim.py**.
|
||||
|
||||
After that, only modify the "modelsim.config" file.
|
||||
|
||||
In the "modelsim.config" file, the first line that starts with "module:" is the name of the target module's **Tester** class. The rest of the lines are signals to be shown.
|
||||
|
||||
For example:
|
||||
```
|
||||
module:DebuggerModuleTest
|
||||
clock
|
||||
inputPin
|
||||
```
|
||||
|
||||
If you don't specify the signals to be filtered, then **ALL** signals will be shown.
|
||||
|
||||
For example:
|
||||
```
|
||||
module:DebuggerModuleTest
|
||||
```
|
||||
|
||||
At last, run it with the following command:
|
||||
```
|
||||
python3 modelsim.py
|
||||
```
|
||||
|
||||
or,
|
||||
```
|
||||
python3 sim/modelsim.py
|
||||
```
|
||||
|
||||
3
hwdbg/sim/modelsim/modelsim.config
Normal file
3
hwdbg/sim/modelsim/modelsim.config
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module:DebuggerModuleTest
|
||||
io_inputPin
|
||||
io_outputPin
|
||||
157
hwdbg/sim/modelsim/modelsim.py
Normal file
157
hwdbg/sim/modelsim/modelsim.py
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import os
|
||||
import subprocess
|
||||
import glob
|
||||
|
||||
MODELSIM = "/home/sina/intelFPGA/20.1/modelsim_ase/bin"
|
||||
|
||||
#
|
||||
# Check modelsim directory
|
||||
#
|
||||
if not os.path.exists(MODELSIM):
|
||||
print("[x] Error: The path does not exist")
|
||||
exit()
|
||||
else:
|
||||
print("[*] Oh, the modelsim path found :)")
|
||||
|
||||
MODELSIM_VCD2WLF = MODELSIM + "/vcd2wlf"
|
||||
MODELSIM_VSIM = MODELSIM + "/vsim"
|
||||
|
||||
#
|
||||
# Config file variables
|
||||
#
|
||||
CONFIG_TEST_MODULE_CLASS = ""
|
||||
CONFIG_SHOW_ALL_WAVES = True
|
||||
CONFIG_WAVES_LIST = []
|
||||
|
||||
#
|
||||
# Check if user is root or not
|
||||
#
|
||||
if os.geteuid() != 0:
|
||||
print("[x] you should run this script with root (sudo) user permission")
|
||||
exit()
|
||||
else:
|
||||
print("[*] user is root")
|
||||
|
||||
#
|
||||
# Get the current script's directory
|
||||
#
|
||||
current_script_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
WAVE_OUTPUT_FILES_PATH = current_script_path + \
|
||||
"/../test_run_dir/DUT_should_pass/"
|
||||
CONFIG_FILE_PATH = current_script_path + "/modelsim.config"
|
||||
print("[*] current script path:", WAVE_OUTPUT_FILES_PATH)
|
||||
|
||||
#
|
||||
# Check config file
|
||||
#
|
||||
if os.path.exists(CONFIG_FILE_PATH) == False:
|
||||
print("[x] config file not found")
|
||||
exit()
|
||||
|
||||
#
|
||||
# Interpreting config file
|
||||
#
|
||||
with open(CONFIG_FILE_PATH, 'r') as file:
|
||||
for line in file:
|
||||
|
||||
if line.lower().startswith("module:") or line.lower().startswith("module :"):
|
||||
# it's the test module name
|
||||
CONFIG_TEST_MODULE_CLASS = line.split(":")[1]
|
||||
print("[*] found module name:", CONFIG_TEST_MODULE_CLASS)
|
||||
else:
|
||||
# it's a wave, so no longer need to show all waves
|
||||
if line.isspace() == False:
|
||||
CONFIG_SHOW_ALL_WAVES = False
|
||||
CONFIG_WAVES_LIST.append(line)
|
||||
print("[*] signal filter for:", line)
|
||||
|
||||
#
|
||||
# Show message if all signals need to be shown
|
||||
#
|
||||
if CONFIG_SHOW_ALL_WAVES == True:
|
||||
print("[*] no signal filter found, assuming all signals to be shown!")
|
||||
|
||||
#
|
||||
# Check if test module is empty or not
|
||||
#
|
||||
if CONFIG_TEST_MODULE_CLASS.isspace() == True:
|
||||
print("[x] main test module not found, please add 'module:' to the config file")
|
||||
exit()
|
||||
|
||||
#
|
||||
# Set the current working directory
|
||||
#
|
||||
os.chdir(current_script_path + "/..")
|
||||
print("[*] current working directory: " + format(os.getcwd()))
|
||||
|
||||
#
|
||||
# Create TCL config file
|
||||
#
|
||||
print("[*] writing to TCL config file: " +
|
||||
current_script_path + '/modelsim.tcl')
|
||||
if CONFIG_SHOW_ALL_WAVES:
|
||||
with open(current_script_path + '/modelsim.tcl', 'w') as f:
|
||||
# add the clock at top of the signals by default
|
||||
f.write("add wave -position insertpoint clock\n")
|
||||
f.write("add wave -position insertpoint *\n")
|
||||
else:
|
||||
with open(current_script_path + '/modelsim.tcl', 'w') as f:
|
||||
for item in CONFIG_WAVES_LIST:
|
||||
f.write("add wave -position insertpoint {*" + item.replace('\n','').replace('\r', '') + '*}\n')
|
||||
|
||||
#
|
||||
# Remove all the previous *.wlf, *.vcd, *.fir files
|
||||
#
|
||||
print("[*] removing previously generated files")
|
||||
for file_name in os.listdir(WAVE_OUTPUT_FILES_PATH):
|
||||
if file_name.endswith('.wlf') or file_name.endswith('.vcd') or file_name.endswith('.fir'):
|
||||
os.remove(os.path.join(WAVE_OUTPUT_FILES_PATH, file_name))
|
||||
|
||||
#
|
||||
# Run the VCD wave generator
|
||||
#
|
||||
print("[*] running chisel VCD file generator for module: " +
|
||||
CONFIG_TEST_MODULE_CLASS)
|
||||
print("running command: '" + "sbt testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1" + "'")
|
||||
result = subprocess.run(
|
||||
["sbt", "testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1"], stdout=subprocess.PIPE)
|
||||
print(result.stdout.decode())
|
||||
|
||||
#
|
||||
# Get all files in directory
|
||||
#
|
||||
files = glob.glob(WAVE_OUTPUT_FILES_PATH + "/*")
|
||||
|
||||
#
|
||||
# Sort files by last modified time
|
||||
#
|
||||
files.sort(key=lambda x: os.path.getmtime(x))
|
||||
|
||||
#
|
||||
# Check if the list is empty or not
|
||||
#
|
||||
if not files or not files[-1].endswith('.vcd') :
|
||||
print("[x] there was an error in generating VCD files")
|
||||
exit()
|
||||
|
||||
#
|
||||
# Get the latest modified file
|
||||
#
|
||||
latest_vcd_file = files[-1]
|
||||
print("[*] latest generated VCD file: " + latest_vcd_file)
|
||||
|
||||
#
|
||||
# Converting VCD to WLF
|
||||
#
|
||||
print("[*] converting VCD file to WLF file")
|
||||
result = subprocess.run(
|
||||
[MODELSIM_VCD2WLF, latest_vcd_file, latest_vcd_file + ".wlf"], stdout=subprocess.PIPE)
|
||||
print(result.stdout.decode())
|
||||
|
||||
#
|
||||
# Run the generated WLF file
|
||||
#
|
||||
print("[*] opening file in vsim: " + latest_vcd_file + ".wlf")
|
||||
subprocess.run([MODELSIM_VSIM, latest_vcd_file + ".wlf",
|
||||
"-do", current_script_path + '/modelsim.tcl'])
|
||||
2
hwdbg/sim/modelsim/modelsim.tcl
Normal file
2
hwdbg/sim/modelsim/modelsim.tcl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
add wave -position insertpoint {*io_inputPin*}
|
||||
add wave -position insertpoint {*io_outputPin*}
|
||||
162
hwdbg/sim/plain-sv/PlainSystemVerilogDUT.sv
Normal file
162
hwdbg/sim/plain-sv/PlainSystemVerilogDUT.sv
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer: Sina Karvandi (sina@hyperdbg.org)
|
||||
//
|
||||
// Create Date: 09/18/2024
|
||||
// Design Name:
|
||||
// Module Name: PlainSystemVerilogDUT
|
||||
// Project Name: PlainSystemVerilogDUT
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: This code is used for plain simulation of the top-level
|
||||
// design of hwdbg debugger
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module PlainSystemVerilogDUT;
|
||||
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
parameter CLK_PERIOD = 10; // Clock period
|
||||
|
||||
//
|
||||
// Signal Declarations
|
||||
//
|
||||
logic clock;
|
||||
logic reset;
|
||||
logic io_en;
|
||||
logic [31:0] io_inputPin; // Array for input pins
|
||||
logic [31:0] io_outputPin; // Array for output pins
|
||||
logic io_plInSignal;
|
||||
logic io_psOutInterrupt;
|
||||
|
||||
//
|
||||
// Instantiate the DUT (Device Under Test)
|
||||
//
|
||||
DebuggerModuleTestingBRAM uut (
|
||||
.clock(clock),
|
||||
.reset(reset),
|
||||
.io_en(io_en),
|
||||
.io_inputPin_0(io_inputPin[0]),
|
||||
.io_inputPin_1(io_inputPin[1]),
|
||||
.io_inputPin_2(io_inputPin[2]),
|
||||
.io_inputPin_3(io_inputPin[3]),
|
||||
.io_inputPin_4(io_inputPin[4]),
|
||||
.io_inputPin_5(io_inputPin[5]),
|
||||
.io_inputPin_6(io_inputPin[6]),
|
||||
.io_inputPin_7(io_inputPin[7]),
|
||||
.io_inputPin_8(io_inputPin[8]),
|
||||
.io_inputPin_9(io_inputPin[9]),
|
||||
.io_inputPin_10(io_inputPin[10]),
|
||||
.io_inputPin_11(io_inputPin[11]),
|
||||
.io_inputPin_12(io_inputPin[12]),
|
||||
.io_inputPin_13(io_inputPin[13]),
|
||||
.io_inputPin_14(io_inputPin[14]),
|
||||
.io_inputPin_15(io_inputPin[15]),
|
||||
.io_inputPin_16(io_inputPin[16]),
|
||||
.io_inputPin_17(io_inputPin[17]),
|
||||
.io_inputPin_18(io_inputPin[18]),
|
||||
.io_inputPin_19(io_inputPin[19]),
|
||||
.io_inputPin_20(io_inputPin[20]),
|
||||
.io_inputPin_21(io_inputPin[21]),
|
||||
.io_inputPin_22(io_inputPin[22]),
|
||||
.io_inputPin_23(io_inputPin[23]),
|
||||
.io_inputPin_24(io_inputPin[24]),
|
||||
.io_inputPin_25(io_inputPin[25]),
|
||||
.io_inputPin_26(io_inputPin[26]),
|
||||
.io_inputPin_27(io_inputPin[27]),
|
||||
.io_inputPin_28(io_inputPin[28]),
|
||||
.io_inputPin_29(io_inputPin[29]),
|
||||
.io_inputPin_30(io_inputPin[30]),
|
||||
.io_inputPin_31(io_inputPin[31]),
|
||||
.io_outputPin_0(io_outputPin[0]),
|
||||
.io_outputPin_1(io_outputPin[1]),
|
||||
.io_outputPin_2(io_outputPin[2]),
|
||||
.io_outputPin_3(io_outputPin[3]),
|
||||
.io_outputPin_4(io_outputPin[4]),
|
||||
.io_outputPin_5(io_outputPin[5]),
|
||||
.io_outputPin_6(io_outputPin[6]),
|
||||
.io_outputPin_7(io_outputPin[7]),
|
||||
.io_outputPin_8(io_outputPin[8]),
|
||||
.io_outputPin_9(io_outputPin[9]),
|
||||
.io_outputPin_10(io_outputPin[10]),
|
||||
.io_outputPin_11(io_outputPin[11]),
|
||||
.io_outputPin_12(io_outputPin[12]),
|
||||
.io_outputPin_13(io_outputPin[13]),
|
||||
.io_outputPin_14(io_outputPin[14]),
|
||||
.io_outputPin_15(io_outputPin[15]),
|
||||
.io_outputPin_16(io_outputPin[16]),
|
||||
.io_outputPin_17(io_outputPin[17]),
|
||||
.io_outputPin_18(io_outputPin[18]),
|
||||
.io_outputPin_19(io_outputPin[19]),
|
||||
.io_outputPin_20(io_outputPin[20]),
|
||||
.io_outputPin_21(io_outputPin[21]),
|
||||
.io_outputPin_22(io_outputPin[22]),
|
||||
.io_outputPin_23(io_outputPin[23]),
|
||||
.io_outputPin_24(io_outputPin[24]),
|
||||
.io_outputPin_25(io_outputPin[25]),
|
||||
.io_outputPin_26(io_outputPin[26]),
|
||||
.io_outputPin_27(io_outputPin[27]),
|
||||
.io_outputPin_28(io_outputPin[28]),
|
||||
.io_outputPin_29(io_outputPin[29]),
|
||||
.io_outputPin_30(io_outputPin[30]),
|
||||
.io_outputPin_31(io_outputPin[31]),
|
||||
.io_plInSignal(io_plInSignal),
|
||||
.io_psOutInterrupt(io_psOutInterrupt)
|
||||
);
|
||||
|
||||
//
|
||||
// Clock generation
|
||||
//
|
||||
initial begin
|
||||
clock = 0;
|
||||
forever #(CLK_PERIOD / 2) clock = ~clock;
|
||||
end
|
||||
|
||||
//
|
||||
// Test procedure
|
||||
//
|
||||
initial begin
|
||||
// Initialize signals
|
||||
reset = 1;
|
||||
io_en = 1;
|
||||
io_plInSignal = 0;
|
||||
io_inputPin = 32'h0; // Initialize all input pins to 0
|
||||
|
||||
#100; // Hold reset for 100 ns
|
||||
|
||||
// Apply reset
|
||||
@(posedge clock);
|
||||
reset = 0; // Release reset
|
||||
@(posedge clock);
|
||||
|
||||
//
|
||||
// Example input stimulus
|
||||
//
|
||||
io_inputPin = 32'hFFFF_FFFF; // Apply some input pattern
|
||||
|
||||
//
|
||||
// Enable PL input signal
|
||||
//
|
||||
io_plInSignal = 1;
|
||||
|
||||
//
|
||||
// Wait for a few clock cycles
|
||||
//
|
||||
repeat (10000) @(posedge clock);
|
||||
|
||||
//
|
||||
// Finish the simulation after some time
|
||||
//
|
||||
repeat (20) @(posedge clock);
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
515
hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
Normal file
515
hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/**
|
||||
* @file
|
||||
* interpreter.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Remote debugger packet interpreter module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-19
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication.interpreter
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
import hwdbg.script._
|
||||
|
||||
object DebuggerPacketInterpreterEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sNewActionReceived, sSendResponse, sDone = Value
|
||||
}
|
||||
}
|
||||
|
||||
class DebuggerPacketInterpreter(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import DebuggerPacketInterpreterEnums.State
|
||||
import DebuggerPacketInterpreterEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Receiving signals
|
||||
//
|
||||
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val requestedActionOfThePacketInputValid = Input(Bool()) // whether data on the requested action is valid or not
|
||||
|
||||
val noNewDataReceiver = Output(Bool()) // are interpreter expects more data?
|
||||
val readNextData = Output(Bool()) // whether the next data should be read or not?
|
||||
|
||||
val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
|
||||
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
|
||||
|
||||
//
|
||||
// Sending signals
|
||||
//
|
||||
val beginSendingBuffer = Output(Bool()) // should sender start sending buffers or not?
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
|
||||
|
||||
val sendWaitForBuffer = Input(Bool()) // should the interpreter send next buffer or not?
|
||||
|
||||
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
|
||||
|
||||
//
|
||||
// Script stage configuration signals
|
||||
//
|
||||
val finishedScriptConfiguration = Output(Bool()) // whether script configuration finished or not?
|
||||
val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
|
||||
val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Last error register
|
||||
//
|
||||
val lastSuccesOrErrorMessage = RegInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Last error register
|
||||
//
|
||||
val enablePinOfScriptBufferHandler = RegInit(false.B)
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val noNewDataReceiver = WireInit(false.B)
|
||||
val readNextData = WireInit(false.B)
|
||||
|
||||
val regBeginSendingBuffer = RegInit(false.B)
|
||||
val noNewDataSender = WireInit(false.B)
|
||||
val dataValidOutput = WireInit(false.B)
|
||||
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
|
||||
val finishedScriptConfiguration = WireInit(false.B)
|
||||
val configureStage = WireInit(false.B)
|
||||
val initialSymbol = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
initialSymbol.Type := 0.U
|
||||
initialSymbol.Value := 0.U
|
||||
val targetOperator = WireInit(initialSymbol)
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Check if the debugger need a new action (a new command is received)
|
||||
//
|
||||
when(io.requestedActionOfThePacketInputValid) {
|
||||
|
||||
//
|
||||
// An action is received
|
||||
//
|
||||
state := sNewActionReceived
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Remain at the same state (no action)
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
|
||||
}
|
||||
is(sNewActionReceived) {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Now, the action needs to be dispatched
|
||||
//
|
||||
val inputAction = io.requestedActionOfThePacketInput
|
||||
|
||||
when(inputAction === HwdbgActionEnums.hwdbgActionSendInstanceInfo.id.U) {
|
||||
|
||||
//
|
||||
// *** Configure sending instance info ***
|
||||
//
|
||||
|
||||
//
|
||||
// Set the response packet type
|
||||
//
|
||||
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U
|
||||
|
||||
//
|
||||
// This action needs a response
|
||||
//
|
||||
state := sSendResponse
|
||||
|
||||
}.elsewhen(inputAction === HwdbgActionEnums.hwdbgActionConfigureScriptBuffer.id.U) {
|
||||
|
||||
//
|
||||
// *** Configure the internal buffer with script ***
|
||||
//
|
||||
|
||||
//
|
||||
// Enable the buffer config module
|
||||
//
|
||||
enablePinOfScriptBufferHandler := true.B
|
||||
|
||||
val (
|
||||
moduleReadNextData,
|
||||
moduleFinishedScriptConfiguration,
|
||||
moduleConfigureStage,
|
||||
moduleTargetOperator
|
||||
) =
|
||||
InterpreterScriptBufferHandler(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
enablePinOfScriptBufferHandler,
|
||||
io.dataValidInput,
|
||||
io.receivingData
|
||||
)
|
||||
|
||||
//
|
||||
// Connect the script stage configuration signals
|
||||
//
|
||||
readNextData := moduleReadNextData
|
||||
configureStage := moduleConfigureStage
|
||||
finishedScriptConfiguration := moduleFinishedScriptConfiguration
|
||||
targetOperator := moduleTargetOperator
|
||||
|
||||
when(moduleFinishedScriptConfiguration === true.B) {
|
||||
|
||||
//
|
||||
// *** Script stage buffer configuration finished! ***
|
||||
//
|
||||
|
||||
//
|
||||
// Disable the buffer config module
|
||||
//
|
||||
enablePinOfScriptBufferHandler := false.B
|
||||
|
||||
//
|
||||
// Set the response packet type
|
||||
//
|
||||
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
|
||||
|
||||
//
|
||||
// Set the success message
|
||||
//
|
||||
lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgOperationWasSuccessful.id.U
|
||||
|
||||
//
|
||||
// This action needs a response
|
||||
//
|
||||
state := sSendResponse
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// *** Script stage buffer configuration NOT finished, read the buffer ***
|
||||
//
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sNewActionReceived
|
||||
}
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// *** Invalid action ***
|
||||
//
|
||||
|
||||
//
|
||||
// Set the response packet type
|
||||
//
|
||||
regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
|
||||
|
||||
//
|
||||
// Set the latest error
|
||||
//
|
||||
lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgErrorInvalidPacket.id.U
|
||||
|
||||
//
|
||||
// This action needs a response
|
||||
//
|
||||
state := sSendResponse
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
}
|
||||
is(sSendResponse) {
|
||||
|
||||
//
|
||||
// Finish the receiving
|
||||
//
|
||||
noNewDataReceiver := true.B
|
||||
|
||||
//
|
||||
// Begin sending response
|
||||
//
|
||||
regBeginSendingBuffer := true.B
|
||||
|
||||
//
|
||||
// Wait until the sender module is reading to send data
|
||||
//
|
||||
when(io.sendWaitForBuffer === true.B) {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Now, the response needs to be sent
|
||||
//
|
||||
when(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U) {
|
||||
|
||||
//
|
||||
// *** Send instance information ***
|
||||
//
|
||||
|
||||
//
|
||||
// Instantiate the instance info module
|
||||
//
|
||||
|
||||
val (
|
||||
noNewDataSenderModule,
|
||||
dataValidOutputModule,
|
||||
sendingDataModule
|
||||
) =
|
||||
InterpreterInstanceInfo(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.sendWaitForBuffer // send waiting for buffer as an activation signal to the module
|
||||
)
|
||||
|
||||
//
|
||||
// Set data validity
|
||||
//
|
||||
dataValidOutput := dataValidOutputModule
|
||||
|
||||
//
|
||||
// Set data
|
||||
//
|
||||
sendingData := sendingDataModule
|
||||
|
||||
//
|
||||
// Once sending data is done, we'll go to the Done state
|
||||
//
|
||||
when(noNewDataSenderModule === true.B) {
|
||||
state := sDone
|
||||
}
|
||||
|
||||
}.elsewhen(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U) {
|
||||
|
||||
//
|
||||
// *** Send result of applying command (and errors) ***
|
||||
//
|
||||
|
||||
//
|
||||
// Instantiate the invalid packet module
|
||||
//
|
||||
val (
|
||||
noNewDataSenderModule,
|
||||
dataValidOutputModule,
|
||||
sendingDataModule
|
||||
) =
|
||||
InterpreterSendSuccessOrError(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.sendWaitForBuffer, // send waiting for buffer as an activation signal to the module
|
||||
lastSuccesOrErrorMessage
|
||||
)
|
||||
|
||||
//
|
||||
// Set data validity
|
||||
//
|
||||
dataValidOutput := dataValidOutputModule
|
||||
|
||||
//
|
||||
// Set data
|
||||
//
|
||||
sendingData := sendingDataModule
|
||||
|
||||
//
|
||||
// Once sending data is done, we'll go to the Done state
|
||||
//
|
||||
when(noNewDataSenderModule === true.B) {
|
||||
state := sDone
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// The sender module is not ready for sending buffer
|
||||
// so, we need to stay at this state
|
||||
//
|
||||
state := sSendResponse
|
||||
}
|
||||
}
|
||||
is(sDone) {
|
||||
|
||||
//
|
||||
// Finish the receiving, sending communication
|
||||
//
|
||||
noNewDataReceiver := true.B
|
||||
noNewDataSender := true.B
|
||||
|
||||
//
|
||||
// No longer need to begin sending data
|
||||
//
|
||||
regBeginSendingBuffer := false.B
|
||||
|
||||
//
|
||||
// Go to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins
|
||||
//
|
||||
io.noNewDataReceiver := noNewDataReceiver
|
||||
io.readNextData := readNextData
|
||||
|
||||
io.beginSendingBuffer := regBeginSendingBuffer
|
||||
io.noNewDataSender := noNewDataSender
|
||||
io.dataValidOutput := dataValidOutput
|
||||
io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
|
||||
io.sendingData := sendingData
|
||||
|
||||
io.configureStage := configureStage
|
||||
io.finishedScriptConfiguration := finishedScriptConfiguration
|
||||
io.targetOperator := targetOperator
|
||||
}
|
||||
|
||||
object DebuggerPacketInterpreter {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
requestedActionOfThePacketInput: UInt,
|
||||
requestedActionOfThePacketInputValid: Bool,
|
||||
dataValidInput: Bool,
|
||||
receivingData: UInt,
|
||||
sendWaitForBuffer: Bool
|
||||
): (Bool, Bool, Bool, Bool, Bool, UInt, UInt, Bool, Bool, HwdbgShortSymbol) = {
|
||||
|
||||
val debuggerPacketInterpreter = Module(
|
||||
new DebuggerPacketInterpreter(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val noNewDataReceiver = Wire(Bool())
|
||||
val readNextData = Wire(Bool())
|
||||
|
||||
val beginSendingBuffer = Wire(Bool())
|
||||
val noNewDataSender = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
|
||||
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
val finishedScriptConfiguration = Wire(Bool())
|
||||
val configureStage = Wire(Bool())
|
||||
val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
debuggerPacketInterpreter.io.en := en
|
||||
|
||||
//
|
||||
// Configure the input signals related to the receiving signals
|
||||
//
|
||||
debuggerPacketInterpreter.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
|
||||
debuggerPacketInterpreter.io.requestedActionOfThePacketInputValid := requestedActionOfThePacketInputValid
|
||||
debuggerPacketInterpreter.io.dataValidInput := dataValidInput
|
||||
debuggerPacketInterpreter.io.receivingData := receivingData
|
||||
|
||||
//
|
||||
// Configure the input signals related to the sending signals
|
||||
//
|
||||
debuggerPacketInterpreter.io.sendWaitForBuffer := sendWaitForBuffer
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
noNewDataReceiver := debuggerPacketInterpreter.io.noNewDataReceiver
|
||||
readNextData := debuggerPacketInterpreter.io.readNextData
|
||||
|
||||
//
|
||||
// Configure the output signals related to sending packets
|
||||
//
|
||||
beginSendingBuffer := debuggerPacketInterpreter.io.beginSendingBuffer
|
||||
noNewDataSender := debuggerPacketInterpreter.io.noNewDataSender
|
||||
dataValidOutput := debuggerPacketInterpreter.io.dataValidOutput
|
||||
|
||||
//
|
||||
// Configure the output signals related to received packets
|
||||
//
|
||||
requestedActionOfThePacketOutput := debuggerPacketInterpreter.io.requestedActionOfThePacketOutput
|
||||
sendingData := debuggerPacketInterpreter.io.sendingData
|
||||
|
||||
//
|
||||
// Configure the output signals related to stage configuration
|
||||
//
|
||||
finishedScriptConfiguration := debuggerPacketInterpreter.io.finishedScriptConfiguration
|
||||
configureStage := debuggerPacketInterpreter.io.configureStage
|
||||
targetOperator := debuggerPacketInterpreter.io.targetOperator
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
noNewDataReceiver,
|
||||
readNextData,
|
||||
beginSendingBuffer,
|
||||
noNewDataSender,
|
||||
dataValidOutput,
|
||||
requestedActionOfThePacketOutput,
|
||||
sendingData,
|
||||
finishedScriptConfiguration,
|
||||
configureStage,
|
||||
targetOperator
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,462 @@
|
|||
/**
|
||||
* @file
|
||||
* port_information.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Send port information (in interpreter)
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-04
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication.interpreter
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is, log2Ceil}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.utils._
|
||||
|
||||
object InterpreterInstanceInfoEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sSendVersion, sSendMaximumNumberOfStages, sSendScriptVariableLength, sSendNumberOfSupportedLocalAndGlobalVariables,
|
||||
sSendNumberOfSupportedTemporaryVariables, sSendMaximumNumberOfSupportedGetScriptOperators, sSendMaximumNumberOfSupportedSetScriptOperators,
|
||||
sSendSharedMemorySize, sSendDebuggerAreaOffset, sSendDebuggeeAreaOffset, sSendNumberOfPins, sSendNumberOfPorts, sSendScriptCapabilities1,
|
||||
sSendScriptCapabilities2, sSendBramAddrWidth, sSendBramDataWidth, sSendPortsConfiguration, sDone = Value
|
||||
}
|
||||
}
|
||||
|
||||
class InterpreterInstanceInfo(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import InterpreterInstanceInfoEnums.State
|
||||
import InterpreterInstanceInfoEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Sending signals
|
||||
//
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
|
||||
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Get number of input/output ports
|
||||
//
|
||||
val numberOfPorts = instanceInfo.portsConfiguration.size
|
||||
|
||||
//
|
||||
// Convert input port pins into vector
|
||||
//
|
||||
// val pinsVec = RegInit(VecInit(Seq.fill(numberOfPorts)(0.U(instanceInfo.bramDataWidth.W))))
|
||||
val pinsVec = VecInit(instanceInfo.portsConfiguration.map(_.U))
|
||||
|
||||
//
|
||||
// Determine the width for numberOfSentPins
|
||||
//
|
||||
val numberOfSentPinsWidth = log2Ceil(numberOfPorts)
|
||||
|
||||
//
|
||||
// Registers for keeping track of sent pin details
|
||||
//
|
||||
val numberOfSentPins = RegInit(0.U(numberOfSentPinsWidth.W))
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val noNewDataSender = WireInit(false.B)
|
||||
val dataValidOutput = WireInit(false.B)
|
||||
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Going to the next state (sending the version of the debugger)
|
||||
//
|
||||
state := sSendVersion
|
||||
}
|
||||
is(sSendVersion) {
|
||||
|
||||
//
|
||||
// Set the version
|
||||
//
|
||||
sendingData := instanceInfo.version.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendMaximumNumberOfStages
|
||||
|
||||
}
|
||||
is(sSendMaximumNumberOfStages) {
|
||||
|
||||
//
|
||||
// Set the maximum number of stages supported by this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.maximumNumberOfStages.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendScriptVariableLength
|
||||
|
||||
}
|
||||
is(sSendScriptVariableLength) {
|
||||
|
||||
//
|
||||
// Set the script variable length of this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.scriptVariableLength.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendNumberOfSupportedLocalAndGlobalVariables
|
||||
|
||||
}
|
||||
is(sSendNumberOfSupportedLocalAndGlobalVariables) {
|
||||
|
||||
//
|
||||
// Set the number of supported local variables for this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.numberOfSupportedLocalAndGlobalVariables.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendNumberOfSupportedTemporaryVariables
|
||||
|
||||
}
|
||||
is(sSendNumberOfSupportedTemporaryVariables) {
|
||||
|
||||
//
|
||||
// Set the number of supported temporary variables for this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.numberOfSupportedTemporaryVariables.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendMaximumNumberOfSupportedGetScriptOperators
|
||||
|
||||
}
|
||||
is(sSendMaximumNumberOfSupportedGetScriptOperators) {
|
||||
|
||||
//
|
||||
// Set the maximum number of supported GET operators by this instance of the
|
||||
// debugger in the script engine
|
||||
//
|
||||
sendingData := instanceInfo.maximumNumberOfSupportedGetScriptOperators.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendMaximumNumberOfSupportedSetScriptOperators
|
||||
|
||||
}
|
||||
is(sSendMaximumNumberOfSupportedSetScriptOperators) {
|
||||
|
||||
//
|
||||
// Set the maximum number of supported SET operators by this instance of the
|
||||
// debugger in the script engine
|
||||
//
|
||||
sendingData := instanceInfo.maximumNumberOfSupportedSetScriptOperators.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendSharedMemorySize
|
||||
|
||||
}
|
||||
is(sSendSharedMemorySize) {
|
||||
|
||||
//
|
||||
// Set the shared memory size used by this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.sharedMemorySize.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendDebuggerAreaOffset
|
||||
|
||||
}
|
||||
is(sSendDebuggerAreaOffset) {
|
||||
|
||||
//
|
||||
// Set the start offset of the debugger to the debuggee memory for this
|
||||
// instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.debuggerAreaOffset.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendDebuggeeAreaOffset
|
||||
|
||||
}
|
||||
is(sSendDebuggeeAreaOffset) {
|
||||
|
||||
//
|
||||
// Set the start offset of the debuggee to the debugger memory for this
|
||||
// instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.debuggeeAreaOffset.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendNumberOfPins
|
||||
|
||||
}
|
||||
is(sSendNumberOfPins) {
|
||||
|
||||
//
|
||||
// Set the number of pins in this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.numberOfPins.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendNumberOfPorts
|
||||
|
||||
}
|
||||
is(sSendNumberOfPorts) {
|
||||
|
||||
//
|
||||
// Set the number of ports in this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.numberOfPorts.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendScriptCapabilities1
|
||||
|
||||
}
|
||||
is(sSendScriptCapabilities1) {
|
||||
|
||||
//
|
||||
// Set the first bits (most significant) of the supported operators capabilities of this instance
|
||||
// of the debugger
|
||||
//
|
||||
sendingData := BitwiseFunction
|
||||
.getBitsInRange(instanceInfo.scriptCapabilities, instanceInfo.bramDataWidth, instanceInfo.bramDataWidth + instanceInfo.bramDataWidth - 1)
|
||||
.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendScriptCapabilities2
|
||||
|
||||
}
|
||||
is(sSendScriptCapabilities2) {
|
||||
|
||||
//
|
||||
// Set the second bits (least significant) of the supported operators capabilities of this instance
|
||||
// of the debugger
|
||||
//
|
||||
sendingData := BitwiseFunction.getBitsInRange(instanceInfo.scriptCapabilities, 0, instanceInfo.bramDataWidth - 1).U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendBramAddrWidth
|
||||
|
||||
}
|
||||
is(sSendBramAddrWidth) {
|
||||
|
||||
//
|
||||
// Set the BRAM address width in this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.bramAddrWidth.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendBramDataWidth
|
||||
|
||||
}
|
||||
is(sSendBramDataWidth) {
|
||||
|
||||
//
|
||||
// Set the BRAM data width in this instance of the debugger
|
||||
//
|
||||
sendingData := instanceInfo.bramDataWidth.U
|
||||
|
||||
//
|
||||
// The output is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
state := sSendPortsConfiguration
|
||||
|
||||
}
|
||||
is(sSendPortsConfiguration) {
|
||||
|
||||
//
|
||||
// Send input port items
|
||||
//
|
||||
|
||||
//
|
||||
// Adjust data
|
||||
//
|
||||
sendingData := pinsVec(numberOfSentPins)
|
||||
|
||||
//
|
||||
// Data is valid
|
||||
//
|
||||
dataValidOutput := true.B
|
||||
|
||||
when(numberOfSentPins === (numberOfPorts - 1).U) {
|
||||
|
||||
//
|
||||
// Reset the pins sent for sending details
|
||||
//
|
||||
numberOfSentPins := 0.U
|
||||
|
||||
state := sDone
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Send next index
|
||||
//
|
||||
numberOfSentPins := numberOfSentPins + 1.U
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sSendPortsConfiguration
|
||||
}
|
||||
}
|
||||
is(sDone) {
|
||||
|
||||
//
|
||||
// Indicate that sending data is done
|
||||
//
|
||||
noNewDataSender := true.B
|
||||
|
||||
//
|
||||
// Goto the idle state
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins
|
||||
//
|
||||
io.noNewDataSender := noNewDataSender
|
||||
io.dataValidOutput := dataValidOutput
|
||||
io.sendingData := sendingData
|
||||
|
||||
}
|
||||
|
||||
object InterpreterInstanceInfo {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool
|
||||
): (Bool, Bool, UInt) = {
|
||||
|
||||
val interpreterInstanceInfo = Module(
|
||||
new InterpreterInstanceInfo(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val noNewDataSender = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
interpreterInstanceInfo.io.en := en
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
noNewDataSender := interpreterInstanceInfo.io.noNewDataSender
|
||||
dataValidOutput := interpreterInstanceInfo.io.dataValidOutput
|
||||
sendingData := interpreterInstanceInfo.io.sendingData
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
noNewDataSender,
|
||||
dataValidOutput,
|
||||
sendingData
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
* @file
|
||||
* script_buffer_handler.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Configures the script stages from shared memory
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-06-14
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication.interpreter
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
import hwdbg.script._
|
||||
|
||||
object InterpreterScriptBufferHandlerEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sReadSizeOfBuffer, sReadTypeOfOperator, sReadValueOfOperator, sDone = Value
|
||||
}
|
||||
}
|
||||
|
||||
class InterpreterScriptBufferHandler(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import InterpreterScriptBufferHandlerEnums.State
|
||||
import InterpreterScriptBufferHandlerEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Receiving signals
|
||||
//
|
||||
val readNextData = Output(Bool()) // whether the next data should be read or not?
|
||||
|
||||
val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
|
||||
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
|
||||
|
||||
//
|
||||
// Script stage configuration signals
|
||||
//
|
||||
val finishedScriptConfiguration = Output(Bool()) // whether configuration finished or not?
|
||||
val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
|
||||
val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Internal registers
|
||||
//
|
||||
val regScriptNumberOfSymbols = Reg(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val readNextData = WireInit(false.B)
|
||||
|
||||
val finishedScriptConfiguration = WireInit(false.B)
|
||||
val configureStage = RegInit(false.B)
|
||||
|
||||
val regTargetOperator = Reg(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Read next data for the size of the buffer
|
||||
//
|
||||
readNextData := true.B
|
||||
|
||||
//
|
||||
// Move to the next state
|
||||
//
|
||||
state := sReadSizeOfBuffer
|
||||
}
|
||||
is(sReadSizeOfBuffer) {
|
||||
|
||||
when(io.dataValidInput) {
|
||||
|
||||
//
|
||||
// Data is valid and number of symbols is now available
|
||||
//
|
||||
regScriptNumberOfSymbols := io.receivingData
|
||||
|
||||
//
|
||||
// Request next data
|
||||
//
|
||||
readNextData := true.B
|
||||
|
||||
//
|
||||
// Move to the configuration state
|
||||
//
|
||||
state := sReadTypeOfOperator
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state since the data is not yet received
|
||||
//
|
||||
state := sReadSizeOfBuffer
|
||||
}
|
||||
}
|
||||
is(sReadTypeOfOperator) {
|
||||
|
||||
//
|
||||
// Not valid for configuring yet
|
||||
//
|
||||
configureStage := false.B
|
||||
|
||||
when(io.dataValidInput) {
|
||||
|
||||
//
|
||||
// Request next data
|
||||
//
|
||||
readNextData := true.B
|
||||
|
||||
//
|
||||
// Read the operator's "Type" data
|
||||
//
|
||||
regTargetOperator.Type := io.receivingData
|
||||
|
||||
//
|
||||
// Next, we need to read "Value"
|
||||
//
|
||||
state := sReadValueOfOperator
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state since the data is not received yet
|
||||
//
|
||||
state := sReadTypeOfOperator
|
||||
}
|
||||
}
|
||||
is(sReadValueOfOperator) {
|
||||
|
||||
when(io.dataValidInput) {
|
||||
|
||||
//
|
||||
// Configure the stages
|
||||
//
|
||||
configureStage := true.B
|
||||
|
||||
//
|
||||
// Read the operator's "Value" data
|
||||
//
|
||||
regTargetOperator.Value := io.receivingData
|
||||
|
||||
//
|
||||
// Decrement the remaining symbols
|
||||
//
|
||||
regScriptNumberOfSymbols := regScriptNumberOfSymbols - 1.U
|
||||
|
||||
//
|
||||
// Check if reading is scripts are finished or not
|
||||
//
|
||||
when(regScriptNumberOfSymbols === 0.U) {
|
||||
|
||||
//
|
||||
// Configurartion was done
|
||||
//
|
||||
state := sDone
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Request next data
|
||||
//
|
||||
readNextData := true.B
|
||||
|
||||
//
|
||||
// Again, read the next type
|
||||
//
|
||||
state := sReadTypeOfOperator
|
||||
}
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state since the data is not received yet
|
||||
//
|
||||
state := sReadValueOfOperator
|
||||
}
|
||||
}
|
||||
is(sDone) {
|
||||
|
||||
//
|
||||
// Not valid for configuring anymore
|
||||
//
|
||||
configureStage := false.B
|
||||
|
||||
//
|
||||
// Finished configuration
|
||||
//
|
||||
finishedScriptConfiguration := true.B
|
||||
|
||||
//
|
||||
// Move to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Connect output pins
|
||||
//
|
||||
io.readNextData := readNextData
|
||||
|
||||
io.finishedScriptConfiguration := finishedScriptConfiguration
|
||||
io.configureStage := configureStage
|
||||
io.targetOperator := regTargetOperator
|
||||
|
||||
}
|
||||
|
||||
object InterpreterScriptBufferHandler {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
dataValidInput: Bool,
|
||||
receivingData: UInt
|
||||
): (Bool, Bool, Bool, HwdbgShortSymbol) = {
|
||||
|
||||
val interpreterScriptBufferHandler = Module(
|
||||
new InterpreterScriptBufferHandler(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val readNextData = Wire(Bool())
|
||||
|
||||
val finishedScriptConfiguration = Wire(Bool())
|
||||
val configureStage = Wire(Bool())
|
||||
val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
interpreterScriptBufferHandler.io.en := en
|
||||
|
||||
//
|
||||
// Configure the input signals related to the receiving signals
|
||||
//
|
||||
interpreterScriptBufferHandler.io.dataValidInput := dataValidInput
|
||||
interpreterScriptBufferHandler.io.receivingData := receivingData
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
readNextData := interpreterScriptBufferHandler.io.readNextData
|
||||
|
||||
//
|
||||
// Configure the output signals related to configuring stage operators
|
||||
//
|
||||
finishedScriptConfiguration := interpreterScriptBufferHandler.io.finishedScriptConfiguration
|
||||
configureStage := interpreterScriptBufferHandler.io.configureStage
|
||||
targetOperator := interpreterScriptBufferHandler.io.targetOperator
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
readNextData,
|
||||
finishedScriptConfiguration,
|
||||
configureStage,
|
||||
targetOperator
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* @file
|
||||
* send_success_or_error.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Send an indication of invalid packet error or success message (in the interpreter)
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-04
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication.interpreter
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
|
||||
class InterpreterSendSuccessOrError(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
val lastSuccessOrError = Input(UInt(instanceInfo.bramDataWidth.W)) // input last error
|
||||
|
||||
//
|
||||
// Sending signals
|
||||
//
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
|
||||
val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val noNewDataSender = WireInit(false.B)
|
||||
val dataValidOutput = WireInit(false.B)
|
||||
val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
//
|
||||
// Set the version
|
||||
//
|
||||
sendingData := io.lastSuccessOrError
|
||||
|
||||
//
|
||||
// Sending the version in one clock cycle
|
||||
//
|
||||
noNewDataSender := true.B
|
||||
dataValidOutput := true.B
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins
|
||||
//
|
||||
io.noNewDataSender := noNewDataSender
|
||||
io.dataValidOutput := dataValidOutput
|
||||
io.sendingData := sendingData
|
||||
|
||||
}
|
||||
|
||||
object InterpreterSendSuccessOrError {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
lastSuccessOrError: UInt
|
||||
): (Bool, Bool, UInt) = {
|
||||
|
||||
val interpreterSendSuccessOrError = Module(
|
||||
new InterpreterSendSuccessOrError(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val noNewDataSender = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
interpreterSendSuccessOrError.io.en := en
|
||||
interpreterSendSuccessOrError.io.lastSuccessOrError := lastSuccessOrError
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
noNewDataSender := interpreterSendSuccessOrError.io.noNewDataSender
|
||||
dataValidOutput := interpreterSendSuccessOrError.io.dataValidOutput
|
||||
sendingData := interpreterSendSuccessOrError.io.sendingData
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
noNewDataSender,
|
||||
dataValidOutput,
|
||||
sendingData
|
||||
)
|
||||
}
|
||||
}
|
||||
444
hwdbg/src/main/scala/hwdbg/communication/receiver.scala
Normal file
444
hwdbg/src/main/scala/hwdbg/communication/receiver.scala
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/**
|
||||
* @file
|
||||
* receiver.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Remote debugger packet receiver module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-08
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
import hwdbg.utils._
|
||||
import hwdbg.constants._
|
||||
|
||||
object DebuggerPacketReceiverEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sReadChecksum, sReadIndicator, sReadTypeOfThePacket, sReadRequestedActionOfThePacket, sRequestedActionIsValid, sWaitToReadActionBuffer,
|
||||
sReadActionBuffer, sDone = Value
|
||||
}
|
||||
}
|
||||
|
||||
class DebuggerPacketReceiver(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import DebuggerPacketReceiverEnums.State
|
||||
import DebuggerPacketReceiverEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
// Note: Only PL input signal is received here,
|
||||
// a separate module will control the PS signal
|
||||
//
|
||||
val plInSignal = Input(Bool()) // PS to PL signal
|
||||
|
||||
//
|
||||
// BRAM (Block RAM) ports
|
||||
//
|
||||
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
|
||||
val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
|
||||
|
||||
//
|
||||
// Receiving signals
|
||||
//
|
||||
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
|
||||
val noNewDataReceiver = Input(Bool()) // receive done or not?
|
||||
|
||||
// this contains and edge-detection mechanism, which means reader should make it low after reading the data
|
||||
val readNextData = Input(Bool()) // whether the next data should be read or not?
|
||||
|
||||
val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
|
||||
val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
|
||||
|
||||
val finishedReceivingBuffer = Output(Bool()) // Receiving is done or not?
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
|
||||
val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
|
||||
val finishedReceivingBuffer = WireInit(false.B)
|
||||
val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
val regRequestedActionOfThePacketOutputValid = RegInit(false.B)
|
||||
val regDataValidOutput = RegInit(false.B)
|
||||
val regReceivingData = RegInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Rising-edge detector for start receiving signal
|
||||
//
|
||||
val risingEdgePlInSignal = io.plInSignal & !RegNext(io.plInSignal)
|
||||
|
||||
//
|
||||
// Rising-edge detector for reading next data signal
|
||||
//
|
||||
val risingEdgeReadNextData = io.readNextData & !RegNext(io.readNextData)
|
||||
|
||||
//
|
||||
// Structure (as wire) of the received packet buffer
|
||||
//
|
||||
val receivedPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket())) // here the wire is not used
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Create logs from communication structure offsets
|
||||
//
|
||||
LogInfo(debug)(f"The offset of Checksum is 0x${receivedPacketBuffer.Offset.checksum}%x")
|
||||
LogInfo(debug)(f"The offset of Indicator is 0x${receivedPacketBuffer.Offset.indicator}%x")
|
||||
LogInfo(debug)(f"The offset of TypeOfThePacket is 0x${receivedPacketBuffer.Offset.typeOfThePacket}%x")
|
||||
LogInfo(debug)(f"The offset of requestedActionOfThePacketOutput is 0x${receivedPacketBuffer.Offset.requestedActionOfThePacket}%x")
|
||||
|
||||
//
|
||||
// Check whether the interrupt from the PS is received or not
|
||||
//
|
||||
when(risingEdgePlInSignal === true.B) {
|
||||
state := sReadChecksum
|
||||
}
|
||||
|
||||
//
|
||||
// Configure the output pins in case of sIdle
|
||||
//
|
||||
rdWrAddr := 0.U
|
||||
regRequestedActionOfThePacketOutput := 0.U
|
||||
regRequestedActionOfThePacketOutputValid := false.B
|
||||
regDataValidOutput := false.B
|
||||
regReceivingData := 0.U
|
||||
finishedReceivingBuffer := false.B
|
||||
|
||||
}
|
||||
is(sReadChecksum) {
|
||||
|
||||
//
|
||||
// Adjust address to read Checksum from BRAM (Not Used)
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.checksum).U
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sReadIndicator
|
||||
|
||||
}
|
||||
is(sReadIndicator) {
|
||||
|
||||
//
|
||||
// Adjust address to read Indicator from BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.indicator).U
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sReadTypeOfThePacket
|
||||
|
||||
}
|
||||
is(sReadTypeOfThePacket) {
|
||||
|
||||
//
|
||||
// Adjust address to read TypeOfThePacket from BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.typeOfThePacket).U
|
||||
|
||||
//
|
||||
// Check whether the indicator is valid or not
|
||||
//
|
||||
LogInfo(debug)(
|
||||
f"Comparing first 0x${BitwiseFunction.getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))}%x number of the indicator (little-endian)"
|
||||
)
|
||||
|
||||
when(
|
||||
io.rdData === BitwiseFunction
|
||||
.getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))
|
||||
.U
|
||||
) {
|
||||
|
||||
//
|
||||
// Indicator of packet is valid
|
||||
// (Goes to the next section)
|
||||
//
|
||||
state := sReadRequestedActionOfThePacket
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Indicator of packet is not valid
|
||||
// (Receiving was done but not found a valid packet,
|
||||
// so, go to the idle state)
|
||||
//
|
||||
state := sDone
|
||||
}
|
||||
}
|
||||
is(sReadRequestedActionOfThePacket) {
|
||||
|
||||
//
|
||||
// Adjust address to read RequestedActionOfThePacket from BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket).U
|
||||
|
||||
//
|
||||
// Save the address into a register
|
||||
//
|
||||
regRdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket + (instanceInfo.bramDataWidth >> 3)).U
|
||||
|
||||
//
|
||||
// Check whether the type of the packet is valid or not
|
||||
//
|
||||
val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL
|
||||
LogInfo(debug)(
|
||||
f"Check packet type with DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x${packetType.id}%x)"
|
||||
)
|
||||
when(io.rdData === packetType.id.U) {
|
||||
|
||||
//
|
||||
// Type of packet is valid
|
||||
// (Goes to the next section)
|
||||
//
|
||||
state := sRequestedActionIsValid
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Type of packet is not valid
|
||||
// (Receiving was done but not found a valid packet,
|
||||
// so, go to the idle state)
|
||||
//
|
||||
state := sDone
|
||||
}
|
||||
|
||||
}
|
||||
is(sRequestedActionIsValid) {
|
||||
|
||||
//
|
||||
// Read the RequestedActionOfThePacket
|
||||
//
|
||||
regRequestedActionOfThePacketOutput := io.rdData
|
||||
|
||||
//
|
||||
// The RequestedActionOfThePacketOutput is valid from now
|
||||
//
|
||||
regRequestedActionOfThePacketOutputValid := true.B
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWaitToReadActionBuffer
|
||||
|
||||
}
|
||||
is(sWaitToReadActionBuffer) {
|
||||
|
||||
//
|
||||
// The value of the received buffer is valid here, however,
|
||||
// in order to make difference when a new value is read, the
|
||||
// following signals goes to the off state
|
||||
//
|
||||
regDataValidOutput := false.B
|
||||
|
||||
//
|
||||
// Check if the caller needs to read the next part of
|
||||
// the block RAM or the receiving data should be finished
|
||||
//
|
||||
when(io.noNewDataReceiver === true.B) {
|
||||
|
||||
//
|
||||
// No new data, the receiving is done
|
||||
//
|
||||
state := sDone
|
||||
|
||||
}.elsewhen(risingEdgeReadNextData === true.B) {
|
||||
|
||||
//
|
||||
// Adjust address to read next data to BRAM
|
||||
//
|
||||
rdWrAddr := regRdWrAddr
|
||||
regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
|
||||
|
||||
//
|
||||
// Read the next offset of the buffer
|
||||
//
|
||||
state := sReadActionBuffer
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sWaitToReadActionBuffer
|
||||
}
|
||||
|
||||
}
|
||||
is(sReadActionBuffer) {
|
||||
|
||||
//
|
||||
// Data outputs are now valid
|
||||
//
|
||||
regDataValidOutput := true.B
|
||||
|
||||
//
|
||||
// Adjust the read buffer data
|
||||
//
|
||||
regReceivingData := io.rdData
|
||||
|
||||
when(io.noNewDataReceiver === true.B) {
|
||||
|
||||
//
|
||||
// No new data, the receiving is done
|
||||
//
|
||||
state := sDone
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Return to the previous state of action
|
||||
//
|
||||
state := sWaitToReadActionBuffer
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
is(sDone) {
|
||||
|
||||
//
|
||||
// Reset the temporary address holder
|
||||
//
|
||||
regRdWrAddr := 0.U
|
||||
|
||||
//
|
||||
// Requested action buffer and the receiving buffer is no longer valid
|
||||
//
|
||||
regRequestedActionOfThePacketOutput := 0.U
|
||||
regRequestedActionOfThePacketOutputValid := false.B
|
||||
regReceivingData := 0.U
|
||||
regDataValidOutput := false.B
|
||||
|
||||
//
|
||||
// The receiving is done at this stage, either
|
||||
// was successful or unsuccessful, we'll release the
|
||||
// sharing bram resource by indicating that the receiving
|
||||
// module is no longer using the bram line
|
||||
//
|
||||
finishedReceivingBuffer := true.B
|
||||
|
||||
//
|
||||
// Go to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins
|
||||
//
|
||||
io.rdWrAddr := rdWrAddr
|
||||
io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
|
||||
io.requestedActionOfThePacketOutputValid := regRequestedActionOfThePacketOutputValid
|
||||
io.dataValidOutput := regDataValidOutput
|
||||
io.receivingData := regReceivingData
|
||||
io.finishedReceivingBuffer := finishedReceivingBuffer
|
||||
|
||||
}
|
||||
|
||||
object DebuggerPacketReceiver {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
plInSignal: Bool,
|
||||
rdData: UInt,
|
||||
noNewDataReceiver: Bool,
|
||||
readNextData: Bool
|
||||
): (UInt, UInt, Bool, Bool, UInt, Bool) = {
|
||||
|
||||
val debuggerPacketReceiver = Module(
|
||||
new DebuggerPacketReceiver(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
|
||||
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
val requestedActionOfThePacketOutputValid = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
val finishedReceivingBuffer = Wire(Bool())
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
debuggerPacketReceiver.io.en := en
|
||||
debuggerPacketReceiver.io.plInSignal := plInSignal
|
||||
debuggerPacketReceiver.io.rdData := rdData
|
||||
debuggerPacketReceiver.io.noNewDataReceiver := noNewDataReceiver
|
||||
debuggerPacketReceiver.io.readNextData := readNextData
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
rdWrAddr := debuggerPacketReceiver.io.rdWrAddr
|
||||
|
||||
//
|
||||
// Configure the output signals related to received packets
|
||||
//
|
||||
requestedActionOfThePacketOutput := debuggerPacketReceiver.io.requestedActionOfThePacketOutput
|
||||
requestedActionOfThePacketOutputValid := debuggerPacketReceiver.io.requestedActionOfThePacketOutputValid
|
||||
dataValidOutput := debuggerPacketReceiver.io.dataValidOutput
|
||||
receivingData := debuggerPacketReceiver.io.receivingData
|
||||
finishedReceivingBuffer := debuggerPacketReceiver.io.finishedReceivingBuffer
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
rdWrAddr,
|
||||
requestedActionOfThePacketOutput,
|
||||
requestedActionOfThePacketOutputValid,
|
||||
dataValidOutput,
|
||||
receivingData,
|
||||
finishedReceivingBuffer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,383 @@
|
|||
/**
|
||||
* @file
|
||||
* send_receive_synchronizer.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Send and receive synchronizer module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-17
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
|
||||
object SendReceiveSynchronizerEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sReceiver, sSender = Value
|
||||
}
|
||||
}
|
||||
|
||||
class SendReceiveSynchronizer(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import SendReceiveSynchronizerEnums.State
|
||||
import SendReceiveSynchronizerEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
//
|
||||
val plInSignal = Input(Bool()) // PS to PL signal
|
||||
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
|
||||
|
||||
//
|
||||
// BRAM (Block RAM) ports
|
||||
//
|
||||
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
|
||||
val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
|
||||
val wrEna = Output(Bool()) // enable writing
|
||||
val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
|
||||
|
||||
//
|
||||
// Receiver ports
|
||||
//
|
||||
val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
|
||||
|
||||
val noNewDataReceiver = Input(Bool()) // receive done or not?
|
||||
val readNextData = Input(Bool()) // whether the next data should be read or not?
|
||||
|
||||
val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
|
||||
val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
|
||||
|
||||
//
|
||||
// Sender ports
|
||||
//
|
||||
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
|
||||
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidInput = Input(Bool()) // should sender send next buffer or not?
|
||||
|
||||
val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
|
||||
|
||||
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Saving state of the controlling pins
|
||||
//
|
||||
val regPlInSignal = RegInit(false.B)
|
||||
val regBeginSendingBuffer = RegInit(false.B)
|
||||
|
||||
//
|
||||
// Shared BRAM pins
|
||||
//
|
||||
val sharedRdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W)) // read/write address
|
||||
val sharedRdData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // read data
|
||||
val sharedWrEna = WireInit(false.B) // enable writing
|
||||
val sharedWrData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // write data
|
||||
|
||||
//
|
||||
// Instantiate the packet receiver module
|
||||
//
|
||||
val (
|
||||
receiverRdWrAddr,
|
||||
requestedActionOfThePacketOutput,
|
||||
requestedActionOfThePacketOutputValid,
|
||||
dataValidOutput,
|
||||
receivingData,
|
||||
finishedReceivingBuffer
|
||||
) =
|
||||
DebuggerPacketReceiver(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
regPlInSignal,
|
||||
io.rdData,
|
||||
io.noNewDataReceiver,
|
||||
io.readNextData
|
||||
)
|
||||
|
||||
//
|
||||
// Instantiate the packet sender module
|
||||
//
|
||||
val (
|
||||
psOutInterrupt,
|
||||
senderRdWrAddr,
|
||||
wrEna,
|
||||
wrData,
|
||||
sendWaitForBuffer,
|
||||
finishedSendingBuffer
|
||||
) =
|
||||
DebuggerPacketSender(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
regBeginSendingBuffer,
|
||||
io.noNewDataSender,
|
||||
io.dataValidInput,
|
||||
io.requestedActionOfThePacketInput,
|
||||
io.sendingData
|
||||
)
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Perform the resource separation of shared BRAM
|
||||
// and apply priority to receive over send
|
||||
//
|
||||
when(io.plInSignal === true.B) {
|
||||
|
||||
//
|
||||
// Activate the receiver module
|
||||
//
|
||||
regPlInSignal := true.B
|
||||
|
||||
//
|
||||
// Go to the receiver state
|
||||
//
|
||||
state := sReceiver
|
||||
|
||||
}.elsewhen(io.beginSendingBuffer === true.B && io.plInSignal === false.B) {
|
||||
|
||||
//
|
||||
// Activate the sender module
|
||||
//
|
||||
regBeginSendingBuffer := true.B
|
||||
|
||||
//
|
||||
// Go to the sender state
|
||||
//
|
||||
state := sSender
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state as there is no communication
|
||||
//
|
||||
state := sIdle
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
is(sReceiver) {
|
||||
|
||||
//
|
||||
// Check whether the receiving is finished
|
||||
//
|
||||
when(finishedReceivingBuffer === true.B) {
|
||||
|
||||
//
|
||||
// No longer in the receiver state
|
||||
//
|
||||
regPlInSignal := false.B
|
||||
|
||||
//
|
||||
// Go to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Connect the address of BRAM reader to the receiver address
|
||||
//
|
||||
sharedRdWrAddr := receiverRdWrAddr
|
||||
|
||||
//
|
||||
// On the receiver, writing is not allowed
|
||||
//
|
||||
sharedWrEna := false.B
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sReceiver
|
||||
|
||||
}
|
||||
}
|
||||
is(sSender) {
|
||||
|
||||
//
|
||||
// Check whether sending data is finished
|
||||
//
|
||||
when(finishedSendingBuffer === true.B) {
|
||||
|
||||
//
|
||||
// No longer in the sender state
|
||||
//
|
||||
regBeginSendingBuffer := false.B
|
||||
|
||||
//
|
||||
// Go to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Connect shared BRAM signals to the sender
|
||||
//
|
||||
sharedRdWrAddr := senderRdWrAddr
|
||||
sharedWrEna := wrEna
|
||||
sharedWrData := wrData
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sSender
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins (Interrupt)
|
||||
//
|
||||
io.psOutInterrupt := psOutInterrupt
|
||||
|
||||
//
|
||||
// Connect output pins (BRAM)
|
||||
//
|
||||
io.rdWrAddr := sharedRdWrAddr
|
||||
io.wrEna := wrEna
|
||||
io.wrData := wrData
|
||||
|
||||
//
|
||||
// Connect output pins (Receiver)
|
||||
//
|
||||
io.requestedActionOfThePacketOutput := requestedActionOfThePacketOutput
|
||||
io.requestedActionOfThePacketOutputValid := requestedActionOfThePacketOutputValid
|
||||
io.dataValidOutput := dataValidOutput
|
||||
io.receivingData := receivingData
|
||||
|
||||
//
|
||||
// Connect output pins (Sender)
|
||||
//
|
||||
io.sendWaitForBuffer := sendWaitForBuffer
|
||||
|
||||
}
|
||||
|
||||
object SendReceiveSynchronizer {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
plInSignal: Bool,
|
||||
rdData: UInt,
|
||||
noNewDataReceiver: Bool,
|
||||
readNextData: Bool,
|
||||
beginSendingBuffer: Bool,
|
||||
noNewDataSender: Bool,
|
||||
dataValidInput: Bool,
|
||||
requestedActionOfThePacketInput: UInt,
|
||||
sendingData: UInt
|
||||
): (Bool, UInt, Bool, UInt, UInt, Bool, Bool, UInt, Bool) = {
|
||||
|
||||
val sendReceiveSynchronizerModule = Module(
|
||||
new SendReceiveSynchronizer(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val psOutInterrupt = Wire(Bool())
|
||||
|
||||
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
|
||||
val wrEna = Wire(Bool())
|
||||
val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
val requestedActionOfThePacketOutputValid = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
|
||||
val sendWaitForBuffer = Wire(Bool())
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
sendReceiveSynchronizerModule.io.en := en
|
||||
sendReceiveSynchronizerModule.io.plInSignal := plInSignal
|
||||
sendReceiveSynchronizerModule.io.rdData := rdData
|
||||
sendReceiveSynchronizerModule.io.noNewDataReceiver := noNewDataReceiver
|
||||
sendReceiveSynchronizerModule.io.readNextData := readNextData
|
||||
sendReceiveSynchronizerModule.io.beginSendingBuffer := beginSendingBuffer
|
||||
sendReceiveSynchronizerModule.io.noNewDataSender := noNewDataSender
|
||||
sendReceiveSynchronizerModule.io.dataValidInput := dataValidInput
|
||||
sendReceiveSynchronizerModule.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
|
||||
sendReceiveSynchronizerModule.io.sendingData := sendingData
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
psOutInterrupt := sendReceiveSynchronizerModule.io.psOutInterrupt
|
||||
rdWrAddr := sendReceiveSynchronizerModule.io.rdWrAddr
|
||||
wrEna := sendReceiveSynchronizerModule.io.wrEna
|
||||
wrData := sendReceiveSynchronizerModule.io.wrData
|
||||
|
||||
requestedActionOfThePacketOutput := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutput
|
||||
requestedActionOfThePacketOutputValid := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutputValid
|
||||
dataValidOutput := sendReceiveSynchronizerModule.io.dataValidOutput
|
||||
receivingData := sendReceiveSynchronizerModule.io.receivingData
|
||||
|
||||
sendWaitForBuffer := sendReceiveSynchronizerModule.io.sendWaitForBuffer
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
psOutInterrupt,
|
||||
rdWrAddr,
|
||||
wrEna,
|
||||
wrData,
|
||||
requestedActionOfThePacketOutput,
|
||||
requestedActionOfThePacketOutputValid,
|
||||
dataValidOutput,
|
||||
receivingData,
|
||||
sendWaitForBuffer
|
||||
)
|
||||
}
|
||||
}
|
||||
494
hwdbg/src/main/scala/hwdbg/communication/sender.scala
Normal file
494
hwdbg/src/main/scala/hwdbg/communication/sender.scala
Normal file
|
|
@ -0,0 +1,494 @@
|
|||
/**
|
||||
* @file
|
||||
* sender.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Remote debugger packet sender module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-16
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.communication
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.{switch, is, log2Ceil}
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
import hwdbg.constants._
|
||||
|
||||
object DebuggerPacketSenderEnums {
|
||||
object State extends ChiselEnum {
|
||||
val sIdle, sWriteChecksum, sWriteIndicator, sWriteTypeOfThePacket, sWriteRequestedActionOfThePacket, sWaitToGetData, sSendData, sDone = Value
|
||||
}
|
||||
}
|
||||
|
||||
class DebuggerPacketSender(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import DebuggerPacketSenderEnums.State
|
||||
import DebuggerPacketSenderEnums.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
// Note: Only PS output signal is exported here,
|
||||
// a separate module will control the PL signal
|
||||
//
|
||||
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
|
||||
|
||||
//
|
||||
// BRAM (Block RAM) ports
|
||||
//
|
||||
val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
|
||||
val wrEna = Output(Bool()) // enable writing
|
||||
val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
|
||||
|
||||
//
|
||||
// Sending signals
|
||||
//
|
||||
val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
|
||||
val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidInput = Input(Bool()) // should sender send next buffer or not?
|
||||
|
||||
val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
|
||||
val finishedSendingBuffer = Output(Bool()) // indicate that the sender finished sending buffers and ready to send next packet
|
||||
|
||||
val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
|
||||
val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// State registers
|
||||
//
|
||||
val state = RegInit(sIdle)
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val psOutInterrupt = WireInit(false.B)
|
||||
val wrEna = WireInit(false.B)
|
||||
val wrData = WireInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
val sendWaitForBuffer = WireInit(false.B)
|
||||
val finishedSendingBuffer = WireInit(false.B)
|
||||
val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
|
||||
|
||||
//
|
||||
// Temporary address and data holder (register)
|
||||
//
|
||||
val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
|
||||
val regDataToSend = RegInit(0.U(instanceInfo.bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Rising-edge detector for start sending signal
|
||||
//
|
||||
val risingEdgeBeginSendingBuffer = io.beginSendingBuffer & !RegNext(io.beginSendingBuffer)
|
||||
|
||||
//
|
||||
// Keeping the state of whether sending data has been started or not
|
||||
// Means that if the sender is in the middle of sending the headers
|
||||
// of the packet or the actual data
|
||||
//
|
||||
val regIsSendingDataStarted = RegInit(false.B)
|
||||
|
||||
//
|
||||
// Used to hold the transferred length of the indicator
|
||||
//
|
||||
val lengthOfIndicator: Int = new DebuggerRemotePacket().Indicator.getWidth
|
||||
val regTransferredIndicatorLength = RegInit(0.U((log2Ceil(lengthOfIndicator) + 1).W))
|
||||
|
||||
//
|
||||
// Structure (as wire) of the received packet buffer
|
||||
//
|
||||
val sendingPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket()))
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(state) {
|
||||
|
||||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Check whether the interrupt from the PS is received or not
|
||||
//
|
||||
when(risingEdgeBeginSendingBuffer === true.B) {
|
||||
state := sWriteChecksum
|
||||
}
|
||||
|
||||
//
|
||||
// Configure the outputs in case of sIdle
|
||||
//
|
||||
psOutInterrupt := false.B
|
||||
rdWrAddr := 0.U
|
||||
regRdWrAddr := 0.U
|
||||
wrEna := false.B
|
||||
wrData := 0.U
|
||||
sendWaitForBuffer := false.B
|
||||
finishedSendingBuffer := false.B
|
||||
|
||||
//
|
||||
// Sending data has not been started
|
||||
//
|
||||
regIsSendingDataStarted := false.B
|
||||
|
||||
}
|
||||
is(sWriteChecksum) {
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write Checksum to BRAM (Not Used)
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.checksum).U
|
||||
|
||||
//
|
||||
// Adjust data to write Checksum
|
||||
//
|
||||
wrData := 0.U // Checksum is ignored
|
||||
|
||||
//
|
||||
// Reset the transferred bytes of the indicator
|
||||
//
|
||||
regTransferredIndicatorLength := 0.U
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWriteIndicator
|
||||
}
|
||||
is(sWriteIndicator) {
|
||||
|
||||
if (instanceInfo.bramDataWidth >= lengthOfIndicator) {
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write Indicator to BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U
|
||||
|
||||
//
|
||||
// Adjust data to write Indicator
|
||||
//
|
||||
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWriteTypeOfThePacket
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write Indicator to BRAM (Address granularity is in the byte format so,
|
||||
// it'll be divided by 8 or shift to right by 3)
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U + (regTransferredIndicatorLength >> 3)
|
||||
|
||||
//
|
||||
// Adjust data to write Indicator
|
||||
//
|
||||
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U >> regTransferredIndicatorLength
|
||||
|
||||
//
|
||||
// Add to the transferred length
|
||||
//
|
||||
regTransferredIndicatorLength := regTransferredIndicatorLength + instanceInfo.bramDataWidth.U
|
||||
|
||||
when(regTransferredIndicatorLength >= lengthOfIndicator.U) {
|
||||
|
||||
//
|
||||
// Disable writing to the BRAM
|
||||
//
|
||||
wrEna := false.B
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWriteTypeOfThePacket
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay at the same state
|
||||
//
|
||||
state := sWriteIndicator
|
||||
}
|
||||
}
|
||||
}
|
||||
is(sWriteTypeOfThePacket) {
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write type of packet to BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.typeOfThePacket).U
|
||||
|
||||
//
|
||||
// Adjust data to write type of packet
|
||||
//
|
||||
val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL
|
||||
wrData := packetType.id.U
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWriteRequestedActionOfThePacket
|
||||
|
||||
}
|
||||
is(sWriteRequestedActionOfThePacket) {
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write requested action of packet to BRAM
|
||||
//
|
||||
rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.requestedActionOfThePacket).U
|
||||
|
||||
//
|
||||
// Adjust data to write requested action of packet
|
||||
//
|
||||
wrData := io.requestedActionOfThePacketInput
|
||||
|
||||
//
|
||||
// Goes to the next section
|
||||
//
|
||||
state := sWaitToGetData
|
||||
|
||||
}
|
||||
is(sWaitToGetData) {
|
||||
|
||||
//
|
||||
// Disable writing to the BRAM
|
||||
//
|
||||
wrEna := false.B
|
||||
|
||||
//
|
||||
// Indicate that the module is waiting for data
|
||||
//
|
||||
sendWaitForBuffer := true.B
|
||||
|
||||
//
|
||||
// Check whether sending actual data already started or not
|
||||
//
|
||||
when(regIsSendingDataStarted === false.B) {
|
||||
|
||||
//
|
||||
// It's not yet started, so we adjust the address to the start
|
||||
// of the buffer after the last field of the header
|
||||
//
|
||||
regRdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.startOfDataBuffer).U
|
||||
|
||||
//
|
||||
// Indicate that sending data already started
|
||||
//
|
||||
regIsSendingDataStarted := true.B
|
||||
}
|
||||
|
||||
//
|
||||
// Wait to receive the data or check whether sending was done at this state
|
||||
// (Two states will go us to the 'done' state)
|
||||
//
|
||||
when(io.noNewDataSender === true.B) {
|
||||
|
||||
//
|
||||
// Sending data was done
|
||||
//
|
||||
state := sDone
|
||||
|
||||
}.elsewhen(io.dataValidInput === true.B) {
|
||||
|
||||
//
|
||||
// Store the data to send in a register
|
||||
//
|
||||
regDataToSend := io.sendingData
|
||||
|
||||
//
|
||||
// The data is valid, so let's send it
|
||||
//
|
||||
state := sSendData
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Stay in the same state as the data is not ready (valid)
|
||||
//
|
||||
state := sWaitToGetData
|
||||
}
|
||||
|
||||
}
|
||||
is(sSendData) {
|
||||
|
||||
//
|
||||
// Not waiting for the buffer at this state
|
||||
//
|
||||
sendWaitForBuffer := false.B
|
||||
|
||||
//
|
||||
// Enable writing to the BRAM
|
||||
//
|
||||
wrEna := true.B
|
||||
|
||||
//
|
||||
// Adjust address to write next data to BRAM (Address granularity is in the byte format so,
|
||||
// it'll be divided by 8 or shift to right by 3)
|
||||
//
|
||||
rdWrAddr := regRdWrAddr
|
||||
regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
|
||||
|
||||
//
|
||||
// Adjust data to write as the sending data
|
||||
//
|
||||
wrData := regDataToSend
|
||||
|
||||
//
|
||||
// Check whether sending was done at this state (Two states will go us to the 'done' state)
|
||||
//
|
||||
when(io.noNewDataSender === true.B) {
|
||||
|
||||
//
|
||||
// Sending data was done
|
||||
//
|
||||
state := sDone
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// Again go to the state for waiting for new data
|
||||
//
|
||||
state := sWaitToGetData
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
is(sDone) {
|
||||
|
||||
//
|
||||
// Adjust the output bits
|
||||
//
|
||||
finishedSendingBuffer := true.B
|
||||
|
||||
//
|
||||
// Interrupt the PS
|
||||
//
|
||||
psOutInterrupt := true.B
|
||||
|
||||
//
|
||||
// Go to the idle state
|
||||
//
|
||||
state := sIdle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect output pins to internal registers
|
||||
//
|
||||
io.psOutInterrupt := psOutInterrupt
|
||||
io.rdWrAddr := rdWrAddr
|
||||
io.wrEna := wrEna
|
||||
io.wrData := wrData
|
||||
io.sendWaitForBuffer := sendWaitForBuffer
|
||||
io.finishedSendingBuffer := finishedSendingBuffer
|
||||
|
||||
}
|
||||
|
||||
object DebuggerPacketSender {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
beginSendingBuffer: Bool,
|
||||
noNewDataSender: Bool,
|
||||
dataValidInput: Bool,
|
||||
requestedActionOfThePacketInput: UInt,
|
||||
sendingData: UInt
|
||||
): (Bool, UInt, Bool, UInt, Bool, Bool) = {
|
||||
|
||||
val debuggerPacketSender = Module(
|
||||
new DebuggerPacketSender(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val psOutInterrupt = Wire(Bool())
|
||||
val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
|
||||
val wrEna = Wire(Bool())
|
||||
val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
|
||||
val sendWaitForBuffer = Wire(Bool())
|
||||
val finishedSendingBuffer = Wire(Bool())
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
debuggerPacketSender.io.en := en
|
||||
debuggerPacketSender.io.beginSendingBuffer := beginSendingBuffer
|
||||
debuggerPacketSender.io.noNewDataSender := noNewDataSender
|
||||
debuggerPacketSender.io.dataValidInput := dataValidInput
|
||||
debuggerPacketSender.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
|
||||
debuggerPacketSender.io.sendingData := sendingData
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
psOutInterrupt := debuggerPacketSender.io.psOutInterrupt
|
||||
rdWrAddr := debuggerPacketSender.io.rdWrAddr
|
||||
wrEna := debuggerPacketSender.io.wrEna
|
||||
wrData := debuggerPacketSender.io.wrData
|
||||
|
||||
//
|
||||
// Configure the output signals related to sending packets
|
||||
//
|
||||
sendWaitForBuffer := debuggerPacketSender.io.sendWaitForBuffer
|
||||
finishedSendingBuffer := debuggerPacketSender.io.finishedSendingBuffer
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(psOutInterrupt, rdWrAddr, wrEna, wrData, sendWaitForBuffer, finishedSendingBuffer)
|
||||
}
|
||||
}
|
||||
52
hwdbg/src/main/scala/hwdbg/configs/config.json
Normal file
52
hwdbg/src/main/scala/hwdbg/configs/config.json
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"Version": {
|
||||
"VERSION_MAJOR": 0,
|
||||
"VERSION_MINOR": 2,
|
||||
"VERSION_PATCH": 0
|
||||
},
|
||||
"DebuggerConfigurations": {
|
||||
"ENABLE_DEBUG": true,
|
||||
"NUMBER_OF_PINS": 32,
|
||||
"PORT_PINS_MAP": [12, 20]
|
||||
},
|
||||
"ScriptEngineConfigurations": {
|
||||
"MAXIMUM_NUMBER_OF_STAGES": 32,
|
||||
"MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS": 2,
|
||||
"MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS": 1,
|
||||
"SCRIPT_VARIABLE_LENGTH": 8,
|
||||
"NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES": 2,
|
||||
"NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES": 2,
|
||||
"SCRIPT_ENGINE_EVAL_CAPABILITIES": [
|
||||
"assign_local_global_var",
|
||||
"assign_registers",
|
||||
"conditional_statements_and_comparison_operators",
|
||||
"stack_assignments",
|
||||
"func_or",
|
||||
"func_xor",
|
||||
"func_and",
|
||||
"func_asl",
|
||||
"func_add",
|
||||
"func_sub",
|
||||
"func_mul",
|
||||
"func_gt",
|
||||
"func_lt",
|
||||
"func_egt",
|
||||
"func_elt",
|
||||
"func_equal",
|
||||
"func_neq",
|
||||
"func_jmp",
|
||||
"func_jz",
|
||||
"func_jnz",
|
||||
"func_mov"
|
||||
]
|
||||
},
|
||||
"MemoryCommunicationConfigurations": {
|
||||
"BLOCK_RAM_ADDR_WIDTH": 13,
|
||||
"BLOCK_RAM_DATA_WIDTH": 32,
|
||||
"ENABLE_BLOCK_RAM_DELAY": true,
|
||||
"DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE": 1024,
|
||||
"BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION": 0,
|
||||
"BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION": 512
|
||||
}
|
||||
}
|
||||
|
||||
500
hwdbg/src/main/scala/hwdbg/configs/configs.scala
Normal file
500
hwdbg/src/main/scala/hwdbg/configs/configs.scala
Normal file
|
|
@ -0,0 +1,500 @@
|
|||
/**
|
||||
* @file
|
||||
* configs.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Configuration files
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-03
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.configs
|
||||
|
||||
import io.circe._
|
||||
import io.circe.parser._
|
||||
import io.circe.generic.auto._
|
||||
import scala.io.Source
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.utils._
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Version of hwdbg (Definition and Default Values)
|
||||
* @warning
|
||||
* will be checked with HyperDbg
|
||||
*/
|
||||
object Version {
|
||||
|
||||
//
|
||||
// Constant version info
|
||||
//
|
||||
var VERSION_MAJOR: Int = 0
|
||||
var VERSION_MINOR: Int = 1
|
||||
var VERSION_PATCH: Int = 0
|
||||
|
||||
def getEncodedVersion: Int = {
|
||||
(VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | VERSION_PATCH
|
||||
}
|
||||
|
||||
def extractMajor(encodedVersion: Int): Int = {
|
||||
encodedVersion >> 16
|
||||
}
|
||||
|
||||
def extractMinor(encodedVersion: Int): Int = {
|
||||
(encodedVersion >> 8) & 0xff // Masking to get only the 8 bits
|
||||
}
|
||||
|
||||
def extractPatch(encodedVersion: Int): Int = {
|
||||
encodedVersion & 0xff // Masking to get only the 8 bits
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Design constants (Definition and Default Values)
|
||||
*/
|
||||
object DebuggerConfigurations {
|
||||
|
||||
//
|
||||
// whether to enable debug or not
|
||||
//
|
||||
var ENABLE_DEBUG: Boolean = true
|
||||
|
||||
//
|
||||
// Number of input/output pins
|
||||
//
|
||||
var NUMBER_OF_PINS: Int = 32
|
||||
|
||||
//
|
||||
// The configuration of ports and pins
|
||||
//
|
||||
// The following constant shows the key value object of the mappings
|
||||
// of pins to ports (used for inputs/outputs)
|
||||
// For example,
|
||||
// port 0 (in) -> contains 12 pins
|
||||
// port 1 (in) -> contains 20 pins
|
||||
//
|
||||
// var PORT_PINS_MAP: Array[Int] = Array(12, 18, 2)
|
||||
// var PORT_PINS_MAP: Array[Int] = Array(12, 10, 5, 3, 2)
|
||||
var PORT_PINS_MAP: Array[Int] = Array(12, 20)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Design constants for script engine (Definition and Default Values)
|
||||
*/
|
||||
object ScriptEngineConfigurations {
|
||||
|
||||
//
|
||||
// Maximum number of stages
|
||||
//
|
||||
var MAXIMUM_NUMBER_OF_STAGES: Int = 32
|
||||
|
||||
//
|
||||
// Maximum number of stages
|
||||
//
|
||||
var MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int = 2 // for get values
|
||||
|
||||
//
|
||||
// Maximum number of stages
|
||||
//
|
||||
var MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int = 1 // for get value
|
||||
|
||||
//
|
||||
// Script variable length
|
||||
//
|
||||
var SCRIPT_VARIABLE_LENGTH: Int = 8
|
||||
|
||||
//
|
||||
// Number supported of local and global variables
|
||||
//
|
||||
var NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int = 2
|
||||
|
||||
//
|
||||
// Number supported of temporary variables
|
||||
//
|
||||
var NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int = 2
|
||||
|
||||
//
|
||||
// Define the capabilities you want to enable
|
||||
//
|
||||
var SCRIPT_ENGINE_EVAL_CAPABILITIES = Seq(
|
||||
//
|
||||
// Statements and expressions
|
||||
//
|
||||
HwdbgScriptCapabilities.assign_local_global_var,
|
||||
HwdbgScriptCapabilities.assign_registers,
|
||||
// HwdbgScriptCapabilities.assign_pseudo_registers,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators,
|
||||
HwdbgScriptCapabilities.stack_assignments,
|
||||
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
HwdbgScriptCapabilities.func_or,
|
||||
HwdbgScriptCapabilities.func_xor,
|
||||
HwdbgScriptCapabilities.func_and,
|
||||
HwdbgScriptCapabilities.func_asl,
|
||||
HwdbgScriptCapabilities.func_add,
|
||||
HwdbgScriptCapabilities.func_sub,
|
||||
HwdbgScriptCapabilities.func_mul,
|
||||
// HwdbgScriptCapabilities.func_div,
|
||||
// HwdbgScriptCapabilities.func_mod,
|
||||
HwdbgScriptCapabilities.func_gt,
|
||||
HwdbgScriptCapabilities.func_lt,
|
||||
HwdbgScriptCapabilities.func_egt,
|
||||
HwdbgScriptCapabilities.func_elt,
|
||||
HwdbgScriptCapabilities.func_equal,
|
||||
HwdbgScriptCapabilities.func_neq,
|
||||
HwdbgScriptCapabilities.func_jmp,
|
||||
HwdbgScriptCapabilities.func_jz,
|
||||
HwdbgScriptCapabilities.func_jnz,
|
||||
HwdbgScriptCapabilities.func_mov
|
||||
// HwdbgScriptCapabilities.func_printf,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The constants for memory communication (Definition and Default Values)
|
||||
*/
|
||||
object MemoryCommunicationConfigurations {
|
||||
|
||||
//
|
||||
// Address width of the Block RAM (BRAM)
|
||||
//
|
||||
var BLOCK_RAM_ADDR_WIDTH: Int = 13
|
||||
|
||||
//
|
||||
// Data width of the Block RAM (BRAM)
|
||||
//
|
||||
var BLOCK_RAM_DATA_WIDTH: Int = 32
|
||||
|
||||
//
|
||||
// Emulate block RAM by inferring a register to delay one clock cycle
|
||||
//
|
||||
var ENABLE_BLOCK_RAM_DELAY: Boolean = true
|
||||
|
||||
//
|
||||
// Default number of bytes used in initialized SRAM memory
|
||||
//
|
||||
var DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int = 8192 / 8 // 8 Kilobits
|
||||
|
||||
//
|
||||
// Base address of PS to PL SRAM communication memory
|
||||
//
|
||||
var BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int = 0
|
||||
|
||||
//
|
||||
// Base address of PL to PS SRAM communication memory
|
||||
//
|
||||
var BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int = DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE / 2
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The structure of script capabilities information in hwdbg
|
||||
* @details
|
||||
* Same as _HWDBG_INSTANCE_INFORMATION in HyperDbg
|
||||
*/
|
||||
case class HwdbgInstanceInformation(
|
||||
version: Int, // Target version of HyperDbg (same as hwdbg)
|
||||
maximumNumberOfStages: Int, // Number of stages that this instance of hwdbg supports (NumberOfSupportedStages == 0 means script engine is disabled)
|
||||
scriptVariableLength: Int, // Maximum length of variables (and other script elements)
|
||||
numberOfSupportedLocalAndGlobalVariables: Int, // Number of supported local (and global) variables
|
||||
numberOfSupportedTemporaryVariables: Int, // Number of supported temporary variables
|
||||
maximumNumberOfSupportedGetScriptOperators: Int, // Maximum supported GET operators in a single func
|
||||
maximumNumberOfSupportedSetScriptOperators: Int, // Maximum supported SET operators in a single func
|
||||
sharedMemorySize: Int, // Size of shared memory
|
||||
debuggerAreaOffset: Int, // The memory offset of debugger
|
||||
debuggeeAreaOffset: Int, // The memory offset of debuggee
|
||||
numberOfPins: Int, // Number of pins
|
||||
numberOfPorts: Int, // Number of ports
|
||||
scriptCapabilities: Long, // Capabilities bitmask
|
||||
bramAddrWidth: Int, // BRAM address width
|
||||
bramDataWidth: Int, // BRAM data width
|
||||
portsConfiguration: Array[Int] // Port arrangement
|
||||
)
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The script engine capabilities (Definition and Default Values)
|
||||
*/
|
||||
object HwdbgScriptCapabilities {
|
||||
|
||||
//
|
||||
// Statements and expressions
|
||||
//
|
||||
val assign_local_global_var: Long = 1L << 0
|
||||
val assign_registers: Long = 1L << 1
|
||||
val assign_pseudo_registers: Long = 1L << 2
|
||||
val conditional_statements_and_comparison_operators: Long = 1L << 3
|
||||
val stack_assignments: Long = 1L << 4
|
||||
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
val func_or: Long = 1L << 5
|
||||
val func_xor: Long = 1L << 6
|
||||
val func_and: Long = 1L << 7
|
||||
val func_asr: Long = 1L << 8
|
||||
val func_asl: Long = 1L << 9
|
||||
val func_add: Long = 1L << 10
|
||||
val func_sub: Long = 1L << 11
|
||||
val func_mul: Long = 1L << 12
|
||||
val func_div: Long = 1L << 13
|
||||
val func_mod: Long = 1L << 14
|
||||
val func_gt: Long = 1L << 15
|
||||
val func_lt: Long = 1L << 16
|
||||
val func_egt: Long = 1L << 17
|
||||
val func_elt: Long = 1L << 18
|
||||
val func_equal: Long = 1L << 19
|
||||
val func_neq: Long = 1L << 20
|
||||
val func_jmp: Long = 1L << 21
|
||||
val func_jz: Long = 1L << 22
|
||||
val func_jnz: Long = 1L << 23
|
||||
val func_mov: Long = 1L << 24
|
||||
val func_printf: Long = 1L << 25
|
||||
|
||||
def allCapabilities: Seq[Long] = Seq(
|
||||
assign_local_global_var,
|
||||
assign_registers,
|
||||
assign_pseudo_registers,
|
||||
conditional_statements_and_comparison_operators,
|
||||
stack_assignments,
|
||||
func_or,
|
||||
func_xor,
|
||||
func_and,
|
||||
func_asr,
|
||||
func_asl,
|
||||
func_add,
|
||||
func_sub,
|
||||
func_mul,
|
||||
func_div,
|
||||
func_mod,
|
||||
func_gt,
|
||||
func_lt,
|
||||
func_egt,
|
||||
func_elt,
|
||||
func_equal,
|
||||
func_neq,
|
||||
func_jmp,
|
||||
func_jz,
|
||||
func_jnz,
|
||||
func_mov,
|
||||
func_printf
|
||||
)
|
||||
|
||||
//
|
||||
// Utility method to create a bitmask from a sequence of capabilities
|
||||
//
|
||||
def createCapabilitiesMask(capabilities: Seq[Long]): Long = {
|
||||
capabilities.foldLeft(0L)(_ | _)
|
||||
}
|
||||
|
||||
//
|
||||
// Function to check if a capability is supported
|
||||
//
|
||||
def isCapabilitySupported(supportedCapabilities: Long, capability: Long): Boolean = {
|
||||
(supportedCapabilities & capability) != 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object HwdbgInstanceInformation {
|
||||
|
||||
//
|
||||
// Function to create an instance of HwdbgInstanceInformation
|
||||
//
|
||||
def createInstanceInformation(
|
||||
version: Int,
|
||||
maximumNumberOfStages: Int,
|
||||
scriptVariableLength: Int,
|
||||
numberOfSupportedLocalAndGlobalVariables: Int,
|
||||
numberOfSupportedTemporaryVariables: Int,
|
||||
maximumNumberOfSupportedGetScriptOperators: Int,
|
||||
maximumNumberOfSupportedSetScriptOperators: Int,
|
||||
sharedMemorySize: Int,
|
||||
debuggerAreaOffset: Int,
|
||||
debuggeeAreaOffset: Int,
|
||||
numberOfPins: Int,
|
||||
numberOfPorts: Int,
|
||||
enabledCapabilities: Seq[Long],
|
||||
bramAddrWidth: Int,
|
||||
bramDataWidth: Int,
|
||||
portsConfiguration: Array[Int]
|
||||
): HwdbgInstanceInformation = {
|
||||
|
||||
val capabilitiesMask = HwdbgScriptCapabilities.createCapabilitiesMask(enabledCapabilities)
|
||||
|
||||
//
|
||||
// Printing the versioning info
|
||||
//
|
||||
LogInfo(true)("=======================================================================")
|
||||
LogInfo(true)(
|
||||
s"Generating code for hwdbg v${Version.extractMajor(version)}.${Version.extractMinor(version)}.${Version.extractPatch(version)} ($version)"
|
||||
)
|
||||
LogInfo(true)("Please visit https://hwdbg.hyperdbg.org/docs for more information...")
|
||||
LogInfo(true)("hwdbg is released under the GNU Public License v3 (GPLv3).")
|
||||
LogInfo(true)("=======================================================================")
|
||||
|
||||
HwdbgInstanceInformation(
|
||||
version = version,
|
||||
maximumNumberOfStages = maximumNumberOfStages,
|
||||
scriptVariableLength = scriptVariableLength,
|
||||
numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
|
||||
numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
|
||||
maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
|
||||
maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
|
||||
sharedMemorySize = sharedMemorySize,
|
||||
debuggerAreaOffset = debuggerAreaOffset,
|
||||
debuggeeAreaOffset = debuggeeAreaOffset,
|
||||
numberOfPins = numberOfPins,
|
||||
numberOfPorts = numberOfPorts,
|
||||
scriptCapabilities = capabilitiesMask,
|
||||
bramAddrWidth = bramAddrWidth,
|
||||
bramDataWidth = bramDataWidth,
|
||||
portsConfiguration = portsConfiguration
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object ConfigLoader {
|
||||
|
||||
//
|
||||
// Case classes for each configuration section
|
||||
//
|
||||
case class VersionConfig(
|
||||
VERSION_MAJOR: Int,
|
||||
VERSION_MINOR: Int,
|
||||
VERSION_PATCH: Int
|
||||
)
|
||||
case class DebuggerConfigurationsConfig(
|
||||
ENABLE_DEBUG: Boolean,
|
||||
NUMBER_OF_PINS: Int,
|
||||
PORT_PINS_MAP: Array[Int]
|
||||
)
|
||||
case class ScriptEngineConfigurationsConfig(
|
||||
MAXIMUM_NUMBER_OF_STAGES: Int,
|
||||
MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int,
|
||||
MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int,
|
||||
SCRIPT_VARIABLE_LENGTH: Int,
|
||||
NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int,
|
||||
NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int,
|
||||
SCRIPT_ENGINE_EVAL_CAPABILITIES: Seq[String]
|
||||
)
|
||||
case class MemoryCommunicationConfigurationsConfig(
|
||||
BLOCK_RAM_ADDR_WIDTH: Int,
|
||||
BLOCK_RAM_DATA_WIDTH: Int,
|
||||
ENABLE_BLOCK_RAM_DELAY: Boolean,
|
||||
DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int,
|
||||
BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int,
|
||||
BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int
|
||||
)
|
||||
case class FullConfig(
|
||||
Version: VersionConfig,
|
||||
DebuggerConfigurations: DebuggerConfigurationsConfig,
|
||||
ScriptEngineConfigurations: ScriptEngineConfigurationsConfig,
|
||||
MemoryCommunicationConfigurations: MemoryCommunicationConfigurationsConfig
|
||||
)
|
||||
|
||||
//
|
||||
// Function to load configuration from a JSON file
|
||||
//
|
||||
def loadConfig(filePath: String): Option[FullConfig] = {
|
||||
val source = Source.fromFile(filePath)
|
||||
val jsonString = try source.getLines().mkString("\n") finally source.close()
|
||||
|
||||
decode[FullConfig](jsonString) match {
|
||||
case Right(config) => Some(config)
|
||||
case Left(error) =>
|
||||
println(s"Failed to parse JSON configuration: $error")
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object LoadConfiguration {
|
||||
|
||||
def loadFromJson(configPath: String): Unit = {
|
||||
|
||||
val configOpt = ConfigLoader.loadConfig(configPath)
|
||||
|
||||
configOpt.foreach { config =>
|
||||
|
||||
//
|
||||
// *** Set the values in the respective objects ***
|
||||
//
|
||||
|
||||
//
|
||||
// Read the version
|
||||
//
|
||||
Version.VERSION_MAJOR = config.Version.VERSION_MAJOR
|
||||
Version.VERSION_MINOR = config.Version.VERSION_MINOR
|
||||
Version.VERSION_PATCH = config.Version.VERSION_PATCH
|
||||
|
||||
//
|
||||
// Read the debugger configurations
|
||||
//
|
||||
DebuggerConfigurations.ENABLE_DEBUG = config.DebuggerConfigurations.ENABLE_DEBUG
|
||||
DebuggerConfigurations.NUMBER_OF_PINS = config.DebuggerConfigurations.NUMBER_OF_PINS
|
||||
DebuggerConfigurations.PORT_PINS_MAP = config.DebuggerConfigurations.PORT_PINS_MAP
|
||||
|
||||
//
|
||||
// Read the script engine configurations
|
||||
//
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS
|
||||
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH = config.ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES
|
||||
|
||||
//
|
||||
// Convert string capability names to the corresponding values in HwdbgScriptCapabilities
|
||||
//
|
||||
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES = config.ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES.flatMap {
|
||||
case "assign_local_global_var" => Some(HwdbgScriptCapabilities.assign_local_global_var)
|
||||
case "assign_registers" => Some(HwdbgScriptCapabilities.assign_registers)
|
||||
case "conditional_statements_and_comparison_operators" => Some(HwdbgScriptCapabilities.conditional_statements_and_comparison_operators)
|
||||
case "stack_assignments" => Some(HwdbgScriptCapabilities.stack_assignments)
|
||||
case "func_or" => Some(HwdbgScriptCapabilities.func_or)
|
||||
case "func_xor" => Some(HwdbgScriptCapabilities.func_xor)
|
||||
case "func_and" => Some(HwdbgScriptCapabilities.func_and)
|
||||
case "func_asl" => Some(HwdbgScriptCapabilities.func_asl)
|
||||
case "func_add" => Some(HwdbgScriptCapabilities.func_add)
|
||||
case "func_sub" => Some(HwdbgScriptCapabilities.func_sub)
|
||||
case "func_mul" => Some(HwdbgScriptCapabilities.func_mul)
|
||||
case "func_gt" => Some(HwdbgScriptCapabilities.func_gt)
|
||||
case "func_lt" => Some(HwdbgScriptCapabilities.func_lt)
|
||||
case "func_egt" => Some(HwdbgScriptCapabilities.func_egt)
|
||||
case "func_elt" => Some(HwdbgScriptCapabilities.func_elt)
|
||||
case "func_equal" => Some(HwdbgScriptCapabilities.func_equal)
|
||||
case "func_neq" => Some(HwdbgScriptCapabilities.func_neq)
|
||||
case "func_jmp" => Some(HwdbgScriptCapabilities.func_jmp)
|
||||
case "func_jz" => Some(HwdbgScriptCapabilities.func_jz)
|
||||
case "func_jnz" => Some(HwdbgScriptCapabilities.func_jnz)
|
||||
case "func_mov" => Some(HwdbgScriptCapabilities.func_mov)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
//
|
||||
// Read memory communication configurations
|
||||
//
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH
|
||||
MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY = config.MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY
|
||||
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE = config.MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION
|
||||
}
|
||||
}
|
||||
}
|
||||
68
hwdbg/src/main/scala/hwdbg/configs/constants.scala
Normal file
68
hwdbg/src/main/scala/hwdbg/configs/constants.scala
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* @file
|
||||
* constants.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Constant values
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-16
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.constants
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Shared value with HyperDbg
|
||||
* @warning
|
||||
* used in HyperDbg
|
||||
*/
|
||||
object HyperDbgSharedConstants {
|
||||
|
||||
//
|
||||
// Constant indicator of a HyperDbg packet
|
||||
//
|
||||
val INDICATOR_OF_HYPERDBG_PACKET: Long = 0x4859504552444247L // HYPERDBG = 0x4859504552444247
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Enumeration for different packet types in HyperDbg packets (DEBUGGER_REMOTE_PACKET_TYPE)
|
||||
* @warning
|
||||
* Used in HyperDbg
|
||||
*/
|
||||
object DebuggerRemotePacketType extends Enumeration {
|
||||
|
||||
//
|
||||
// Debugger to debuggee (vmx-root)
|
||||
//
|
||||
val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT = Value(1)
|
||||
|
||||
//
|
||||
// Debugger to debuggee (user-mode)
|
||||
//
|
||||
val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_USER_MODE = Value(2)
|
||||
|
||||
//
|
||||
// Debuggee to debugger (user-mode and kernel-mode, vmx-root mode)
|
||||
//
|
||||
val DEBUGGEE_TO_DEBUGGER = Value(3)
|
||||
|
||||
//
|
||||
// Debugger to debuggee (hardware), used in hwdbg
|
||||
//
|
||||
val DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL = Value(4)
|
||||
|
||||
//
|
||||
// Debuggee to debugger (hardware), used in hwdbg
|
||||
//
|
||||
val DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL = Value(5)
|
||||
}
|
||||
36
hwdbg/src/main/scala/hwdbg/configs/test_configs.scala
Normal file
36
hwdbg/src/main/scala/hwdbg/configs/test_configs.scala
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file
|
||||
* configs.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Configuration files for testing hwdbg
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-15
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.configs
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The configuration constants for testing
|
||||
*/
|
||||
object TestingConfigurations {
|
||||
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/instance_info.hex.txt"
|
||||
val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_buffer.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_pins.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_pin_assignments.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_port_assignments.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports_with_port_assignments.hex.txt"
|
||||
// val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statement_global_var.txt"
|
||||
|
||||
}
|
||||
105
hwdbg/src/main/scala/hwdbg/libs/mem/init_mem.scala
Normal file
105
hwdbg/src/main/scala/hwdbg/libs/mem/init_mem.scala
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* @file
|
||||
* init_mem.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Initialize SRAM memory from a file
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-03
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.libs.mem
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.experimental.loadMemoryFromFileInline
|
||||
|
||||
import hwdbg.configs._
|
||||
|
||||
class InitMemInline(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
memoryFile: String,
|
||||
addrWidth: Int,
|
||||
width: Int,
|
||||
size: Int
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val enable = Input(Bool())
|
||||
val write = Input(Bool())
|
||||
val addr = Input(UInt(addrWidth.W))
|
||||
val dataIn = Input(UInt(width.W))
|
||||
val dataOut = Output(UInt(width.W))
|
||||
})
|
||||
|
||||
val mem = SyncReadMem(size / width, UInt(width.W))
|
||||
|
||||
//
|
||||
// Initialize memory
|
||||
//
|
||||
if (memoryFile.trim().nonEmpty) {
|
||||
loadMemoryFromFileInline(mem, memoryFile)
|
||||
}
|
||||
|
||||
io.dataOut := DontCare
|
||||
|
||||
when(io.enable) {
|
||||
val rdwrPort = mem(io.addr)
|
||||
when(io.write) {
|
||||
rdwrPort := io.dataIn
|
||||
}.otherwise {
|
||||
io.dataOut := rdwrPort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object InitMemInline {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
memoryFile: String,
|
||||
addrWidth: Int,
|
||||
width: Int,
|
||||
size: Int
|
||||
)(
|
||||
enable: Bool,
|
||||
write: Bool,
|
||||
addr: UInt,
|
||||
dataIn: UInt
|
||||
): UInt = {
|
||||
|
||||
val initMemInlineModule = Module(
|
||||
new InitMemInline(
|
||||
debug,
|
||||
memoryFile,
|
||||
addrWidth,
|
||||
width,
|
||||
size
|
||||
)
|
||||
)
|
||||
|
||||
val dataOut = Wire(UInt(width.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
initMemInlineModule.io.enable := enable
|
||||
initMemInlineModule.io.write := write
|
||||
initMemInlineModule.io.addr := addr
|
||||
initMemInlineModule.io.dataIn := dataIn
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
dataOut := initMemInlineModule.io.dataOut
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
dataOut
|
||||
}
|
||||
}
|
||||
159
hwdbg/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
Normal file
159
hwdbg/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
* @file
|
||||
* init_reg_mem_from_file.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Initialize registers from a file
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-14
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.libs.mem
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.io.Source
|
||||
|
||||
import chisel3._
|
||||
|
||||
import hwdbg.utils._
|
||||
import hwdbg.configs._
|
||||
|
||||
object InitRegMemFromFileTools {
|
||||
def readmemh(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
path: String,
|
||||
width: Int
|
||||
): Seq[UInt] = {
|
||||
|
||||
var counter: Int = 0
|
||||
val buffer = new ArrayBuffer[UInt]
|
||||
for (line <- Source.fromFile(path).getLines()) {
|
||||
|
||||
val tokens: Array[String] = line.split("(//)").map(_.trim)
|
||||
|
||||
if (tokens.nonEmpty && tokens.head != "" && tokens.head.split(";")(0).trim != "") {
|
||||
|
||||
val i = Integer.parseInt(tokens.head.split(";")(0).trim, 16)
|
||||
|
||||
LogInfo(debug)(
|
||||
f"Initialize memory [${counter}%x]: 0x${i}%x"
|
||||
)
|
||||
|
||||
counter = counter + 4
|
||||
buffer.append(i.U(width.W))
|
||||
}
|
||||
}
|
||||
|
||||
buffer.toSeq
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class InitRegMemFromFile(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
emulateBlockRamDelay: Boolean,
|
||||
memoryFile: String,
|
||||
addrWidth: Int,
|
||||
width: Int,
|
||||
size: Int
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val enable = Input(Bool())
|
||||
val write = Input(Bool())
|
||||
val addr = Input(UInt(addrWidth.W))
|
||||
val dataIn = Input(UInt(width.W))
|
||||
val dataOut = Output(UInt(width.W))
|
||||
})
|
||||
|
||||
//
|
||||
// Not needed to show the BRAM information
|
||||
//
|
||||
val mem = RegInit(VecInit(InitRegMemFromFileTools.readmemh(false, memoryFile, width)))
|
||||
|
||||
val actualAddr = Wire(UInt(addrWidth.W))
|
||||
val actualData = Wire(UInt(width.W))
|
||||
val actualWrite = Wire(Bool())
|
||||
|
||||
//
|
||||
// This because the address of the saved registers are using 4 bytes granularities
|
||||
// E.g., 4 Rsh 2 = 1 | 8 Rsh 2 = 2 | 12 Rsh 2 = 3
|
||||
//
|
||||
if (emulateBlockRamDelay) {
|
||||
//
|
||||
// In case, if it is an emulation of BRAM, a one clock delay is injected
|
||||
//
|
||||
actualAddr := RegNext(io.addr >> 2)
|
||||
actualData := RegNext(io.dataIn)
|
||||
actualWrite := RegNext(io.write)
|
||||
} else {
|
||||
actualAddr := io.addr >> 2
|
||||
actualData := io.dataIn
|
||||
actualWrite := io.write
|
||||
}
|
||||
|
||||
when(io.enable) {
|
||||
val rdwrPort = mem(actualAddr)
|
||||
io.dataOut := rdwrPort
|
||||
|
||||
when(actualWrite) {
|
||||
mem(actualAddr) := actualData
|
||||
}
|
||||
}.otherwise {
|
||||
io.dataOut := 0.U
|
||||
}
|
||||
}
|
||||
|
||||
object InitRegMemFromFile {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
emulateBlockRamDelay: Boolean,
|
||||
memoryFile: String,
|
||||
addrWidth: Int,
|
||||
width: Int,
|
||||
size: Int
|
||||
)(
|
||||
enable: Bool,
|
||||
write: Bool,
|
||||
addr: UInt,
|
||||
dataIn: UInt
|
||||
): UInt = {
|
||||
|
||||
val initRegMemFromFileModule = Module(
|
||||
new InitRegMemFromFile(
|
||||
debug,
|
||||
emulateBlockRamDelay,
|
||||
memoryFile,
|
||||
addrWidth,
|
||||
width,
|
||||
size
|
||||
)
|
||||
)
|
||||
|
||||
val dataOut = Wire(UInt(width.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
initRegMemFromFileModule.io.enable := enable
|
||||
initRegMemFromFileModule.io.write := write
|
||||
initRegMemFromFileModule.io.addr := addr
|
||||
initRegMemFromFileModule.io.dataIn := dataIn
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
dataOut := initRegMemFromFileModule.io.dataOut
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
dataOut
|
||||
}
|
||||
}
|
||||
73
hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_io.scala
Normal file
73
hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_io.scala
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @file
|
||||
* mux_2_to_1_io.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Implementation of MUX 2 to 1 (I/O)
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-05
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.libs.mux
|
||||
|
||||
import chisel3._
|
||||
|
||||
import hwdbg.configs._
|
||||
|
||||
class Mux2To1IO(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
val a = Input(Bool())
|
||||
val b = Input(Bool())
|
||||
val select = Input(Bool())
|
||||
val out = Output(Bool())
|
||||
|
||||
})
|
||||
io.out := io.a & io.select | io.b & (~io.select)
|
||||
|
||||
}
|
||||
|
||||
object Mux2To1IO {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
|
||||
)(
|
||||
a: Bool,
|
||||
b: Bool,
|
||||
select: Bool
|
||||
): (Bool) = {
|
||||
|
||||
val mux2To1IO = Module(
|
||||
new Mux2To1IO(
|
||||
debug
|
||||
)
|
||||
)
|
||||
|
||||
val out = Wire(Bool())
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
mux2To1IO.io.a := a
|
||||
mux2To1IO.io.b := b
|
||||
mux2To1IO.io.select := select
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
out := mux2To1IO.io.out
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
out
|
||||
}
|
||||
}
|
||||
80
hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_lookup.scala
Normal file
80
hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_lookup.scala
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* @file
|
||||
* mux_2_to_1_lookup.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Implementation of MUX 2 to 1 (Mux-Lookup)
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-05
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.libs.mux
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
|
||||
class Mux2To1Lookup(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
val a = Input(Bool())
|
||||
val b = Input(Bool())
|
||||
val select = Input(Bool())
|
||||
val out = Output(Bool())
|
||||
|
||||
})
|
||||
|
||||
val inputs = Array(
|
||||
false.B -> io.a,
|
||||
true.B -> io.b
|
||||
)
|
||||
|
||||
io.out := MuxLookup(io.select, io.a)(inputs)
|
||||
|
||||
}
|
||||
|
||||
object Mux2To1Lookup {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
|
||||
)(
|
||||
a: Bool,
|
||||
b: Bool,
|
||||
select: Bool
|
||||
): (Bool) = {
|
||||
|
||||
val mux2To1Lookup = Module(
|
||||
new Mux2To1Lookup(
|
||||
debug
|
||||
)
|
||||
)
|
||||
|
||||
val out = Wire(Bool())
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
mux2To1Lookup.io.a := a
|
||||
mux2To1Lookup.io.b := b
|
||||
mux2To1Lookup.io.select := select
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
out := mux2To1Lookup.io.out
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
out
|
||||
}
|
||||
}
|
||||
83
hwdbg/src/main/scala/hwdbg/libs/mux/mux_4_to_1_onehot.scala
Normal file
83
hwdbg/src/main/scala/hwdbg/libs/mux/mux_4_to_1_onehot.scala
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* @file
|
||||
* mux_4_to_1_onehot.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Implementation of MUX 4 to 1 (One Hot)
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-05
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.libs.mux
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
|
||||
class Mux4To1OneHot(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
width: Int = 32
|
||||
) extends Module {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
val in0 = Input(UInt(width.W))
|
||||
val in1 = Input(UInt(width.W))
|
||||
val in2 = Input(UInt(width.W))
|
||||
val in3 = Input(UInt(width.W))
|
||||
val sel = Input(UInt(log2Ceil(width).W))
|
||||
val out = Output(UInt(width.W))
|
||||
|
||||
})
|
||||
|
||||
io.out := Mux1H(io.sel, Seq(io.in0, io.in1, io.in2, io.in3))
|
||||
|
||||
}
|
||||
|
||||
object Mux4To1OneHot {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
width: Int = 32
|
||||
)(
|
||||
in0: UInt,
|
||||
in1: UInt,
|
||||
in2: UInt,
|
||||
in3: UInt,
|
||||
sel: UInt
|
||||
): (UInt) = {
|
||||
|
||||
val mux4To1OneHot = Module(
|
||||
new Mux4To1OneHot(
|
||||
debug
|
||||
)
|
||||
)
|
||||
|
||||
val out = Wire(UInt(width.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
mux4To1OneHot.io.in0 := in0
|
||||
mux4To1OneHot.io.in1 := in1
|
||||
mux4To1OneHot.io.in2 := in2
|
||||
mux4To1OneHot.io.in3 := in3
|
||||
mux4To1OneHot.io.sel := sel
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
out := mux4To1OneHot.io.out
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
out
|
||||
}
|
||||
}
|
||||
320
hwdbg/src/main/scala/hwdbg/main.scala
Normal file
320
hwdbg/src/main/scala/hwdbg/main.scala
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/**
|
||||
* @file
|
||||
* main.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* hwdbg's main debugger module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-04
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg
|
||||
|
||||
import chisel3._
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.types._
|
||||
import hwdbg.utils._
|
||||
import hwdbg.script._
|
||||
import hwdbg.communication._
|
||||
import hwdbg.communication.interpreter._
|
||||
|
||||
class DebuggerMain(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
numberOfPins: Int,
|
||||
maximumNumberOfStages: Int,
|
||||
maximumNumberOfSupportedGetScriptOperators: Int,
|
||||
maximumNumberOfSupportedSetScriptOperators: Int,
|
||||
sharedMemorySize: Int,
|
||||
debuggerAreaOffset: Int,
|
||||
debuggeeAreaOffset: Int,
|
||||
scriptVariableLength: Int,
|
||||
numberOfSupportedLocalAndGlobalVariables: Int,
|
||||
numberOfSupportedTemporaryVariables: Int,
|
||||
scriptCapabilities: Seq[Long],
|
||||
bramAddrWidth: Int,
|
||||
bramDataWidth: Int,
|
||||
portsConfiguration: Array[Int]
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Ensure sum of input port values equals numberOfPins (NUMBER_OF_PINS)
|
||||
//
|
||||
require(
|
||||
portsConfiguration.sum == numberOfPins,
|
||||
"err, the sum of the portsConfiguration (PORT_PINS_MAP) values must equal the numberOfPins (NUMBER_OF_PINS)."
|
||||
)
|
||||
|
||||
//
|
||||
// Ensure script variable length is not bigger than BRAM data width
|
||||
//
|
||||
require(
|
||||
bramDataWidth >= scriptVariableLength,
|
||||
"err, the script variable length should not be bigger than BRAM data width."
|
||||
)
|
||||
|
||||
//
|
||||
// Ensure the maximum number of stages is not bigger than the maximum number
|
||||
// that can be stored within the script variable length. This is because
|
||||
// if a JUMP for conditional statements wants to set the target location,
|
||||
// it cannot store its destination in a script variable.
|
||||
//
|
||||
require(
|
||||
maximumNumberOfStages < math.pow(2, scriptVariableLength),
|
||||
"err, the maximum number of stages should be less than 2 to the power of the script variable length."
|
||||
)
|
||||
|
||||
//
|
||||
// Ensure the number of pin + ports is not bigger than the maximum number
|
||||
// that can be stored within the script variable length. This is because
|
||||
// for setting and getting pins/ports values, hwdbg uses an index which
|
||||
// should fit within a variable size.
|
||||
//
|
||||
require(
|
||||
numberOfPins + portsConfiguration.size < math.pow(2, scriptVariableLength),
|
||||
"err, the maximum number of pins + ports should be less than 2 to the power of the script variable length."
|
||||
)
|
||||
|
||||
//
|
||||
// Ensure the number of set operators are equal to 1 since otherwise two variables (local, global and
|
||||
// temp) might be written simultaneously.
|
||||
//
|
||||
require(
|
||||
maximumNumberOfSupportedSetScriptOperators == 1,
|
||||
"err, the supported number of SET operators can be only 1."
|
||||
)
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Input/Output signals
|
||||
//
|
||||
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
|
||||
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
//
|
||||
val plInSignal = Input(Bool()) // PS to PL signal
|
||||
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
|
||||
|
||||
//
|
||||
// BRAM (Block RAM) ports
|
||||
//
|
||||
val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
|
||||
val rdData = Input(UInt(bramDataWidth.W)) // read data
|
||||
val wrEna = Output(Bool()) // enable writing
|
||||
val wrData = Output(UInt(bramDataWidth.W)) // write data
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// *** Create an instance of the debugger ***
|
||||
//
|
||||
val instanceInfo = HwdbgInstanceInformation.createInstanceInformation(
|
||||
version = Version.getEncodedVersion,
|
||||
maximumNumberOfStages = maximumNumberOfStages,
|
||||
scriptVariableLength = scriptVariableLength,
|
||||
numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
|
||||
numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
|
||||
maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
|
||||
maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
|
||||
sharedMemorySize = sharedMemorySize,
|
||||
debuggerAreaOffset = debuggerAreaOffset,
|
||||
debuggeeAreaOffset = debuggeeAreaOffset,
|
||||
numberOfPins = numberOfPins,
|
||||
numberOfPorts = portsConfiguration.size,
|
||||
enabledCapabilities = scriptCapabilities,
|
||||
bramAddrWidth = bramAddrWidth,
|
||||
bramDataWidth = bramDataWidth,
|
||||
portsConfiguration = portsConfiguration
|
||||
)
|
||||
|
||||
//
|
||||
// Wire signals for the synchronizer
|
||||
//
|
||||
val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
|
||||
val requestedActionOfThePacketOutputValid = Wire(Bool())
|
||||
val dataValidOutput = Wire(Bool())
|
||||
val receivingData = Wire(UInt(bramDataWidth.W))
|
||||
val sendWaitForBuffer = Wire(Bool())
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Create instance from interpreter
|
||||
//
|
||||
val (
|
||||
noNewDataReceiver,
|
||||
readNextData,
|
||||
beginSendingBuffer,
|
||||
noNewDataSender,
|
||||
dataValidInterpreterOutput,
|
||||
requestedActionOfThePacketInterpreterOutput,
|
||||
sendingData,
|
||||
finishedScriptConfiguration,
|
||||
configureStage,
|
||||
targetOperator
|
||||
) =
|
||||
DebuggerPacketInterpreter(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
requestedActionOfThePacketOutput,
|
||||
requestedActionOfThePacketOutputValid,
|
||||
dataValidOutput,
|
||||
receivingData,
|
||||
sendWaitForBuffer
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Create instance from script execution engine
|
||||
//
|
||||
val (outputPin) =
|
||||
ScriptExecutionEngine(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
finishedScriptConfiguration,
|
||||
configureStage,
|
||||
targetOperator,
|
||||
io.inputPin
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Create instance from synchronizer
|
||||
//
|
||||
val (
|
||||
psOutInterrupt,
|
||||
rdWrAddr,
|
||||
wrEna,
|
||||
wrData,
|
||||
outRequestedActionOfThePacketOutput,
|
||||
outRequestedActionOfThePacketOutputValid,
|
||||
outDataValidOutput,
|
||||
outReceivingData,
|
||||
outSendWaitForBuffer
|
||||
) =
|
||||
SendReceiveSynchronizer(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
io.plInSignal,
|
||||
io.rdData,
|
||||
noNewDataReceiver,
|
||||
readNextData,
|
||||
beginSendingBuffer,
|
||||
noNewDataSender,
|
||||
dataValidInterpreterOutput,
|
||||
requestedActionOfThePacketInterpreterOutput,
|
||||
sendingData
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Connect synchronizer signals to wires
|
||||
//
|
||||
requestedActionOfThePacketOutput := outRequestedActionOfThePacketOutput
|
||||
requestedActionOfThePacketOutputValid := outRequestedActionOfThePacketOutputValid
|
||||
dataValidOutput := outDataValidOutput
|
||||
receivingData := outReceivingData
|
||||
sendWaitForBuffer := outSendWaitForBuffer
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Configure the output signals
|
||||
//
|
||||
io.wrEna := wrEna
|
||||
io.wrData := wrData
|
||||
io.rdWrAddr := rdWrAddr
|
||||
|
||||
io.outputPin := outputPin
|
||||
|
||||
io.psOutInterrupt := psOutInterrupt
|
||||
|
||||
}
|
||||
|
||||
object DebuggerMain {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
numberOfPins: Int,
|
||||
maximumNumberOfStages: Int,
|
||||
maximumNumberOfSupportedGetScriptOperators: Int,
|
||||
maximumNumberOfSupportedSetScriptOperators: Int,
|
||||
sharedMemorySize: Int,
|
||||
debuggerAreaOffset: Int,
|
||||
debuggeeAreaOffset: Int,
|
||||
scriptVariableLength: Int,
|
||||
numberOfSupportedLocalAndGlobalVariables: Int,
|
||||
numberOfSupportedTemporaryVariables: Int,
|
||||
scriptCapabilities: Seq[Long],
|
||||
bramAddrWidth: Int,
|
||||
bramDataWidth: Int,
|
||||
portsConfiguration: Array[Int]
|
||||
)(
|
||||
en: Bool,
|
||||
inputPin: Vec[UInt],
|
||||
plInSignal: Bool,
|
||||
rdData: UInt
|
||||
): (Vec[UInt], Bool, UInt, Bool, UInt) = {
|
||||
|
||||
val debuggerMainModule = Module(
|
||||
new DebuggerMain(
|
||||
debug,
|
||||
numberOfPins,
|
||||
maximumNumberOfStages,
|
||||
maximumNumberOfSupportedGetScriptOperators,
|
||||
maximumNumberOfSupportedSetScriptOperators,
|
||||
sharedMemorySize,
|
||||
debuggerAreaOffset,
|
||||
debuggeeAreaOffset,
|
||||
scriptVariableLength,
|
||||
numberOfSupportedLocalAndGlobalVariables,
|
||||
numberOfSupportedTemporaryVariables,
|
||||
scriptCapabilities,
|
||||
bramAddrWidth,
|
||||
bramDataWidth,
|
||||
portsConfiguration
|
||||
)
|
||||
)
|
||||
|
||||
val outputPin = Wire(Vec(numberOfPins, UInt(1.W)))
|
||||
val psOutInterrupt = Wire(Bool())
|
||||
val rdWrAddr = Wire(UInt(bramAddrWidth.W))
|
||||
val wrEna = Wire(Bool())
|
||||
val wrData = Wire(UInt(bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
debuggerMainModule.io.en := en
|
||||
debuggerMainModule.io.inputPin := inputPin
|
||||
debuggerMainModule.io.plInSignal := plInSignal
|
||||
debuggerMainModule.io.rdData := rdData
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
outputPin := debuggerMainModule.io.outputPin
|
||||
psOutInterrupt := debuggerMainModule.io.psOutInterrupt
|
||||
rdWrAddr := debuggerMainModule.io.rdWrAddr
|
||||
wrEna := debuggerMainModule.io.wrEna
|
||||
wrData := debuggerMainModule.io.wrData
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData)
|
||||
}
|
||||
}
|
||||
507
hwdbg/src/main/scala/hwdbg/script/eval.scala
Normal file
507
hwdbg/src/main/scala/hwdbg/script/eval.scala
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
/**
|
||||
* @file
|
||||
* eval.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Script execution engine
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-17
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.script
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.utils._
|
||||
import hwdbg.stage._
|
||||
|
||||
class ScriptEngineEval(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import operators enum
|
||||
//
|
||||
import hwdbg.script.ScriptEvalFunc.ScriptOperators
|
||||
import hwdbg.script.ScriptEvalFunc.ScriptOperators._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Stage configuration signals
|
||||
//
|
||||
val stageConfig = Input(new Stage(debug, instanceInfo))
|
||||
val nextStage = Output(
|
||||
UInt(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
)
|
||||
)
|
||||
|
||||
//
|
||||
// Output signals
|
||||
//
|
||||
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
|
||||
val resultingLocalGlobalVariables = Output(
|
||||
Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
|
||||
) // output of local (and global) variables
|
||||
val resultingTempVariables =
|
||||
Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // output of temporary variables
|
||||
})
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val nextStage = WireInit(
|
||||
0.U(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
)
|
||||
)
|
||||
|
||||
//
|
||||
// Assign operator value (split the signal into only usable part)
|
||||
//
|
||||
LogInfo(debug)("Usable size of Value in the SYMBOL: " + ScriptOperators().getWidth)
|
||||
val mainOperatorValue = io.stageConfig.stageSymbol.Value(ScriptOperators().getWidth - 1, 0).asTypeOf(ScriptOperators())
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get value module
|
||||
//
|
||||
val getValueModuleOutput = Wire(Vec(instanceInfo.maximumNumberOfSupportedGetScriptOperators, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
|
||||
for (i <- 0 until instanceInfo.maximumNumberOfSupportedGetScriptOperators) {
|
||||
|
||||
getValueModuleOutput(i) := ScriptEngineGetValue(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
io.stageConfig.getOperatorSymbol(i),
|
||||
io.stageConfig.localGlobalVariables,
|
||||
io.stageConfig.tempVariables,
|
||||
io.stageConfig.pinValues
|
||||
)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// *** Implementing the evaluation engine ***
|
||||
//
|
||||
//
|
||||
val srcVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedGetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
|
||||
val desVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedSetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(mainOperatorValue) {
|
||||
|
||||
is(sFuncOr) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_or) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) | srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncXor) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_xor) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) ^ srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncAnd) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_and) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) & srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncAsr) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asr) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) >> srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncAsl) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asl) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) << srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncAdd) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_add) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) + srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncSub) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_sub) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) - srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncMul) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mul) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) * srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncDiv) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_div) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) / srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncMod) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mod) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) % srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncGt) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_gt) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) > srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncLt) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_lt) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) < srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncEgt) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) >= srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncElt) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) <= srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncEqual) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_equal) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) === srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncNeq) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_neq) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
desVal(0) := srcVal(0) =/= srcVal(1)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncJmp) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jmp) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
nextStage := srcVal(0)
|
||||
}
|
||||
}
|
||||
is(sFuncJz) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jz) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
when(srcVal(1) === 0.U) {
|
||||
nextStage := srcVal(0)
|
||||
}.otherwise {
|
||||
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
|
||||
}
|
||||
}
|
||||
}
|
||||
is(sFuncJnz) {
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jnz) == true &&
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
srcVal(1) := getValueModuleOutput(1)
|
||||
|
||||
when(srcVal(1) =/= 0.U) {
|
||||
nextStage := srcVal(0)
|
||||
}.otherwise {
|
||||
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
is(sFuncMov) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mov) == true) {
|
||||
|
||||
srcVal(0) := getValueModuleOutput(0)
|
||||
|
||||
desVal(0) := srcVal(0)
|
||||
|
||||
nextStage := io.stageConfig.stageIndex + 3.U // one main operator + one GET operators + one SET operator
|
||||
}
|
||||
}
|
||||
is(sFuncPrintf) {
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_printf) == true) {
|
||||
|
||||
//
|
||||
// To be implemented
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Set value module
|
||||
//
|
||||
val setValueModuleInput = Wire(Vec(instanceInfo.maximumNumberOfSupportedSetScriptOperators, Vec(instanceInfo.numberOfPins, UInt(1.W))))
|
||||
val outputLocalGlobalVariables = Wire(
|
||||
Vec(
|
||||
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
|
||||
Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
|
||||
)
|
||||
)
|
||||
val outputTempVariables = Wire(
|
||||
Vec(
|
||||
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
|
||||
Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))
|
||||
)
|
||||
)
|
||||
|
||||
for (i <- 0 until instanceInfo.maximumNumberOfSupportedSetScriptOperators) {
|
||||
|
||||
val (
|
||||
outputPin,
|
||||
resultingLocalGlobalVariables,
|
||||
resultingTempVariables
|
||||
) = ScriptEngineSetValue(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
io.en,
|
||||
io.stageConfig.setOperatorSymbol(i),
|
||||
io.stageConfig.localGlobalVariables,
|
||||
io.stageConfig.tempVariables,
|
||||
desVal(i),
|
||||
io.stageConfig.pinValues
|
||||
)
|
||||
|
||||
//
|
||||
// Connect SET output pins
|
||||
//
|
||||
setValueModuleInput(i) := outputPin
|
||||
outputLocalGlobalVariables(i) := resultingLocalGlobalVariables
|
||||
outputTempVariables(i) := resultingTempVariables
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect the output signals
|
||||
//
|
||||
io.outputPin := setValueModuleInput(0)
|
||||
io.resultingLocalGlobalVariables := outputLocalGlobalVariables(0)
|
||||
io.resultingTempVariables := outputTempVariables(0)
|
||||
io.nextStage := nextStage
|
||||
}
|
||||
|
||||
object ScriptEngineEval {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
stageConfig: Stage
|
||||
): (UInt, Vec[UInt], Vec[UInt], Vec[UInt]) = {
|
||||
|
||||
val scriptEngineEvalModule = Module(
|
||||
new ScriptEngineEval(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
|
||||
val resultingLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
val resultingTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
val nextStage = Wire(
|
||||
UInt(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
)
|
||||
)
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
scriptEngineEvalModule.io.en := en
|
||||
scriptEngineEvalModule.io.stageConfig := stageConfig
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
nextStage := scriptEngineEvalModule.io.nextStage
|
||||
outputPin := scriptEngineEvalModule.io.outputPin
|
||||
resultingLocalGlobalVariables := scriptEngineEvalModule.io.resultingLocalGlobalVariables
|
||||
resultingTempVariables := scriptEngineEvalModule.io.resultingTempVariables
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
nextStage,
|
||||
outputPin,
|
||||
resultingLocalGlobalVariables,
|
||||
resultingTempVariables
|
||||
)
|
||||
}
|
||||
}
|
||||
373
hwdbg/src/main/scala/hwdbg/script/exec.scala
Normal file
373
hwdbg/src/main/scala/hwdbg/script/exec.scala
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
/**
|
||||
* @file
|
||||
* exec.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Script execution engine
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-07
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.script
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.stage._
|
||||
|
||||
object ScriptExecutionEngineConfigStage {
|
||||
object State extends ChiselEnum {
|
||||
val sConfigStageSymbol, sConfigGetSymbol, sConfigSetSymbol = Value
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptExecutionEngine(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import state enum
|
||||
//
|
||||
import ScriptExecutionEngineConfigStage.State
|
||||
import ScriptExecutionEngineConfigStage.State._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Script stage configuration signals
|
||||
//
|
||||
val finishedScriptConfiguration = Input(Bool()) // whether script configuration finished or not?
|
||||
val configureStage = Input(Bool()) // whether the configuration of stage should start or not?
|
||||
val targetOperator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
|
||||
|
||||
//
|
||||
// Input/Output signals
|
||||
//
|
||||
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
|
||||
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
|
||||
})
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
|
||||
|
||||
//
|
||||
// Stage registers
|
||||
//
|
||||
val stageRegs = Reg(Vec(instanceInfo.maximumNumberOfStages, new Stage(debug, instanceInfo)))
|
||||
|
||||
//
|
||||
// Stage configuration done
|
||||
// Whether the state are configured or not
|
||||
//
|
||||
val stageConfigurationValid = RegInit(false.B)
|
||||
|
||||
//
|
||||
// Stage configuration registers
|
||||
//
|
||||
val configState = RegInit(sConfigStageSymbol)
|
||||
val configStageNumber = RegInit(0.U(log2Ceil(instanceInfo.maximumNumberOfStages).W))
|
||||
|
||||
//
|
||||
// Calculate the maximum of the two values since we only want to use one register for
|
||||
// both GET and SET
|
||||
//
|
||||
val maxOperators = math.max(instanceInfo.maximumNumberOfSupportedGetScriptOperators, instanceInfo.maximumNumberOfSupportedSetScriptOperators)
|
||||
|
||||
//
|
||||
// Create a register with the width based on the maximum value
|
||||
//
|
||||
val configGetSetOperatorNumber = RegInit(0.U(log2Ceil(maxOperators).W))
|
||||
val stageIndex = RegInit(
|
||||
0.U(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
)
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
//
|
||||
// *** Configure stage buffers ***
|
||||
//
|
||||
when(io.configureStage === true.B) {
|
||||
|
||||
switch(configState) {
|
||||
|
||||
is(sConfigStageSymbol) {
|
||||
|
||||
//
|
||||
// Since the chip is in the configuring status, just pass all the input
|
||||
// to output since the stage data is not valid at this stage
|
||||
//
|
||||
stageConfigurationValid := false.B
|
||||
|
||||
//
|
||||
// Configure the stage symbol (The first symbol is the stage operator)
|
||||
//
|
||||
stageRegs(configStageNumber).stageSymbol := io.targetOperator
|
||||
|
||||
//
|
||||
// Set the stage index
|
||||
//
|
||||
stageRegs(configStageNumber).stageIndex := stageIndex // store the stage index
|
||||
stageRegs(configStageNumber).targetStage := 0.U // reset the target stage
|
||||
stageIndex := stageIndex + 1.U // increment stage index
|
||||
|
||||
//
|
||||
// If it is the very first configuration symbol, then we disable all stages
|
||||
//
|
||||
when(configStageNumber === 0.U) {
|
||||
for (i <- 0 until instanceInfo.maximumNumberOfStages) {
|
||||
stageRegs(i).stageEnable := false.B
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Going to the next state
|
||||
//
|
||||
configState := sConfigGetSymbol
|
||||
}
|
||||
is(sConfigGetSymbol) {
|
||||
|
||||
//
|
||||
// Config GET operator
|
||||
//
|
||||
stageRegs(configStageNumber).getOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
|
||||
configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
|
||||
|
||||
//
|
||||
// Check whether this stage number should be counted in stage indexes or its empty
|
||||
//
|
||||
when(io.targetOperator.Type =/= 0.U) {
|
||||
stageIndex := stageIndex + 1.U
|
||||
}
|
||||
|
||||
when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedGetScriptOperators - 1).U) {
|
||||
|
||||
configGetSetOperatorNumber := 0.U // reset the counter
|
||||
configState := sConfigSetSymbol // go to the next state
|
||||
}.otherwise {
|
||||
configState := sConfigGetSymbol // stay at the same state
|
||||
}
|
||||
}
|
||||
is(sConfigSetSymbol) {
|
||||
|
||||
//
|
||||
// Config SET operator
|
||||
//
|
||||
stageRegs(configStageNumber).setOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
|
||||
stageRegs(configStageNumber).stageEnable := true.B // this stage is enabled
|
||||
configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
|
||||
|
||||
when(io.targetOperator.Type =/= 0.U) {
|
||||
stageIndex := stageIndex + 1.U
|
||||
}
|
||||
|
||||
when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedSetScriptOperators - 1).U) {
|
||||
|
||||
configGetSetOperatorNumber := 0.U // reset the counter
|
||||
|
||||
when(io.finishedScriptConfiguration === true.B) {
|
||||
|
||||
//
|
||||
// Not configuring anymore, reset the stage number
|
||||
//
|
||||
configStageNumber := 0.U // reset the stage number
|
||||
stageIndex := 0.U // reset the stage index
|
||||
configState := sConfigStageSymbol
|
||||
|
||||
//
|
||||
// Stage data is now valid and can be used (scripts can apply from now on)
|
||||
//
|
||||
stageConfigurationValid := true.B
|
||||
|
||||
}.otherwise {
|
||||
configStageNumber := configStageNumber + 1.U // Increment the stage number holder of current configuration
|
||||
configState := sConfigStageSymbol // the next state is again a stage symbol
|
||||
}
|
||||
}.otherwise {
|
||||
configState := sConfigSetSymbol // stay at the same state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
//
|
||||
// *** Move each register (input vector) to the next stage at each clock ***
|
||||
//
|
||||
for (i <- 0 until instanceInfo.maximumNumberOfStages) {
|
||||
|
||||
if (i == 0) {
|
||||
|
||||
//
|
||||
// At the first stage, the input registers should be passed to the
|
||||
// first registers set of the stage registers
|
||||
//
|
||||
stageRegs(0).pinValues := io.inputPin
|
||||
|
||||
//
|
||||
// Each pin start initially start from 0th target stage
|
||||
//
|
||||
stageRegs(0).targetStage := 0.U
|
||||
|
||||
} else if (i == (instanceInfo.maximumNumberOfStages - 1)) {
|
||||
|
||||
//
|
||||
// At the last stage, the state registers should be passed to the output
|
||||
// Note: At this stage script symbol is useless
|
||||
//
|
||||
outputPin := stageRegs(i - 1).pinValues
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Check if this stage should be ignored (passed to the next stage) or be evaluated
|
||||
// (i - 1) is because the 0th index registers are used for storing data but the
|
||||
// script engine assumes that the symbols start from 0, so -1 is used here
|
||||
//
|
||||
// Also, if the stage data is valid (configuration applied at least once)
|
||||
//
|
||||
when(stageConfigurationValid === true.B && stageRegs(i - 1).stageIndex === stageRegs(i - 1).targetStage && stageRegs(i - 1).stageEnable === true.B) {
|
||||
|
||||
//
|
||||
// *** Based on target stage, this stage needs evaluation ***
|
||||
//
|
||||
|
||||
//
|
||||
// Instantiate an eval engine for this stage
|
||||
//
|
||||
val (
|
||||
nextStage,
|
||||
outputPin,
|
||||
resultingLocalGlobalVariables,
|
||||
resultingTempVariables
|
||||
) = ScriptEngineEval(
|
||||
debug,
|
||||
instanceInfo
|
||||
)(
|
||||
stageRegs(i - 1).stageEnable,
|
||||
stageRegs(i - 1)
|
||||
)
|
||||
|
||||
//
|
||||
// At the normal (middle) stage, the result of state registers should be passed to
|
||||
// the next level of stage registers
|
||||
//
|
||||
stageRegs(i).pinValues := outputPin
|
||||
|
||||
//
|
||||
// Pass the target stage symbol number to the next stage
|
||||
//
|
||||
stageRegs(i).targetStage := nextStage
|
||||
|
||||
//
|
||||
// Pass the local (and global) and temporary variables to the next stage
|
||||
//
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
stageRegs(i).localGlobalVariables := resultingLocalGlobalVariables
|
||||
}
|
||||
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
stageRegs(i).tempVariables := resultingTempVariables
|
||||
}
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// *** Based on target stage, this stage should be ignore ***
|
||||
//
|
||||
|
||||
//
|
||||
// Just pass all the values to the next stage
|
||||
//
|
||||
stageRegs(i).pinValues := stageRegs(i - 1).pinValues
|
||||
stageRegs(i).targetStage := stageRegs(i - 1).targetStage
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
stageRegs(i).localGlobalVariables := stageRegs(i - 1).localGlobalVariables
|
||||
}
|
||||
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
stageRegs(i).tempVariables := stageRegs(i - 1).tempVariables
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Connect the output signals
|
||||
//
|
||||
io.outputPin := outputPin
|
||||
|
||||
}
|
||||
|
||||
object ScriptExecutionEngine {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
finishedScriptConfiguration: Bool,
|
||||
configureStage: Bool,
|
||||
targetOperator: HwdbgShortSymbol,
|
||||
inputPin: Vec[UInt]
|
||||
): (Vec[UInt]) = {
|
||||
|
||||
val scriptExecutionEngineModule = Module(
|
||||
new ScriptExecutionEngine(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
scriptExecutionEngineModule.io.en := en
|
||||
scriptExecutionEngineModule.io.finishedScriptConfiguration := finishedScriptConfiguration
|
||||
scriptExecutionEngineModule.io.configureStage := configureStage
|
||||
scriptExecutionEngineModule.io.targetOperator := targetOperator
|
||||
scriptExecutionEngineModule.io.inputPin := inputPin
|
||||
|
||||
//
|
||||
// Configure the output signals
|
||||
//
|
||||
outputPin := scriptExecutionEngineModule.io.outputPin
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(outputPin)
|
||||
}
|
||||
}
|
||||
238
hwdbg/src/main/scala/hwdbg/script/get_value.scala
Normal file
238
hwdbg/src/main/scala/hwdbg/script/get_value.scala
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/**
|
||||
* @file
|
||||
* get_value.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Script engine get value
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-29
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.script
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.utils._
|
||||
import hwdbg.stage._
|
||||
|
||||
class ScriptEngineGetValue(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import script data types enum
|
||||
//
|
||||
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
|
||||
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Evaluation operator symbol
|
||||
//
|
||||
val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
|
||||
//
|
||||
// Input variables
|
||||
//
|
||||
val localGlobalVariables =
|
||||
Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
|
||||
val tempVariables = Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
|
||||
|
||||
//
|
||||
// Input signals
|
||||
//
|
||||
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
|
||||
|
||||
//
|
||||
// Output value
|
||||
//
|
||||
val outputValue = Output(UInt(instanceInfo.scriptVariableLength.W)) // output value
|
||||
})
|
||||
|
||||
val outputValue = WireInit(0.U(instanceInfo.scriptVariableLength.W))
|
||||
|
||||
//
|
||||
// Assign operator type (split the signal into only usable part)
|
||||
//
|
||||
LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
|
||||
val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
|
||||
|
||||
//
|
||||
// *** Implementing the getting data logic ***
|
||||
//
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(mainOperatorType) {
|
||||
|
||||
is(symbolGlobalIdType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
//
|
||||
// Set output to local (and global) variables
|
||||
//
|
||||
outputValue := io.localGlobalVariables(io.operator.Value)
|
||||
}
|
||||
}
|
||||
is(symbolLocalIdType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
//
|
||||
// Set output to local (and global) variables
|
||||
//
|
||||
outputValue := io.localGlobalVariables(io.operator.Value)
|
||||
}
|
||||
}
|
||||
is(symbolNumType) {
|
||||
|
||||
//
|
||||
// Constant value
|
||||
//
|
||||
outputValue := io.operator.Value
|
||||
}
|
||||
is(symbolRegisterType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
|
||||
|
||||
//
|
||||
// Registers are pins and ports
|
||||
//
|
||||
when(instanceInfo.numberOfPins.U > io.operator.Value) {
|
||||
|
||||
//
|
||||
// *** Used for getting the pin value ***
|
||||
//
|
||||
outputValue := io.inputPin(io.operator.Value)
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// *** Used for getting the port value ***
|
||||
//
|
||||
|
||||
//
|
||||
// Create a vector of wires
|
||||
//
|
||||
val ports = Wire(Vec(instanceInfo.numberOfPorts, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
var currentPortIndex: Int = 0
|
||||
var currentPortNum: Int = 0
|
||||
|
||||
//
|
||||
// Iterate based on port configuration
|
||||
//
|
||||
for (port <- instanceInfo.portsConfiguration) {
|
||||
|
||||
LogInfo(debug)(f"connect port(${currentPortIndex}) to inputPin(${currentPortNum} to ${currentPortNum + port}) for SET")
|
||||
ports(currentPortIndex) := io.inputPin.asUInt(currentPortNum + port - 1, currentPortNum)
|
||||
|
||||
currentPortNum += port
|
||||
currentPortIndex += 1
|
||||
}
|
||||
|
||||
//
|
||||
// Set the output
|
||||
//
|
||||
outputValue := ports(io.operator.Value - instanceInfo.numberOfPins.U)
|
||||
}
|
||||
}
|
||||
}
|
||||
is(symbolPseudoRegType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
|
||||
//
|
||||
// To be implemented
|
||||
//
|
||||
outputValue := 0.U
|
||||
}
|
||||
}
|
||||
is(symbolStackIndexType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
|
||||
//
|
||||
// To be implemented
|
||||
//
|
||||
outputValue := 0.U // io.inputPin.asUInt
|
||||
}
|
||||
}
|
||||
is(symbolTempType) {
|
||||
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
//
|
||||
// Set output to temporary variables
|
||||
//
|
||||
outputValue := io.tempVariables(io.operator.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Connect the output signals
|
||||
//
|
||||
io.outputValue := outputValue
|
||||
|
||||
}
|
||||
|
||||
object ScriptEngineGetValue {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
operator: HwdbgShortSymbol,
|
||||
localGlobalVariables: Vec[UInt],
|
||||
tempVariables: Vec[UInt],
|
||||
inputPin: Vec[UInt]
|
||||
): (UInt) = {
|
||||
|
||||
val scriptEngineGetValueModule = Module(
|
||||
new ScriptEngineGetValue(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val outputValue = Wire(UInt(instanceInfo.scriptVariableLength.W))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
scriptEngineGetValueModule.io.en := en
|
||||
scriptEngineGetValueModule.io.operator := operator
|
||||
scriptEngineGetValueModule.io.localGlobalVariables := localGlobalVariables
|
||||
scriptEngineGetValueModule.io.tempVariables := tempVariables
|
||||
scriptEngineGetValueModule.io.inputPin := inputPin
|
||||
|
||||
//
|
||||
// Configure the output signal
|
||||
//
|
||||
outputValue := scriptEngineGetValueModule.io.outputValue
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(outputValue)
|
||||
}
|
||||
}
|
||||
50
hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
Normal file
50
hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package hwdbg.script
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The structure of HWDBG_SHORT_SYMBOL used in script engine of HyperDbg
|
||||
*/
|
||||
class HwdbgShortSymbol(
|
||||
scriptVariableLength: Int
|
||||
) extends Bundle {
|
||||
|
||||
//
|
||||
// Ensure that the script variable length is at least 8 bits or 1 byte
|
||||
//
|
||||
require(
|
||||
scriptVariableLength >= 8,
|
||||
f"err, the minimum script variable length is 8 bits (1 byte)."
|
||||
)
|
||||
|
||||
val Type = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
|
||||
val Value = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Constant values for the script engine
|
||||
*/
|
||||
object ScriptConstants {
|
||||
val SYMBOL_MEM_VALID_CHECK_MASK = 1 << 31
|
||||
val INVALID = 0x80000000
|
||||
val LALR_ACCEPT = 0x7fffffff
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Constant type values for the script engine
|
||||
*/
|
||||
object ScriptConstantTypes {
|
||||
object ScriptDataTypes extends ChiselEnum {
|
||||
val symbolUndefined, symbolGlobalIdType, symbolLocalIdType, symbolNumType, symbolRegisterType, symbolPseudoRegType, symbolSemanticRuleType, symbolTempType, symbolStringType, symbolVariableCountType, symbolInvalid, symbolWstringType, symbolFunctionParameterIdType, symbolReturnAddressType, symbolFunctionParameterType, symbolStackIndexType, symbolStackBaseIndexType, symbolReturnValueType = Value
|
||||
}
|
||||
}
|
||||
|
||||
object ScriptEvalFunc {
|
||||
object ScriptOperators extends ChiselEnum {
|
||||
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncLbr_save, sFuncLbr_dump, sFuncLbr_print, sFuncLbr_restore, sFuncLbr_check, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncLbr_restore_by_filter, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
|
||||
}
|
||||
}
|
||||
389
hwdbg/src/main/scala/hwdbg/script/set_value.scala
Normal file
389
hwdbg/src/main/scala/hwdbg/script/set_value.scala
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
/**
|
||||
* @file
|
||||
* set_value.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Script engine set value
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-29
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.script
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.utils._
|
||||
import hwdbg.stage._
|
||||
|
||||
class ScriptEngineSetValue(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Module {
|
||||
|
||||
//
|
||||
// Import script data types enum
|
||||
//
|
||||
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
|
||||
import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
|
||||
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Evaluation operator symbol
|
||||
//
|
||||
val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
|
||||
|
||||
//
|
||||
// Input variables
|
||||
//
|
||||
val inputLocalGlobalVariables =
|
||||
Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
|
||||
val inputTempVariables =
|
||||
Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
|
||||
|
||||
//
|
||||
// Input value
|
||||
//
|
||||
val inputValue = Input(UInt(instanceInfo.scriptVariableLength.W)) // input value
|
||||
|
||||
//
|
||||
// Output signals
|
||||
//
|
||||
val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
|
||||
val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
|
||||
|
||||
//
|
||||
// Output variables
|
||||
//
|
||||
val outputLocalGlobalVariables =
|
||||
Output(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
|
||||
val outputTempVariables =
|
||||
Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// Temp input
|
||||
//
|
||||
val inputLocalGlobalVariables = io.inputLocalGlobalVariables
|
||||
val inputTempVariables = io.inputTempVariables
|
||||
val inputPin = io.inputPin.asUInt
|
||||
|
||||
//
|
||||
// Output pins
|
||||
//
|
||||
val outputPin = WireInit(0.U(instanceInfo.numberOfPins.W))
|
||||
val outputLocalGlobalVariables = WireInit(
|
||||
VecInit(Seq.fill(instanceInfo.numberOfSupportedLocalAndGlobalVariables)(0.U(instanceInfo.scriptVariableLength.W)))
|
||||
) // Local (and Global) variables
|
||||
val outputTempVariables = WireInit(
|
||||
VecInit(Seq.fill(instanceInfo.numberOfSupportedTemporaryVariables)(0.U(instanceInfo.scriptVariableLength.W)))
|
||||
) // Temporary variables
|
||||
|
||||
//
|
||||
// Assign operator type (split the signal into only usable part)
|
||||
//
|
||||
LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
|
||||
val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
|
||||
|
||||
//
|
||||
// *** Implementing the setting data logic ***
|
||||
//
|
||||
|
||||
//
|
||||
// Apply the chip enable signal
|
||||
//
|
||||
when(io.en === true.B) {
|
||||
|
||||
switch(mainOperatorType) {
|
||||
|
||||
is(symbolUndefined) {
|
||||
|
||||
//
|
||||
// In case of undefined SET value, just pass every input to the next step
|
||||
//
|
||||
outputPin := inputPin
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
|
||||
}
|
||||
is(symbolGlobalIdType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
|
||||
//
|
||||
// Set the local (and global) variables
|
||||
//
|
||||
outputPin := inputPin
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
|
||||
//
|
||||
// Set the target variable
|
||||
//
|
||||
outputLocalGlobalVariables(io.operator.Value) := io.inputValue
|
||||
}
|
||||
|
||||
}
|
||||
is(symbolLocalIdType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
|
||||
//
|
||||
// Set the target local/global variable
|
||||
//
|
||||
outputPin := inputPin
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
|
||||
//
|
||||
// Set the target local/global variable
|
||||
//
|
||||
outputLocalGlobalVariables(io.operator.Value) := io.inputValue
|
||||
}
|
||||
|
||||
}
|
||||
is(symbolRegisterType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
|
||||
|
||||
when(instanceInfo.numberOfPins.U > io.operator.Value) {
|
||||
|
||||
//
|
||||
// *** Used for setting the pin value ***
|
||||
//
|
||||
|
||||
//
|
||||
// Registers are pins (set the value based on less significant bit)
|
||||
//
|
||||
val tempShiftedBit = (1.U << io.operator.Value)
|
||||
|
||||
when(io.inputValue(0) === 1.U) {
|
||||
outputPin := inputPin | tempShiftedBit; // Set the N-th bit to 1
|
||||
}.otherwise {
|
||||
outputPin := inputPin & ~tempShiftedBit; // Clear the N-th bit to 0
|
||||
}
|
||||
|
||||
}.otherwise {
|
||||
|
||||
//
|
||||
// *** Used for setting the port value ***
|
||||
//
|
||||
|
||||
//
|
||||
// Iterate based on port configuration
|
||||
//
|
||||
var currentPortNum: Int = 0
|
||||
val numPorts = instanceInfo.portsConfiguration.length
|
||||
|
||||
for ((port, index) <- instanceInfo.portsConfiguration.zipWithIndex) {
|
||||
|
||||
LogInfo(debug)(f"========================= port assignment (${index} - port size: ${port}) =========================")
|
||||
|
||||
when(io.operator.Value === (index + instanceInfo.numberOfPins).U) {
|
||||
|
||||
//
|
||||
// If the current port's bit width is bigger than the script variable length,
|
||||
// we need to append zero
|
||||
//
|
||||
val targetInputValue = WireInit(0.U(port.W))
|
||||
|
||||
if (port > instanceInfo.scriptVariableLength) {
|
||||
|
||||
//
|
||||
// Since the port size is bigger than the variable size,
|
||||
// we need to append zeros to the target value
|
||||
//
|
||||
LogInfo(debug)(
|
||||
f"Appending zeros (${port - instanceInfo.scriptVariableLength}) to input variable (targetInputValue) to support port num: ${index}"
|
||||
)
|
||||
targetInputValue := Cat(io.inputValue, 0.U((port - instanceInfo.scriptVariableLength).W))
|
||||
} else {
|
||||
//
|
||||
// Since the variable size is bigger than the port size,
|
||||
// we need only a portion of the input value
|
||||
//
|
||||
targetInputValue := io.inputValue(port - 1, 0)
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the range of bits to be modified
|
||||
//
|
||||
val high = currentPortNum + port - 1
|
||||
val low = currentPortNum
|
||||
|
||||
// Create the modified outputPin based on whether it's the first, last or a middle port
|
||||
val modifiedOutputPin = if (index == 0) {
|
||||
|
||||
//
|
||||
// First port: keep higher bits unchanged, set lower bits to input value
|
||||
//
|
||||
LogInfo(debug)(
|
||||
f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0)"
|
||||
)
|
||||
Cat(
|
||||
inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
|
||||
targetInputValue // New value for the specified range
|
||||
)
|
||||
} else if (index == numPorts - 1) {
|
||||
|
||||
//
|
||||
// Last port: keep lower bits unchanged, set higher bits to input value
|
||||
//
|
||||
LogInfo(debug)(f"Set connecting index=${index} - targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)")
|
||||
Cat(
|
||||
targetInputValue, // New value for the specified range
|
||||
inputPin(low - 1, 0) // Bits below the range to keep unchanged
|
||||
)
|
||||
} else {
|
||||
|
||||
//
|
||||
// Middle port: keep both higher and lower bits unchanged
|
||||
//
|
||||
LogInfo(debug)(
|
||||
f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)"
|
||||
)
|
||||
Cat(
|
||||
inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
|
||||
targetInputValue, // New value for the specified range
|
||||
inputPin(low - 1, 0) // Bits below the range to keep unchanged
|
||||
)
|
||||
}
|
||||
|
||||
//
|
||||
// Assign the modified outputPin back to outputPin
|
||||
//
|
||||
outputPin := modifiedOutputPin
|
||||
}
|
||||
|
||||
currentPortNum += port
|
||||
}
|
||||
}
|
||||
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
}
|
||||
}
|
||||
is(symbolPseudoRegType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
|
||||
//
|
||||
// To be implemented
|
||||
//
|
||||
outputPin := 0.U
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
}
|
||||
|
||||
}
|
||||
is(symbolStackIndexType) {
|
||||
|
||||
if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
|
||||
//
|
||||
// To be implemented
|
||||
//
|
||||
outputPin := inputPin
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
}
|
||||
|
||||
}
|
||||
is(symbolTempType) {
|
||||
|
||||
if (
|
||||
HwdbgScriptCapabilities.isCapabilitySupported(
|
||||
instanceInfo.scriptCapabilities,
|
||||
HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
|
||||
) == true
|
||||
) {
|
||||
//
|
||||
// Set the temporary variables
|
||||
//
|
||||
outputPin := inputPin
|
||||
outputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
outputTempVariables := inputTempVariables
|
||||
|
||||
//
|
||||
// Set the target temporary variable
|
||||
//
|
||||
outputTempVariables(io.operator.Value) := io.inputValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Connect the output signals
|
||||
//
|
||||
io.outputLocalGlobalVariables := outputLocalGlobalVariables
|
||||
io.outputTempVariables := outputTempVariables
|
||||
|
||||
for (i <- 0 until instanceInfo.numberOfPins) {
|
||||
io.outputPin(i) := outputPin(i)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object ScriptEngineSetValue {
|
||||
|
||||
def apply(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
)(
|
||||
en: Bool,
|
||||
operator: HwdbgShortSymbol,
|
||||
inputLocalGlobalVariables: Vec[UInt],
|
||||
inputTempVariables: Vec[UInt],
|
||||
inputValue: UInt,
|
||||
inputPin: Vec[UInt]
|
||||
): (Vec[UInt], Vec[UInt], Vec[UInt]) = {
|
||||
|
||||
val scriptEngineSetValueModule = Module(
|
||||
new ScriptEngineSetValue(
|
||||
debug,
|
||||
instanceInfo
|
||||
)
|
||||
)
|
||||
|
||||
val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
|
||||
val outputLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
val outputTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
|
||||
|
||||
//
|
||||
// Configure the input signals
|
||||
//
|
||||
scriptEngineSetValueModule.io.en := en
|
||||
scriptEngineSetValueModule.io.operator := operator
|
||||
scriptEngineSetValueModule.io.inputLocalGlobalVariables := inputLocalGlobalVariables
|
||||
scriptEngineSetValueModule.io.inputTempVariables := inputTempVariables
|
||||
scriptEngineSetValueModule.io.inputValue := inputValue
|
||||
scriptEngineSetValueModule.io.inputPin := inputPin
|
||||
|
||||
//
|
||||
// Configure the output signal
|
||||
//
|
||||
outputPin := scriptEngineSetValueModule.io.outputPin
|
||||
outputLocalGlobalVariables := scriptEngineSetValueModule.io.outputLocalGlobalVariables
|
||||
outputTempVariables := scriptEngineSetValueModule.io.outputTempVariables
|
||||
|
||||
//
|
||||
// Return the output result
|
||||
//
|
||||
(
|
||||
outputPin,
|
||||
outputLocalGlobalVariables,
|
||||
outputTempVariables
|
||||
)
|
||||
}
|
||||
}
|
||||
183
hwdbg/src/main/scala/hwdbg/types/communication.scala
Normal file
183
hwdbg/src/main/scala/hwdbg/types/communication.scala
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/**
|
||||
* @file
|
||||
* communication.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Data types for the communication
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-08
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.types
|
||||
|
||||
import chisel3._
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Structure in C:
|
||||
//
|
||||
// typedef struct _DEBUGGER_REMOTE_PACKET
|
||||
// {
|
||||
// BYTE Checksum;
|
||||
// UINT64 Indicator; /* Shows the type of the packet */
|
||||
// DEBUGGER_REMOTE_PACKET_TYPE TypeOfThePacket;
|
||||
// DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION RequestedActionOfThePacket;
|
||||
//
|
||||
// } DEBUGGER_REMOTE_PACKET, *PDEBUGGER_REMOTE_PACKET;
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The packet used for communication with the remote debugger
|
||||
*/
|
||||
class DebuggerRemotePacket() extends Bundle {
|
||||
|
||||
//
|
||||
// Structure fields
|
||||
//
|
||||
val Checksum = UInt(8.W) // 1 bytes
|
||||
val Alignment0 = UInt((64 - 8).W) // 7 bytes
|
||||
val Indicator = UInt(64.W) // 8 bytes
|
||||
val TypeOfThePacket = UInt(32.W) // 4 bytes
|
||||
val RequestedActionOfThePacket = UInt(32.W) // 4 bytes
|
||||
|
||||
//
|
||||
// Offset of structure fields
|
||||
//
|
||||
object Offset {
|
||||
|
||||
val checksum = (0) / 8
|
||||
|
||||
val indicator = (Checksum.getWidth + Alignment0.getWidth) / 8
|
||||
|
||||
val typeOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth) / 8
|
||||
|
||||
val requestedActionOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth) / 8
|
||||
|
||||
val startOfDataBuffer =
|
||||
(Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth + RequestedActionOfThePacket.getWidth) / 8
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Structure in C:
|
||||
//
|
||||
// typedef struct _HWDBG_PORT_INFORMATION
|
||||
// {
|
||||
// UINT32 CountOfPorts;
|
||||
//
|
||||
// /*
|
||||
//
|
||||
// Here the pin information details will be available.
|
||||
//
|
||||
// UINT32
|
||||
// Port Size
|
||||
//
|
||||
// */
|
||||
//
|
||||
// } HWDBG_PORT_INFORMATION, *PHWDBG_PORT_INFORMATION;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The structure of port information in hwdbg
|
||||
*/
|
||||
class HwdbgPortInformation() extends Bundle {
|
||||
|
||||
//
|
||||
// Structure fields
|
||||
//
|
||||
val CountOfPorts = UInt(32.W) // 4 bytes
|
||||
|
||||
//
|
||||
// Offset of structure fields
|
||||
//
|
||||
object Offset {
|
||||
|
||||
val countOfPorts = (0) / 8
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Structure in C:
|
||||
//
|
||||
// typedef struct _HWDBG_PORT_INFORMATION_ITEMS
|
||||
// {
|
||||
// UINT32 PortIndex;
|
||||
//
|
||||
// } HWDBG_PORT_INFORMATION_ITEMS, *PHWDBG_PORT_INFORMATION_ITEMS;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The structure of port information (each item) in hwdbg
|
||||
*/
|
||||
class HwdbgPortInformationItems() extends Bundle {
|
||||
|
||||
//
|
||||
// Structure fields
|
||||
//
|
||||
val PortSize = UInt(32.W) // 4 bytes
|
||||
|
||||
//
|
||||
// Offset of structure fields
|
||||
//
|
||||
object Offset {
|
||||
|
||||
val portSize = (0) / 8
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Different action of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ACTION_ENUMS)
|
||||
* @warning
|
||||
* Used in HyperDbg
|
||||
*/
|
||||
object HwdbgActionEnums extends Enumeration {
|
||||
|
||||
val hwdbgActionSendInstanceInfo = Value(1)
|
||||
val hwdbgActionConfigureScriptBuffer = Value(2)
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_RESPONSE_ENUMS)
|
||||
* @warning
|
||||
* Used in HyperDbg
|
||||
*/
|
||||
object HwdbgResponseEnums extends Enumeration {
|
||||
|
||||
val hwdbgResponseSuccessOrErrorMessage = Value(1)
|
||||
val hwdbgResponseInstanceInfo = Value(2)
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ERROR_ENUMS)
|
||||
* @warning
|
||||
*/
|
||||
object HwdbgSuccessOrErrorEnums extends Enumeration {
|
||||
|
||||
val hwdbgOperationWasSuccessful = Value(0x7fffffff)
|
||||
val hwdbgErrorInvalidPacket = Value(1)
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
71
hwdbg/src/main/scala/hwdbg/types/stage.scala
Normal file
71
hwdbg/src/main/scala/hwdbg/types/stage.scala
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* @file
|
||||
* stage.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Data types related to stage registers
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-05-07
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.stage
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.log2Ceil
|
||||
|
||||
import hwdbg.configs._
|
||||
import hwdbg.script._
|
||||
|
||||
class Stage(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
instanceInfo: HwdbgInstanceInformation
|
||||
) extends Bundle {
|
||||
|
||||
val pinValues = Vec(
|
||||
instanceInfo.numberOfPins,
|
||||
UInt(1.W)
|
||||
) // The value of each pin in each stage (should be passed to the next stage)
|
||||
|
||||
val stageSymbol = new HwdbgShortSymbol(
|
||||
instanceInfo.scriptVariableLength
|
||||
) // Interpreted script symbol for the target stage (should NOT be passed to the next stage)
|
||||
|
||||
val getOperatorSymbol = Vec(
|
||||
instanceInfo.maximumNumberOfSupportedGetScriptOperators,
|
||||
new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
|
||||
) // GET symbol operand (should NOT be passed to the next stage)
|
||||
|
||||
val setOperatorSymbol = Vec(
|
||||
instanceInfo.maximumNumberOfSupportedSetScriptOperators,
|
||||
new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
|
||||
) // SET symbol operand (should NOT be passed to the next stage)
|
||||
|
||||
val targetStage = UInt(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
) // Target stage that needs to be executed for the current pin values (should be passed to the next stage)
|
||||
|
||||
val tempVariables = Vec(
|
||||
instanceInfo.numberOfSupportedTemporaryVariables,
|
||||
UInt(instanceInfo.scriptVariableLength.W)
|
||||
) // Temporary variables
|
||||
|
||||
val localGlobalVariables = Vec(
|
||||
instanceInfo.numberOfSupportedLocalAndGlobalVariables,
|
||||
UInt(instanceInfo.scriptVariableLength.W)
|
||||
) // Local (and Global) variables
|
||||
|
||||
val stageIndex = UInt(
|
||||
log2Ceil(
|
||||
instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
|
||||
).W
|
||||
) // Target stage index of the current stage (configured with script configuration and remains constant during execution)
|
||||
|
||||
val stageEnable = Bool() // Target stage is enabled (configured) or not
|
||||
}
|
||||
59
hwdbg/src/main/scala/hwdbg/utils/utils.scala
Normal file
59
hwdbg/src/main/scala/hwdbg/utils/utils.scala
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @file
|
||||
* utils.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* Different utilities and functionalities
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-12
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg.utils
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Create logs and debug messages
|
||||
*/
|
||||
object LogInfo {
|
||||
|
||||
def apply(debug: Boolean)(message: String): Unit = {
|
||||
if (debug) {
|
||||
println("[*] debug msg: " + message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object BitwiseFunction {
|
||||
|
||||
def getFirstNBits(num: Long, n: Int): Long = {
|
||||
|
||||
val mask = (1L << n) - 1 // Create a bitmask with the first 'n' bits set to 1
|
||||
val shifted = num >>> (java.lang.Long.SIZE - n) // Shift the bits to the right to keep the first 'n' bits
|
||||
val firstNBits = shifted & mask // Extract the first 'n' bits by performing a bitwise AND operation
|
||||
|
||||
firstNBits
|
||||
}
|
||||
|
||||
def getBitsInRange(num: Long, start: Int, end: Int): Long = {
|
||||
|
||||
require(start >= 0 && start <= 63, "Starting point must be between 0 and 63")
|
||||
require(end >= 0 && end <= 63, "Ending point must be between 0 and 63")
|
||||
require(start <= end, "Starting point must be less than or equal to ending point")
|
||||
|
||||
val numBits = end - start + 1 // Number of bits in the range
|
||||
val mask = (1L << numBits) - 1 // Create a bitmask with 'numBits' bits set to 1
|
||||
val shifted = num >>> (java.lang.Long.SIZE - end - 1) // Shift the bits to the right to align the range with the rightmost position
|
||||
val bitsInRange = shifted & mask // Extract the bits within the specified range
|
||||
|
||||
bitsInRange
|
||||
}
|
||||
|
||||
}
|
||||
143
hwdbg/src/main/scala/top.scala
Normal file
143
hwdbg/src/main/scala/top.scala
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* @file
|
||||
* top.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* hwdbg's top module
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-03
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg
|
||||
|
||||
import chisel3._
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg._
|
||||
import hwdbg.configs._
|
||||
|
||||
class DebuggerModule(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
numberOfPins: Int,
|
||||
maximumNumberOfStages: Int,
|
||||
maximumNumberOfSupportedGetScriptOperators: Int,
|
||||
maximumNumberOfSupportedSetScriptOperators: Int,
|
||||
sharedMemorySize: Int,
|
||||
debuggerAreaOffset: Int,
|
||||
debuggeeAreaOffset: Int,
|
||||
scriptVariableLength: Int,
|
||||
numberOfSupportedLocalAndGlobalVariables: Int,
|
||||
numberOfSupportedTemporaryVariables: Int,
|
||||
scriptCapabilities: Seq[Long],
|
||||
bramAddrWidth: Int,
|
||||
bramDataWidth: Int,
|
||||
portsConfiguration: Array[Int]
|
||||
) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Input/Output signals
|
||||
//
|
||||
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
|
||||
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
//
|
||||
val plInSignal = Input(Bool()) // PS to PL signal
|
||||
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
|
||||
|
||||
//
|
||||
// BRAM (Block RAM) ports
|
||||
//
|
||||
val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
|
||||
val rdData = Input(UInt(bramDataWidth.W)) // read data
|
||||
val wrEna = Output(Bool()) // enable writing
|
||||
val wrData = Output(UInt(bramDataWidth.W)) // write data
|
||||
|
||||
})
|
||||
|
||||
//
|
||||
// Instantiate the debugger's main module
|
||||
//
|
||||
val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
|
||||
DebuggerMain(
|
||||
debug,
|
||||
numberOfPins,
|
||||
maximumNumberOfStages,
|
||||
maximumNumberOfSupportedGetScriptOperators,
|
||||
maximumNumberOfSupportedSetScriptOperators,
|
||||
sharedMemorySize,
|
||||
debuggerAreaOffset,
|
||||
debuggeeAreaOffset,
|
||||
scriptVariableLength,
|
||||
numberOfSupportedLocalAndGlobalVariables,
|
||||
numberOfSupportedTemporaryVariables,
|
||||
scriptCapabilities,
|
||||
bramAddrWidth,
|
||||
bramDataWidth,
|
||||
portsConfiguration
|
||||
)(
|
||||
io.en,
|
||||
io.inputPin,
|
||||
io.plInSignal,
|
||||
io.rdData
|
||||
)
|
||||
|
||||
io.outputPin := outputPin
|
||||
io.psOutInterrupt := psOutInterrupt
|
||||
io.rdWrAddr := rdWrAddr
|
||||
io.wrEna := wrEna
|
||||
io.wrData := wrData
|
||||
|
||||
}
|
||||
|
||||
object Main extends App {
|
||||
|
||||
//
|
||||
// Load configuration from JSON file
|
||||
//
|
||||
LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
|
||||
|
||||
//
|
||||
// Generate hwdbg verilog files
|
||||
//
|
||||
println(
|
||||
ChiselStage.emitSystemVerilog(
|
||||
new DebuggerModule(
|
||||
DebuggerConfigurations.ENABLE_DEBUG,
|
||||
DebuggerConfigurations.NUMBER_OF_PINS,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
|
||||
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
|
||||
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
|
||||
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
|
||||
DebuggerConfigurations.PORT_PINS_MAP
|
||||
),
|
||||
firtoolOpts = Array(
|
||||
"-disable-all-randomization",
|
||||
// "-strip-debug-info",
|
||||
"--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
|
||||
"-o",
|
||||
"generated/"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
176
hwdbg/src/main/scala/top_test.scala
Normal file
176
hwdbg/src/main/scala/top_test.scala
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
* @file
|
||||
* top_test.scala
|
||||
* @author
|
||||
* Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief
|
||||
* hwdbg's top module (with BRAM) for testing
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date
|
||||
* 2024-04-04
|
||||
*
|
||||
* @copyright
|
||||
* This project is released under the GNU Public License v3.
|
||||
*/
|
||||
package hwdbg
|
||||
|
||||
import chisel3._
|
||||
import circt.stage.ChiselStage
|
||||
|
||||
import hwdbg._
|
||||
import hwdbg.configs._
|
||||
import hwdbg.libs.mem._
|
||||
|
||||
class DebuggerModuleTestingBRAM(
|
||||
debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
|
||||
numberOfPins: Int,
|
||||
maximumNumberOfStages: Int,
|
||||
maximumNumberOfSupportedGetScriptOperators: Int,
|
||||
maximumNumberOfSupportedSetScriptOperators: Int,
|
||||
sharedMemorySize: Int,
|
||||
debuggerAreaOffset: Int,
|
||||
debuggeeAreaOffset: Int,
|
||||
scriptVariableLength: Int,
|
||||
numberOfSupportedLocalAndGlobalVariables: Int,
|
||||
numberOfSupportedTemporaryVariables: Int,
|
||||
scriptCapabilities: Seq[Long],
|
||||
bramAddrWidth: Int,
|
||||
bramDataWidth: Int,
|
||||
portsConfiguration: Array[Int]
|
||||
) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
|
||||
//
|
||||
// Chip signals
|
||||
//
|
||||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Input/Output signals
|
||||
//
|
||||
val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
|
||||
val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
|
||||
|
||||
//
|
||||
// Interrupt signals (lines)
|
||||
//
|
||||
val plInSignal = Input(Bool()) // PS to PL signal
|
||||
val psOutInterrupt = Output(Bool()) // PL to PS interrupt
|
||||
|
||||
//
|
||||
// *** BRAM (Block RAM) ports are initialized from an external file ***
|
||||
//
|
||||
|
||||
})
|
||||
|
||||
val bramEn = WireInit(false.B)
|
||||
val bramWrite = WireInit(false.B)
|
||||
val bramAddr = WireInit(0.U(bramAddrWidth.W))
|
||||
val bramDataIn = WireInit(0.U(bramDataWidth.W))
|
||||
|
||||
val bramDataOut = WireInit(0.U(bramDataWidth.W))
|
||||
|
||||
//
|
||||
// Instantiate the BRAM memory initializer module
|
||||
//
|
||||
val dataOut =
|
||||
InitRegMemFromFile(
|
||||
debug,
|
||||
MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY,
|
||||
TestingConfigurations.BRAM_INITIALIZATION_FILE_PATH,
|
||||
bramAddrWidth,
|
||||
bramDataWidth,
|
||||
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
|
||||
)(
|
||||
bramEn,
|
||||
bramWrite,
|
||||
bramAddr,
|
||||
bramDataIn
|
||||
)
|
||||
|
||||
bramDataOut := dataOut
|
||||
|
||||
//
|
||||
// Instantiate the debugger's main module
|
||||
//
|
||||
val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
|
||||
DebuggerMain(
|
||||
debug,
|
||||
numberOfPins,
|
||||
maximumNumberOfStages,
|
||||
maximumNumberOfSupportedGetScriptOperators,
|
||||
maximumNumberOfSupportedSetScriptOperators,
|
||||
sharedMemorySize,
|
||||
debuggerAreaOffset,
|
||||
debuggeeAreaOffset,
|
||||
scriptVariableLength,
|
||||
numberOfSupportedLocalAndGlobalVariables,
|
||||
numberOfSupportedTemporaryVariables,
|
||||
scriptCapabilities,
|
||||
bramAddrWidth,
|
||||
bramDataWidth,
|
||||
portsConfiguration
|
||||
)(
|
||||
io.en,
|
||||
io.inputPin,
|
||||
io.plInSignal,
|
||||
bramDataOut
|
||||
)
|
||||
|
||||
//
|
||||
// Connect BRAM Pins
|
||||
//
|
||||
bramEn := io.en // enable BRAM when the main chip enabled
|
||||
bramAddr := rdWrAddr
|
||||
bramWrite := wrEna
|
||||
bramDataIn := wrData
|
||||
|
||||
//
|
||||
// Connect I/O pins
|
||||
//
|
||||
io.outputPin := outputPin
|
||||
io.psOutInterrupt := psOutInterrupt
|
||||
|
||||
}
|
||||
|
||||
object MainWithInitializedBRAM extends App {
|
||||
|
||||
//
|
||||
// Load configuration from JSON file
|
||||
//
|
||||
LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
|
||||
|
||||
//
|
||||
// Generate hwdbg verilog files
|
||||
//
|
||||
println(
|
||||
ChiselStage.emitSystemVerilog(
|
||||
new DebuggerModuleTestingBRAM(
|
||||
DebuggerConfigurations.ENABLE_DEBUG,
|
||||
DebuggerConfigurations.NUMBER_OF_PINS,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
|
||||
ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
|
||||
MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
|
||||
MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
|
||||
ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
|
||||
ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
|
||||
ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
|
||||
MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
|
||||
DebuggerConfigurations.PORT_PINS_MAP
|
||||
),
|
||||
firtoolOpts = Array(
|
||||
"-disable-all-randomization",
|
||||
// "-strip-debug-info",
|
||||
"--lowering-options=disallowLocalVariables", // because icarus doesn't support 'automatic logic', this option prevents such logics
|
||||
"--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
|
||||
"-o",
|
||||
"generated/"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
4620
hwdbg/src/main/systemverilog/sensors/constraints/top.xdc
Normal file
4620
hwdbg/src/main/systemverilog/sensors/constraints/top.xdc
Normal file
File diff suppressed because it is too large
Load diff
64
hwdbg/src/main/systemverilog/sensors/src/PL_CORE.v
Normal file
64
hwdbg/src/main/systemverilog/sensors/src/PL_CORE.v
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 03/08/2024 04:39:27 PM
|
||||
// Design Name:
|
||||
// Module Name: PL_CORE
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module PL_CORE(
|
||||
|
||||
(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_P,
|
||||
(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_N,
|
||||
|
||||
// input wire reg_clk,
|
||||
input wire uart_rx_line,
|
||||
// input wire reg_eop,
|
||||
// input logic SPI_nCS,
|
||||
// output wire clk_reg_out,
|
||||
output wire uart_tx_line,
|
||||
// output logic laser_module_trigger,
|
||||
|
||||
output wire [3:0] led_out_ff
|
||||
);
|
||||
|
||||
wire clk_main;
|
||||
clk_wiz_11 clock_main
|
||||
(
|
||||
// Clock out ports
|
||||
.clk_main(clk_main), // output clk_main
|
||||
// Status and control signals
|
||||
.reset(reset), // input reset
|
||||
.locked(locked), // output locked
|
||||
// Clock in ports
|
||||
.clk_in1_p(QDR4_CLK_100MHZ_P), // input clk_in1_p
|
||||
.clk_in1_n(QDR4_CLK_100MHZ_N) // input clk_in1_n
|
||||
);
|
||||
|
||||
|
||||
UART_FF UART_FF_INS (
|
||||
.clk (clk_main),
|
||||
.rst ('b0),
|
||||
.reg_clk (clk_main),
|
||||
.reg_eop (clk_main),
|
||||
.uart_rx_line (uart_rx_line),
|
||||
.uart_tx_line (uart_tx_line),
|
||||
.gpio (gpio),
|
||||
.led_out_ff (led_out_ff)
|
||||
);
|
||||
|
||||
endmodule
|
||||
89
hwdbg/src/main/systemverilog/sensors/src/ff_fanout.sv
Normal file
89
hwdbg/src/main/systemverilog/sensors/src/ff_fanout.sv
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 11/16/2023 02:48:20 PM
|
||||
// Design Name:
|
||||
// Module Name: ff_fanout
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module ff_fanout(
|
||||
input wire clk,
|
||||
input wire CE,
|
||||
input wire rst,
|
||||
input wire inp,
|
||||
output reg res
|
||||
);
|
||||
|
||||
|
||||
|
||||
//reg rst_em; // input clock on FPGA
|
||||
//reg[27:0] counter=28'd0;
|
||||
//parameter DIVISOR = 28'd1;
|
||||
//// The frequency of the output clk_out
|
||||
//// = The frequency of the input clk_in divided by DIVISOR
|
||||
//// For example: Fclk_in = 50Mhz, if you want to get 1Hz signal to blink LEDs
|
||||
//// You will modify the DIVISOR parameter value to 28'd50.000.000
|
||||
//// Then the frequency of the output clk_out = 50Mhz/50.000.000 = 1Hz
|
||||
//always @(posedge rst)
|
||||
//begin
|
||||
// counter <= counter + 28'd1;
|
||||
// if(counter>=(DIVISOR-1))
|
||||
// counter <= 28'd0;
|
||||
|
||||
|
||||
// rst_em <= (counter<DIVISOR/2)?1'b1:1'b0;
|
||||
//end
|
||||
|
||||
|
||||
|
||||
localparam size_i = 256;
|
||||
|
||||
|
||||
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] q_output;
|
||||
(* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] d_input;
|
||||
assign d_input = ({size_i{inp}});
|
||||
wire CLR;
|
||||
assign CLR= 1'b0;
|
||||
always @(posedge clk)begin
|
||||
|
||||
res <= &q_output;
|
||||
|
||||
end
|
||||
|
||||
(* S = "TRUE" *) (* KEEP = "TRUE" *) FDRE #(.INIT(1'b0)) FDRE_inst[size_i-1:0](
|
||||
.Q(q_output),
|
||||
.C(clk),
|
||||
.CE(1'b1),
|
||||
.R(rst),
|
||||
.D(d_input)
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
// (* S = "TRUE" *) (* KEEP = "TRUE" *) FDRE #(.INIT(1'b0)) FDRE_inst[size_i-1:0](
|
||||
// .Q(q_output),
|
||||
// .C(clk),
|
||||
// .CE(CE),
|
||||
// .R(1'b0),
|
||||
// .D(d_input)
|
||||
|
||||
|
||||
// );
|
||||
|
||||
endmodule
|
||||
78
hwdbg/src/main/systemverilog/sensors/src/freq_generator.sv
Normal file
78
hwdbg/src/main/systemverilog/sensors/src/freq_generator.sv
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 06/20/2024 10:21:57 AM
|
||||
// Design Name:
|
||||
// Module Name: freq_generator
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module freq_generator(
|
||||
input logic clk_in, // Input clock
|
||||
input logic reset, // Reset signal
|
||||
input logic [31:0] div_int, // Integer part of the division factor
|
||||
input logic [31:0] div_frac, // Fractional part of the division factor (in fixed-point format, e.g., 0.5 = 32'd50000000)
|
||||
output logic clk_out // Output clock
|
||||
);
|
||||
|
||||
logic [31:0] int_counter;
|
||||
logic [31:0] frac_counter;
|
||||
logic frac_tick;
|
||||
logic clk_out_internal;
|
||||
|
||||
// Integer Clock Division Logic
|
||||
always_ff @(posedge clk_in or posedge reset) begin
|
||||
if (reset) begin
|
||||
int_counter <= 32'd0;
|
||||
clk_out_internal <= 1'b0;
|
||||
end else begin
|
||||
if (int_counter >= (div_int - 1)) begin
|
||||
int_counter <= 32'd0;
|
||||
clk_out_internal <= ~clk_out_internal;
|
||||
end else begin
|
||||
int_counter <= int_counter + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Fractional Clock Division Logic
|
||||
always_ff @(posedge clk_in or posedge reset) begin
|
||||
if (reset) begin
|
||||
frac_counter <= 32'd0;
|
||||
frac_tick <= 1'b0;
|
||||
end else begin
|
||||
frac_counter <= frac_counter + div_frac;
|
||||
if (frac_counter >= 32'd100000000) begin // When the counter exceeds 1.0 in fixed-point format
|
||||
frac_counter <= frac_counter - 32'd100000000;
|
||||
frac_tick <= 1'b1;
|
||||
end else begin
|
||||
frac_tick <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Combine Integer and Fractional Divisions
|
||||
always_ff @(posedge clk_in or posedge reset) begin
|
||||
if (reset) begin
|
||||
clk_out <= 1'b0;
|
||||
end else if (int_counter == 0 && frac_tick) begin
|
||||
clk_out <= ~clk_out_internal;
|
||||
end else begin
|
||||
clk_out <= clk_out_internal;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
29
hwdbg/src/main/systemverilog/sensors/src/inverter.v
Normal file
29
hwdbg/src/main/systemverilog/sensors/src/inverter.v
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 08/29/2023 01:50:41 PM
|
||||
// Design Name:
|
||||
// Module Name: inverter
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module inverter(
|
||||
in_data,out_data
|
||||
);
|
||||
input in_data;
|
||||
output out_data;
|
||||
(* dont_touch = "yes" *) assign out_data = !in_data;
|
||||
endmodule
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue