xref: /freebsd/sys/i386/i386/db_interface.c (revision aa0a1e58)
1 /*-
2  * Mach Operating System
3  * Copyright (c) 1991,1990 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie the
24  * rights to redistribute these changes.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 /*
31  * Interface to new debugger.
32  */
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/cons.h>
36 #include <sys/kdb.h>
37 #include <sys/pcpu.h>
38 #include <sys/proc.h>
39 
40 #include <machine/cpu.h>
41 
42 #include <vm/vm.h>
43 #include <vm/pmap.h>
44 
45 #include <ddb/ddb.h>
46 
47 /*
48  * Read bytes from kernel address space for debugger.
49  */
50 int
51 db_read_bytes(vm_offset_t addr, size_t size, char *data)
52 {
53 	jmp_buf jb;
54 	void *prev_jb;
55 	char *src;
56 	int ret;
57 
58 	prev_jb = kdb_jmpbuf(jb);
59 	ret = setjmp(jb);
60 	if (ret == 0) {
61 		src = (char *)addr;
62 		while (size-- > 0)
63 			*data++ = *src++;
64 	}
65 	(void)kdb_jmpbuf(prev_jb);
66 	return (ret);
67 }
68 
69 /*
70  * Write bytes to kernel address space for debugger.
71  */
72 int
73 db_write_bytes(vm_offset_t addr, size_t size, char *data)
74 {
75 	jmp_buf jb;
76 	void *prev_jb;
77 	char *dst;
78 	pt_entry_t *ptep0 = NULL;
79 	pt_entry_t oldmap0 = 0;
80 	vm_offset_t addr1;
81 	pt_entry_t *ptep1 = NULL;
82 	pt_entry_t oldmap1 = 0;
83 	int ret;
84 
85 	prev_jb = kdb_jmpbuf(jb);
86 	ret = setjmp(jb);
87 	if (ret == 0) {
88 		if (addr > trunc_page((vm_offset_t)btext) - size &&
89 		    addr < round_page((vm_offset_t)etext)) {
90 
91 			ptep0 = pmap_pte(kernel_pmap, addr);
92 			oldmap0 = *ptep0;
93 			*ptep0 |= PG_RW;
94 
95 			/*
96 			 * Map another page if the data crosses a page
97 			 * boundary.
98 			 */
99 			if ((*ptep0 & PG_PS) == 0) {
100 				addr1 = trunc_page(addr + size - 1);
101 				if (trunc_page(addr) != addr1) {
102 					ptep1 = pmap_pte(kernel_pmap, addr1);
103 					oldmap1 = *ptep1;
104 					*ptep1 |= PG_RW;
105 				}
106 			} else {
107 				addr1 = trunc_4mpage(addr + size - 1);
108 				if (trunc_4mpage(addr) != addr1) {
109 					ptep1 = pmap_pte(kernel_pmap, addr1);
110 					oldmap1 = *ptep1;
111 					*ptep1 |= PG_RW;
112 				}
113 			}
114 
115 			invltlb();
116 		}
117 
118 		dst = (char *)addr;
119 
120 		while (size-- > 0)
121 			*dst++ = *data++;
122 	}
123 
124 	(void)kdb_jmpbuf(prev_jb);
125 
126 	if (ptep0) {
127 		*ptep0 = oldmap0;
128 
129 		if (ptep1)
130 			*ptep1 = oldmap1;
131 
132 		invltlb();
133 	}
134 
135 	return (ret);
136 }
137 
138 void
139 db_show_mdpcpu(struct pcpu *pc)
140 {
141 
142 	db_printf("APIC ID      = %d\n", pc->pc_apic_id);
143 	db_printf("currentldt   = 0x%x\n", pc->pc_currentldt);
144 }
145