Subversion Repositories HelenOS

Rev

Rev 3005 | Rev 3099 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2008 Jiri Svoboda
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup debug
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <sys/types.h>
  38. #include <udebug.h>
  39.  
  40. #include "../../../cons.h"
  41. #include "../../../main.h"
  42. #include "../../../breakpoint.h"
  43. #include "../../../include/arch.h"
  44.  
  45. #define OPCODE_BREAK        0x0000000d
  46.  
  47. static istate_t istate;
  48.  
  49. int arch_breakpoint_set(breakpoint_t *b)
  50. {
  51.     uint32_t brkp;
  52.     int rc;
  53.  
  54.     rc = udebug_mem_read(app_phone, &b->arch.back, b->addr,
  55.         sizeof(b->arch.back));
  56.     if (rc < 0) return rc;
  57.  
  58.     cons_printf("udebug_mem_read() -> %d\n", rc);
  59.     brkp = OPCODE_BREAK;
  60.     rc = udebug_mem_write(app_phone, &brkp, b->addr, sizeof(brkp));
  61.     cons_printf("udebug_mem_write() -> %d\n", rc);
  62.     if (rc < 0) return rc;
  63.  
  64.     return 0;
  65. }
  66.  
  67. int arch_breakpoint_remove(breakpoint_t *b)
  68. {
  69.     int rc;
  70.  
  71.     if (b->active) {
  72.         rc = udebug_mem_write(app_phone, &b->arch.back, b->addr + 4, 4);
  73.         if (rc < 0) {
  74.             cons_printf("error writing memory\n");
  75.             return rc;
  76.         }
  77.         active_bkpt = NULL;
  78.     } else {
  79.             rc = udebug_mem_write(app_phone, &b->arch.back, b->addr, 4);
  80.         if (rc < 0) {
  81.             cons_printf("error writing memory\n");
  82.             return rc;
  83.         }
  84.     }
  85.  
  86.     return 0;
  87.  
  88. }
  89.  
  90. void arch_event_breakpoint(thash_t thread_hash)
  91. {
  92.     breakpoint_t *b;
  93.     dthread_t *dt;
  94.     int rc;
  95.     uint32_t epc;
  96.     int brk_addr;
  97.     uint32_t brkp;
  98.  
  99.     brkp = OPCODE_BREAK;
  100.  
  101.     cons_printf("arch_event_breakpoint\n");
  102.  
  103.     rc = udebug_regs_read(app_phone, thread_hash, &istate);
  104.     cons_printf("udebug_regs_read -> %d\n", rc);
  105.     epc = istate_get_pc(&istate);
  106.     cons_printf("EPC was 0x%08x\n", epc);
  107.     brk_addr = epc;
  108.  
  109.     b = breakpoint_find_by_addr(brk_addr);
  110.     if (b != NULL) {
  111.         cons_printf("move breakpoint\b");
  112.             rc = udebug_mem_write(app_phone, &b->arch.back, brk_addr, 4);
  113.         rc = udebug_mem_read(app_phone, &b->arch.back, brk_addr + 4, 4);
  114.             rc = udebug_mem_write(app_phone, &brkp, brk_addr + 4, 4);
  115.         active_bkpt = b;
  116.         b->active = true;
  117.  
  118.         cons_printf("breakpoint_hit...\n");
  119.         breakpoint_hit(b);
  120.         cons_printf("end_hit...\n");
  121.         return;
  122.     }
  123.  
  124.     b = breakpoint_find_by_addr(brk_addr - 4);
  125.     if (b != NULL && b->active) {
  126.         cons_printf("restoring breakpoint %d\n", b->id);
  127.             rc = udebug_mem_write(app_phone, &b->arch.back, brk_addr, 4);
  128.         rc = udebug_mem_read(app_phone, &b->arch.back, brk_addr - 4, 4);
  129.             rc = udebug_mem_write(app_phone, &brkp, brk_addr - 4, 4);
  130.         active_bkpt = NULL;
  131.        
  132.         if (dt->arch.singlestep) {
  133.             singlestep_hit();
  134.  
  135.             rc = udebug_mem_read(app_phone, &dt->arch.sstep_back, brk_addr + 4, 4);
  136.             rc = udebug_mem_write(app_phone, &brkp, brk_addr + 4, 4);
  137.         }
  138.         return;
  139.     }
  140.  
  141.     dt = dthread_get();
  142.  
  143.     if (dt->arch.singlestep) {
  144.         cons_printf("advance singlestep\n");
  145.             rc = udebug_mem_write(app_phone, &dt->arch.sstep_back, brk_addr, 4);
  146.         rc = udebug_mem_read(app_phone, &dt->arch.sstep_back, brk_addr + 4, 4);
  147.             rc = udebug_mem_write(app_phone, &brkp, brk_addr + 4, 4);
  148.  
  149.         singlestep_hit();
  150.  
  151.         return;
  152.     }
  153.  
  154.     cons_printf("Unrecognized breakpoint at 0x%lx\n", brk_addr);
  155. }
  156.  
  157. void arch_event_trap(dthread_t *dt)
  158. {
  159.     /* Unused */
  160.     (void)dt;
  161. }
  162.  
  163. void arch_dump_regs(thash_t thash)
  164. {
  165. }
  166.  
  167. void arch_set_singlestep(dthread_t *dt, int enable)
  168. {
  169.     int rc;
  170.     uint32_t epc;
  171.     uint32_t brk;
  172.     breakpoint_t *b1, *b2;
  173.  
  174.     brk = OPCODE_BREAK;
  175.  
  176.     cons_printf("arch_set_singlestep(dt, %d)\n", enable);
  177.     rc = udebug_regs_read(app_phone, dt->hash, &istate);
  178.     cons_printf("udebug_regs_read -> %d\n", rc);
  179.     epc = istate_get_pc(&istate);
  180.     cons_printf("EPC was 0x%08x\n", epc);
  181.  
  182.     b1 = breakpoint_find_by_addr(epc - 4);
  183.     b2 = breakpoint_find_by_addr(epc);
  184.  
  185.     if (enable && !dt->arch.singlestep) {
  186.         if (b1 && b1->active) {
  187.             dt->arch.sstep_back = b1->arch.back;
  188.         } else if (b2) {
  189.             dt->arch.sstep_back = b2->arch.back;
  190.         } else {
  191.             cons_printf("initial set singlestep\b");
  192.             rc = udebug_mem_read(app_phone, &dt->arch.sstep_back, epc + 4, 4);
  193.             rc = udebug_mem_write(app_phone, &brk, epc + 4, 4);
  194.             if (rc < 0) { cons_printf("error writing mem\n"); return; }
  195.         }
  196.     } else if (!enable && dt->arch.singlestep) {
  197.         if ((b1 && b1->active) || b2) {
  198.             /* Do not remove BRK instruction */
  199.         } else  {
  200.             cons_printf("remove singlestep\b");
  201.             rc = udebug_mem_write(app_phone, &dt->arch.sstep_back, epc + 4, 4);
  202.         }
  203.     }
  204.     dt->arch.singlestep = enable;
  205. }
  206.  
  207. /** @}
  208.  */
  209.