1 /* $Id: dbg_machdep.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
4 * Copyright (c) 2000-2001 Opsycon AB (http://www.opsycon.se)
5 * Copyright (c) 2000-2001 RTMX, Inc (http://www.rtmx.com)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for Rtmx, Inc by
18 * Opsycon Open System Consulting AB, Sweden.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #include <sys/ioctl.h>
45 #include <sys/ioctl.h>
48 #include <machine/cpu.h>
52 #include "mod_debugger.h"
54 extern struct trapframe DBGREG
;
55 extern u_int32_t FPREG
[];
56 extern int memorysize
;
57 extern u_int8_t end
[];
71 * This function clears all client registers for launch.
80 for(i
= 0; i
< 32; i
++) {
88 tf
->srr1
= initial_sr
;
90 savebat(&tf
->batreg
[0]); /* Initially use PMON mapping */
94 * This function sets the client stack pointer.
100 DBGREG
.fixreg
[1] = sp
;
104 * This function sets the client sr to the given value.
114 * ator returns either 32 bit or 64 bit conversion
115 * depending on CPU word length. PPC is for now 32.
123 return(atob((void *)vp
, p
, base
));
127 * This function sets the SP to the new value given if it's
128 * non zero. The old value of sp is returned.
136 oldsp
= DBGREG
.fixreg
[1];
138 DBGREG
.fixreg
[1] = newsp
;
144 * This function returns true if the address range given is
145 * invalid for load, eg will overwrite PMON or its working
146 * areas or other protected memory areas or load into
150 md_valid_load_addr(first_addr
, last_addr
)
154 /* XXX This should be more clever */
155 if((first_addr
< (paddr_t
)end
) || (last_addr
> (paddr_t
)memorysize
)) {
162 * This function sets the arguments to client code so
163 * the client sees the arguments as if it was called
164 * with the arguments.
167 md_setargs(a1
, a2
, a3
, a4
)
173 struct trapframe
*tf
;
190 * This function sets the client sr to do a trace.
199 #if NMOD_DEBUGGER > 0
201 * This function returns the value of the clients sr.
210 * This function sets the client sr to do a trace.
215 DBGREG
.srr1
|= PSL_SE
;
219 * This function returns the PC value that is supposed
220 * to be used at restore to client state. Do not confuse
221 * with the value of the exception PC. (Diff on some arches).
226 return((void *)DBGREG
.srr0
);
230 * This function is called from exception(). It's purpose
231 * is to decode the exception and return the exception
232 * type to the caller for further processing.
236 struct trapframe
*frame
;
239 /* XXX DSI check for DABP */
246 frame
->srr1
&= ~(PSL_SE
| PSL_BE
);
248 case EX_PRGM
: /* Check for BP instruction */
249 if(load_word(md_get_excpc(frame
)) == BPT_CODE
) {
260 * This function returns the value of the PC reg when an
261 * exception have been take.
265 struct trapframe
*frame
;
267 return((void *)frame
->srr0
);
272 struct trapframe
*frame
;
278 return("Machine Check");
284 return("External Interrupt");
292 return("Decrementer");
294 return("System Call");
298 return("FP Assistance");
300 return("Performance Monitor");
302 return("Instruction BP");
304 return("System Management");
309 * This function returns true if the instruction pointed
310 * by 'p' is a subroutine call instruction.
320 * This function returns true if the instruction pointed
321 * by 'p' is a branch type instruction.
331 * Returns true and sets the location pointed by vp to the value
332 * of the specified register or false if not recognized. Register
333 * names can be n the form <regno> r<nr> or sp.
334 * Some special registers are also detected.
345 if(i
>= 0 || i
<= 31) {
346 *vp
= DBGREG
.fixreg
[i
];
350 else if((*p
== 'r' || *p
== 'R') && isdigit(*(p
+1))) {
352 if(i
>= 0 || i
<= 31) {
353 *vp
= DBGREG
.fixreg
[i
];
357 else if(strcmp(p
, "cpc") == 0) {
361 else if(strcmp(p
, "sr") == 0) {
379 if(i
>= 0 || i
<= 31) {
380 *r
= (register_t
*)&DBGREG
.fixreg
[i
];
384 else if((*p
== 'r' || *p
== 'R') && isdigit(*(p
+1))) {
386 if(i
>= 0 || i
<= 31) {
387 *r
= (register_t
*)&DBGREG
.fixreg
[i
];
391 else if((*p
== 'f' || *p
== 'F') && isdigit(*(p
+1))) {
393 if(i
>= 0 || i
<= 31) {
394 *r
= (register_t
*)&FPREG
[i
+i
];
398 else if(strcmp(p
, "cpc") == 0) {
399 *r
= (register_t
*)&DBGREG
.srr0
;
402 else if(strcmp(p
, "sr") == 0) {
403 *r
= (register_t
*)&DBGREG
.srr1
;
406 else if(strcmp(p
, "fsr") == 0) {
407 *r
= (register_t
*)&FPREG
[64];
410 else if(strcmp(p
, "lr") == 0) {
411 *r
= (register_t
*)&DBGREG
.lr
;
414 else if(strcmp(p
, "ctr") == 0) {
415 *r
= (register_t
*)&DBGREG
.ctr
;
425 md_disp_as_reg(r
, c
, w
)
433 const Optdesc md_r_opts
[] = {
434 {"*", "display all registers"},
435 {"r*", "display all general registers"},
436 {"f*", "display all fp registers"},
437 {"reg value", "set specified register"},
446 for(regno
= 0; regno
< 32; regno
++) {
447 if((regno
% 8) == 0) {
448 printf("\nr%02d-%02d ", regno
, regno
+ 7);
450 printf(" %08x", DBGREG
.fixreg
[regno
]);
460 for(regno
= 0; regno
< 32; regno
++) {
461 if((regno
% 4) == 0) {
462 printf("\nf%02d-%02d ", regno
, regno
+ 3);
464 printf(" %08x%08x", FPREG
[regno
*2], FPREG
[regno
*2+1]);
467 printf("fsr = %08x%08x\n", FPREG
[64], FPREG
[65]);
471 * Machine dependent register display/modify code.
481 ioctl(STDIN
, CBREAK
, NULL
);
484 case 1: /* No args, display general registers */
489 if(strcmp(av
[1], "*") == 0) {
492 printf("cpc = %08x, lr = %08x, ctr = %08x, sr = %08x\n",
493 DBGREG
.srr0
, DBGREG
.lr
, DBGREG
.ctr
, DBGREG
.srr1
);
495 else if(strcmp(av
[1], "r*") == 0) {
498 else if(strcmp(av
[1], "f*") == 0) {
502 if(md_getregaddr(&rp
, av
[1])) {
503 printf("%s = %08x\n", av
[1], *rp
);
506 printf("%s: unkown.\n", av
[1]);
513 if(md_getregaddr(&rp
, av
[1]) == 0) {
514 printf("%s: unkown.\n", av
[1]);
517 if(!get_rsa_reg(&rn
, av
[2])) {
527 #endif /* NMOD_DEBUGGER */