FreeBSD/Linux Kernel Cross Reference
sys/ttd/ttd_stub.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992 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 "AS IS"
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 Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * TTD Stub code for the kernel. Misc, LowfaceTTD code.
28 *
29 * HISTORY:
30 * $Log: ttd_stub.c,v $
31 * Revision 2.2 93/05/10 23:25:04 rvb
32 * Turned kttd debugging output off by default.
33 * [93/05/10 15:15:11 grm]
34 *
35 * Checkin for MK80 branch.
36 * [93/05/10 15:09:57 grm]
37 *
38 * Revision 2.1.2.2 93/04/20 10:59:12 grm
39 * Changed the types for protocol version 2.4. Changed the logic
40 * for dropping packets.
41 * [93/04/20 grm]
42 *
43 * Revision 2.1.2.1 93/03/03 14:35:18 grm
44 * Second version of code. It works.
45 * [93/03/03 grm]
46 *
47 * Revision 2.1.1.9 93/01/28 15:19:13 grm
48 * Added ttd_loop_status. Last checkin before locore rewrite.
49 *
50 * Revision 2.1.1.8 93/01/22 15:53:23 grm
51 * Added request length checks.
52 *
53 * Revision 2.1.1.7 93/01/21 13:05:26 grm
54 * Changed to Ansi C prototypes. Modified code for single stepping.
55 *
56 * Revision 2.1.1.6 92/10/23 21:23:09 grm
57 * First pass at single stepping. Left over code from debugging.
58 * [92/10/23 grm]
59 *
60 * Revision 2.1.1.5 92/10/08 14:30:40 grm
61 * Small changes. Checkin before ttd-ether rewrite.
62 * [92/10/08 grm]
63 *
64 * Revision 2.1.1.4 92/10/01 15:37:20 grm
65 * KTTD restructuring checkpoint.
66 * [92/10/01 grm]
67 *
68 * Revision 2.1.1.3 92/09/30 13:31:16 grm
69 * Added sync and async routines. Filled in kttd_trap.
70 * [92/09/30 grm]
71 *
72 * Revision 2.1.1.2 92/09/25 15:12:12 grm
73 * checkpointing...
74 * [92/09/25 grm]
75 *
76 * Revision 2.1.1.1 92/09/09 14:44:34 grm
77 * Initial Checkin.
78 *
79 */
80 /***********************************************************
81 Copyright 1992 by Digital Equipment Corporation, Maynard, Massachusetts,
82
83 All Rights Reserved
84
85 Permission to use, copy, modify, and distribute this software and its
86 documentation for any purpose and without fee is hereby granted, provided
87 that the above copyright notice appear in all copies and that both that
88 copyright notice and this permission notice appear in supporting
89 documentation, and that the name of Digital not be used in advertising
90 or publicity pertaining to distribution of the software without specific,
91 written prior permission. Digital makes no representations about the
92 suitability of this software for any purpose. It is provided "as is"
93 without express or implied warranty.
94
95 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
96 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
97 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
98 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
99 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
100 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
101 SOFTWARE.
102
103 ******************************************************************/
104
105 #include <sys/types.h>
106 #include <mach/mach_types.h>
107 #include <sys/reboot.h>
108 #include <ipc/ipc_kmsg.h>
109 #include <mach_kdb.h>
110 #include <ttd/ttd_types.h>
111 #include <ttd/ttd_msg.h>
112 #include <ttd/ttd_stub.h>
113
114 /*
115 * Status and Debugging flags
116 */
117 boolean_t kttd_enabled = FALSE; /* are we catching traps with ttd? */
118 integer_t kttd_active = MIN_KTTD_ACTIVE; /* are we in ttd NOW? */
119 boolean_t kttd_debug_init = FALSE; /* != 0 waits for host at bootstrap */
120 boolean_t kttd_debug = FALSE; /* are we debugging kttd? */
121
122 /*
123 * Pointer to the current request, and its length. It must be a
124 * global since it must be set in the async entry point which may
125 * indirectly jump to the kttd_task_trap routine (as in the i386at
126 * version).
127 */
128 vm_offset_t kttd_current_request;
129 natural_t kttd_current_length;
130 ipc_kmsg_t kttd_current_kmsg;
131
132 ttd_status_t kttd_run_status;
133
134 /*
135 * Allocate a static net_kmsg_get buffer for receives
136 *
137 * ttd_request_msg is really used as a net_kmsg_t
138 *
139 * ttd_reply_msg is NOT used as a net_kmsg_t, but only as
140 * the actual msg!!!
141 *
142 * Added four bytes so that we can shift alignment around.
143 */
144 char ttd_request_msg_array[MAX_TTD_MSG_SIZE + BYTE_ALIGNMENT];
145 char ttd_reply_msg_array[MAX_TTD_MSG_SIZE + BYTE_ALIGNMENT];
146
147 char * ttd_request_msg = NULL;
148 char * ttd_reply_msg = NULL;
149
150 /*
151 * The low level ethernet driver vars:
152 */
153 integer_t ttd_device_unit = -1;
154 int (*ttd_get_packet)() = NULL;
155 int (*ttd_send_packet)() = NULL;
156 struct ether_hardware_address ttd_host_ether_id;
157
158
159 /*
160 * Initialize the TTD code.
161 *
162 * Allocate static buffer, etc.
163 *
164 */
165 void ttd_init(void)
166 {
167 extern int boothowto;
168
169 if (boothowto & RB_KDB) {
170
171 /*
172 * Set 'em up so that bootp can work.
173 * Must be redone before high level protocols with
174 * 32 bit structure members can be used.
175 */
176 ttd_request_msg = &ttd_request_msg_array[0];
177 ttd_reply_msg = &ttd_reply_msg_array[0];
178
179 boothowto &= ~RB_KDB;
180 kttd_enabled = TRUE;
181
182 /*
183 * Init console kgdb device.
184 */
185 if(!kttd_console_init()) {
186 kttd_active = FALSE;
187 kttd_enabled = FALSE;
188 return;
189 }
190
191 /*
192 * Init the ttd_server.
193 */
194 ttd_server_initialize();
195
196 printf("TTD enabled, protocol version: %d.%d.\n",
197 TTD_VERSION/10, TTD_VERSION%10);
198
199 if (kttd_debug_init) {
200 /*
201 * Debugging init procedure, break here.
202 */
203 printf("TTD waiting...");
204 kttd_break();
205 printf(" connected.\n");
206
207 }
208 } else
209 kttd_enabled = FALSE;
210 }
211
212 /*
213 * kttd_handle_async:
214 *
215 * This routine deals with asynchronous ttd requests. These requests are
216 * obtained via interrupts when the kernel is running. Normally this is
217 * when an ethernet packet has just arrived.
218 *
219 * If the current ethernet packet is a valid ttd request, we service it.
220 * It returns FALSE if the kernel should send the packet to the filter,
221 * or TRUE if it was a ttd packet and has been handled already.
222 *
223 * The main difference between this routine and the sychronous one, is
224 * that the kernel target is not stopped before service, which allows
225 * only a small set of possible ttd operations to occur on the kernel
226 * (get_info, probe_server, stop_target).
227 *
228 */
229 boolean_t kttd_handle_async(ipc_kmsg_t kmsg)
230 {
231 vm_offset_t ttd_msg;
232 natural_t ttd_length;
233
234 /*
235 * Return if not supported.
236 */
237 if (!kttd_supported()) {
238 kttd_enabled = FALSE;
239 if (kttd_debug)
240 printf("kttd_handle_async: kttd not supported!\n");
241 return FALSE;
242 }
243
244 if (!kttd_valid_request(kmsg, FALSE, &ttd_msg, &ttd_length))
245 return FALSE;
246
247 /*
248 * If we are already servicing a TTD interrupt,
249 * we just drop this packet.
250 */
251 if ((kttd_run_status != RUNNING) || (kttd_single_stepping)) {
252
253 if (kttd_debug)
254 printf("kttd_handle_async: dropping packet, !run or sstep.\n");
255
256 /*
257 * Put the kmsg back in the free queue:
258 */
259 net_kmsg_put(kmsg);
260
261 /*
262 * Tell it we handled it.
263 */
264 return TRUE;
265 }
266
267 /*
268 * Set up variables for use after we enter the
269 * Teledebug service code. Teledebug service
270 * code will net_put_kmsg of the kmsg after the
271 * request has been processed.
272 */
273 kttd_current_request = ttd_msg;
274 kttd_current_length = ttd_length;
275 kttd_current_kmsg = kmsg;
276 kttd_run_status = ONE_STOP;
277
278 if (kttd_debug)
279 printf("kttd_async: calling kttd_intr()\n");
280
281 /*
282 * "Call teledebugger"
283 */
284 kttd_intr();
285
286 if (kttd_debug)
287 printf("kttd_handle_async: returning\n");
288
289 return TRUE;
290 }
291
292 /*
293 * kttd_task_trap:
294 *
295 * This routine is called by the kttd_trap routine in the
296 * kttd_interface.c file. Both asyncronous and syncronous entries call
297 * this routine.
298 *
299 */
300 void kttd_task_trap(int type, int code, boolean_t user_space)
301 {
302 if (kttd_debug)
303 printf("kttd_task_trap entered. type = %d, code = %x, from %s space\n",
304 type, code, (user_space ? "USER" : "KERNEL"));
305
306 if (kttd_run_status == FULL_STOP) {
307
308 /*
309 * We're at a full stop. So:
310 *
311 * - Halt the other processors
312 * - Take us out of single stepping mode
313 *
314 */
315 kttd_halt_processors();
316
317 /*
318 * Update the kernel state. ie. we're stopped now...
319 */
320 kttd_stop_target();
321
322 if (kttd_debug)
323 printf("kttd_task_trap: stopping kernel target.\n");
324
325 /*
326 * Turn off single stepping if this is a
327 * single step trap/breakpoint.
328 */
329 if (kttd_single_stepping) {
330 if (!kttd_clear_single_step(NULL))
331 printf("ttd_trap: Couldn't clear single stepping!!\n");
332 }
333
334 /*
335 * Async entry already has request, so we need to get
336 * one to catch up.
337 */
338 (void) kttd_get_request(&kttd_current_request,
339 &kttd_current_length);
340
341 /*
342 * Fill in the kttd globals to deal with this
343 * msg. A NULL ptr means that we should use the
344 * ttd_request_msg.
345 */
346 kttd_current_kmsg = NULL;
347 }
348
349 /*
350 * Update kernel target info (ie. why we're stopped, etc.)
351 */
352 kttd_type_to_ttdtrap(type);
353
354 /*
355 * The packet "command" loop, where we respond to remote
356 * debugging commands.
357 *
358 * Service request(s) now...
359 */
360
361 if (kttd_debug)
362 printf("kttd_task_trap: servicing requests\n");
363
364 for(;;) {
365 ttd_service_request();
366
367 /*
368 * If the request came from a kmsg, we need
369 * to put it back onto the net_queue_free list.
370 */
371 if (kttd_current_kmsg != NULL) {
372 net_kmsg_put(kttd_current_kmsg);
373 kttd_current_kmsg = NULL;
374 }
375
376 /*
377 * If we are in ONE_STOP mode, we're done
378 * with processing packets, so we should exit
379 * the "command" loop.
380 */
381 if (kttd_run_status == ONE_STOP)
382 break;
383
384 /*
385 * We must be at a FULL_STOP, so we need to get
386 * another ttd packet, and fill in the globals.
387 *
388 * kttd_get_request sets the first parameter to point
389 * at the struct ttd_request in the ttd_request_msg.
390 */
391 kttd_get_request(&kttd_current_request, &kttd_current_length);
392 kttd_current_kmsg = NULL;
393 }
394 }
Cache object: ad00ca725c4acc6553abc7f6fd976da8
|