Annotation of XNU/osfmk/kdp/ml/i386/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/machine.h>
                     36: #include <mach/exception_types.h>
                     37: #include <i386/trap.h>
                     38: #include <kdp/kdp_internal.h>
                     39: 
                     40: #define KDP_TEST_HARNESS 0
                     41: #if KDP_TEST_HARNESS
                     42: #define dprintf(x) printf x
                     43: #else
                     44: #define dprintf(x)
                     45: #endif
                     46: 
                     47: void print_saved_state(void *);
                     48: void kdp_call(void);
                     49: void kdp_i386_trap(unsigned int, struct i386_saved_state *, kern_return_t, vm_offset_t);
                     50: int kdp_getc(void);
                     51: 
                     52: void
                     53: kdp_exception(
                     54:     unsigned char      *pkt,
                     55:     int        *len,
                     56:     unsigned short     *remote_port,
                     57:     unsigned int       exception,
                     58:     unsigned int       code,
                     59:     unsigned int       subcode
                     60: )
                     61: {
                     62:     kdp_exception_t    *rq = (kdp_exception_t *)pkt;
                     63: 
                     64:     rq->hdr.request = KDP_EXCEPTION;
                     65:     rq->hdr.is_reply = 0;
                     66:     rq->hdr.seq = kdp.exception_seq;
                     67:     rq->hdr.key = 0;
                     68:     rq->hdr.len = sizeof (*rq);
                     69:     
                     70:     rq->n_exc_info = 1;
                     71:     rq->exc_info[0].cpu = 0;
                     72:     rq->exc_info[0].exception = exception;
                     73:     rq->exc_info[0].code = code;
                     74:     rq->exc_info[0].subcode = subcode;
                     75:     
                     76:     rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
                     77:     
                     78:     bcopy((char *)rq, (char *)pkt, rq->hdr.len);
                     79: 
                     80:     kdp.exception_ack_needed = TRUE;
                     81:     
                     82:     *remote_port = kdp.exception_port;
                     83:     *len = rq->hdr.len;
                     84: }
                     85: 
                     86: boolean_t
                     87: kdp_exception_ack(
                     88:     unsigned char      *pkt,
                     89:     int                        len
                     90: )
                     91: {
                     92:     kdp_exception_ack_t        *rq = (kdp_exception_ack_t *)pkt;
                     93: 
                     94:     if (len < sizeof (*rq))
                     95:        return(FALSE);
                     96:        
                     97:     if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
                     98:        return(FALSE);
                     99:        
                    100:     dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
                    101:        
                    102:     if (rq->hdr.seq == kdp.exception_seq) {
                    103:        kdp.exception_ack_needed = FALSE;
                    104:        kdp.exception_seq++;
                    105:     }
                    106:     return(TRUE);
                    107: }
                    108: 
                    109: void
                    110: kdp_getstate(
                    111:     i386_thread_state_t                *state
                    112: )
                    113: {
                    114:     struct i386_saved_state    *saved_state;
                    115:     
                    116:     saved_state = (struct i386_saved_state *)kdp.saved_state;
                    117:     
                    118:     *state = (i386_thread_state_t) { 0 };      
                    119:     state->eax = saved_state->eax;
                    120:     state->ebx = saved_state->ebx;
                    121:     state->ecx = saved_state->ecx;
                    122:     state->edx = saved_state->edx;
                    123:     state->edi = saved_state->edi;
                    124:     state->esi = saved_state->esi;
                    125:     state->ebp = saved_state->ebp;
                    126: 
                    127:     if ((saved_state->cs & 0x3) == 0){ /* Kernel State */
                    128:        state->esp = (unsigned int) &saved_state->uesp;
                    129:         state->ss = KERNEL_DS;
                    130:     } else {
                    131:        state->esp = saved_state->uesp;
                    132:        state->ss = saved_state->ss;
                    133:     }
                    134: 
                    135:     state->eflags = saved_state->efl;
                    136:     state->eip = saved_state->eip;
                    137:     state->cs = saved_state->cs;
                    138:     state->ds = saved_state->ds;
                    139:     state->es = saved_state->es;
                    140:     state->fs = saved_state->fs;
                    141:     state->gs = saved_state->gs;
                    142: }
                    143: 
                    144: 
                    145: void
                    146: kdp_setstate(
                    147:     i386_thread_state_t                *state
                    148: )
                    149: {
                    150:     struct i386_saved_state    *saved_state;
                    151:     
                    152:     saved_state = (struct i386_saved_state *)kdp.saved_state;
                    153: 
                    154:     saved_state->eax = state->eax;
                    155:     saved_state->ebx = state->ebx;
                    156:     saved_state->ecx = state->ecx;
                    157:     saved_state->edx = state->edx;
                    158:     saved_state->edi = state->edi;
                    159:     saved_state->esi = state->esi;
                    160:     saved_state->ebp = state->ebp;
                    161:     saved_state->efl = state->eflags;
                    162: #if    0
                    163:     saved_state->frame.eflags &= ~( EFL_VM | EFL_NT | EFL_IOPL | EFL_CLR );
                    164:     saved_state->frame.eflags |=  ( EFL_IF | EFL_SET );
                    165: #endif
                    166:     saved_state->eip = state->eip;
                    167:     saved_state->fs = state->fs;
                    168:     saved_state->gs = state->gs;
                    169: }
                    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 i386_THREAD_STATE:
                    183:        dprintf(("kdp_readregs THREAD_STATE\n"));
                    184:        kdp_getstate((i386_thread_state_t *)data);
                    185:        *size = sizeof (i386_thread_state_t);
                    186:        return KDPERR_NO_ERROR;
                    187:        
                    188:     case i386_THREAD_FPSTATE:
                    189:        dprintf(("kdp_readregs THREAD_FPSTATE\n"));
                    190:        *(i386_thread_fpstate_t *)data = (i386_thread_fpstate_t) { 0 }; 
                    191:        *size = sizeof (i386_thread_fpstate_t);
                    192:        return KDPERR_NO_ERROR;
                    193:        
                    194:     default:
                    195:        dprintf(("kdp_readregs bad flavor %d\n"));
                    196:        return KDPERR_BADFLAVOR;
                    197:     }
                    198: }
                    199: 
                    200: kdp_error_t
                    201: kdp_machine_write_regs(
                    202:     unsigned int cpu,
                    203:     unsigned int flavor,
                    204:     char *data,
                    205:     int *size
                    206: )
                    207: {
                    208:     switch (flavor) {
                    209: 
                    210:     case i386_THREAD_STATE:
                    211:        dprintf(("kdp_writeregs THREAD_STATE\n"));
                    212:        kdp_setstate((i386_thread_state_t *)data);
                    213:        return KDPERR_NO_ERROR;
                    214:        
                    215:     case i386_THREAD_FPSTATE:
                    216:        dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
                    217:        return KDPERR_NO_ERROR;
                    218:        
                    219:     default:
                    220:        dprintf(("kdp_writeregs bad flavor %d\n"));
                    221:        return KDPERR_BADFLAVOR;
                    222:     }
                    223: }
                    224: 
                    225: 
                    226: 
                    227: void
                    228: kdp_machine_hostinfo(
                    229:     kdp_hostinfo_t *hostinfo
                    230: )
                    231: {
                    232:     machine_slot_t     m;
                    233:     int                        i;
                    234: 
                    235:     hostinfo->cpus_mask = 0;
                    236: 
                    237:     for (i = 0; i < machine_info.max_cpus; i++) {
                    238:         m = &machine_slot[i];
                    239:         if (!m->is_cpu)
                    240:             continue;
                    241:        
                    242:         hostinfo->cpus_mask |= (1 << i);
                    243:     }
                    244: 
                    245:    /* FIXME?? */
                    246:     hostinfo->cpu_type = CPU_TYPE_I386;
                    247:     hostinfo->cpu_subtype = CPU_SUBTYPE_486;
                    248: }
                    249: 
                    250: void
                    251: kdp_panic(
                    252:     const char         *msg
                    253: )
                    254: {
                    255:     printf("kdp panic: %s\n", msg);    
                    256:     __asm__ volatile("hlt");   
                    257: }
                    258: 
                    259: 
                    260: void
                    261: kdp_reboot(void)
                    262: {
                    263:     kdreboot();
                    264: }
                    265: 
                    266: int
                    267: kdp_intr_disbl(void)
                    268: {
                    269:    return splhigh();
                    270: }
                    271: 
                    272: void
                    273: kdp_intr_enbl(int s)
                    274: {
                    275:        splx(s);
                    276: }
                    277: 
                    278: int
                    279: kdp_getc()
                    280: {
                    281:        return  cnmaygetc();
                    282: }
                    283: 
                    284: void
                    285: kdp_us_spin(int usec)
                    286: {
                    287:     extern void delay(int);
                    288: 
                    289:     delay(usec/100);
                    290: }
                    291: 
                    292: void print_saved_state(void *state)
                    293: {
                    294:     struct i386_saved_state    *saved_state;
                    295: 
                    296:     saved_state = state;
                    297: 
                    298:        printf("pc = 0x%x\n", saved_state->eip);
                    299:        printf("cr3= 0x%x\n", saved_state->cr2);
                    300:        printf("rp = TODO FIXME\n");
                    301:        printf("sp = 0x%x\n", saved_state->esp);
                    302: 
                    303: }
                    304: 
                    305: void
                    306: kdp_sync_cache()
                    307: {
                    308:        return; /* No op here. */
                    309: }
                    310: 
                    311: void
                    312: kdp_call()
                    313: {
                    314:        __asm__ volatile ("int  $3");   /* Let the processor do the work */
                    315: }
                    316: 
                    317: 
                    318: typedef struct _cframe_t {
                    319:     struct _cframe_t   *prev;
                    320:     unsigned           caller;
                    321:     unsigned           args[0];
                    322: } cframe_t;
                    323: 
                    324: 
                    325: #define MAX_FRAME_DELTA                65536
                    326: 
                    327: void
                    328: kdp_i386_backtrace(void        *_frame, int nframes)
                    329: {
                    330:        cframe_t        *frame = (cframe_t *)_frame;
                    331:        int i;
                    332: 
                    333:        for (i=0; i<nframes; i++) {
                    334:            if ((vm_offset_t)frame < VM_MIN_KERNEL_ADDRESS ||
                    335:                (vm_offset_t)frame > VM_MAX_KERNEL_ADDRESS) {
                    336:                goto invalid;
                    337:            }
                    338:            printf("frame %x called by %x ",
                    339:                frame, frame->caller);
                    340:            printf("args %x %x %x %x\n",
                    341:                frame->args[0], frame->args[1],
                    342:                frame->args[2], frame->args[3]);
                    343:            if ((frame->prev < frame) ||        /* wrong direction */
                    344:                ((frame->prev - frame) > MAX_FRAME_DELTA)) {
                    345:                goto invalid;
                    346:            }
                    347:            frame = frame->prev;
                    348:        }
                    349:        return;
                    350: invalid:
                    351:        printf("invalid frame pointer %x\n",frame->prev);
                    352: }
                    353: 
                    354: void
                    355: kdp_i386_trap(
                    356:     unsigned int               trapno,
                    357:     struct i386_saved_state    *saved_state,
                    358:     kern_return_t      result,
                    359:     vm_offset_t                va
                    360: )
                    361: {
                    362:     unsigned int exception, subcode = 0, code;
                    363: 
                    364:     if (trapno != T_INT3 && trapno != T_DEBUG)
                    365:        printf("unexpected kernel trap %x eip %x\n", trapno, saved_state->eip);
                    366: 
                    367:     switch (trapno) {
                    368:     
                    369:     case T_DIVIDE_ERROR:
                    370:        exception = EXC_ARITHMETIC;
                    371:        code = EXC_I386_DIVERR;
                    372:        break;
                    373:     
                    374:     case T_OVERFLOW:
                    375:        exception = EXC_SOFTWARE;
                    376:        code = EXC_I386_INTOFLT;
                    377:        break;
                    378:     
                    379:     case T_OUT_OF_BOUNDS:
                    380:        exception = EXC_ARITHMETIC;
                    381:        code = EXC_I386_BOUNDFLT;
                    382:        break;
                    383:     
                    384:     case T_INVALID_OPCODE:
                    385:        exception = EXC_BAD_INSTRUCTION;
                    386:        code = EXC_I386_INVOPFLT;
                    387:        break;
                    388:     
                    389:     case T_SEGMENT_NOT_PRESENT:
                    390:        exception = EXC_BAD_INSTRUCTION;
                    391:        code = EXC_I386_SEGNPFLT;
                    392:        subcode = saved_state->err;
                    393:        break;
                    394:     
                    395:     case T_STACK_FAULT:
                    396:        exception = EXC_BAD_INSTRUCTION;
                    397:        code = EXC_I386_STKFLT;
                    398:        subcode = saved_state->err;
                    399:        break;
                    400:     
                    401:     case T_GENERAL_PROTECTION:
                    402:        exception = EXC_BAD_INSTRUCTION;
                    403:        code = EXC_I386_GPFLT;
                    404:        subcode = saved_state->err;
                    405:        break;
                    406:        
                    407:     case T_PAGE_FAULT:
                    408:        exception = EXC_BAD_ACCESS;
                    409:        code = result;
                    410:        subcode = va;
                    411:        break;
                    412:     
                    413:     case T_WATCHPOINT:
                    414:        exception = EXC_SOFTWARE;
                    415:        code = EXC_I386_ALIGNFLT;
                    416:        break;
                    417:        
                    418:     case T_DEBUG:
                    419:     case T_INT3:
                    420:        exception = EXC_BREAKPOINT;
                    421:        code = EXC_I386_BPTFLT;
                    422:        break;
                    423: 
                    424:     default:
                    425:        exception = EXC_BAD_INSTRUCTION;
                    426:        code = trapno;
                    427:        break;
                    428:     }
                    429: 
                    430: //  kdp_i386_backtrace((void *) saved_state->ebp, 10);
                    431: 
                    432:     kdp_raise_exception(exception, code, subcode, saved_state);
                    433: }
                    434: 
                    435: boolean_t 
                    436: kdp_call_kdb(
                    437:         void) 
                    438: {       
                    439:         return(FALSE);
                    440: }

unix.superglobalmegacorp.com

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