|
|
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) 1997 Apple Computer, Inc. All rights reserved.
27: * Copyright (c) 1994 NeXT Computer, Inc. All rights reserved.
28: *
29: * machdep/ppc/miniMonMachdep.c
30: *
31: * Machine-dependent code for Remote Debugging Protocol
32: *
33: * March, 1997 Created. Umesh Vaishampayan [[email protected]]
34: *
35: */
36:
37: #include <sys/reboot.h>
1.1.1.2 ! root 38:
! 39: #include <mach/vm_param.h>
! 40:
! 41: #include <machdep/ppc/pmap.h>
! 42: #include <machdep/ppc/pmap_internals.h>
! 43:
1.1 root 44: #include <kern/miniMonPrivate.h>
45:
46:
47: static boolean_t ishex(char c)
48: {
49: if ((c >= '0' && c <= '9') ||
50: (c >= 'a' && c <= 'f') ||
51: (c >= 'A' && c <= 'F'))
52: return TRUE;
53: return FALSE;
54: }
55:
56: static int xx(char c)
57: {
58: if (c >= '0' && c <= '9')
59: return c - '0';
60: if (c >= 'a' && c <= 'f')
61: return c - 'a' + 10;
62: if (c >= 'A' && c <= 'F')
63: return c - 'A' + 10;
64: return 0;
65: }
66:
1.1.1.2 ! root 67: static void
! 68: xtoi(char *str, unsigned *nump)
! 69: {
! 70: for (*nump = 0; *str && ishex(*str); str++)
! 71: *nump = 16*(*nump) + xx(*str);
! 72: }
! 73:
! 74: static unsigned found_valu = 0;
! 75: static unsigned prev_valu = 0;
! 76:
! 77: static boolean_t
! 78: miniMonFind(char *line)
1.1 root 79: {
1.1.1.2 ! root 80: static unsigned *start = (unsigned *)0;
! 81: static unsigned howmany = 0;
! 82: static unsigned prev_howmany = 0;
! 83: struct phys_entry *pp;
! 84: struct mapping *mp;
! 85: static unsigned found = 0;
! 86: extern unsigned *find_phys();
! 87: extern vm_size_t mem_size;
! 88: extern vm_offset_t virtual_avail;
! 89:
! 90: /* Skip command name */
! 91: while (*line && (*line != ' ' && *line != '\t'))
! 92: line++;
! 93: /* Skip whitespace */
! 94: while (*line && (*line == ' ' || *line == '\t'))
! 95: line++;
! 96:
! 97: xtoi(line, &found_valu);
1.1 root 98:
1.1.1.2 ! root 99: /* Skip found_valu */
! 100: while (*line && (*line != ' ' && *line != '\t'))
! 101: line++;
! 102: /* Skip whitespace */
! 103: while (*line && (*line == ' ' || *line == '\t'))
! 104: line++;
! 105:
! 106: xtoi(line, &howmany);
! 107:
! 108: if (found_valu == 0 && howmany == 0) {
! 109: found_valu = prev_valu;
! 110: howmany = prev_howmany;
! 111: } else {
! 112: start = (unsigned *)0;
! 113: prev_valu = found_valu;
! 114: prev_howmany = howmany;
! 115: found = 0;
! 116: }
! 117:
! 118: if (howmany == 0)
! 119: howmany = (unsigned)(-1);
! 120:
! 121: for (; howmany--; start++) {
! 122: start = find_phys(found_valu, start, mem_size);
! 123: if (start == (unsigned *)0)
! 124: break;
! 125: if (start == &found_valu || start == &prev_valu)
! 126: continue;
! 127: safe_prf("P: %08x V:", start);
! 128: found++;
! 129: if (start < (unsigned *)virtual_avail)
! 130: safe_prf(" 0/%08x", start);
! 131: else if ((pp = pmap_find_physentry((vm_offset_t)start))) {
! 132: queue_iterate(&pp->phys_link, mp, struct mapping *, phys_link)
! 133: {
! 134: safe_prf(" %x/%08x ", mp->pmap->space,
! 135: (mp->vm_info.bits.page << PPC_PGSHIFT) |
! 136: ((unsigned)start & (PPC_PGBYTES - 1)));
! 137: }
! 138: }
! 139: safe_prf("\n");
1.1 root 140: }
1.1.1.2 ! root 141: safe_prf("%d found.\n", found);
! 142: return TRUE;
1.1 root 143: }
144:
145: static boolean_t
146: miniMonDump(char *line)
147: {
148: int addr, count;
1.1.1.2 ! root 149: static unsigned int *ptr = (unsigned int *)0x10000;
1.1 root 150: static unsigned int old_count = 8;
151: int text;
152:
153: text = ((*line) == 't');
154:
155: /* Skip command name */
156: while (*line && (*line != ' ' && *line != '\t'))
157: line++;
158: /* Skip whitespace */
159: while (*line && (*line == ' ' || *line == '\t'))
160: line++;
1.1.1.2 ! root 161:
! 162: xtoi(line, &addr);
1.1 root 163: if (addr != 0)
164: ptr = (unsigned int *)addr;
1.1.1.2 ! root 165:
1.1 root 166: /* Skip address */
167: while (*line && (*line != ' ' && *line != '\t'))
168: line++;
169: /* Skip whitespace */
170: while (*line && (*line == ' ' || *line == '\t'))
171: line++;
1.1.1.2 ! root 172:
1.1 root 173: if (*line == 's') {
1.1.1.2 ! root 174: safe_prf("%08x (as string) : %s\n", ptr, (char *) ptr);
1.1 root 175: return TRUE;
176: }
1.1.1.2 ! root 177:
! 178: xtoi(line, &count);
1.1 root 179: if (count == 0)
180: count = old_count;
181: else
182: old_count = count;
183: if (count > 1024) count = 1024;
184: safe_prf("%08x : ", ptr);
185: while (count > 0)
186: if( text) {
187: miniMonPutchar(*((char *)ptr)++);
188: count--;
189: } else {
190: safe_prf("%08x ",*ptr++);
191: count -= 4;
192: }
193: safe_prf("\n");
194: return TRUE;
195: }
196:
197: miniMonCommand_t miniMonMDCommands[] =
198: {
199: {"dump", miniMonDump, "Dump memory"},
200: {"text", miniMonDump, "Dump text"},
1.1.1.2 ! root 201: {"find", miniMonFind, "Find value in physical memory"},
1.1 root 202: {0,0,0}
203: };
204:
205:
206: /*
207: * Reboot without sync.
208: */
209: boolean_t
210: miniMonReboot(char *line)
211: {
212: boot(RB_BOOT, RB_AUTOBOOT|RB_NOSYNC, "");
213: return FALSE;
214: }
215:
216: /*
217: * Halt with sync.
218: */
219: boolean_t
220: miniMonHalt(char *line)
221: {
222: reboot_mach(RB_HALT);
223: return FALSE;
224: }
225:
226: boolean_t
227: miniMonGdb(char *line)
228: {
229: call_kdp();
230: return FALSE;
231: }
232:
233: int
234: miniMonTryGetchar(void)
235: {
236: return kmtrygetc();
237: }
238:
239: int
240: miniMonGetchar(void)
241: {
242: register int c;
243: do {
244: c = kmtrygetc();
245: } while (c == NO_CHAR);
246: switch (c) {
247: case '\177':
248: c = '\b';
249: break;
250: case '\r':
251: kmputc(0,'\r');
252: c = '\n';
253: break;
254: case 'u'&037:
255: c = '\025';
256: break;
257: default:
258: break;
259: }
260: kmputc(0,c);
261: return c;
262: }
263:
264: void
265: miniMonPutchar(int ch)
266: {
267: kmputc(0,ch);
268: };
269:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.