db_memrw.c revision 1.4 1 /* $NetBSD: db_memrw.c,v 1.4 1994/11/28 19:33:08 gwr Exp $ */
2
3 /*
4 * Copyright (c) 1994 Gordon W. Ross
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * Interface to the debugger for virtual memory read/write.
32 * To write in the text segment, we have to first make
33 * the page writable, do the write, then restore the PTE.
34 * For reads, validate address first to avoid MMU trap.
35 */
36
37 #include <sys/param.h>
38 #include <sys/proc.h>
39
40 #include <vm/vm.h>
41
42 #include <machine/db_machdep.h>
43 #include <machine/pte.h>
44
45 /*
46 * Read one byte somewhere in the kernel.
47 * It does not matter if this is slow. -gwr
48 */
49 static char
50 db_read_data(src)
51 char *src;
52 {
53 int oldpte;
54 vm_offset_t pgva;
55 int ch;
56
57 pgva = sun3_trunc_page((long)src);
58 oldpte = get_pte(pgva);
59
60 if ((oldpte & PG_VALID) == 0) {
61 db_printf(" address 0x%x not a valid page\n", src);
62 return 0;
63 }
64 return (*src);
65 }
66
67 /*
68 * Read bytes from kernel address space for debugger.
69 * It does not matter if this is slow. -gwr
70 */
71 void
72 db_read_bytes(addr, size, data)
73 vm_offset_t addr;
74 register int size;
75 register char *data;
76 {
77 char *src, *limit;
78
79 src = (char *)addr;
80 limit = src + size;
81
82 while (src < limit) {
83 *data = db_read_data(src);
84 data++;
85 src++;
86 }
87 }
88
89 /*
90 * Write one byte somewhere in kernel text.
91 * It does not matter if this is slow. -gwr
92 */
93 static void
94 db_write_text(dst, ch)
95 char *dst;
96 int ch;
97 {
98 int oldpte, tmppte;
99 vm_offset_t pgva;
100
101 pgva = sun3_trunc_page((long)dst);
102 oldpte = get_pte(pgva);
103
104 if ((oldpte & PG_VALID) == 0) {
105 db_printf(" address 0x%x not a valid page\n", dst);
106 return;
107 }
108
109 tmppte = oldpte | PG_WRITE;
110 set_pte(pgva, tmppte);
111
112 *dst = (char) ch;
113
114 set_pte(pgva, oldpte);
115 }
116
117 /*
118 * Write one byte somewhere outside kernel text.
119 * It does not matter if this is slow. -gwr
120 */
121 static void
122 db_write_data(dst, ch)
123 char *dst;
124 int ch;
125 {
126 int oldpte;
127 vm_offset_t pgva;
128
129 pgva = sun3_trunc_page((long)dst);
130 oldpte = get_pte(pgva);
131
132 if ((oldpte & (PG_VALID | PG_WRITE)) == 0) {
133 db_printf(" address 0x%x not a valid page\n", dst);
134 return;
135 }
136 *dst = (char) ch;
137 }
138
139 /*
140 * Write bytes to kernel address space for debugger.
141 */
142 void
143 db_write_bytes(addr, size, data)
144 vm_offset_t addr;
145 int size;
146 char *data;
147 {
148 extern char start[], etext[] ;
149 char *dst, *limit;
150
151 dst = (char *)addr;
152 limit = dst + size;
153
154 while (dst < limit) {
155 if ((dst >= start) && (dst < etext))
156 db_write_text(dst, *data);
157 else
158 db_write_data(dst, *data);
159 dst++;
160 data++;
161 }
162 }
163