1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19: 20:
21:
22: #include "../cmdsvc.h"
23: #include <sys/sysinfo.h>
24:
25: EXPORT UW regStack[39 + 10 + 2];
26:
27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
52:
53: #define L_REGNM 8
54: typedef struct {
55: UB name[L_REGNM];
56: UW id;
57: } REGTAB;
58:
59: #define R_GEN 0x001000
60: #define R_CTL 0x002000
61: #define R_GRP 0x010000
62:
63: #define R_LF 0x080000
64: #define R_GAP 0x040000
65:
66: #define R_ONLY 0x100
67: #define SPEC(n) (0x200 | (n))
68:
69: #define ixCPSR 10
70: #define ixPC 11
71:
72: #define ixUSR 12
73: #define ixFIQ (19 + 1)
74: #define ixIRQ (27 - 4)
75: #define ixABT (30 - 4)
76: #define ixUND (33 - 4)
77: #define ixSVC (36 - 4)
78: #define ixSP_SVC (ixSVC + 5)
79:
80: #define ixCP15 39
81: #define ixCP15R1 (ixCP15 + 0)
82:
83: #define N_ACTREGS (16 + 7 + 7 + 8 + 7 + 10)
84: #define N_REGS (N_ACTREGS + 3)
85:
86: LOCAL const REGTAB regTab[N_REGS] = {
87: {"R0 ", R_GEN + 0x00 },
88: {"R1 ", R_GEN + 0x01 },
89: {"R2 ", R_GEN + 0x02 },
90: {"R3 ", R_GEN + 0x03 + R_LF },
91: {"R4 ", R_GEN + 0x04 },
92: {"R5 ", R_GEN + 0x05 },
93: {"R6 ", R_GEN + 0x06 },
94: {"R7 ", R_GEN + 0x07 + R_LF },
95: {"R8 ", R_GEN + SPEC(0x00) },
96: {"R9 ", R_GEN + SPEC(0x01) },
97: {"R10/SL ", R_GEN + SPEC(0x02) },
98: {"R11/FP ", R_GEN + SPEC(0x03) + R_LF },
99: {"R12/IP ", R_GEN + SPEC(0x04) },
100: {"R13/SP ", R_GEN + SPEC(0x05) },
101: {"R14/LR ", R_GEN + SPEC(0x06) },
102: {"R15/PC ", R_GEN + ixPC + R_LF },
103:
104: {"R8_USR ", R_GEN + ixUSR + 0 + R_GAP },
105: {"R9_USR ", R_GEN + ixUSR + 1 },
106: {"R10_USR ", R_GEN + ixUSR + 2 },
107: {"R11_USR ", R_GEN + ixUSR + 3 + R_LF },
108: {"R12_USR ", R_GEN + ixUSR + 4 },
109: {"R13_USR ", R_GEN + ixUSR + 5 },
110: {"R14_USR ", R_GEN + ixUSR + 6 + R_LF },
111:
112: {"R8_FIQ ", R_GEN + ixFIQ + 0 },
113: {"R9_FIQ ", R_GEN + ixFIQ + 1 },
114: {"R10_FIQ ", R_GEN + ixFIQ + 2 },
115: {"R11_FIQ ", R_GEN + ixFIQ + 3 + R_LF },
116: {"R12_FIQ ", R_GEN + ixFIQ + 4 },
117: {"R13_FIQ ", R_GEN + ixFIQ + 5 },
118: {"R14_FIQ ", R_GEN + ixFIQ + 6 + R_LF },
119:
120: {"R13_IRQ ", R_GEN + ixIRQ + 5 },
121: {"R14_IRQ ", R_GEN + ixIRQ + 6 },
122: {"R13_SVC ", R_GEN + ixSVC + 5 },
123: {"R14_SVC ", R_GEN + ixSVC + 6 + R_LF },
124: {"R13_ABT ", R_GEN + ixABT + 5 },
125: {"R14_ABT ", R_GEN + ixABT + 6 },
126: {"R13_UND ", R_GEN + ixUND + 5 },
127: {"R14_UND ", R_GEN + ixUND + 6 + R_LF },
128:
129: {"CPSR ", R_CTL + ixCPSR + R_GAP },
130: {"SPSR ", R_CTL + SPEC(0x08) },
131: {"SPSR_FIQ", R_CTL + ixFIQ - 1 },
132: {"SPSR_IRQ", R_CTL + ixIRQ + 4 + R_LF },
133: {"SPSR_SVC", R_CTL + ixSVC + 4 },
134: {"SPSR_ABT", R_CTL + ixABT + 4 },
135: {"SPSR_UND", R_CTL + ixUND + 4 + R_LF },
136:
137: {"SCTLR ", R_CTL + SPEC(0x0F) + 0 + R_GAP },
138: {"TTBR0 ", R_CTL + ixCP15 + 1 + R_ONLY },
139: {"TTBR1 ", R_CTL + ixCP15 + 2 + R_ONLY },
140: {"TTBCR ", R_CTL + ixCP15 + 3 + R_ONLY + R_LF},
141: {"DACR ", R_CTL + ixCP15 + 4 },
142: {"DFSR ", R_CTL + ixCP15 + 5 },
143: {"IFSR ", R_CTL + ixCP15 + 6 },
144: {"DFAR ", R_CTL + ixCP15 + 7 + R_LF },
145: {"IFAR ", R_CTL + ixCP15 + 8 },
146: {"CTXIDR ", R_CTL + ixCP15 + 9 + R_LF },
147:
148: {"G ", R_GRP|R_GEN },
149: {"C ", R_GRP|R_CTL },
150: {"A ", R_GRP|R_GEN|R_CTL },
151: };
152: 153: 154:
155: EXPORT W searchRegister(UB *name, W grp)
156: {
157: W i, n, a;
158: UB bf[L_REGNM];
159: REGTAB *p;
160:
161: if (name[L_REGNM] != ' ') return -1;
162:
163: for (p = (REGTAB*)regTab, i = 0; i < N_REGS; p++, i++) {
164: for (n = 0; n < L_REGNM; n++) if (p->name[n] == '/') break;
165: if (n == L_REGNM) {
166: if (memcmp(name, p->name, L_REGNM)) continue;
167: } else {
168:
169: memset(bf, ' ', sizeof(bf));
170: memcpy(bf, p->name + (n + 1), L_REGNM - (n + 1));
171: a = memcmp(name, bf, L_REGNM - n);
172:
173:
174: memset(bf, ' ', sizeof(bf));
175: memcpy(bf, p->name, n);
176: if (a && memcmp(name, bf, n + 1)) continue;
177: }
178: if (grp == 0 && (p->id & R_GRP)) break;
179: return i;
180: }
181: return -1;
182: }
183: 184: 185:
186: LOCAL W ixCpuMode(void)
187: {
188:
189: switch(regStack[ixCPSR] & PSR_M(31)) {
190: case PSR_USR:
191: case PSR_SYS: return ixUSR;
192: case PSR_FIQ: return ixFIQ;
193: case PSR_IRQ: return ixIRQ;
194: case PSR_SVC: return ixSVC;
195: case PSR_ABT: return ixABT;
196: case PSR_UND: return ixUND;
197: }
198: return 0;
199: }
200: 201: 202:
203: EXPORT UW getRegister(W regno)
204: {
205: W i, ix;
206:
207: i = regTab[regno].id & (R_GRP | 0x3ff);
208:
209:
210: if (i < SPEC(0)) return regStack[i & 0xff];
211:
212:
213: ix = ixCpuMode();
214:
215:
216: switch(i) {
217: case SPEC(0x00):
218: case SPEC(0x01):
219: case SPEC(0x02):
220: case SPEC(0x03):
221: case SPEC(0x04):
222: if (ix != ixFIQ) ix = ixUSR;
223: case SPEC(0x05):
224: case SPEC(0x06):
225: return regStack[ix + i - SPEC(0)];
226: case SPEC(0x08):
227: if (ix == ixUSR) return 0;
228: if (ix == ixFIQ) ix -= 5;
229: return regStack[ix + 4];
230: case SPEC(0x0F):
231: return regStack[ixCP15R1];
232: }
233:
234: return 0;
235: }
236: 237: 238:
239: EXPORT ER setRegister(W regno, UW val)
240: {
241: W i, ix;
242:
243: i = regTab[regno].id & (R_GRP | 0x3ff);
244: if (i & R_ONLY) return E_RONLY;
245:
246: if (i < SPEC(0)) {
247: regStack[i & 0xff] = val;
248: return 0;
249: }
250:
251:
252: ix = ixCpuMode();
253:
254:
255: switch(i) {
256: case SPEC(0x00):
257: case SPEC(0x01):
258: case SPEC(0x02):
259: case SPEC(0x03):
260: case SPEC(0x04):
261: if (ix != ixFIQ) ix = ixUSR;
262: case SPEC(0x05):
263: case SPEC(0x06):
264: regStack[ix + i - SPEC(0x00)] = val;
265: break;
266: case SPEC(0x08):
267: if (ix == ixUSR) break;
268: if (ix == ixFIQ) ix -= 5;
269: regStack[ix + 4] = val;
270: break;
271: case SPEC(0x0F):
272: regStack[ixCP15R1] &= MASK_CACHEMMU;
273: regStack[ixCP15R1] |= val & VALID_CACHEMMU;
274: break;
275: default:
276: return E_PAR;
277: }
278: return 0;
279: }
280: 281: 282: 283:
284: EXPORT void dispRegister(W regno)
285: {
286: W i, j, n, id, rid;
287:
288: if (regno >= N_REGS) return;
289:
290: id = (regno < 0) ? (R_GRP | R_GEN) : regTab[regno].id;
291:
292: for (n = i = 0; i < N_ACTREGS; i++) {
293: rid = regTab[i].id;
294: if (!(i == regno || ((id & R_GRP) && (rid & id)))) continue;
295: if (n != 0 && (rid & R_GAP)) DSP_LF;
296: if (n++ & 0x0f) DSP_S(" ");
297: for (j = 0; j < L_REGNM; j++) DSP_CH(regTab[i].name[j]);
298: DSP_F2(S,": ", 08X,getRegister(i));
299: if (rid & R_LF) {DSP_LF; n = 0x10;}
300: if ((id & R_GRP) == 0) break;
301: }
302: if (n & 0x0f) DSP_LF;
303: }
304: 305: 306:
307: EXPORT UW getCurCPSR(void)
308: {
309: return regStack[ixCPSR];
310: }
311: 312: 313:
314: EXPORT UW getCurSPSR(void)
315: {
316: return getRegister(39);
317: }
318: 319: 320:
321: EXPORT UW getCurPC(void)
322: {
323:
324: return regStack[ixPC] | ((regStack[ixCPSR] & PSR_T) ? 1 : 0);
325: }
326: EXPORT UW getCurPCX(void)
327: {
328: return regStack[ixPC];
329: }
330: EXPORT UW getCP15(W reg, W opcd)
331: {
332: W i, d;
333: LOCAL const UH reg_op[] = {
334: 0x1000, 0x2000, 0x2001, 0x2002, 0x3000, 0x5000, 0x5001, 0x6000,
335: 0x6002, 0xd001,
336: };
337:
338: d = ((reg & 0x0f) << 12) | (opcd & 0x0fff);
339:
340: for (i = 0; i < sizeof(reg_op) / sizeof(UH); i++) {
341: if (reg_op[i] == d) return regStack[ixCP15 + i];
342: }
343: return 0;
344: }
345: 346: 347:
348: EXPORT void setCurPC(UW val)
349: {
350: if (regStack[ixPC] != val) {
351:
352: if (val & 0x3) regStack[ixCPSR] |= PSR_T;
353: else regStack[ixCPSR] &= ~PSR_T;
354: regStack[ixPC] = val & ~0x1;
355: }
356: }
357: EXPORT void setCurPCX(UW val)
358: {
359:
360: regStack[ixPC] = val & ~0x1;
361: }
362: 363: 364:
365: EXPORT void setUpBoot( void *start, BootInfo *bootinfo )
366: {
367: bootFlag = 1;
368:
369: regStack[ixCPSR] = PSR_I | PSR_F | PSR_SVC;
370: regStack[0] = (UW)bootinfo;
371: regStack[ixPC] = (UW)start;
372: regStack[ixSP_SVC] = (UW)&__stack_bottom;
373:
374:
375: regStack[ixCP15R1] &= MASK_CACHEMMU;
376: regStack[ixCP15R1] |= ENB_MMUONLY;
377:
378:
379: resetSystem(1);
380: }
381: 382: 383:
384: EXPORT W isKillValid(void)
385: {
386:
387: if ( SCArea->intvec[SWI_KILLPROC] == NULL ) return -1;
388: return 0;
389: }
390:
391: #if REF_TKOBJECT
392: 393: 394:
395: EXPORT W isTKDSValid(void)
396: {
397:
398: if ( SCArea->intvec[SWI_DEBUG] == NULL ) return -1;
399: return 0;
400: }
401:
402: 403: 404:
405: EXPORT W PrintTaskRegister( int (*prfn)( const char *format, ... ),
406: T_REGS *gr, T_EIT *er, T_CREGS *cr )
407: {
408: 409: 410: 411: 412: 413: 414: 415:
416: (*prfn)("PC: %08x CPSR:%08x TMF:%08x\n",
417: (UW)er->pc, er->cpsr, er->taskmode);
418: (*prfn)("R0: %08x R1: %08x R2: %08x R3: %08x\n",
419: gr->r[0], gr->r[1], gr->r[2], gr->r[3]);
420: (*prfn)("R4: %08x R5: %08x R6: %08x R7: %08x\n",
421: gr->r[4], gr->r[5], gr->r[6], gr->r[7]);
422: (*prfn)("R8: %08x R9: %08x R10:%08x R11:%08x\n",
423: gr->r[8], gr->r[9], gr->r[10], gr->r[11]);
424: (*prfn)("IP: %08x LR: %08x\n",
425: gr->r[12], (UW)gr->lr);
426: (*prfn)("USP:%08x SSP:%08x LSID:%-4d UATB:%08x\n",
427: (UW)cr->usp, (UW)cr->ssp, cr->lsid, (UW)cr->uatb);
428: return 6;
429: }
430: #endif