home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / mondfe / bkpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  11.6 KB  |  475 lines

  1. static char _[] = " @(#)bkpt.c    5.20 93/07/30 16:38:20, Srini, AMD ";
  2. /******************************************************************************
  3.  * Copyright 1991 Advanced Micro Devices, Inc.
  4.  *
  5.  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
  6.  * specifically  grants the user the right to modify, use and distribute this
  7.  * software provided this notice is not removed or altered.  All other rights
  8.  * are reserved by AMD.
  9.  *
  10.  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
  11.  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
  12.  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
  13.  * USE OF THIS SOFTWARE.
  14.  *
  15.  * So that all may benefit from your experience, please report  any  problems
  16.  * or  suggestions about this software to the 29K Technical Support Center at
  17.  * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
  18.  * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
  19.  *
  20.  * Advanced Micro Devices, Inc.
  21.  * 29K Support Products
  22.  * Mail Stop 573
  23.  * 5900 E. Ben White Blvd.
  24.  * Austin, TX 78741
  25.  * 800-292-9263
  26.  *****************************************************************************
  27.  *      Engineer: Srini Subramanian.
  28.  *****************************************************************************
  29.  **       This module contains the functions used to provide breakpointing
  30.  **      capability.
  31.  *****************************************************************************
  32.  */
  33.  
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include "memspcs.h"
  37. #include "main.h"
  38. #include "monitor.h"
  39. #include "miniint.h"
  40. #include "error.h"
  41.  
  42. #ifdef    MSDOS
  43. #include <stdlib.h>
  44. #include <string.h>
  45.  
  46. #else
  47. #include <strings.h>
  48.  
  49. #endif
  50.  
  51. /*
  52. ** Definitions
  53. */
  54.  
  55. int   get_addr_29k_m PARAMS((char *, struct addr_29k_t *, INT32));
  56. int   addr_29k_ok PARAMS((struct addr_29k_t *));
  57. int   get_word PARAMS((char *, INT32 *));
  58. int   get_word_decimal PARAMS((char *, INT32 *));
  59.  
  60. INT32   clear_table PARAMS((void));
  61. INT32   clear_bkpt PARAMS((struct addr_29k_t));
  62. INT32   show_table PARAMS((void));
  63. INT32   set_bkpt PARAMS((struct addr_29k_t,
  64.              INT32, 
  65.              INT32));
  66.  
  67. INT32 match_entry PARAMS((ADDR32 offset,
  68.               INT32 space,
  69.               int *id));
  70. INT32 remove_from_table PARAMS((int id));
  71.  
  72. INT32 add_to_table PARAMS((ADDR32 offset, 
  73.                INT32 space,
  74.                INT32 passcnt,
  75.                INT32 bktype,
  76.                int id));
  77.  
  78. extern    struct    bkpt_t    *bkpt_table;
  79.  
  80. /*
  81. ** The function below is used in manipulating breakpoints.
  82. ** This function is called in the main command loop parser
  83. ** of the monitor.  The parameters passed to this function
  84. ** are:
  85. **
  86. ** token - This is an array of pointers to strings.  Each string
  87. **         referenced by this array is a "token" of the user's
  88. **         input, translated to lower case.
  89. **
  90. ** token_count - This is the number of tokens in "token".
  91. **
  92. */
  93.  
  94.  
  95. INT32
  96. bkpt_cmd(token, token_count)
  97.    char   *token[];
  98.    int     token_count;
  99.    {
  100.    INT32    result;
  101.    struct addr_29k_t addr_29k;
  102.    INT32  pass_count;
  103.    INT32  bkpt_type;
  104.  
  105.    /*
  106.    ** Clear breakpoint(s)
  107.    */
  108.    if (strcmp(token[0], "bc") == 0) {
  109.       if (token_count == 1) {
  110.          result = clear_table();
  111.          return (result);
  112.          }
  113.       else
  114.  
  115.       /* Clear a specific breakpoints */
  116.       if (token_count == 2) {
  117.          result = get_addr_29k_m(token[1], &addr_29k, I_MEM);
  118.          if (result != 0)
  119.             return (result);
  120.          result = addr_29k_ok(&addr_29k);
  121.          if (result != 0)
  122.             return (result);
  123.      if (addr_29k.memory_space == (INT32) GENERIC_SPACE)
  124.         addr_29k.memory_space = (INT32) I_MEM;
  125.          result = clear_bkpt(addr_29k);
  126.          return (result);
  127.          }
  128.       else  /* token_count != 1 or 2 */
  129.          return (EMSYNTAX);
  130.       }
  131.    else
  132.  
  133.    /*
  134.    ** Set breakpoint(s)
  135.    */
  136.  
  137.    if ((strcmp(token[0], "b") == 0) ||
  138.        (strcmp(token[0], "b050p") == 0) ||
  139.        (strcmp(token[0], "b050v") == 0) ||
  140.        (strcmp(token[0], "b050") == 0)) { /* b050 defaults to b050p */
  141.  
  142.       if (strcmp(token[0], "b") == 0)
  143.          bkpt_type = BKPT_29000;
  144.       else
  145.       if (strcmp(token[0], "b050p") == 0)
  146.          bkpt_type = BKPT_29050_BTE_0;    /* translation disabled */
  147.       else
  148.       if (strcmp(token[0], "b050v") == 0)
  149.          bkpt_type = BKPT_29050_BTE_1;
  150.       else
  151.       if (strcmp(token[0], "b050") == 0)
  152.          bkpt_type = BKPT_29050_BTE_0;    /* translation disabled */
  153.       else
  154.          return (EMSYNTAX);
  155.  
  156.       if (token_count == 1) {
  157.          result = show_table();
  158.          return (result);
  159.          }
  160.       else
  161.  
  162.       /* Set breakpoint with pass count of 1 */
  163.       if (token_count == 2) {
  164.          result = get_addr_29k_m(token[1], &addr_29k, I_MEM);
  165.          if (result != 0)
  166.             return (result);
  167.          result = addr_29k_ok(&addr_29k);
  168.          if (result != 0)
  169.             return (result);
  170.          /* The TIP checks the memory space for acceptance */
  171.      if (addr_29k.memory_space == (INT32) GENERIC_SPACE)
  172.         addr_29k.memory_space = (INT32) I_MEM;
  173.          result = set_bkpt(addr_29k, (INT32) 1, bkpt_type);
  174.          return (result);
  175.          }
  176.       else
  177.  
  178.       /* Set breakpoint with pass count */
  179.       if (token_count == 3) {
  180.          result = get_addr_29k_m(token[1], &addr_29k, I_MEM);
  181.          if (result != 0)
  182.             return (result);
  183.          result = addr_29k_ok(&addr_29k);
  184.          if (result != 0)
  185.             return (result);
  186.          result = get_word_decimal(token[2], &pass_count);
  187.          if (result != 0)
  188.             return (EMSYNTAX);
  189.      if (addr_29k.memory_space == (INT32) GENERIC_SPACE)
  190.         addr_29k.memory_space = (INT32) I_MEM;
  191.          result = set_bkpt(addr_29k, pass_count, bkpt_type);
  192.          return (result);
  193.          }
  194.       else  /* too many parms for set breakpoint */
  195.       return (EMSYNTAX);
  196.       }
  197.    else /* not a proper 'b" command */
  198.       return (EMSYNTAX);
  199.  
  200.    }  /* end bkpt_cmd() */
  201.  
  202.  
  203.  
  204. /*
  205. ** Functions used by bkpt_cmd()
  206. */
  207.  
  208.  
  209. /*
  210. ** This function is used to remove a breakpoint from the
  211. ** target and from the host breakpoint table.
  212. */
  213.  
  214. INT32
  215. clear_bkpt(addr_29k)
  216.    struct addr_29k_t  addr_29k;
  217. {
  218.    int    breakid;
  219.    INT32    retval;
  220.  
  221.    (void) match_entry (addr_29k.address, 
  222.                addr_29k.memory_space,
  223.                &breakid);
  224.  
  225.    /* Did we find the breakpoint? */
  226.    if (breakid <= (int) 0) {
  227.       warning (EMBKPTRM);
  228.       return (FAILURE);
  229.    };
  230.  
  231.    /* if a valid breakpoint entry is found */
  232.    if ((retval = Mini_bkpt_rm (breakid))  != SUCCESS) {
  233.       return(FAILURE);
  234.    } else if (retval == SUCCESS) {
  235.       /* remove breakpoint from table */
  236.       if (remove_from_table(breakid) != SUCCESS) {
  237.      /* this shouldn't occur */
  238.      return(FAILURE);
  239.       };
  240.       return(SUCCESS);
  241.    };
  242.  
  243. }  /* end clear_bkpt() */
  244.  
  245.  
  246.  
  247. /*
  248. ** This function is used to set a breakpoint on the
  249. ** target and in the host breakpoint table.
  250. */
  251.  
  252. INT32
  253. set_bkpt(addr_29k, pass_count, bkpt_type)
  254.    struct   addr_29k_t addr_29k;
  255.    INT32    pass_count;
  256.    INT32    bkpt_type;
  257.    {
  258.    INT32    retval;
  259.    int    breakid;
  260.  
  261.    /* is there one already at the same place */
  262.    (void) match_entry(addr_29k.address, 
  263.               addr_29k.memory_space,
  264.               &breakid);
  265.  
  266.    if (breakid > (int) 0) {
  267.       warning (EMBKPTUSED);
  268.       return (FAILURE);
  269.    };
  270.  
  271.    /* else set the breakpoint */
  272.    breakid = (int) 0;
  273.    if ((retval = Mini_bkpt_set (addr_29k.memory_space,
  274.                 addr_29k.address,
  275.                 pass_count,
  276.                 bkpt_type,
  277.                 &breakid)) != SUCCESS) {
  278.        return(FAILURE);
  279.    } else  {
  280.       /* Add breakpoint to table */
  281.       if (breakid > (int) 0) { /* double checking */
  282.      return (add_to_table(addr_29k.address,
  283.               addr_29k.memory_space,
  284.               pass_count,
  285.               bkpt_type,
  286.               breakid));
  287.       };
  288.       return(FAILURE);
  289.    };
  290. }  /* end set_bkpt() */
  291.  
  292.  
  293.  
  294. INT32
  295. add_to_table(offset, space, passcnt, bktype, id )
  296. ADDR32    offset;
  297. INT32    space;
  298. INT32    passcnt;
  299. INT32    bktype;
  300. int    id;
  301. {
  302.   struct   bkpt_t  *temp, *temp2;
  303.  
  304.   if ((temp = (struct bkpt_t *) malloc (sizeof(struct bkpt_t))) == NULL) {
  305.      return(EMALLOC);
  306.   } else {
  307.     temp->break_id = id;
  308.     temp->memory_space =  space;
  309.     temp->address = offset;
  310.     temp->pass_count = passcnt;
  311.     temp->curr_count = passcnt;
  312.     temp->bkpt_type = bktype;
  313.     temp->next = NULL;
  314.   };
  315.  
  316.   if (bkpt_table == NULL) { /* first element */
  317.      bkpt_table = temp;
  318.   } else { /* add at end */
  319.      temp2 = bkpt_table;
  320.      while (temp2->next != NULL)
  321.        temp2 = temp2->next;
  322.      temp2->next = temp;   /* add */
  323.   }
  324.   return(SUCCESS);
  325. }
  326.  
  327. INT32
  328. match_entry(offset, space, id)
  329. ADDR32    offset;
  330. INT32    space;
  331. int    *id;
  332. {
  333.   struct  bkpt_t  *temp;
  334.  
  335.   if (bkpt_table == NULL) { /* empty, so no match */
  336.     *id = (int) 0;
  337.     return(SUCCESS);
  338.   } else {
  339.     temp = bkpt_table;
  340.     if ((temp->address == offset) && 
  341.              (temp->memory_space == space)) { /* match */
  342.        *id = temp->break_id;
  343.        return(SUCCESS);
  344.     } else {
  345.        while (temp->next != NULL) {
  346.       if ((temp->next->address == offset) && 
  347.           (temp->next->memory_space == space)) {
  348.          *id = temp->next->break_id;
  349.          return(SUCCESS);
  350.       } else {
  351.          temp = temp->next;
  352.       };
  353.        }
  354.        *id = (int) 0;
  355.        return(SUCCESS);
  356.     };
  357.   };
  358. }
  359.  
  360. INT32
  361. remove_from_table(id)
  362. int   id;
  363. {
  364.   struct  bkpt_t  *temp;
  365.  
  366.   if (bkpt_table == NULL) { /* empty table */
  367.      return(FAILURE);
  368.   } else {
  369.      temp = bkpt_table;
  370.      if (bkpt_table->break_id == id) { /* remove first element */
  371.     bkpt_table = bkpt_table->next;
  372.     return(SUCCESS);
  373.      } else {
  374.     while (temp->next != NULL) {
  375.       if (temp->next->break_id == id) {
  376.          temp->next = temp->next->next;
  377.          return(SUCCESS);
  378.       } else {
  379.          temp = temp->next;
  380.       };
  381.     }
  382.     return(FAILURE);
  383.      };
  384.   }
  385. }
  386.  
  387. INT32
  388. clear_table()
  389. {
  390.   struct bkpt_t  *tmp;
  391.   INT32    retval;
  392.  
  393.  
  394.   if (bkpt_table == NULL) { /* no entries */
  395.     fprintf(stderr, "no breakpoints in use.\n");
  396.     if (io_config.echo_mode == (INT32) TRUE)
  397.        fprintf(io_config.echo_file, "no breakpoints in use.\n");
  398.   } else {
  399.      while (bkpt_table) {
  400.         if ((retval = Mini_bkpt_rm (bkpt_table->break_id))  != SUCCESS) {
  401.            return(FAILURE);
  402.         } else if (retval == SUCCESS) {
  403.            /* remove breakpoint from table */
  404.        tmp = bkpt_table;
  405.            bkpt_table = bkpt_table->next;
  406.        (void) free ((char *) tmp);
  407.         };
  408.      };
  409.   }
  410.   return(SUCCESS);
  411. }
  412.  
  413. INT32
  414. show_table()
  415. {
  416.   struct  bkpt_t  *temp;
  417.    INT32    retval;
  418.    ADDR32    temp_addr;
  419.    INT32    temp_space;
  420.    INT32    curr_count;
  421.    INT32    temp_passcnt, temp_bktype;
  422.    int        i;
  423.  
  424.   if (bkpt_table == NULL) { /* no entries */
  425.   } else {
  426.     do {
  427.        temp = bkpt_table;
  428.        bkpt_table = bkpt_table->next;
  429.        (void) free ((char *) temp);
  430.     } while (bkpt_table != NULL);
  431.   };
  432.  
  433.   for (i = 1;1;i++) {
  434.      retval = Mini_bkpt_stat( i,
  435.                   &temp_addr,
  436.                   &temp_space,
  437.                   &temp_passcnt,
  438.                   &temp_bktype,
  439.                   &curr_count);
  440.      if ((retval == (INT32) MONBreakInvalid) ||
  441.          (retval == (INT32) FAILURE)) {
  442.     continue;
  443.      } else if (retval == (INT32) MONBreakNoMore) {
  444.     return (SUCCESS);
  445.      } else {
  446.      /* add entry in the table */
  447.      if ((retval = add_to_table ((ADDR32) temp_addr,
  448.                        (INT32) temp_space,
  449.                        (INT32) temp_passcnt,
  450.                        (INT32) temp_bktype,
  451.                        i)) != SUCCESS)
  452.         return (retval);
  453.          /* Mark Am29050 breakpoints with a '*' */
  454.          if (temp_bktype == BKPT_29050)
  455.              fprintf(stderr, "*");
  456.          else
  457.              fprintf(stderr, " ");
  458.          fprintf(stderr, "(%#05d: %#08lx[%#02d])\n", i, 
  459.                    temp_addr, 
  460.                    temp_passcnt);
  461.      if (io_config.echo_mode == (INT32) TRUE)  {
  462.              if (temp_bktype == BKPT_29050)
  463.                  fprintf(io_config.echo_file, "*");
  464.              else
  465.                 fprintf(io_config.echo_file, " ");
  466.              fprintf(io_config.echo_file, "(%#05d: %#08lx[%#02d])\n", i, 
  467.                        temp_addr, 
  468.                        temp_passcnt);
  469.      }
  470.      };
  471.   }
  472.   return(SUCCESS);
  473. }
  474.  
  475.