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 / montip / lcb29k.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  12.9 KB  |  461 lines

  1. static char _[]="@(#)lcb29k.c    5.22 93/10/26 09:57:08, Srini, AMD.";
  2. /******************************************************************************
  3.  * Copyright 1992 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 Systems Engineering
  22.  * Mail Stop 573
  23.  * 5204 E. Ben White Blvd.
  24.  * Austin, TX 78741
  25.  * 800-292-9263
  26.  * 29k-support@AMD.COM
  27.  ****************************************************************************
  28.  * Engineer: Srini Subramanian.
  29.  ****************************************************************************
  30.  **       This file defines functions which initialize and access the
  31.  **       LCB29K (Low Cost Board 29K) or "squirt" board from YARC.
  32.  **
  33.  ****************************************************************************
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include <memory.h>
  38. #include "types.h"
  39. #include "lcb29k.h"
  40. #include "memspcs.h"
  41. #include "mtip.h"
  42. #include "tdfunc.h"
  43. #include "macros.h"
  44.  
  45. #include <conio.h>
  46. #include <dos.h>
  47.  
  48. void    endian_cvt PARAMS((union msg_t *, int));
  49. void    tip_convert32 PARAMS ((BYTE *));
  50.  
  51.  
  52. /*
  53. ** This function is used to initialize the communication
  54. ** channel.  This consists of setting the window location
  55. ** of the LCB29K to the value defined by the values in
  56. ** the file lcb29k.h.
  57. */
  58.  
  59. INT32
  60. init_comm_lcb29k(PC_port_base, PC_mem_seg)
  61. INT32    PC_port_base;
  62. INT32    PC_mem_seg;
  63.    {
  64.    int  result;
  65.    int  control_reg;
  66.  
  67.    /*** check for existence of the board ***/
  68.  
  69.    /* Initialize Control Port Register 0 */
  70.    /* (But don't set LCB29K_RST)         */
  71.    control_reg = (LCB29K_CLRINPC | LCB29K_INTEN | LCB29K_WEN);
  72.    result = outp((unsigned int) PC_port_base,
  73.                  control_reg);
  74.  
  75.    return(0);
  76.    }  /* end init_comm_lcb29k() */
  77.  
  78.  
  79. /*
  80. ** This function is used to send a message to the LCB29K.
  81. ** If the message is successfully sent, a zero is
  82. ** returned.  If the message was not sendable, a -1
  83. ** is returned.
  84. **
  85. ** Also note that this function does endian conversion on the
  86. ** returned message.  This is necessary because the Am29000
  87. ** target will be sending big-endian messages and the PC will
  88. ** be expecting little-endian.
  89. */
  90.  
  91. INT32
  92. msg_send_lcb29k(msg_ptr, PC_port_base)
  93.    union  msg_t  *msg_ptr;
  94.    INT32    PC_port_base;
  95.    {
  96.    int    result;
  97.    int    control_reg;
  98.    INT32  message_size;
  99.  
  100.  
  101. #if 0
  102.    INT32    semaphore;
  103.    /* Set semaphore (LCB29K_RECV_BUF_PTR) to zero */
  104.    semaphore = 0;
  105.    result = (int) Mini_write_memory((INT32)  D_MEM,
  106.                                 (ADDR32) LCB29K_RECV_BUF_PTR,
  107.                                 (INT32)  sizeof(INT32),
  108.                                 (BYTE *) &semaphore);
  109.  
  110.    if (result != 0)
  111.       return(-1);
  112. #endif
  113.    /* Get size of whole message */
  114.    message_size = (msg_ptr->generic_msg).length + (2 * sizeof(INT32));
  115.  
  116.    /* Do endian conversion */
  117.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  118.       endian_cvt(msg_ptr, OUTGOING_MSG);
  119.  
  120.    /* Send message */
  121.    result = (int) Mini_write_memory((INT32)  D_MEM,
  122.                                 (ADDR32) LCB29K_SEND_BUF,
  123.                                 (INT32)  message_size,
  124.                                 (BYTE *) msg_ptr);
  125.  
  126.    if (result != 0)
  127.       return(-1);
  128.  
  129.    /* Interrupt target (write to "LCB29K" mailbox) */
  130.    /* Note:  This sequence of bytes written to the
  131.    **        port of the low cost board should cause
  132.    **        the target to be interrupted.  This
  133.    **        sequence was given to AMD by YARC systems.
  134.    */
  135.  
  136. /*
  137.    control_reg = (LCB29K_RST);
  138.    result = outp((unsigned int) (PC_port_base),
  139.                  control_reg);
  140.  
  141.    control_reg = (LCB29K_RST | LCB29K_WEN);
  142.    result = outp((unsigned int) (PC_port_base),
  143.                  control_reg);
  144. */
  145.  
  146.    control_reg = (LCB29K_RST | LCB29K_INTEN | LCB29K_WEN);
  147.    result = outp((unsigned int) (PC_port_base),
  148.                  control_reg);
  149.  
  150.    control_reg = (LCB29K_RST | LCB29K_INTEN | LCB29K_WEN |
  151.                   LCB29K_INT29);
  152.    result = outp((unsigned int) (PC_port_base),
  153.                  control_reg);
  154. /*
  155.    control_reg = (LCB29K_RST | LCB29K_INTEN | LCB29K_WEN |
  156.                   LCB29K_INT29);
  157.    result = outp((unsigned int) (PC_port_base),
  158.                  control_reg);
  159. */
  160.    return(0);
  161.  
  162.    }  /* end msg_send_lcb29k() */
  163.  
  164.  
  165.  
  166.  
  167. /*
  168. ** This function is used to receive a message to the LCB29K.
  169. ** If the message is waiting in the buffer, a zero is
  170. ** returned and the buffer pointed to by msg_ptr is filled
  171. ** in.  If no message was available, a -1 is returned.
  172. **
  173. ** Note that this function does endian conversion on the
  174. ** returned message.  This is necessary because the Am29000
  175. ** target will be sending big-endian messages and the PC will
  176. ** be expecting little-endian.
  177. */
  178.  
  179. INT32
  180. msg_recv_lcb29k(msg_ptr, PC_port_base, Mode)
  181.    union  msg_t  *msg_ptr;
  182.    INT32    PC_port_base;
  183.    INT32    Mode;
  184.    {
  185.    int    result;
  186.    ADDR32 recv_buf_addr;
  187.    INT32  parms_length;
  188.    INT32  header_size;
  189.    INT32  semaphore;
  190.    int    control_reg;
  191.  
  192.    /* Poll LCB29K control register */
  193.    control_reg = inp((unsigned int) PC_port_base);
  194.  
  195.    /* If LCB29K_INTPC flag set, message ready */
  196.    if ((control_reg & LCB29K_INTPC) != 0) {
  197.      /* Clear LCB29K_INTPC (and don't interrupt 29K) */
  198.      control_reg = ((control_reg & ~(LCB29K_INT29)) | LCB29K_CLRINPC);
  199.  
  200.      result = outp((unsigned int) (PC_port_base),
  201.                    control_reg);
  202.  
  203.      control_reg = (control_reg & ~(LCB29K_CLRINPC));
  204.  
  205.      result = outp((unsigned int) (PC_port_base),
  206.                    control_reg);
  207.    }
  208.  
  209.    /* Get receive buffer address */
  210.    result = (int) Mini_read_memory((INT32)  D_MEM,
  211.                                (ADDR32) LCB29K_RECV_BUF_PTR,
  212.                                (INT32)  sizeof(ADDR32),
  213.                                (BYTE *) &recv_buf_addr);
  214.  
  215.    if (result != 0)
  216.       return(-1);
  217.  
  218.    /* Change endian of recv_buf_addr (if necessary) */
  219.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  220.       tip_convert32((BYTE *) &recv_buf_addr);
  221.  
  222.    /* If no message waiting, return -1 (This shouldn't happen) */
  223.    if (recv_buf_addr == (ADDR32) 0)
  224.       return (-1);
  225.  
  226.    /* Get message header */
  227.    header_size = (INT32) (2 * sizeof(INT32));
  228.    result = (int) Mini_read_memory((INT32)  D_MEM,
  229.                                (ADDR32) recv_buf_addr,
  230.                                (INT32)  header_size,
  231.                                (BYTE *) msg_ptr);
  232.  
  233.    if (result != 0)
  234.       return(-1);
  235.  
  236.    /* Get rest of message */
  237.    parms_length = (msg_ptr->generic_msg).length;
  238.  
  239.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  240.       tip_convert32((BYTE *) &parms_length);
  241.  
  242.  
  243.    result = (int) Mini_read_memory((INT32)  D_MEM,
  244.                                (ADDR32) (recv_buf_addr + header_size),
  245.                                (INT32)  parms_length,
  246.                                (BYTE *) &(msg_ptr->generic_msg.byte));
  247.    if (result != 0)
  248.       return(-1);
  249.  
  250.    /* Do endian conversion (if necessary) */
  251.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  252.       endian_cvt(msg_ptr, INCOMING_MSG);
  253.  
  254.    /* Write Clear LCB29K_INPC */
  255.    control_reg = (LCB29K_RST | LCB29K_CLRINPC | LCB29K_INTEN |
  256.                   LCB29K_WEN);
  257.    result = outp((unsigned int) (PC_port_base),
  258.                  control_reg);
  259.  
  260.    /* Set semaphore (LCB29K_RECV_BUF_PTR) to zero */
  261.    semaphore = 0;
  262.    result = (int) Mini_write_memory((INT32)  D_MEM,
  263.                                 (ADDR32) LCB29K_RECV_BUF_PTR,
  264.                                 (INT32)  sizeof(INT32),
  265.                                 (BYTE *) &semaphore);
  266.  
  267.    if (result != 0)
  268.       return(-1);
  269.  
  270.  
  271.    return(msg_ptr->generic_msg.code);
  272.    }  /* end msg_recv_lcb29k() */
  273.  
  274.  
  275.  
  276.  
  277. /*
  278. ** This function is used to reset the communication
  279. ** channel.  This is used when resyncing the host and
  280. ** target and when exiting the monitor.
  281. */
  282.  
  283. INT32
  284. exit_comm_lcb29k(PC_port_base, PC_mem_seg)
  285. INT32    PC_port_base;
  286. INT32    PC_mem_seg;
  287.    {
  288.      return (0);
  289.    }
  290.  
  291. INT32
  292. reset_comm_lcb29k(PC_port_base, PC_mem_seg)
  293. INT32    PC_port_base;
  294. INT32    PC_mem_seg;
  295.    {
  296.    int  result;
  297.    int  control_reg;
  298.  
  299.    /*** check for existence of the board ***/
  300.  
  301.    /* Initialize Control Port Register 0 */
  302.    /* (But don't set LCB29K_RST)         */
  303.    control_reg = (LCB29K_CLRINPC | LCB29K_INTEN | LCB29K_WEN);
  304.    result = outp((unsigned int) PC_port_base,
  305.                  control_reg);
  306.  
  307.    return(0);
  308.    }  /* end reset_comm_lcb29k() */
  309.  
  310.  
  311.  
  312. /*
  313. ** This function is used to "kick" the LCB29K.  This
  314. ** amounts to yanking the *RESET line low.  Code
  315. ** will begin execution at ROM address 0.
  316. */
  317.  
  318. void
  319. go_lcb29k(PC_port_base, PC_mem_seg)
  320. INT32    PC_port_base;
  321. INT32    PC_mem_seg;
  322.    {
  323.    int  result;
  324.    int  control_reg;
  325.  
  326.    /* Clear the RST bit in Control Port Register 0 */
  327.    control_reg = (LCB29K_CLRINPC | LCB29K_INTEN | LCB29K_WEN);
  328.    result = outp((unsigned int) PC_port_base,
  329.                  control_reg);
  330.  
  331.    /* Set the RST bit in Control Port Register 0 */
  332.    control_reg = (LCB29K_RST | LCB29K_INTEN | LCB29K_WEN);
  333.    result = outp((unsigned int) PC_port_base,
  334.                  control_reg);
  335.  
  336.    }  /* end go_lcb29k() */
  337.  
  338.  
  339.  
  340.  
  341. /*
  342. ** This function is used to write a string of bytes to
  343. ** the Am29000 memory on the LCB29K board.
  344. **
  345. */
  346.  
  347. INT32
  348. write_memory_lcb29k(memory_space, address, data, byte_count, PC_port_base, PC_mem_seg)
  349.    INT32    memory_space;
  350.    ADDR32   address;
  351.    BYTE    *data;
  352.    INT32    byte_count;
  353.    INT32    PC_port_base;
  354.    INT32    PC_mem_seg;
  355.    {
  356.    INT32  bytes_in_window;
  357.    INT32  copy_count;
  358.    int    result;
  359.  
  360.    while (byte_count > 0) {
  361.  
  362.       /* Write out low order address bits */
  363.       result = outp((unsigned int) (PC_port_base+1),
  364.                     (int) ((address >> 14) & 0xff));
  365.  
  366.       /* Write out high order address bits */
  367.       if (memory_space == I_MEM)
  368.          result = outp((unsigned int) (PC_port_base+2),
  369.                        (int) (((address >> 22) & 0x7f) | LCB29K_I_MEM));
  370.       else
  371.       if (memory_space == D_MEM)
  372.          result = outp((unsigned int) (PC_port_base+2),
  373.                        (int) (((address >> 22) & 0x7f) | LCB29K_D_MEM));
  374.       else /* Must be either Instruction or Data memory */
  375.          return (-1);
  376.  
  377.       bytes_in_window = 0x4000 - (address & 0x3fff);
  378.       copy_count = MIN(byte_count, bytes_in_window);
  379.  
  380.       (void) movedata((unsigned int) FP_SEG(data),
  381.                       (unsigned int) FP_OFF(data),
  382.                       (unsigned int) PC_mem_seg,
  383.                       (unsigned int) (address & 0x3fff), 
  384.                       (int) copy_count);
  385.  
  386.       data = data + copy_count;
  387.       address = address + copy_count;
  388.       byte_count = byte_count - copy_count;
  389.  
  390.       }  /* end while loop */
  391.  
  392.    return(0);
  393.  
  394.    }  /* End write_memory_lcb29k() */
  395.  
  396.  
  397.  
  398.  
  399. /*
  400. ** This function is used to read a string of bytes from
  401. ** the Am29000 memory on the LCB29K board.   A zero is
  402. ** returned if the data is read successfully, otherwise
  403. ** a -1 is returned.
  404. */
  405.  
  406. INT32
  407. read_memory_lcb29k(memory_space, address, data, byte_count, PC_port_base, PC_mem_seg)
  408.    INT32    memory_space;
  409.    ADDR32   address;
  410.    BYTE    *data;
  411.    INT32    byte_count;
  412.    INT32    PC_port_base;
  413.    INT32    PC_mem_seg;
  414.    {
  415.    INT32  bytes_in_window;
  416.    INT32  copy_count;
  417.    int    result;
  418.  
  419.    while (byte_count > 0) {
  420.  
  421.       /* Write out low order address bits */
  422.       result = outp((unsigned int) (PC_port_base+1),
  423.                     (int) ((address >> 14) & 0xff));
  424.  
  425.       /* Write out high order address bits */
  426.       if (memory_space == I_MEM)
  427.          result = outp((unsigned int) (PC_port_base+2),
  428.                        (int) (((address >> 22) & 0x7f) | LCB29K_I_MEM));
  429.       else
  430.       if (memory_space == D_MEM)
  431.          result = outp((unsigned int) (PC_port_base+2),
  432.                        (int) (((address >> 22) & 0x7f) | LCB29K_D_MEM));
  433.       else /* Must be either Instruction or Data memory */
  434.          return (-1);
  435.  
  436.       bytes_in_window = 0x4000 - (address & 0x3fff);
  437.       copy_count = MIN(byte_count, bytes_in_window);
  438.  
  439.       (void) movedata((unsigned int) PC_mem_seg,
  440.                       (unsigned int) (address & 0x3fff), 
  441.                       (unsigned int) FP_SEG(data),
  442.                       (unsigned int) FP_OFF(data),
  443.                       (int) copy_count);
  444.  
  445.       data = data + copy_count;
  446.       address = address + copy_count;
  447.       byte_count = byte_count - copy_count;
  448.  
  449.       }  /* end while loop */
  450.  
  451.    return(0);
  452.  
  453.    }  /* End read_memory_lcb29k() */
  454.  
  455. INT32
  456. fill_memory_lcb29k()
  457. {
  458.  return (0);
  459. }
  460.  
  461.