|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1993 NeXT Computer, Inc. All rights reserved.
27: *
28: * kdp.c -- Kernel Debugging Protocol.
29: *
30: * History:
31: *
32: * 06 Nov 1997 Herb Ruth [[email protected]]
33: * Added extern declarations for implicit function declarations.
34: * Added KDP_TEST_HARNESS macro.
35: * Changed dprintf macro to call kprintf() instead of safe_prf() when
36: * KDP_TEST_HARNESS==1
37: *
38: */
39:
40: #import <mach/mach_types.h>
41:
42: #import <bsd/sys/param.h>
43: #import <sys/systm.h>
44: #import <bsd/sys/socket.h>
45: #import <bsd/net/if.h>
46: #import <bsd/netinet/in.h>
47:
48: #import <kern/kdp_internal.h>
49: #import <kern/kdp_private.h>
50: #import <kern/miniMon.h>
51:
52: /* 06 Nov 1997 */
53: #warning extern declarations -- FIXME XXX
54:
55: extern void kprintf(const char *format, ...);
56: extern int copy_for_kdp(vm_offset_t src, vm_offset_t dst, unsigned count, int dir);
57:
58: #define DO_ALIGN 1 /* align all packet data accesses */
59:
60: #define KDP_TEST_HARNESS 0
61: #if KDP_TEST_HARNESS
62: /*#define dprintf(x) safe_prf x*/
63: #define dprintf(x) kprintf x
64: #else
65: #define dprintf(x)
66: #endif
67:
68: static kdp_dispatch_t
69: dispatch_table[KDP_TERMINATION - KDP_CONNECT + 1] =
70: {
71: /* 0 */ kdp_connect,
72: /* 1 */ kdp_disconnect,
73: /* 2 */ kdp_hostinfo,
74: /* 3 */ kdp_regions,
75: /* 4 */ kdp_maxbytes,
76: /* 5 */ kdp_readmem,
77: /* 6 */ kdp_writemem,
78: /* 7 */ kdp_readregs,
79: /* 8 */ kdp_writeregs,
80: /* 9 */ kdp_unknown,
81: /* A */ kdp_unknown,
82: /* B */ kdp_suspend,
83: /* C */ kdp_resumecpus,
84: /* D */ kdp_unknown, /* KDP_EXCEPTION */
85: /* E */ kdp_unknown /* KDP_TERMINATION */
86: };
87:
88: kdp_glob_t kdp;
89:
90: boolean_t
91: kdp_packet(
92: unsigned char *pkt,
93: int *len,
94: unsigned short *reply_port
95: )
96: {
97: static unsigned aligned_pkt[1538/sizeof(unsigned)+1]; // max ether pkt
98: kdp_pkt_t *rd = (kdp_pkt_t *)&aligned_pkt;
99: int plen = *len;
100: unsigned int req;
101: boolean_t ret;
102:
103: #if DO_ALIGN
104: bcopy(pkt, rd, sizeof(aligned_pkt));
105: #else
106: rd = (kdp_pkt_t *)pkt;
107: #endif
108: if (plen < sizeof (rd->hdr) || rd->hdr.len != plen) {
109: dprintf(("kdp_packet: bad len pkt %d hdr %d\n", plen, rd->hdr.len));
110:
111: return (FALSE);
112: }
113:
114: if (rd->hdr.is_reply) {
115: dprintf(("kdp_packet: reply recvd req 0x%x seq 0x%x\n",
116: rd->hdr.request, rd->hdr.seq));
117:
118: return (FALSE);
119: }
120:
121: req = rd->hdr.request;
122: if (req < KDP_CONNECT || req > KDP_TERMINATION) {
123: dprintf(("kdp_packet: bad request 0x%x, len %d, seq 0x%x, key 0x%x\n",
124: rd->hdr.request, rd->hdr.len, rd->hdr.seq, rd->hdr.key));
125:
126: return (FALSE);
127: }
128:
129: ret = ((*dispatch_table[req - KDP_CONNECT])(rd, len, reply_port));
130: #if DO_ALIGN
131: bcopy(rd, pkt, *len);
132: #endif
133: return ret;
134: }
135:
136: static boolean_t
137: kdp_unknown(
138: kdp_pkt_t *pkt,
139: int *len,
140: unsigned short *reply_port
141: )
142: {
143: kdp_pkt_t *rd = (kdp_pkt_t *)pkt;
144:
145: dprintf(("kdp_unknown: request 0x%x, len %d, seq 0x%x, key 0x%x\n",
146: rd->hdr.request, rd->hdr.len, rd->hdr.seq, rd->hdr.key));
147:
148: return (FALSE);
149: }
150:
151: static boolean_t
152: kdp_connect(
153: kdp_pkt_t *pkt,
154: int *len,
155: unsigned short *reply_port
156: )
157: {
158: kdp_connect_req_t *rq = &pkt->connect_req;
159: int plen = *len;
160: kdp_connect_reply_t *rp = &pkt->connect_reply;
161:
162: if (plen < sizeof (*rq))
163: return (FALSE);
164:
165: dprintf(("kdp_connect: seq 0x%x, greeting %s\n", rq->hdr.seq, rq->greeting));
166:
167: if (kdp.is_conn) {
168: if (rq->hdr.seq == kdp.conn_seq) /* duplicate request */
169: rp->error = KDPERR_NO_ERROR;
170: else
171: rp->error = KDPERR_ALREADY_CONNECTED;
172: }
173: else {
174: kdp.reply_port = rq->req_reply_port;
175: kdp.exception_port = rq->exc_note_port;
176: kdp.is_conn = TRUE;
177: kdp.conn_seq = rq->hdr.seq;
178:
179: rp->error = KDPERR_NO_ERROR;
180: }
181:
182: rp->hdr.is_reply = 1;
183: rp->hdr.len = sizeof (*rp);
184:
185: *reply_port = kdp.reply_port;
186: *len = rp->hdr.len;
187:
188: return (TRUE);
189: }
190:
191: static boolean_t
192: kdp_disconnect(
193: kdp_pkt_t *pkt,
194: int *len,
195: unsigned short *reply_port
196: )
197: {
198: kdp_disconnect_req_t *rq = &pkt->disconnect_req;
199: int plen = *len;
200: kdp_disconnect_reply_t *rp = &pkt->disconnect_reply;
201:
202: if (plen < sizeof (*rq))
203: return (FALSE);
204:
205: if (!kdp.is_conn)
206: return (FALSE);
207:
208: dprintf(("kdp_disconnect\n"));
209:
210: *reply_port = kdp.reply_port;
211:
212: kdp.reply_port = kdp.exception_port = 0;
213: kdp.is_halted = kdp.is_conn = FALSE;
214: kdp.exception_seq = kdp.conn_seq = 0;
215:
216: rp->hdr.is_reply = 1;
217: rp->hdr.len = sizeof (*rp);
218:
219: *len = rp->hdr.len;
220:
221: return (TRUE);
222: }
223:
224: static boolean_t
225: kdp_hostinfo(
226: kdp_pkt_t *pkt,
227: int *len,
228: unsigned short *reply_port
229: )
230: {
231: kdp_hostinfo_req_t *rq = &pkt->hostinfo_req;
232: int plen = *len;
233: kdp_hostinfo_reply_t *rp = &pkt->hostinfo_reply;
234:
235: if (plen < sizeof (*rq))
236: return (FALSE);
237:
238: rp->hdr.is_reply = 1;
239: rp->hdr.len = sizeof (*rp);
240:
241: dprintf(("kdp_hostinfo\n"));
242:
243: kdp_machine_hostinfo(&rp->hostinfo);
244:
245: *reply_port = kdp.reply_port;
246: *len = rp->hdr.len;
247:
248: return (TRUE);
249: }
250:
251: static boolean_t
252: kdp_suspend(
253: kdp_pkt_t *pkt,
254: int *len,
255: unsigned short *reply_port
256: )
257: {
258: kdp_suspend_req_t *rq = &pkt->suspend_req;
259: int plen = *len;
260: kdp_suspend_reply_t *rp = &pkt->suspend_reply;
261:
262: if (plen < sizeof (*rq))
263: return (FALSE);
264:
265: rp->hdr.is_reply = 1;
266: rp->hdr.len = sizeof (*rp);
267:
268: dprintf(("kdp_suspend\n"));
269:
270: kdp.is_halted = TRUE;
271:
272: *reply_port = kdp.reply_port;
273: *len = rp->hdr.len;
274:
275: return (TRUE);
276: }
277:
278: static boolean_t
279: kdp_resumecpus(
280: kdp_pkt_t *pkt,
281: int *len,
282: unsigned short *reply_port
283: )
284: {
285: kdp_resumecpus_req_t *rq = &pkt->resumecpus_req;
286: int plen = *len;
287: kdp_resumecpus_reply_t *rp = &pkt->resumecpus_reply;
288:
289: if (plen < sizeof (*rq))
290: return (FALSE);
291:
292: rp->hdr.is_reply = 1;
293: rp->hdr.len = sizeof (*rp);
294:
295: dprintf(("kdp_resumecpus: cpu mask 0x%x\n", rq->cpu_mask));
296:
297: kdp.is_halted = FALSE;
298:
299: *reply_port = kdp.reply_port;
300: *len = rp->hdr.len;
301:
302: return (TRUE);
303: }
304:
305: static boolean_t
306: kdp_writemem(
307: kdp_pkt_t *pkt,
308: int *len,
309: unsigned short *reply_port
310: )
311: {
312: kdp_writemem_req_t *rq = &pkt->writemem_req;
313: int plen = *len;
314: kdp_writemem_reply_t *rp = &pkt->writemem_reply;
315:
316: if (plen < sizeof (*rq))
317: return (FALSE);
318:
319: if (rq->nbytes > MAX_KDP_DATA_SIZE)
320: rp->error = KDPERR_BAD_NBYTES;
321: else {
322: dprintf(("kdp_writemem: addr 0x%08x, size %d bytes\n", rq->address, rq->nbytes));
323: /* kernacc() ?? */
324: #if defined(ppc)
325: if (copy_for_kdp((vm_offset_t)rq->data, (vm_offset_t)rq->address, rq->nbytes, 1))
326: rp->error = KDPERR_BAD_NBYTES;
327: else
328: rp->error = KDPERR_NO_ERROR;
329: #else
330: copywithin(rq->data, rq->address, rq->nbytes);
331: rp->error = KDPERR_NO_ERROR;
332: #endif
333: }
334:
335: rp->hdr.is_reply = 1;
336: rp->hdr.len = sizeof (*rp);
337:
338: *reply_port = kdp.reply_port;
339: *len = rp->hdr.len;
340:
341: return (TRUE);
342: }
343:
344: static boolean_t
345: kdp_readmem(
346: kdp_pkt_t *pkt,
347: int *len,
348: unsigned short *reply_port
349: )
350: {
351: kdp_readmem_req_t *rq = &pkt->readmem_req;
352: int plen = *len;
353: kdp_readmem_reply_t *rp = &pkt->readmem_reply;
354:
355: if (plen < sizeof (*rq))
356: return (FALSE);
357:
358: rp->hdr.is_reply = 1;
359: rp->hdr.len = sizeof (*rp);
360:
361: if (rq->nbytes > MAX_KDP_DATA_SIZE)
362: rp->error = KDPERR_BAD_NBYTES;
363: else {
364: unsigned int n = rq->nbytes;
365:
366: dprintf(("kdp_readmem: addr 0x%08x, size %d bytes\n", rq->address, rq->nbytes));
367: /* kernacc() ?? */
368: #if defined(ppc)
369: if (copy_for_kdp((vm_offset_t)rq->address, (vm_offset_t)rp->data, rq->nbytes, 0))
370: rp->error = KDPERR_BAD_NBYTES;
371: else
372: rp->error = KDPERR_NO_ERROR;
373: #else
374: copywithin(rq->address, rp->data, rq->nbytes);
375: rp->error = KDPERR_NO_ERROR;
376: #endif
377:
378: rp->hdr.len += n;
379: }
380:
381: *reply_port = kdp.reply_port;
382: *len = rp->hdr.len;
383:
384: return (TRUE);
385: }
386:
387: static boolean_t
388: kdp_maxbytes(
389: kdp_pkt_t *pkt,
390: int *len,
391: unsigned short *reply_port
392: )
393: {
394: kdp_maxbytes_req_t *rq = &pkt->maxbytes_req;
395: int plen = *len;
396: kdp_maxbytes_reply_t *rp = &pkt->maxbytes_reply;
397:
398: if (plen < sizeof (*rq))
399: return (FALSE);
400:
401: rp->hdr.is_reply = 1;
402: rp->hdr.len = sizeof (*rp);
403:
404: dprintf(("kdp_maxbytes\n"));
405:
406: rp->max_bytes = MAX_KDP_DATA_SIZE;
407:
408: *reply_port = kdp.reply_port;
409: *len = rp->hdr.len;
410:
411: return (TRUE);
412: }
413:
414: static boolean_t
415: kdp_regions(
416: kdp_pkt_t *pkt,
417: int *len,
418: unsigned short *reply_port
419: )
420: {
421: kdp_regions_req_t *rq = &pkt->regions_req;
422: int plen = *len;
423: kdp_regions_reply_t *rp = &pkt->regions_reply;
424: kdp_region_t *r;
425:
426: if (plen < sizeof (*rq))
427: return (FALSE);
428:
429: rp->hdr.is_reply = 1;
430: rp->hdr.len = sizeof (*rp);
431:
432: dprintf(("kdp_regions\n"));
433:
434: r = rp->regions;
435: rp->nregions = 0;
436:
437: #if !defined(ppc)
438: (vm_offset_t)r->address = VM_MIN_KERNEL_ADDRESS;
439: r->nbytes = VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS;
440: #else
441: (vm_offset_t)r->address = VM_MIN_KERNEL_ADDRESS;
442: r->nbytes = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) + 0x50000000;
443: #endif
444: r->protection = VM_PROT_ALL; r++; rp->nregions++;
445:
446: rp->hdr.len += rp->nregions * sizeof (kdp_region_t);
447:
448: *reply_port = kdp.reply_port;
449: *len = rp->hdr.len;
450:
451: return (TRUE);
452: }
453:
454: static boolean_t
455: kdp_writeregs(
456: kdp_pkt_t *pkt,
457: int *len,
458: unsigned short *reply_port
459: )
460: {
461: kdp_writeregs_req_t *rq = &pkt->writeregs_req;
462: int plen = *len;
463: int size;
464: kdp_writeregs_reply_t *rp = &pkt->writeregs_reply;
465:
466: if (plen < sizeof (*rq))
467: return (FALSE);
468:
469: size = rq->hdr.len - sizeof(kdp_hdr_t) - sizeof(unsigned int);
470: rp->error = kdp_machine_write_regs(rq->cpu, rq->flavor, rq->data, &size);
471:
472: rp->hdr.is_reply = 1;
473: rp->hdr.len = sizeof (*rp);
474:
475: dprintf(("kdp_writeregs\n"));
476:
477: *reply_port = kdp.reply_port;
478: *len = rp->hdr.len;
479:
480: return (TRUE);
481: }
482:
483: static boolean_t
484: kdp_readregs(
485: kdp_pkt_t *pkt,
486: int *len,
487: unsigned short *reply_port
488: )
489: {
490: kdp_readregs_req_t *rq = &pkt->readregs_req;
491: int plen = *len;
492: kdp_readregs_reply_t *rp = &pkt->readregs_reply;
493: int size;
494:
495: if (plen < sizeof (*rq))
496: return (FALSE);
497:
498: rp->hdr.is_reply = 1;
499: rp->hdr.len = sizeof (*rp);
500:
501: dprintf(("kdp_readregs\n"));
502:
503: rp->error = kdp_machine_read_regs(rq->cpu, rq->flavor, rp->data, &size);
504: rp->hdr.len += size;
505:
506: *reply_port = kdp.reply_port;
507: *len = rp->hdr.len;
508:
509: return (TRUE);
510: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.