1+ // Constants specific to the application core
2+ __constant U32 _CPUCONF_ADDR = 0x52011000;
3+ __constant U32 _PROCESSOR_ID = 2;
4+ __constant U32 _DOMAIN_ID = 2;
5+ __constant U32 _NUM_OTHER_PROCESSORS = 1;
6+ const U32 _OTHER_PROCESSOR_IDS[1] = {3};
7+
18// Debug Halting Control and Status Register
2- __constant U32 _DHCSR_ADDR = 0xE000EDF0;
3- __constant U32 _DHCSR_DBGKEY = (0xA05F << 16);
4- __constant U32 _DHCSR_C_DEBUGEN = (1 << 0);
5- __constant U32 _DHCSR_C_HALT = (1 << 1);
9+ __constant U32 _DHCSR_ADDR = 0xE000EDF0;
10+ __constant U32 _DHCSR_DBGKEY = (0xA05F << 16);
11+ __constant U32 _DHCSR_C_DEBUGEN = (1 << 0);
12+ __constant U32 _DHCSR_C_HALT = (1 << 1);
613
714// Debug Exception and Monitor Control Register
8- __constant U32 _DEMCR_ADDR = 0xE000EDFC;
9- __constant U32 _DEMCR_VC_CORERESET = (1 << 0);
10- __constant U32 _DEMCR_TRCENA = (1 << 24);
15+ __constant U32 _DEMCR_ADDR = 0xE000EDFC;
16+ __constant U32 _DEMCR_VC_CORERESET = (1 << 0);
17+ __constant U32 _DEMCR_TRCENA = (1 << 24);
1118
1219// CPU wait enable register
13- __constant U32 _CPUCONF_CPUWAIT_ADDR = 0x5201150C;
20+ __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C;
21+
22+ // CTRL-AP
23+ __constant U32 _CTRLAP_ID = 4;
24+ __constant U32 _CTRLAP_READY_BANK = 0;
25+ __constant U32 _CTRLAP_READY_OFFSET = 1;
26+ __constant U32 _CTRLAP_READY = 0;
27+ __constant U32 _CTRLAP_MAILBOX_BANK = 1;
28+ __constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0;
29+ __constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1;
30+ __constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2;
31+ __constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3;
32+ __constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0;
33+ __constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1;
34+ __constant int _CTRLAP_TIMEOUT_MS = 500;
35+
36+ // ADAC transaction buffers
37+ static U32 _adacTx[20];
38+ static U32 _adacRx[20];
39+
40+ // Failed to send to the CTRL-AP MAILBOX
41+ __constant int _ERR_TX = -1;
42+ // Failed to receive from the CTRL-AP MAILBOX
43+ __constant int _ERR_RX = -2;
44+ // ADAC command returned an error
45+ __constant int _ERR_REPLY = -3;
46+
47+ // Wait for an AP register read to return the expected value.
48+ int _WaitForDataStatus(U32 regOffset, int expectedStatus)
49+ {
50+ int status;
51+ int ret;
52+ int start;
53+ int elapsed;
54+
55+ status = 0;
56+ start = JLINK_GetTime();
57+ elapsed = 0;
58+
59+ do {
60+ ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status);
61+ elapsed = JLINK_GetTime() - start;
62+ } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS));
63+
64+ if (ret < 0) {
65+ return ret;
66+ }
67+
68+ return status;
69+ }
70+
71+ // Continuously read from the CTRL-AP MAILBOX until there is no more pending data.
72+ void _DrainMailbox(void)
73+ {
74+ int ret;
75+ int status;
76+ int data;
77+
78+ ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status);
79+ while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) {
80+ JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data);
81+ ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status);
82+ }
83+ }
84+
85+ // Perform an ADAC transaction by:
86+ // * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS
87+ // readiness before each write.
88+ // * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before
89+ // each read.
90+ //
91+ // The message to send is read from _adacTx and the reply is written to _adacRx.
92+ // Optionally checks if a single data word is returned and returns an error if it is non-zero.
93+ //
94+ // Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP.
95+ int _DoAdacTransaction(int checkReplyStatus)
96+ {
97+ int numWords;
98+ int ret;
99+ int data;
100+ int i;
101+
102+ i = 0;
103+ numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message
104+
105+ while (i < numWords) {
106+ ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET,
107+ _CTRLAP_MAILBOX_NO_DATA_PENDING);
108+ if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) {
109+ JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ",
110+ ret);
111+ return _ERR_TX;
112+ }
113+
114+ ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]);
115+ if (ret < 0) {
116+ JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret);
117+ return _ERR_TX;
118+ }
119+
120+ i += 1;
121+ }
122+
123+ i = 0;
124+ numWords = 2; // Minimum message length
125+
126+ while (i < numWords) {
127+ ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET,
128+ _CTRLAP_MAILBOX_DATA_PENDING);
129+ if (ret != _CTRLAP_MAILBOX_DATA_PENDING) {
130+ JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret);
131+ return _ERR_RX;
132+ }
133+
134+ ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data);
135+ if (ret < 0) {
136+ JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret);
137+ return _ERR_RX;
138+ }
139+
140+ if (i == 1) {
141+ // Update total length based on the message length field
142+ numWords = 2 + (data >> 2);
143+ }
144+
145+ _adacRx[i] = data;
146+ i += 1;
147+ }
148+
149+ if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) {
150+ JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]);
151+ return _ERR_REPLY;
152+ }
153+
154+ return 0;
155+ }
156+
157+ int ResetTarget(void)
158+ {
159+ int err;
160+ U32 adacMajorVersion;
161+ U32 i;
162+
163+ // Select CTRL-AP bank 0, used for the READY register
164+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0,
165+ (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4));
166+
167+ // Wait for the READY register to indicate that the AP can be used.
168+ err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY);
169+ if (err < 0) {
170+ JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err);
171+ return -1;
172+ }
173+
174+ // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication
175+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0,
176+ (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4));
177+
178+ // Extract any pre-existing data from the mailbox in case there was previously
179+ // an aborted transaction.
180+ _DrainMailbox();
181+
182+ // Read the ADAC version
183+ _adacTx[0] = 0xA3000000; // Command VERSION
184+ _adacTx[1] = 0x00000004; // Data length 4 bytes
185+ _adacTx[2] = 0x00000000; // Type 0 (ADAC version)
186+ err = _DoAdacTransaction(0);
187+ if (err < 0) {
188+ return -1;
189+ }
190+
191+ adacMajorVersion = (_adacRx[2] >> 24) & 0xff;
192+ JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion);
193+
194+ if (adacMajorVersion >= 2) {
195+ // There is a very small chance that this command fails if the domain reset itself
196+ // at the exact same time the command was issued. Therefore we retry a few times.
197+ i = 0;
198+ while (i < 3) {
199+ // Reset non-essential domains
200+ _adacTx[0] = 0xA30A0000; // Command RESET
201+ _adacTx[1] = 0x00000004; // Data length 4 bytes
202+ _adacTx[2] = 0x00000000; // (reserved)
203+ err = _DoAdacTransaction(1);
204+ if (err >= 0) {
205+ break;
206+ } else if (err != _ERR_REPLY) {
207+ return -1;
208+ }
209+
210+ i = i + 1;
211+ }
212+
213+ // Start the core in halted mode
214+ _adacTx[0] = 0xA3090000; // Command START
215+ _adacTx[1] = 0x00000004; // Data length 4 bytes
216+ _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT
217+ err = _DoAdacTransaction(1);
218+ if (err < 0) {
219+ return -1;
220+ }
14221
15- int ResetTarget(void) {
16- // ADAC reset
17- JLINK_CORESIGHT_WriteDP(2, 0x04000010);
18- JLINK_CORESIGHT_WriteAP(0, 0xA3030000);
19- JLINK_CORESIGHT_WriteAP(0, 0x00000004);
20- JLINK_CORESIGHT_WriteAP(0, 0x01020000);
222+ // Start other cores normally (will fail silently if no firmware is present)
223+ i = 0;
224+ while (i < _NUM_OTHER_PROCESSORS) {
225+ _adacTx[0] = 0xA3090000; // Command START
226+ _adacTx[1] = 0x00000004; // Data length 4 bytes
227+ _adacTx[2] = 0x00000000 |
228+ (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags
229+ err = _DoAdacTransaction(0);
230+ if (err < 0 && err != _ERR_REPLY) {
231+ return -1;
232+ }
21233
22- JLINK_SYS_Sleep(100);
23- JLINK_CORESIGHT_ReadAP(2);
24- JLINK_CORESIGHT_ReadAP(2);
25- JLINK_CORESIGHT_ReadAP(2);
26- JLINK_CORESIGHT_ReadAP(2);
234+ i = i + 1;
235+ }
236+ } else {
237+ // Reset single domain via legacy implementation
238+ _adacTx[0] = 0xA3030000; // Command RESET
239+ _adacTx[1] = 0x00000004; // Data length 4 bytes
240+ _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT
241+ err = _DoAdacTransaction(1);
242+ if (err < 0) {
243+ return -1;
244+ }
245+ }
27246
28247 // Halt the CPU
29248 JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN));
@@ -32,7 +251,7 @@ int ResetTarget(void) {
32251 JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA));
33252
34253 // Disable CPU wait
35- JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR , 0);
254+ JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET , 0);
36255
37256 // Clear vector catch stuff
38257 JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA);
0 commit comments