Annotation of XNU/osfmk/kdp/ml/ppc/kdp_machdep.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1997 Apple Computer, Inc.  All rights reserved.
                     24:  * Copyright (c) 1994 NeXT Computer, Inc.  All rights reserved.
                     25:  *
                     26:  * machdep/ppc/kdp_machdep.c
                     27:  *
                     28:  * Machine-dependent code for Remote Debugging Protocol
                     29:  *
                     30:  * March, 1997 Created.        Umesh Vaishampayan [[email protected]]
                     31:  *
                     32:  */
                     33:  
                     34: #include <mach/mach_types.h>
                     35: #include <mach/exception_types.h>
                     36: #include <ppc/exception.h>
                     37: #include <ppc/proc_reg.h>
                     38: #include <kdp/kdp_internal.h>
                     39: #include <ppc/savearea.h>
                     40: #include <kern/debug.h>
                     41: 
                     42: #define KDP_TEST_HARNESS 0
                     43: #if KDP_TEST_HARNESS
                     44: #define dprintf(x) kprintf x
                     45: #else
                     46: #define dprintf(x)
                     47: #endif
                     48: 
                     49: void print_saved_state(void *);
                     50: void kdp_call(void);
                     51: void kdp_trap( unsigned int, struct ppc_thread_state *);
                     52: int kdp_getc(void);
                     53: boolean_t kdp_call_kdb(void);
                     54: 
                     55: void
                     56: kdp_exception(
                     57:     unsigned char      *pkt,
                     58:     int        *len,
                     59:     unsigned short     *remote_port,
                     60:     unsigned int       exception,
                     61:     unsigned int       code,
                     62:     unsigned int       subcode
                     63: )
                     64: {
                     65:     struct {
                     66:        kdp_exception_t pkt;
                     67:        kdp_exc_info_t  exc;
                     68:     }                  aligned_pkt;
                     69:     kdp_exception_t    *rq = (kdp_exception_t *)&aligned_pkt;
                     70: 
                     71:     bcopy((char *)pkt, (char *)rq, sizeof(*rq));
                     72:     rq->hdr.request = KDP_EXCEPTION;
                     73:     rq->hdr.is_reply = 0;
                     74:     rq->hdr.seq = kdp.exception_seq;
                     75:     rq->hdr.key = 0;
                     76:     rq->hdr.len = sizeof (*rq) + sizeof(kdp_exc_info_t);
                     77:     
                     78:     rq->n_exc_info = 1;
                     79:     rq->exc_info[0].cpu = 0;
                     80:     rq->exc_info[0].exception = exception;
                     81:     rq->exc_info[0].code = code;
                     82:     rq->exc_info[0].subcode = subcode;
                     83:     
                     84:     rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
                     85:     
                     86:     bcopy((char *)rq, (char *)pkt, rq->hdr.len);
                     87: 
                     88:     kdp.exception_ack_needed = TRUE;
                     89:     
                     90:     *remote_port = kdp.exception_port;
                     91:     *len = rq->hdr.len;
                     92: }
                     93: 
                     94: boolean_t
                     95: kdp_exception_ack(
                     96:     unsigned char      *pkt,
                     97:     int                        len
                     98: )
                     99: {
                    100:     kdp_exception_ack_t        aligned_pkt;
                    101:     kdp_exception_ack_t        *rq = (kdp_exception_ack_t *)&aligned_pkt;
                    102: 
                    103:     if (len < sizeof (*rq))
                    104:        return(FALSE);
                    105:        
                    106:     bcopy((char *)pkt, (char *)rq, sizeof(*rq));
                    107: 
                    108:     if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
                    109:        return(FALSE);
                    110:        
                    111:     dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
                    112:        
                    113:     if (rq->hdr.seq == kdp.exception_seq) {
                    114:        kdp.exception_ack_needed = FALSE;
                    115:        kdp.exception_seq++;
                    116:     }
                    117:     return(TRUE);
                    118: }
                    119: 
                    120: static void
                    121: kdp_getintegerstate(
                    122:     struct ppc_thread_state            *state
                    123: )
                    124: {
                    125:     struct ppc_thread_state    *saved_state;
                    126:    
                    127:     saved_state = kdp.saved_state;
                    128:    
                    129:     bzero((char *)state,sizeof (struct ppc_thread_state)) ;
                    130: 
                    131:     state->srr0        = saved_state->srr0;
                    132:     state->srr1        = saved_state->srr1;
                    133:     state->r0  = saved_state->r0;
                    134:     state->r1  = saved_state->r1;
                    135:     state->r2  = saved_state->r2;
                    136:     state->r3  = saved_state->r3;
                    137:     state->r4  = saved_state->r4;
                    138:     state->r5  = saved_state->r5;
                    139:     state->r6  = saved_state->r6;
                    140:     state->r7  = saved_state->r7;
                    141:     state->r8  = saved_state->r8;
                    142:     state->r9  = saved_state->r9;
                    143:     state->r10 = saved_state->r10;
                    144:     state->r11 = saved_state->r11;
                    145:     state->r12 = saved_state->r12;
                    146:     state->r13 = saved_state->r13;
                    147:     state->r14 = saved_state->r14;
                    148:     state->r15 = saved_state->r15;
                    149:     state->r16 = saved_state->r16;
                    150:     state->r17 = saved_state->r17;
                    151:     state->r18 = saved_state->r18;
                    152:     state->r19 = saved_state->r19;
                    153:     state->r20 = saved_state->r20;
                    154:     state->r21 = saved_state->r21;
                    155:     state->r22 = saved_state->r22;
                    156:     state->r23 = saved_state->r23;
                    157:     state->r24 = saved_state->r24;
                    158:     state->r25 = saved_state->r25;
                    159:     state->r26 = saved_state->r26;
                    160:     state->r27 = saved_state->r27;
                    161:     state->r28 = saved_state->r28;
                    162:     state->r29 = saved_state->r29;
                    163:     state->r30 = saved_state->r30;
                    164:     state->r31 = saved_state->r31;
                    165:     state->cr  = saved_state->cr;
                    166:     state->xer = saved_state->xer;
                    167:     state->lr  = saved_state->lr;
                    168:     state->ctr = saved_state->ctr;
                    169:     state->mq  = saved_state->mq; /* This is BOGUS ! (601) ONLY */
                    170: }
                    171: 
                    172: kdp_error_t
                    173: kdp_machine_read_regs(
                    174:     unsigned int cpu,
                    175:     unsigned int flavor,
                    176:     char *data,
                    177:     int *size
                    178: )
                    179: {
                    180:     switch (flavor) {
                    181: 
                    182:     case PPC_THREAD_STATE:
                    183:                dprintf(("kdp_readregs THREAD_STATE\n"));
                    184:                kdp_getintegerstate((struct ppc_thread_state *)data);
                    185:                *size = PPC_THREAD_STATE_COUNT * sizeof(int);
                    186:                return KDPERR_NO_ERROR;
                    187:        
                    188:     case PPC_FLOAT_STATE:
                    189:                dprintf(("kdp_readregs THREAD_FPSTATE\n"));
                    190:                bzero((char *)data ,sizeof(struct ppc_float_state));    
                    191:                *size = PPC_FLOAT_STATE_COUNT * sizeof(int);
                    192:                return KDPERR_NO_ERROR;
                    193:        
                    194:     default:
                    195:                dprintf(("kdp_readregs bad flavor %d\n"));
                    196:                return KDPERR_BADFLAVOR;
                    197:     }
                    198: }
                    199: 
                    200: static void
                    201: kdp_setintegerstate(
                    202:     struct ppc_thread_state            *state
                    203: )
                    204: {
                    205:     struct ppc_thread_state    *saved_state;
                    206:    
                    207:     saved_state = kdp.saved_state;
                    208: 
                    209:     saved_state->srr0  = state->srr0;
                    210:     saved_state->srr1  = state->srr1;
                    211:     saved_state->r0    = state->r0;
                    212:     saved_state->r1    = state->r1;
                    213:     saved_state->r2    = state->r2;
                    214:     saved_state->r3    = state->r3;
                    215:     saved_state->r4    = state->r4;
                    216:     saved_state->r5    = state->r5;
                    217:     saved_state->r6    = state->r6;
                    218:     saved_state->r7    = state->r7;
                    219:     saved_state->r8    = state->r8;
                    220:     saved_state->r9    = state->r9;
                    221:     saved_state->r10   = state->r10;
                    222:     saved_state->r11   = state->r11;
                    223:     saved_state->r12   = state->r12;
                    224:     saved_state->r13   = state->r13;
                    225:     saved_state->r14   = state->r14;
                    226:     saved_state->r15   = state->r15;
                    227:     saved_state->r16   = state->r16;
                    228:     saved_state->r17   = state->r17;
                    229:     saved_state->r18   = state->r18;
                    230:     saved_state->r19   = state->r19;
                    231:     saved_state->r20   = state->r20;
                    232:     saved_state->r21   = state->r21;
                    233:     saved_state->r22   = state->r22;
                    234:     saved_state->r23   = state->r23;
                    235:     saved_state->r24   = state->r24;
                    236:     saved_state->r25   = state->r25;
                    237:     saved_state->r26   = state->r26;
                    238:     saved_state->r27   = state->r27;
                    239:     saved_state->r28   = state->r28;
                    240:     saved_state->r29   = state->r29;
                    241:     saved_state->r30   = state->r30;
                    242:     saved_state->r31   = state->r31;
                    243:     saved_state->cr    = state->cr;
                    244:     saved_state->xer   = state->xer;
                    245:     saved_state->lr    = state->lr;
                    246:     saved_state->ctr   = state->ctr;
                    247:     saved_state->mq    = state->mq; /* BOGUS! (601)ONLY */
                    248: }
                    249: 
                    250: kdp_error_t
                    251: kdp_machine_write_regs(
                    252:     unsigned int cpu,
                    253:     unsigned int flavor,
                    254:     char *data,
                    255:     int *size
                    256: )
                    257: {
                    258:     switch (flavor) {
                    259: 
                    260:     case PPC_THREAD_STATE:
                    261:                dprintf(("kdp_writeregs THREAD_STATE\n"));
                    262:                kdp_setintegerstate((struct ppc_thread_state *)data);
                    263: 
                    264: #if KDP_TEST_HARNESS
                    265:                DumpTheSave((struct savearea *)data);           /* (TEST/DEBUG) */
                    266: #endif
                    267:                return KDPERR_NO_ERROR;
                    268:        
                    269:     case PPC_FLOAT_STATE:
                    270:                dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
                    271:                return KDPERR_NO_ERROR;
                    272:        
                    273:     default:
                    274:                dprintf(("kdp_writeregs bad flavor %d\n"));
                    275:                return KDPERR_BADFLAVOR;
                    276:     }
                    277: }
                    278: 
                    279: void
                    280: kdp_machine_hostinfo(
                    281:     kdp_hostinfo_t *hostinfo
                    282: )
                    283: {
                    284:     machine_slot_t     m;
                    285:     int                        i;
                    286: 
                    287:     hostinfo->cpus_mask = 0;
                    288: 
                    289:     for (i = 0; i < machine_info.max_cpus; i++) {
                    290:         m = &machine_slot[i];
                    291:         if (!m->is_cpu)
                    292:             continue;
                    293:        
                    294:         hostinfo->cpus_mask |= (1 << i);
                    295:         if (hostinfo->cpu_type == 0) {
                    296:             hostinfo->cpu_type = m->cpu_type;
                    297:             hostinfo->cpu_subtype = m->cpu_subtype;
                    298:         }
                    299:     }
                    300: }
                    301: 
                    302: void
                    303: kdp_panic(
                    304:     const char         *msg
                    305: )
                    306: {
                    307:     printf("kdp panic: %s\n", msg);    
                    308:     while(1) {}
                    309: }
                    310: 
                    311: 
                    312: void
                    313: kdp_reboot(void)
                    314: {
                    315:        halt_all_cpus(TRUE);;
                    316: }
                    317: 
                    318: int
                    319: kdp_intr_disbl(void)
                    320: {
                    321:     return (splhigh());
                    322: }
                    323: 
                    324: void
                    325: kdp_intr_enbl(int s)
                    326: {
                    327:     splx(s);
                    328: }
                    329: 
                    330: void
                    331: kdp_us_spin(int usec)
                    332: {
                    333:     extern void delay(int);
                    334: 
                    335:     delay(usec/100);
                    336: }
                    337: 
                    338: void print_saved_state(void *state)
                    339: {
                    340:     struct ppc_thread_state    *saved_state;
                    341: 
                    342:     saved_state = state;
                    343: 
                    344:        printf("pc = 0x%x\n", saved_state->srr0);
                    345:        printf("msr = 0x%x\n", saved_state->srr1);
                    346:        printf("rp = 0x%x\n", saved_state->lr);
                    347:        printf("sp = 0x%x\n", saved_state->r1);
                    348: 
                    349: }
                    350: 
                    351: void
                    352: kdp_call()
                    353: {
                    354:        Debugger("inline call to debugger(machine_startup)");
                    355: }
                    356: 
                    357: /*
                    358:  * table to convert system specific code to generic codes for kdb
                    359:  */
                    360: int kdp_trap_codes[] = {
                    361:        EXC_BAD_ACCESS, /* 0x0000  INVALID EXCEPTION */
                    362:        EXC_BAD_ACCESS, /* 0x0100  System reset */
                    363:        EXC_BAD_ACCESS, /* 0x0200  Machine check */
                    364:        EXC_BAD_ACCESS, /* 0x0300  Data access */
                    365:        EXC_BAD_ACCESS, /* 0x0400  Instruction access */
                    366:        EXC_BAD_ACCESS, /* 0x0500  External interrupt */
                    367:        EXC_BAD_ACCESS, /* 0x0600  Alignment */
                    368:        EXC_BREAKPOINT, /* 0x0700  Program - fp exc, ill/priv instr, trap */
                    369:        EXC_ARITHMETIC, /* 0x0800  Floating point disabled */
                    370:        EXC_SOFTWARE,   /* 0x0900  Decrementer */
                    371:        EXC_BAD_ACCESS, /* 0x0A00  I/O controller interface */
                    372:        EXC_BAD_ACCESS, /* 0x0B00  INVALID EXCEPTION */
                    373:        EXC_SOFTWARE,   /* 0x0C00  System call exception */
                    374:        EXC_BREAKPOINT, /* 0x0D00  Trace */
                    375:        EXC_SOFTWARE,   /* 0x0E00  FP assist */
                    376:        EXC_SOFTWARE,   /* 0x0F00  Performance monitoring */
                    377:        EXC_ARITHMETIC, /* 0x0F20  Altivec disabled */
                    378:        EXC_BAD_ACCESS, /* 0x1000  Instruction PTE miss */
                    379:        EXC_BAD_ACCESS, /* 0x1100  Data load PTE miss */
                    380:        EXC_BAD_ACCESS, /* 0x1200  Data store PTE miss */
                    381:        EXC_BREAKPOINT, /* 0x1300  Instruction bkpt */
                    382:        EXC_SOFTWARE,   /* 0x1400  System management */
                    383:        EXC_BAD_ACCESS, /* 0x1500  INVALID EXCEPTION */
                    384:        EXC_ARITHMETIC, /* 0x1600  Altivec Assist */
                    385:        EXC_BAD_ACCESS, /* 0x1700  INVALID EXCEPTION */
                    386:        EXC_BAD_ACCESS, /* 0x1800  INVALID EXCEPTION */
                    387:        EXC_BAD_ACCESS, /* 0x1900  INVALID EXCEPTION */
                    388:        EXC_BAD_ACCESS, /* 0x1A00  INVALID EXCEPTION */
                    389:        EXC_BAD_ACCESS, /* 0x1B00  INVALID EXCEPTION */
                    390:        EXC_BAD_ACCESS, /* 0x1C00  INVALID EXCEPTION */
                    391:        EXC_BAD_ACCESS, /* 0x1D00  INVALID EXCEPTION */
                    392:        EXC_BAD_ACCESS, /* 0x1E00  INVALID EXCEPTION */
                    393:        EXC_BAD_ACCESS, /* 0x1F00  INVALID EXCEPTION */
                    394:        EXC_BREAKPOINT, /* 0x2000  Run Mode/Trace */
                    395:        EXC_BAD_ACCESS, /* 0x2100  INVALID EXCEPTION */
                    396:        EXC_BAD_ACCESS, /* 0x2200  INVALID EXCEPTION */
                    397:        EXC_BAD_ACCESS, /* 0x2300  INVALID EXCEPTION */
                    398:        EXC_BAD_ACCESS, /* 0x2400  INVALID EXCEPTION */
                    399:        EXC_BAD_ACCESS, /* 0x2500  INVALID EXCEPTION */
                    400:        EXC_BAD_ACCESS, /* 0x2600  INVALID EXCEPTION */
                    401:        EXC_BAD_ACCESS, /* 0x2700  INVALID EXCEPTION */
                    402:        EXC_BAD_ACCESS, /* 0x2800  INVALID EXCEPTION */
                    403:        EXC_BAD_ACCESS, /* 0x2900  INVALID EXCEPTION */
                    404:        EXC_BAD_ACCESS, /* 0x2A00  INVALID EXCEPTION */
                    405:        EXC_BAD_ACCESS, /* 0x2B00  INVALID EXCEPTION */
                    406:        EXC_BAD_ACCESS, /* 0x2C00  INVALID EXCEPTION */
                    407:        EXC_BAD_ACCESS, /* 0x2D00  INVALID EXCEPTION */
                    408:        EXC_BAD_ACCESS, /* 0x2E00  INVALID EXCEPTION */
                    409:        EXC_BAD_ACCESS, /* 0x2F00  INVALID EXCEPTION */
                    410:        EXC_SOFTWARE    /* 0x3000  AST trap (software) */
                    411: };
                    412: 
                    413: int
                    414: kdp_getc()
                    415: {
                    416:        return(cnmaygetc());
                    417: }
                    418: 
                    419: int kdp_backtrace;
                    420: int kdp_sr_dump;
                    421: int kdp_dabr;
                    422: int kdp_noisy;
                    423: 
                    424: #define kdp_code(x) kdp_trap_codes[((x)==T_AST?0x31:(x)/T_VECTOR_SIZE)]
                    425: 
                    426: void
                    427: kdp_trap(
                    428:     unsigned int               exception,
                    429:     struct ppc_thread_state    *saved_state
                    430: )
                    431: {
                    432:        unsigned int *fp;
                    433:         unsigned int register sp;
                    434:        struct ppc_thread_state *state;
                    435: 
                    436:        if (kdp_noisy) {
                    437:                if (kdp_backtrace) {
                    438:                        printf("\nvector=%x, \n", exception/4);
                    439: #ifdef XXX
                    440:                        regDump(saved_state);
                    441: #endif
                    442:                        sp = saved_state->r1;
                    443:                        printf("stack backtrace - sp(%x)  ", sp);
                    444:                        fp = (unsigned int *) *((unsigned int *)sp);
                    445:                        while (fp) {
                    446:                                printf("0x%08x ", fp[2]);
                    447:                                fp = (unsigned int *)*fp;
                    448:                        }
                    449:                        printf("\n");
                    450:                }
                    451: #ifdef XXX
                    452:                if (kdp_sr_dump) {
                    453:                        dump_segment_registers();
                    454:                }
                    455: #endif
                    456:        
                    457:        printf("vector=%d  ", exception/4);
                    458:        }
                    459: 
                    460:        kdp_raise_exception(kdp_code(exception), 0, 0, saved_state);
                    461: 
                    462:        if (kdp_noisy)
                    463:                printf("kdp_trap: kdp_raise_exception() ret\n");
                    464: 
                    465:        if (*((int *)saved_state->srr0) == 0x7c800008)
                    466:                saved_state->srr0 += 4; /* BKPT_SIZE */
                    467:                
                    468:        if(saved_state->srr1 & (MASK(MSR_SE) | MASK(MSR_BE))) { /* Are we just stepping or continuing */
                    469:                db_run_mode = STEP_ONCE;                                /* We are stepping */
                    470:        }
                    471:        else db_run_mode = STEP_CONTINUE;                       /* Otherwise we are continuing */
                    472: 
                    473: 
                    474: #ifdef XXX
                    475:        mtspr(dabr, kdp_dabr);
                    476: #endif
                    477: }
                    478: 
                    479: boolean_t 
                    480: kdp_call_kdb(
                    481:        void)
                    482: {
                    483:        switch_debugger=1;
                    484:        return(TRUE);
                    485: }
                    486: 
                    487: void kdp_print_registers(struct ppc_saved_state *state)
                    488: {
                    489:        int i;
                    490:        for (i=0; i<32; i++) {
                    491:                if ((i % 8) == 0)
                    492:                        printf("\n%4d :",i);
                    493:                        printf(" %08x",*(&state->r0+i));
                    494:        }
                    495:        printf("\n");
                    496:        printf("cr        = 0x%08x\t\t",state->cr);
                    497:        printf("xer       = 0x%08x\n",state->xer);
                    498:        printf("lr        = 0x%08x\t\t",state->lr);
                    499:        printf("ctr       = 0x%08x\n",state->ctr);
                    500:        printf("srr0(iar) = 0x%08x\t\t",state->srr0);
                    501:        printf("srr1(msr) = 0x%08B\n",state->srr1,
                    502:                "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18"
                    503:                "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT");
                    504:        printf("mq        = 0x%08x\t\t",state->mq);
                    505:        printf("sr_copyin = 0x%08x\n",state->sr_copyin);
                    506:        printf("\n");
                    507: }
                    508: 
                    509: void
                    510: kdp_print_backtrace(
                    511:     unsigned int                exception,
                    512:     struct ppc_saved_state     *saved_state)
                    513: {
                    514:        extern void kdp_print_registers(struct ppc_saved_state *);
                    515:        extern void print_backtrace(struct ppc_saved_state *);
                    516:        extern unsigned int debug_mode, disableDebugOuput;
                    517: 
                    518:        disableDebugOuput = FALSE;
                    519:        debug_mode = TRUE;
                    520:        printf("re-entering kdp:\n");
                    521:        printf("vector=%x, \n", exception/4);
                    522:        kdp_print_registers(saved_state);
                    523:        print_backtrace(saved_state);
                    524:        printf("panic: We are hanging here...\n");
                    525:        while(1);
                    526: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.