PageRenderTime 32ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/kernel/ttd/ttd_server.c

https://github.com/Prajna/mach
C | 1678 lines | 895 code | 233 blank | 550 comment | 151 complexity | b72986c5cf80db76b8aa70cd0b18d23c MD5 | raw file
  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 Communications parsing code for the kernel ttd server.
  28. *
  29. * HISTORY:
  30. * $Log: ttd_server.c,v $
  31. * Revision 2.2 93/05/10 23:24:51 rvb
  32. * Checkin for MK80 branch.
  33. * [93/05/10 15:08:55 grm]
  34. *
  35. * Revision 2.1.2.3 93/04/20 11:06:02 grm
  36. * Changed types for use with a more universal protocol. Added code
  37. * to support the use of multiple endian machines. Alignment code
  38. * added.
  39. * [93/04/20 grm]
  40. *
  41. * Revision 2.1.2.2 93/03/29 16:30:24 grm
  42. * Version for protocol 2.2
  43. * [93/03/29 grm]
  44. *
  45. * Revision 2.1.2.1 93/03/03 14:41:22 grm
  46. * Second version of code. It works.
  47. * [93/03/03 grm]
  48. *
  49. * Revision 2.1.1.8 93/01/28 15:14:51 grm
  50. * Added ttd_loop_type. Last checkin before locore rewrite.
  51. *
  52. * Revision 2.1.1.7 93/01/22 15:52:52 grm
  53. * Added request length checks.
  54. *
  55. * Revision 2.1.1.6 93/01/21 13:03:49 grm
  56. * Changed to Ansi C prototypes. Added kttd_debug statements.
  57. *
  58. * Revision 2.1.1.5 92/10/30 12:44:18 grm
  59. * Fixed single stepping and set_state_action bug.
  60. * [92/10/30 grm]
  61. *
  62. * Revision 2.1.1.4 92/10/23 21:21:39 grm
  63. * Added first pass at single stepping code. Fixed bug in
  64. * stop/restart logic.
  65. * [92/10/23 grm]
  66. *
  67. * Revision 2.1.1.3 92/10/08 14:29:28 grm
  68. * Fixed clear_breakpoint function. Added some debugging code.
  69. * [92/10/08 grm]
  70. *
  71. * Revision 2.1.1.2 92/10/01 15:36:54 grm
  72. * KTTD restructuring checkpoint.
  73. * [92/10/01 grm]
  74. *
  75. * Revision 2.1.1.1 92/09/25 15:10:26 grm
  76. * Initial checkin.
  77. * [92/09/25 grm]
  78. *
  79. */
  80. /***********************************************************
  81. Copyright 1992 by Digital Equipment Corporation, Maynard, Massachusetts,
  82. All Rights Reserved
  83. Permission to use, copy, modify, and distribute this software and its
  84. documentation for any purpose and without fee is hereby granted, provided
  85. that the above copyright notice appear in all copies and that both that
  86. copyright notice and this permission notice appear in supporting
  87. documentation, and that the name of Digital not be used in advertising
  88. or publicity pertaining to distribution of the software without specific,
  89. written prior permission. Digital makes no representations about the
  90. suitability of this software for any purpose. It is provided "as is"
  91. without express or implied warranty.
  92. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  93. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  94. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  95. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  96. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  97. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  98. SOFTWARE.
  99. ******************************************************************/
  100. #include <mach/boolean.h>
  101. #include <mach/vm_param.h>
  102. #include <ttd/ttd_comm.h>
  103. #include <ttd/ttd_types.h>
  104. #include <ttd/ttd_msg.h>
  105. #include <ttd/kernel_ttd.h>
  106. #include <ttd/ttd_stub.h>
  107. #include <ttd/ttd_server.h>
  108. #include <ttd/ttd_debug.h>
  109. struct ttd_reply prev_reply; /* saved reply for idempotency */
  110. natural_t prev_reply_length;
  111. ttd_operation prev_operation;
  112. static boolean_t ttd_server_initialized;
  113. #define END_ADDRESS(x) ((ttd_address)((natural_t)&(x) + sizeof(x)))
  114. #define TTD_KMSG(kmsg) ((kmsg == NULL) ? ttd_request_msg : kmsg)
  115. #define target_is_kernel(target) (target == TTD_KERNEL_MID)
  116. #define target_stopped() kttd_target.is_stopped
  117. #define valid_count(count) (count <= TTD_MAX_BLOCK_SIZE)
  118. /*
  119. * Aligned TTD Request.
  120. */
  121. struct ttd_request aligned_request;
  122. /*
  123. * Kernel target state:
  124. */
  125. boolean_t kttd_single_stepping = FALSE;
  126. ttd_seq kttd_current_seq;
  127. kttd_breakpoint kttd_breaktable[KTTD_MAXBPT];
  128. ttd_target_info kttd_target;
  129. ttd_machine_type ttd_target_machine_type;
  130. /*
  131. * Used by the ttd_stub code.
  132. */
  133. void kttd_stop_target(void)
  134. {
  135. kttd_target.is_stopped = TRUE;
  136. }
  137. /*
  138. * Used by the machine dependent code for single stepping.
  139. */
  140. boolean_t break_set(ttd_address addr,
  141. ttd_saved_inst *inst)
  142. {
  143. kttd_breakno b;
  144. for (b = 0; b < KTTD_MAXBPT; b++) {
  145. if ((!kttd_breaktable[b].free) &&
  146. (kttd_breaktable[b].address == addr)) {
  147. *inst = kttd_breaktable[b].saved_inst;
  148. return TRUE;
  149. }
  150. }
  151. return FALSE;
  152. }
  153. /*
  154. * Misc. routines for this module:
  155. */
  156. static boolean_t find_break(ttd_address addr,
  157. ttd_thread thread,
  158. kttd_breakno *bn)
  159. {
  160. kttd_breakno b;
  161. for (b = 0; b < KTTD_MAXBPT; b++) {
  162. if ((!kttd_breaktable[b].free) &&
  163. (kttd_breaktable[b].address == addr) &&
  164. (kttd_breaktable[b].thread == thread)) {
  165. *bn = b;
  166. return TRUE;
  167. }
  168. }
  169. return FALSE;
  170. }
  171. static boolean_t find_free_breakentry(kttd_breakno *breakno)
  172. {
  173. kttd_breakno b;
  174. for(b = 0; b < KTTD_MAXBPT; b++) {
  175. if (kttd_breaktable[b].free) {
  176. *breakno = b;
  177. return TRUE;
  178. }
  179. }
  180. return FALSE;
  181. }
  182. static boolean_t valid_thread(ttd_thread thread)
  183. {
  184. /* XXX Fix... */
  185. return TRUE;
  186. }
  187. static void init_break_table(void)
  188. {
  189. kttd_breakno bn;
  190. for (bn = 0; bn < KTTD_MAXBPT; bn++)
  191. kttd_breaktable[bn].free = TRUE;
  192. }
  193. static void init_kernel_target(void)
  194. {
  195. kttd_target.is_targeted = FALSE;
  196. kttd_target.is_stopped = FALSE;
  197. kttd_target.trapped_thread = 0;
  198. kttd_current_seq = 0x7fffffff;
  199. init_break_table();
  200. kttd_single_stepping = FALSE;
  201. }
  202. /*
  203. * Check to see if this message is a duplicate. Updates
  204. * the current sequence number as a side effect.
  205. */
  206. static boolean_t duplicate(ttd_seq s)
  207. {
  208. boolean_t dup;
  209. dup = (kttd_current_seq == s);
  210. if (kttd_debug && (s < kttd_current_seq))
  211. printf("TTD:duplicate, SRC code bites us here.\n");
  212. kttd_current_seq = s;
  213. return dup;
  214. }
  215. /*
  216. * Note: since the kernel is the only kttd target, the target is
  217. * implicit.
  218. */
  219. static void get_kernel_target_info(ttd_target_info *ti)
  220. {
  221. ti->is_stopped = kttd_target.is_stopped;
  222. ti->is_targeted = kttd_target.is_targeted;
  223. ti->trapped_thread = 1; /* XXX Fix */
  224. ti->debug_reason.length = 0;
  225. #if NOT_NOW
  226. strcpy("Hi!", ti->debug_reason.chars);
  227. #endif /* NOT_NOW */
  228. }
  229. /*******************/
  230. /* Action Routines */
  231. /*******************/
  232. /*
  233. * Read and write to kernel VM.
  234. */
  235. static ttd_code_t read_write_action(vm_prot_t access,
  236. ttd_address mem_ptr,
  237. ttd_address buffer,
  238. ttd_count length)
  239. {
  240. vm_size_t size;
  241. /*
  242. * handle this in pages
  243. */
  244. while (length > 0) {
  245. /*
  246. * get the number of bytes that we can
  247. * access in this page
  248. */
  249. size = trunc_page(mem_ptr + PAGE_SIZE) - mem_ptr;
  250. if (length < size)
  251. size = length;
  252. if (!kttd_mem_access(mem_ptr, access)) {
  253. if (kttd_debug)
  254. printf("can't read memory\n");
  255. return MemoryReferenceFailed;
  256. }
  257. /*
  258. * we can move anything on this page
  259. */
  260. if (access & VM_PROT_WRITE) {
  261. bcopy(buffer, mem_ptr, size);
  262. kttd_flush_cache(mem_ptr, size);
  263. }else if (access & VM_PROT_READ) {
  264. bcopy(mem_ptr, buffer, size);
  265. }else{
  266. return InvalidArgument;
  267. }
  268. mem_ptr += size;
  269. buffer += size;
  270. length -= size;
  271. }
  272. return Okay;
  273. }
  274. /*
  275. * XXX Fix it.
  276. */
  277. static boolean_t get_next_thread_action(ttd_thread *thread)
  278. {
  279. #if 0
  280. boolean_t found_prev;
  281. hardware_processor_number p;
  282. found_prev = (*thread == 0);
  283. for (p = 0; p < hardware_max_processors; p++) {
  284. if (ISIN (heaP->up, p)) {
  285. if (found_prev) {
  286. *thread = current_thread(p);
  287. return TRUE;
  288. }
  289. found_prev = (*thread == Current_thread(p));
  290. }
  291. }
  292. *thread = 0;
  293. return found_prev;
  294. #endif
  295. }
  296. static void get_state_action(ttd_thread thread,
  297. ttd_thread_info *thread_info,
  298. ttd_trap_info *trap_info,
  299. ttd_machine_state *machine_state)
  300. {
  301. /*
  302. * Don't do the thread_info, or trap_info now. XXX Fix it?
  303. */
  304. kttd_machine_getregs(machine_state);
  305. }
  306. static void set_state_action(ttd_thread thread,
  307. ttd_thread_info *thread_info,
  308. ttd_trap_info *trap_info,
  309. ttd_machine_state *machine_state)
  310. {
  311. /*
  312. * Don't do the thread_info, or trap_info now either. XXX Fix it?
  313. */
  314. kttd_machine_setregs(machine_state);
  315. }
  316. static void insert_break(kttd_breakno bn,
  317. ttd_address addr,
  318. ttd_thread thread,
  319. ttd_flavor flavor,
  320. ttd_saved_inst saved_inst)
  321. {
  322. kttd_breaktable[bn].free = FALSE;
  323. kttd_breaktable[bn].address = addr;
  324. kttd_breaktable[bn].thread = thread;
  325. kttd_breaktable[bn].flavor = flavor;
  326. kttd_breaktable[bn].saved_inst = saved_inst;
  327. }
  328. static ttd_code_t set_break_action(ttd_address addr,
  329. ttd_thread thread,
  330. ttd_flavor flavor,
  331. ttd_saved_inst *saved_inst)
  332. {
  333. kttd_breakno bn;
  334. boolean_t found = FALSE;
  335. /*
  336. * Check to see if a breakpoint is already set there for a
  337. * different thread.
  338. */
  339. for(bn = 0; bn < KTTD_MAXBPT; bn++) {
  340. if (!kttd_breaktable[bn].free &&
  341. (kttd_breaktable[bn].address == addr)) {
  342. *saved_inst = kttd_breaktable[bn].saved_inst;
  343. found = TRUE;
  344. break;
  345. }
  346. }
  347. /*
  348. * Get a free table entry.
  349. */
  350. if (!find_free_breakentry(&bn))
  351. return TooManyBreakpoints;
  352. /*
  353. * Insert into table if already have saved_inst.
  354. */
  355. if (found) {
  356. insert_break(bn, addr, thread, flavor, *saved_inst);
  357. return Okay;
  358. }
  359. /*
  360. * Fault in memory if not available.
  361. */
  362. if (!kttd_mem_access(addr, VM_PROT_WRITE))
  363. return MemoryReferenceFailed;
  364. /*
  365. * Insert the breakpoint into physical memory and flush the
  366. * cache.
  367. */
  368. if (!kttd_insert_breakpoint(addr, saved_inst))
  369. return MemoryReferenceFailed;
  370. kttd_flush_cache(addr, sizeof(ttd_saved_inst));
  371. /*
  372. * Insert breakpoint into table.
  373. */
  374. insert_break(bn, addr, thread, flavor, *saved_inst);
  375. if (kttd_debug) {
  376. printf("Inserting breakpoint into table at bn = %d\n",bn);
  377. }
  378. return Okay;
  379. }
  380. static ttd_code_t clear_break_action(ttd_address addr, ttd_thread thread)
  381. {
  382. kttd_breakno b;
  383. kttd_breakno bn = 0;
  384. ttd_count count = 0;
  385. ttd_saved_inst saved_inst;
  386. boolean_t found = FALSE;
  387. /*
  388. * Cycle through breaktable. If more than one breakpoint
  389. * at addr, we know not to replace memory with saved_inst.
  390. */
  391. for(b = 0; b < KTTD_MAXBPT; b++) {
  392. if (!kttd_breaktable[b].free &&
  393. (kttd_breaktable[b].address == addr)) {
  394. if (kttd_breaktable[b].thread == thread) {
  395. found = TRUE;
  396. bn = b;
  397. }
  398. if (++count > 1) {
  399. break;
  400. }
  401. }
  402. }
  403. /*
  404. * Didn't find breakpoint in table, return
  405. */
  406. if (!found) {
  407. if (kttd_debug) {
  408. printf("Couldn't find breakpoint in table.\n");
  409. }
  410. return InvalidArgument;
  411. }
  412. /*
  413. * Only one breakpoint at that address, fault in memory
  414. * and clear the breakpoint.
  415. */
  416. if (count == 1) {
  417. if (!kttd_mem_access(addr, VM_PROT_WRITE))
  418. return MemoryReferenceFailed;
  419. saved_inst = kttd_breaktable[bn].saved_inst;
  420. if (!kttd_remove_breakpoint(addr, saved_inst))
  421. return MemoryReferenceFailed;
  422. }
  423. /*
  424. * Free entry in breaktable.
  425. */
  426. kttd_breaktable[bn].free = TRUE;
  427. return Okay;
  428. }
  429. static ttd_code_t get_next_break_action(boolean_t all_breaks,
  430. ttd_address *addr,
  431. ttd_thread *thread,
  432. ttd_flavor *flavor,
  433. ttd_saved_inst *saved_inst)
  434. {
  435. kttd_breakno bn;
  436. kttd_breakno start;
  437. /*
  438. * If addr is zero, then start from beginning of list.
  439. * Otherwise, start from the breakno after addr's breakno.
  440. */
  441. if (*addr == 0) {
  442. start = 0;
  443. }else{
  444. /*
  445. * Find the first matching breakpoint entry.
  446. */
  447. for(bn = 0; bn < KTTD_MAXBPT; bn++) {
  448. if (!kttd_breaktable[bn].free &&
  449. (kttd_breaktable[bn].address == *addr) &&
  450. (kttd_breaktable[bn].thread == *thread))
  451. break;
  452. }
  453. /*
  454. * If ran off the end, it's an invalid argument.
  455. * Even all_breaks will have a valid addr and thread.
  456. */
  457. if (!all_breaks && (bn > KTTD_MAXBPT))
  458. return InvalidArgument;
  459. if (bn < KTTD_MAXBPT - 1) {
  460. start = bn + 1;
  461. }else{
  462. /*
  463. * Ran off the end. No more breakpoints
  464. * in the table. Return zeros in vars.
  465. */
  466. *addr = 0;
  467. *flavor = 0;
  468. bzero(saved_inst, sizeof(ttd_saved_inst));
  469. return Okay;
  470. }
  471. }
  472. for(bn = start; bn < KTTD_MAXBPT; bn ++) {
  473. if (!kttd_breaktable[bn].free &&
  474. (all_breaks ||
  475. (kttd_breaktable[bn].thread == *thread))) {
  476. *addr = kttd_breaktable[bn].address;
  477. *thread = kttd_breaktable[bn].thread;
  478. *flavor = kttd_breaktable[bn].flavor;
  479. *saved_inst = kttd_breaktable[bn].saved_inst;
  480. return Okay;
  481. }
  482. }
  483. *addr = 0;
  484. *flavor = 0;
  485. bzero(saved_inst, sizeof(ttd_saved_inst));
  486. return Okay;
  487. }
  488. /*
  489. * The Operations:
  490. */
  491. /*
  492. * probe_server:
  493. *
  494. * Probe server returns the version number of the KTTD implementation
  495. * and the machine type that it is executing on.
  496. *
  497. */
  498. static void probe_server(ttd_request_t request,
  499. ttd_reply_t reply,
  500. ttd_address *reply_end)
  501. {
  502. if (kttd_debug) {
  503. printf("TTD:Probe Server, version = %d, machine_type = %d\n",
  504. TTD_VERSION, ttd_target_machine_type);
  505. }
  506. reply->u.probe_server.version = netswap_4_bytes(TTD_VERSION);
  507. reply->u.probe_server.machine_type = netswap_4_bytes(ttd_target_machine_type);
  508. *reply_end = END_ADDRESS (reply->u.probe_server);
  509. }
  510. /*
  511. * get_target_info:
  512. *
  513. * Get target info returns the target_info struct for the given target.
  514. * Since this is the kttd implementation, the only valid target is the
  515. * kernel target (ie. it only returns the target info for the kernel.
  516. *
  517. */
  518. static void get_target_info(ttd_request_t request,
  519. ttd_reply_t reply,
  520. ttd_address *reply_end)
  521. {
  522. ttd_target target;
  523. ttd_target_info target_info;
  524. target = request->u.get_target_info.target;
  525. if (!target_is_kernel(target)) {
  526. reply->result.code = InvalidTarget;
  527. if (kttd_debug) {
  528. printf("TTD:get_target_info, invalid target %d\n", target);
  529. }
  530. return;
  531. }
  532. get_kernel_target_info(&target_info);
  533. reply->u.get_target_info.target_info = target_info;
  534. *reply_end = END_ADDRESS (reply->u.get_target_info);
  535. if (kttd_debug) {
  536. printf("TTD:get_target_info, target %d is %s, %s, th = 0x%x\n",
  537. target,
  538. target_info.is_stopped ? "stopped" : "running",
  539. target_info.is_targeted ? "targeted" : "untargeted",
  540. target_info.trapped_thread);
  541. }
  542. }
  543. /*
  544. * connect_to_target:
  545. *
  546. * Connect to target connects to the target. The only valid target
  547. * in the kttd implemetation is the kernel, all other targets are
  548. * invalid. If the kernel is already targeted, it can only succeed
  549. * if the key value that is passed in the request message is valid.
  550. *
  551. * Note: In this early implementation of kttd there is no security
  552. * built into the ttd protocol (ie. a value of MASTER_KEY
  553. * allows anyone to override the current connection).
  554. *
  555. */
  556. static void connect_to_target(ttd_request_t request,
  557. ttd_reply_t reply,
  558. ttd_address *reply_end)
  559. {
  560. ttd_target target;
  561. ttd_key key;
  562. ttd_target_info target_info;
  563. target = request->u.connect_to_target.target;
  564. key = request->u.connect_to_target.key;
  565. if (!target_is_kernel(target)) {
  566. reply->result.code = InvalidTarget;
  567. if (kttd_debug)
  568. printf("TTD:connect_to_target, invalid target %d\n", target);
  569. return;
  570. } else if (kttd_target.is_targeted && (key != MASTER_KEY)) {
  571. reply->result.code = TargetNotAvailable;
  572. if (kttd_debug)
  573. printf("TTD:connect_to_target, target %d unavailable\n", target);
  574. return;
  575. }
  576. kttd_target.is_targeted = TRUE;
  577. kttd_current_seq = 0;
  578. get_kernel_target_info(&target_info);
  579. reply->u.connect_to_target.target = TTD_KERNEL_MID;
  580. reply->u.connect_to_target.target_info = target_info;
  581. reply->result.argno = 2;
  582. *reply_end = END_ADDRESS (reply->u.connect_to_target);
  583. if (kttd_debug)
  584. printf("TTD:connect_to_target, connected kttd to target %d\n",target);
  585. }
  586. /*
  587. * disconnect_from_target:
  588. *
  589. * Disconnect from target disconnects from the specified target.
  590. * The kernel target is the only valid target in the kttd implemen-
  591. * tation.
  592. *
  593. * Note: This routine does not implicitly restart the target.
  594. *
  595. */
  596. static void disconnect_from_target(ttd_request_t request,
  597. ttd_reply_t reply,
  598. ttd_address *reply_end)
  599. {
  600. /*
  601. * The target checking is done in the kttd_service_request
  602. * routine. We know the target is the kernel if we get this
  603. * far.
  604. */
  605. kttd_target.is_targeted = FALSE;
  606. if (kttd_debug)
  607. printf("TTD:disconnect_from_target, disconnected from kttd target\n");
  608. }
  609. /*
  610. * read_from_target:
  611. *
  612. * Read from target reads count number of bytes from the target's
  613. * address space (the kernel in this implementation) and places them
  614. * in the reply message's buffer.
  615. *
  616. */
  617. static void read_from_target(ttd_request_t request,
  618. ttd_reply_t reply,
  619. ttd_address *reply_end)
  620. {
  621. ttd_address start;
  622. ttd_count count;
  623. ttd_address buffer;
  624. /*
  625. * Target must be stopped in order to do this operation.
  626. */
  627. if (!target_stopped()) {
  628. reply->result.code = TargetNotStopped;
  629. if (kttd_debug)
  630. printf("TTD:read_from_target, target not stopped.\n");
  631. return;
  632. }
  633. start = (ttd_address) request->u.read_from_target.start;
  634. count = request->u.read_from_target.count;
  635. buffer = (ttd_address) &reply->u.read_from_target.data[0];
  636. if (!valid_count(count)) {
  637. reply->result.code = InvalidArgument;
  638. if (kttd_debug)
  639. printf("TTD:read_from_target, invalid count 0x%x!!\n",
  640. count);
  641. return;
  642. }
  643. #if VERBOSE
  644. if (kttd_debug)
  645. printf("TTD:read_from_target, start= 0x%x count=0x%x,",
  646. start, count);
  647. #endif /* VERBOSE */
  648. reply->result.code = read_write_action(VM_PROT_READ, start, buffer, count);
  649. if (reply->result.code == Okay) {
  650. reply->u.read_from_target.count = count;
  651. *reply_end = (ttd_address)
  652. &reply->u.read_from_target.data[count];
  653. reply->result.argno = 2;
  654. #if VERBOSE
  655. if (kttd_debug)
  656. printf("OK! readbytes=0x%x\n",count);
  657. #endif /* VERBOSE */
  658. }
  659. }
  660. /*
  661. * write_info_target:
  662. *
  663. * Write into target writes count bytes into the target's address
  664. * space (the kernel's address space) at the address addr from the
  665. * request message's buffer.
  666. *
  667. */
  668. static void write_into_target(ttd_request_t request,
  669. ttd_reply_t reply,
  670. ttd_address *reply_end)
  671. {
  672. ttd_address start;
  673. ttd_count count;
  674. ttd_address buffer;
  675. /*
  676. * Target must be stopped in order to do this operation.
  677. */
  678. if (!target_stopped()) {
  679. reply->result.code = TargetNotStopped;
  680. if (kttd_debug)
  681. printf("TTD:write_into_target, target not stopped\n");
  682. return;
  683. }
  684. start = (ttd_address) request->u.write_into_target.start;
  685. count = request->u.write_into_target.count;
  686. buffer = (ttd_address) &request->u.write_into_target.data[0];
  687. if (!valid_count(count)) {
  688. reply->result.code = InvalidArgument;
  689. if (kttd_debug)
  690. printf("TTD:write_into_target, invalid count 0x%x\n",
  691. count);
  692. return;
  693. }
  694. reply->result.code = read_write_action(VM_PROT_WRITE, start, buffer, count);
  695. if (kttd_debug)
  696. printf("TTD:write_into_target, start=0x%x count=0x%x, result = %s\n",
  697. start, count, (reply->result.code == Okay) ? "OK" : "ERR");
  698. }
  699. /*
  700. * get_next_thread:
  701. *
  702. * Get next thread returns the next thread in the taks's (target's)
  703. * thread list starting at the thread in the request message. If the
  704. * request thread's value is NULL, the first thread in the task's
  705. * thread list is returned, otherwise we return the next thread.
  706. *
  707. */
  708. static void get_next_thread(ttd_request_t request,
  709. ttd_reply_t reply,
  710. ttd_address *reply_end)
  711. {
  712. ttd_thread thread;
  713. /*
  714. * Target must be stopped in order to do this operation.
  715. */
  716. if (!target_stopped()) {
  717. reply->result.code = TargetNotStopped;
  718. if (kttd_debug)
  719. printf("TTD:get_next_thread, target not stopped\n");
  720. return;
  721. }
  722. thread = request->u.get_next_thread.thread;
  723. if (!get_next_thread_action(&thread)) {
  724. reply->result.code = InvalidArgument;
  725. return;
  726. }
  727. reply->u.get_next_thread.next = thread;
  728. reply->result.argno = 1;
  729. *reply_end = END_ADDRESS (reply->u.get_next_thread);
  730. if (kttd_debug)
  731. printf("TTD:get_next_thread, orig= 0x%x, thread=0x%x\n",
  732. request->u.get_next_thread.thread, thread);
  733. }
  734. /*
  735. * get_thread_info:
  736. *
  737. * Get thread info returns information about the thread specified
  738. * in the request message. There are three parts to the thread info:
  739. *
  740. * thread_info: the thread's state (ie. what's returned by
  741. * thread_getstatus).
  742. *
  743. * trap_info: information on which trap caused the thread
  744. * to trap (if it is stopped).
  745. *
  746. * machine_state: the thread's register state.
  747. *
  748. * Note: In this implementation, we only support the machine state.
  749. *
  750. */
  751. static void get_thread_info(ttd_request_t request,
  752. ttd_reply_t reply,
  753. ttd_address *reply_end)
  754. {
  755. ttd_thread thread;
  756. ttd_thread_info thread_info;
  757. ttd_trap_info trap_info;
  758. ttd_machine_state machine_state;
  759. /*
  760. * Target must be stopped in order to do this operation.
  761. */
  762. if (!target_stopped()) {
  763. reply->result.code = TargetNotStopped;
  764. if (kttd_debug)
  765. printf("TTD:get_thread_info, target not stopped.\n");
  766. return;
  767. }
  768. thread = request->u.get_thread_info.thread;
  769. if (!valid_thread(thread)) {
  770. reply->result.code = InvalidArgument;
  771. if (kttd_debug)
  772. printf("TTD:get_thread_info, invalid thread.\n");
  773. return;
  774. }
  775. get_state_action(thread, &thread_info, &trap_info, &machine_state);
  776. if (kttd_debug)
  777. printf("TTD:get_thread_info, thread= 0x%x, ...\n", thread);
  778. reply->u.get_thread_info.thread_info = thread_info;
  779. reply->u.get_thread_info.trap_info = trap_info;
  780. reply->u.get_thread_info.machine_state = machine_state;
  781. reply->result.argno = 3;
  782. *reply_end = END_ADDRESS (reply->u.get_thread_info);
  783. }
  784. /*
  785. * set_thread_info:
  786. *
  787. * Set thread info sets the specified thread's three states to
  788. * parameters in the request message. These thread states are the
  789. * ones outlined above in the get_thread_info call.
  790. *
  791. * Note: Only the thread's machine_state is set in this implemen-
  792. * tation.
  793. *
  794. */
  795. static void set_thread_info(ttd_request_t request,
  796. ttd_reply_t reply,
  797. ttd_address *reply_end)
  798. {
  799. ttd_thread thread;
  800. ttd_thread_info *thread_info;
  801. ttd_trap_info *trap_info;
  802. ttd_machine_state *machine_state;
  803. /*
  804. * Target must be stopped in order to do this operation.
  805. */
  806. if (!target_stopped()) {
  807. reply->result.code = TargetNotStopped;
  808. if (kttd_debug)
  809. printf("TTD:set_thread_info, target not stopped.\n");
  810. return;
  811. }
  812. #if FUTURE
  813. thread = request->u.set_thread_info.thread;
  814. thread_info = &(request->u.set_thread_info.thread_info);
  815. trap_info = &(request->u.set_thread_info.trap_info);
  816. #endif /* FUTURE */
  817. machine_state = &(request->u.set_thread_info.machine_state);
  818. #if FUTURE
  819. if (!valid_thread(thread)) {
  820. reply->result.code = InvalidArgument;
  821. if (kttd_debug)
  822. printf("TTD:set_thread_info, invalid thread.\n");
  823. return;
  824. }
  825. #endif /* FUTURE */
  826. set_state_action(thread, thread_info, trap_info, machine_state);
  827. if (kttd_debug)
  828. printf("TTD:set_thread_info, thread= 0x%x, ...\n");
  829. }
  830. /*
  831. * stop_target:
  832. *
  833. * Stop target stops the target specified in the request message.
  834. * In order to issue this command, the client must have successfull
  835. * issued an attach_to_target request previous to this request.
  836. *
  837. * Note: this command was not directly supported by the original
  838. * NubTTD implementation. It is supported by kttd since
  839. * the kttd client can communicate with the kttd server
  840. * asynchronously.
  841. *
  842. * Note: This implementation stops all threads in a task. Future
  843. * versions will work on a per-thread basis.
  844. *
  845. */
  846. static void stop_target(ttd_request_t request,
  847. ttd_reply_t reply,
  848. ttd_address *reply_end)
  849. {
  850. /*
  851. * Return error message if already stopped.
  852. */
  853. if (target_stopped()) {
  854. reply->result.code = TargetStopped;
  855. if (kttd_debug)
  856. printf("TTD:stop_target, target ALREADY stopped.\n");
  857. return;
  858. }
  859. /*
  860. * All we need to do to stop the kernel is call
  861. * kttd_break. This will cause this "thread" to
  862. * enter the kttd_handle_sync() routine which will:
  863. *
  864. * 1. Halt all the processors.
  865. *
  866. * 2. Stop the kernel (kttd_target.is_stopped = TRUE).
  867. *
  868. */
  869. if (kttd_debug)
  870. printf("TTD:stop_target, stopping kernel.\n");
  871. kttd_halt_processors();
  872. kttd_target.is_stopped = TRUE;
  873. #if PRE_MIPS_CODE
  874. kttd_stop_status = FULL_STOP;
  875. #else
  876. kttd_run_status = FULL_STOP;
  877. #endif /* PRE_MIPS_CODE */
  878. }
  879. /*
  880. * probe_target:
  881. *
  882. * Probe target returns the target info of the current target. This
  883. * is used extensively by the asynhronous client. In general the client
  884. * will poll the kttd target until it is stopped, and only then issue
  885. * requests.
  886. *
  887. */
  888. static void probe_target(ttd_request_t request,
  889. ttd_reply_t reply,
  890. ttd_address *reply_end)
  891. {
  892. ttd_target_info target_info;
  893. get_kernel_target_info(&target_info);
  894. reply->u.probe_target.target_info = target_info;
  895. reply->result.argno = 1;
  896. *reply_end = END_ADDRESS (reply->u.probe_target);
  897. if (kttd_debug)
  898. printf("TTD:probe_target, Kernel target is %s, %s, th = 0x%x\n",
  899. target_info.is_stopped ? "stopped" : "running",
  900. target_info.is_targeted ? "targeted" : "untargeted",
  901. target_info.trapped_thread);
  902. }
  903. /*
  904. * restart_target:
  905. *
  906. * Restart target resume's the kttd target's (the kernel's) execution.
  907. *
  908. * Note: The current implementation restarts all a tasks threads at once.
  909. * Future versions will work on a per thread basis.
  910. *
  911. */
  912. static ttd_response_t restart_target(ttd_request_t request,
  913. ttd_reply_t reply,
  914. ttd_address *reply_end)
  915. {
  916. ttd_thread thread;
  917. /*
  918. * If target already running return error code.
  919. */
  920. if (!target_stopped()) {
  921. reply->result.code = TargetNotStopped;
  922. if (kttd_debug)
  923. printf("TTD:restart_target, target not stopped.\n");
  924. return SEND_REPLY;
  925. }
  926. if (kttd_debug)
  927. printf("TTD:restart_target, restarting target....\n");
  928. /*
  929. * We don't need to save a message for duplicate replies since
  930. * restart doesn't send a reply. We have a check when we check
  931. * for duplicates that determines if it's a duplicate restart packet.
  932. * If it is, then we just ignore it.
  933. *
  934. * The same holds for duplicate single_step packets.
  935. */
  936. /* This will make it restart. */
  937. #if PRE_MIPS_CODE
  938. kttd_stop_status = ONE_STOP;
  939. #else
  940. kttd_run_status = ONE_STOP;
  941. #endif /* PRE_MIPS_CODE */
  942. kttd_target.is_stopped = FALSE;
  943. #if SECOND_ATTEMPT
  944. /* Restart operations do not expect a reply. */
  945. return NO_REPLY;
  946. #else
  947. /*
  948. * Second way didn't send reply now, but third way will.
  949. * We'll cache the reply and send it whenever we receive
  950. * a duplicate! Duhhhhhh....
  951. */
  952. return SEND_REPLY;
  953. #endif /* SECOND_ATTEMPT */
  954. }
  955. /*
  956. * set_breakpoint_in_target
  957. *
  958. * Set breakpoint in target sets a breakpoint for a specified thread in
  959. * in the current task's (the kernel task) at a specified address with
  960. * a specified flavor. If the thread is NULL, it applies to all threads
  961. * in the target's task (all kernel threads).
  962. *
  963. */
  964. static void set_breakpoint_in_target(ttd_request_t request,
  965. ttd_reply_t reply,
  966. ttd_address *reply_end)
  967. {
  968. ttd_address addr;
  969. ttd_thread thread;
  970. ttd_flavor flavor;
  971. kttd_breakno bn;
  972. ttd_saved_inst saved_inst;
  973. /*
  974. * Target must be stopped in order to do this operation.
  975. */
  976. if (!target_stopped()) {
  977. reply->result.code = TargetNotStopped;
  978. if (kttd_debug)
  979. printf("TTD:set_breakpoint, target not stopped.\n");
  980. return;
  981. }
  982. addr = (ttd_address) request->u.set_breakpoint_in_target.address;
  983. thread = (ttd_thread) request->u.set_breakpoint_in_target.thread;
  984. flavor = request->u.set_breakpoint_in_target.flavor;
  985. if (thread && !valid_thread(thread)) {
  986. reply->result.code = InvalidArgument;
  987. if (kttd_debug) {
  988. printf("TTD:set_breakpoint, Invalid thread.\n");
  989. }
  990. return;
  991. }
  992. if (kttd_debug) {
  993. printf("TTD:set_breakpoint, addr= 0x%x, thread= 0x%x, flavor= %d, ",
  994. addr, thread, flavor);
  995. }
  996. if (find_break(addr, thread, &bn)) {
  997. kttd_breaktable[bn].flavor = flavor;
  998. saved_inst = kttd_breaktable[bn].saved_inst;
  999. }else{
  1000. reply->result.code = set_break_action(addr, thread,
  1001. flavor, &saved_inst);
  1002. }
  1003. if (!reply->result.code == Okay) {
  1004. if (kttd_debug)
  1005. printf("ERR\n");
  1006. return;
  1007. }
  1008. if (kttd_debug)
  1009. printf("OK\n");
  1010. reply->u.set_breakpoint_in_target.saved_inst = saved_inst;
  1011. reply->result.argno = 1;
  1012. *reply_end = END_ADDRESS(reply->u.set_breakpoint_in_target);
  1013. }
  1014. /*
  1015. * clear_breakpoint_in_target:
  1016. *
  1017. * Clear breakpoint in target removes the breakpoint from target's
  1018. * breakpoint table. Like the set breakpoint request above, it takes
  1019. * an address and a thread. If the thread is NULL, it only clears
  1020. * the breakpoints that apply to all threads.
  1021. *
  1022. */
  1023. static void clear_breakpoint_in_target(ttd_request_t request,
  1024. ttd_reply_t reply,
  1025. ttd_address *reply_end)
  1026. {
  1027. ttd_address addr;
  1028. ttd_thread thread;
  1029. /*
  1030. * Target must be stopped in order to do this operation.
  1031. */
  1032. if (!target_stopped()) {
  1033. reply->result.code = TargetNotStopped;
  1034. if (kttd_debug)
  1035. printf("TTD:clear_break, target not stopped.\n");
  1036. return;
  1037. }
  1038. addr = (ttd_address)request->u.clear_breakpoint_in_target.address;
  1039. thread = (ttd_thread)request->u.clear_breakpoint_in_target.thread;
  1040. if (kttd_debug)
  1041. printf("TTD:clear_breakpoint, addr= 0x%x, thread= 0x%x\n",
  1042. addr, thread);
  1043. /*
  1044. * Doesn't have to be a legal thread. Might want to clear a
  1045. * breakpoint for a thread that has been destroyed. The
  1046. * clear break action procedure will ignore threads that don't
  1047. * have breakpoints in the table.
  1048. */
  1049. reply->result.code = clear_break_action(addr, thread);
  1050. }
  1051. /*
  1052. * get_next_breakpoint_in_target:
  1053. *
  1054. * Get next breakpoint in target returns the next breakpoint in the
  1055. * target's (the kernel's) breakpoint list. This request returns the
  1056. * next breakpoint with respect to the breakpoint passed in the request.
  1057. * If the request breakpoint is NULL, it starts at the beginning of the
  1058. * breakpoint list. If all_breaks is TRUE it returns the next breakpoint
  1059. * without regard to the breakpoint's associated thread. If all_breaks
  1060. * is FALSE it only returns the next breakpoint that is associated with
  1061. * the thread specified in the request message.
  1062. *
  1063. * Note: This request can be issued on a running target.
  1064. *
  1065. */
  1066. static void get_next_breakpoint_in_target(ttd_request_t request,
  1067. ttd_reply_t reply,
  1068. ttd_address *reply_end)
  1069. {
  1070. ttd_address addr;
  1071. ttd_thread thread;
  1072. ttd_flavor flavor;
  1073. ttd_saved_inst saved_inst;
  1074. boolean_t all_breaks;
  1075. addr = (ttd_address)request->u.get_next_breakpoint_in_target.address;
  1076. thread = (ttd_thread)request->u.get_next_breakpoint_in_target.thread;
  1077. all_breaks = request->u.get_next_breakpoint_in_target.all_breaks;
  1078. if (kttd_debug)
  1079. printf("TTD:get_break, address= 0x%x, thread= 0x%x, allbreaks= 0x%x\n",
  1080. addr, thread, all_breaks);
  1081. reply->result.code = get_next_break_action(all_breaks, &addr, &thread,
  1082. &flavor, &saved_inst);
  1083. if (reply->result.code != Okay)
  1084. return;
  1085. reply->u.get_next_breakpoint_in_target.address = (ttd_address) addr;
  1086. reply->u.get_next_breakpoint_in_target.flavor = flavor;
  1087. reply->u.get_next_breakpoint_in_target.saved_inst = saved_inst;
  1088. *reply_end = END_ADDRESS (reply->u.get_next_breakpoint_in_target);
  1089. }
  1090. /*
  1091. * kttd_single_step:
  1092. *
  1093. * KTTD Single Step sets the machine independent single stepping
  1094. * values to single stepping state. It then calls the machine
  1095. * dependent code to turn the machine into single stepping mode.
  1096. *
  1097. */
  1098. boolean_t kttd_single_step(void)
  1099. {
  1100. if (kttd_single_stepping) {
  1101. printf("kttd_single_step: Already Single stepping!!!\n");
  1102. return FALSE;
  1103. }
  1104. kttd_single_stepping = TRUE;
  1105. /*
  1106. * In the current implementation, we can only set and
  1107. * clear single step in the kernel task.
  1108. */
  1109. return(kttd_set_machine_single_step(NULL));
  1110. }
  1111. /*
  1112. * kttd_clear_single_step:
  1113. *
  1114. * KTTD Clear Single Step clear the machine independent single stepping
  1115. * mechanism, and takes the machine out of single stepping mode.
  1116. *
  1117. */
  1118. boolean_t kttd_clear_single_step(void)
  1119. {
  1120. if (!kttd_single_stepping) {
  1121. printf("kttd_clear_single_step: Already out of single stepping!!\n");
  1122. }
  1123. kttd_single_stepping = FALSE;
  1124. /*
  1125. * In the current implementation, we can only set and
  1126. * clear single step in the kernel task.
  1127. */
  1128. return (kttd_clear_machine_single_step(NULL));
  1129. }
  1130. boolean_t kttd_in_single_step(void)
  1131. {
  1132. return (kttd_single_stepping);
  1133. }
  1134. /*
  1135. * single_step_thread:
  1136. *
  1137. * Single step thread starts a thread specified in the request message
  1138. * executing in single step mode.
  1139. *
  1140. * Note: In this implementation you can only single step the current
  1141. * thread.
  1142. *
  1143. */
  1144. static ttd_response_t single_step_thread(ttd_request_t request,
  1145. ttd_reply_t reply,
  1146. ttd_address *reply_end)
  1147. {
  1148. ttd_thread thread;
  1149. /*
  1150. * Target must be stopped in order to do this operation.
  1151. */
  1152. if (!target_stopped()) {
  1153. reply->result.code = TargetNotStopped;
  1154. if (kttd_debug)
  1155. printf("TTD:single_step, target not stopped.\n");
  1156. return SEND_REPLY;
  1157. }
  1158. #if DO_LATER
  1159. thread = request->u.single_step_thread.thread;
  1160. if (!valid_thread(thread)) {
  1161. reply->result.code = InvalidArgument;
  1162. return SEND_REPLY;
  1163. }
  1164. #endif /* DO_LATER */
  1165. /*
  1166. * Note: in this implementation a thread is assumed to
  1167. * be stopped if it's target (task) is not running,
  1168. * make sure the check that the thread is stopped
  1169. * when the implementation is changed to allow
  1170. * thread stoppages.
  1171. */
  1172. /*
  1173. * What should happen here:
  1174. *
  1175. * 1. swap in the specified thread.
  1176. *
  1177. */
  1178. if (!kttd_single_step()) {
  1179. reply->result.code = SingleSteppingError;
  1180. if (kttd_debug)
  1181. printf("TTD:single_step, single stepping ERROR!\n");
  1182. return SEND_REPLY;
  1183. }
  1184. if (kttd_debug)
  1185. printf("TTD:single_step, single step.\n");
  1186. /* This will restart the kernel */
  1187. #if PRE_MIPS_CODE
  1188. kttd_stop_status = ONE_STOP;
  1189. #else
  1190. kttd_run_status = ONE_STOP;
  1191. #endif /* PRE_MIPS_CODE */
  1192. kttd_target.is_stopped = FALSE;
  1193. #if SECOND_ATTEMPT
  1194. return NO_REPLY;
  1195. #else
  1196. /* See comments in restart_target. */
  1197. return SEND_REPLY;
  1198. #endif /* SECOND_ATTEMPT */
  1199. }
  1200. /*
  1201. * ttd_decode_request:
  1202. *
  1203. * Returns TRUE if a reply should be sent, FALSE if no reply
  1204. * should be sent.
  1205. *
  1206. */
  1207. static ttd_response_t ttd_decode_request(ttd_request_t request,
  1208. ttd_reply_t reply,
  1209. natural_t * reply_length)
  1210. {
  1211. ttd_address reply_end;
  1212. boolean_t targeted_op;
  1213. ttd_response_t sr;
  1214. /*
  1215. * Convert from network to host byte ordering.
  1216. */
  1217. request->server = netswap_4_bytes(request->server);
  1218. request->seq = netswap_4_bytes(request->seq);
  1219. request->target = netswap_4_bytes(request->target);
  1220. request->operation = netswap_4_bytes(request->operation);
  1221. targeted_op = request->operation > CONNECT_TO_TARGET;
  1222. /*
  1223. * Setup the reply's return values that are common
  1224. * to all operations:
  1225. */
  1226. reply->server = netswap_4_bytes(KERNEL_TTD);
  1227. reply->target = netswap_4_bytes(TTD_KERNEL_MID);
  1228. reply->result.code = Okay;
  1229. reply->result.argno = 0;
  1230. reply->operation = netswap_4_bytes(request->operation);
  1231. reply_end = END_ADDRESS(reply->operation);
  1232. /*
  1233. * Set this now for those requests that return before the end.
  1234. */
  1235. *reply_length = (natural_t)reply_end - (natural_t)reply;
  1236. /*
  1237. * For untargeted operations, set the sequence number of the
  1238. * reply to the seq # of the last valid targeted operation.
  1239. * This is used by the client end to determine restart and single
  1240. * stepping reception.
  1241. */
  1242. reply->seq = netswap_4_bytes(kttd_current_seq);
  1243. if (request->server != KERNEL_TTD) {
  1244. reply->result.code = ServerNotAvailable;
  1245. if (kttd_debug)
  1246. printf("KTTD Server not available.\n");
  1247. return SEND_REPLY;
  1248. }
  1249. /*
  1250. * Make sure that there aren't any idempotent operations
  1251. * that aren't targeted operations, since the duplicate
  1252. * sequence checking takes place in this if-clause!
  1253. */
  1254. if (targeted_op) {
  1255. if (!target_is_kernel(request->target)) {
  1256. reply->result.code = InvalidTarget;
  1257. if (kttd_debug)
  1258. printf("Invalid KTTD target.\n");
  1259. return SEND_REPLY;
  1260. }
  1261. if (!kttd_target.is_targeted) {
  1262. reply->result.code = TargetNotAvailable;
  1263. if (kttd_debug)
  1264. printf("Kernel not targeted.\n");
  1265. return SEND_REPLY;
  1266. }
  1267. if (duplicate(request->seq)) {
  1268. #if SECOND_ATTEMPT
  1269. /*
  1270. * The problem is, what happens when we get a duplicate
  1271. * restart or single step message? There wasn't a
  1272. * reply for it, so we can't resend it. So we just
  1273. * act like we're ignoring it (like we did the first
  1274. * message), and "know" that we've already restarted
  1275. * or single stepped the kernel.
  1276. */
  1277. if ((prev_operation == RESTART_TARGET) ||
  1278. (prev_operation == SINGLE_STEP_THREAD))
  1279. return NO_REPLY;
  1280. #endif /* SECOND_ATTEMPT */
  1281. bcopy(&prev_reply, reply, prev_reply_length);
  1282. if (kttd_debug)
  1283. #if KTTD_VERBOSE
  1284. printf("Duplicate, resending last reply.\n");
  1285. #else
  1286. printf("<D>");
  1287. #endif /* KTTD_VERBOSE */
  1288. return SEND_REPLY;
  1289. }
  1290. }
  1291. switch(request->operation) {
  1292. case PROBE_SERVER:
  1293. probe_server(request, reply, &reply_end);
  1294. sr = SEND_REPLY;
  1295. break;
  1296. case GET_TARGET_INFO:
  1297. get_target_info(request, reply, &reply_end);
  1298. sr = SEND_REPLY;
  1299. break;
  1300. case CONNECT_TO_TARGET:
  1301. connect_to_target(request, reply, &reply_end);
  1302. sr = SEND_REPLY;
  1303. break;
  1304. case DISCONNECT_FROM_TARGET:
  1305. disconnect_from_target(request, reply, &reply_end);
  1306. sr = SEND_REPLY;
  1307. break;
  1308. case READ_FROM_TARGET:
  1309. read_from_target(request, reply, &reply_end);
  1310. sr = SEND_REPLY;
  1311. break;
  1312. case WRITE_INTO_TARGET:
  1313. write_into_target(request, reply, &reply_end);
  1314. sr = SEND_REPLY;
  1315. break;
  1316. case GET_NEXT_THREAD:
  1317. get_next_thread(request, reply, &reply_end);
  1318. sr = SEND_REPLY;
  1319. break;
  1320. case GET_THREAD_INFO:
  1321. get_thread_info(request, reply, &reply_end);
  1322. sr = SEND_REPLY;
  1323. break;
  1324. case SET_THREAD_INFO:
  1325. set_thread_info(request, reply, &reply_end);
  1326. sr = SEND_REPLY;
  1327. break;
  1328. case STOP_TARGET:
  1329. stop_target(request, reply, &reply_end);
  1330. sr = SEND_REPLY;
  1331. break;
  1332. case PROBE_TARGET:
  1333. probe_target(request, reply, &reply_end);
  1334. sr = SEND_REPLY;
  1335. break;
  1336. case RESTART_TARGET:
  1337. sr = restart_target(request, reply, &reply_end);
  1338. break;
  1339. case SET_BREAKPOINT_IN_TARGET:
  1340. set_breakpoint_in_target(request, reply, &reply_end);
  1341. sr = SEND_REPLY;
  1342. break;
  1343. case CLEAR_BREAKPOINT_IN_TARGET:
  1344. clear_breakpoint_in_target(request, reply, &reply_end);
  1345. sr = SEND_REPLY;
  1346. break;
  1347. case GET_NEXT_BREAKPOINT_IN_TARGET:
  1348. get_next_breakpoint_in_target(request, reply, &reply_end);
  1349. sr = SEND_REPLY;
  1350. break;
  1351. case SINGLE_STEP_THREAD:
  1352. sr = single_step_thread(request, reply, &reply_end);
  1353. break;
  1354. default:
  1355. sr = SEND_REPLY;
  1356. reply->result.code = InvalidOperation;
  1357. /*
  1358. * Don't return here, we might've already set up our
  1359. * seq # as the duplicate seq #, and we therefore need
  1360. * to make sure that the prev_reply_length field is set
  1361. * properly.
  1362. */
  1363. }
  1364. /*
  1365. * See above comment dealing with the reply->seq.
  1366. */
  1367. if (targeted_op)
  1368. reply->seq = netswap_4_bytes(request->seq);
  1369. *reply_length = (natural_t)reply_end - (natural_t)reply;
  1370. prev_operation = request->operation;
  1371. return (sr);
  1372. }
  1373. /*
  1374. * ttd_service_request:
  1375. *
  1376. */
  1377. void ttd_service_request(void)
  1378. {
  1379. natural_t kttd_reply_length;
  1380. ttd_request_t request;
  1381. ttd_reply_t reply;
  1382. /*
  1383. * If the length is bad, just drop the packet.
  1384. */
  1385. if (kttd_current_length > sizeof(struct ttd_request)) {
  1386. if (kttd_debug)
  1387. printf("INVALID TTD Request Size!! 0x%x > 0x%x\n",
  1388. kttd_current_length, sizeof(struct ttd_request));
  1389. return;
  1390. }
  1391. request = (ttd_request_t)kttd_current_request;
  1392. reply = skip_net_headers(ttd_reply_msg);
  1393. if ((int)request % BYTE_ALIGNMENT) {
  1394. request = &aligned_request;
  1395. bcopy(kttd_current_request, request,
  1396. ((kttd_current_length) > sizeof(struct ttd_request) ?
  1397. sizeof(struct ttd_request) : kttd_current_length));
  1398. }
  1399. if (ttd_decode_request(request, reply, &kttd_reply_length) == SEND_REPLY) {
  1400. /*
  1401. * We've only built the ttd_reply_msg portion of the
  1402. * reply. Now build the ether/ip/udp parts and cache
  1403. * the reply for duplicate retransmissions.
  1404. *
  1405. * Save this reply so that duplicate requests
  1406. * receive the right reply (idempotent requests).
  1407. *
  1408. * Remember that kttd_reply_msg is the
  1409. * skip_net_headers(ttd_reply_msg)!
  1410. *
  1411. * Just save the struct ttd_reply_msg, we'll build the
  1412. * reply header and ip/udp contents later.
  1413. *
  1414. */
  1415. bcopy(skip_net_headers(ttd_reply_msg),
  1416. &prev_reply,
  1417. kttd_reply_length);
  1418. prev_reply_length = kttd_reply_length;
  1419. /*
  1420. * Build the Full reply msg, then send it.
  1421. */
  1422. complete_and_send_ttd_reply(kttd_reply_length);
  1423. }
  1424. }
  1425. void ttd_server_initialize(void)
  1426. {
  1427. if (ttd_server_initialized)
  1428. return;
  1429. init_kernel_target();
  1430. ttd_target_machine_type = get_ttd_machine_type();
  1431. ttd_request_msg = &ttd_request_msg_array[0];
  1432. ttd_reply_msg = &ttd_reply_msg_array[0];
  1433. /*
  1434. * Get it to line up on the last 2 byte boundary before a
  1435. * BYTE_ALIGNMENT boundary.
  1436. */
  1437. ttd_reply_msg = (char *)((int)ttd_reply_msg +
  1438. (int)ttd_reply_msg % BYTE_ALIGNMENT +
  1439. (BYTE_ALIGNMENT - 2));;
  1440. ttd_server_initialized = TRUE;
  1441. }