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 / eb030.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  11.2 KB  |  408 lines

  1. static char _[] = "@(#)eb030.c    5.20 93/10/26 09:57:05, 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 file defines functions which initialize and access the
  30.  **       the EB030 "Lynx" board.  This file is based heavily on the
  31.  **       eb29k.c file.
  32.  *****************************************************************************
  33.  */
  34.  
  35. #include <memory.h>
  36. #include <string.h>
  37. #include "eb030.h"
  38. #include "types.h"
  39. #include "memspcs.h"
  40. #include "macros.h"
  41. #include "mtip.h"
  42. #include "tdfunc.h"
  43.  
  44.  
  45. #include <conio.h>
  46. #include <dos.h>
  47. void  endian_cvt PARAMS((union msg_t *, int));
  48. void  tip_convert32 PARAMS((BYTE *));
  49.  
  50. /*
  51. ** Global variables
  52. */
  53.  
  54.  
  55.  
  56. /*
  57. ** This function is used to initialize the communication
  58. ** channel.  This consists of setting the window location
  59. ** of the EB030 to the value defined by the values in
  60. ** the file eb030.h.
  61. */
  62.  
  63. INT32
  64. init_comm_eb030(PC_port_base, PC_mem_seg)
  65. INT32    PC_port_base;
  66. INT32    PC_mem_seg;
  67.    {
  68.    int  result;
  69.  
  70.    /*** check for existence of the board ***/
  71.  
  72.    /* Set up memory window location */
  73.    result = outp((unsigned int) PC_port_base,
  74.                  ((int) ((PC_mem_seg >> 10) & 0x1f)));
  75.  
  76.    /* Set up window base to zero */
  77.    outp ((unsigned int) (PC_port_base+1), (unsigned int) 0);
  78.    outp ((unsigned int) (PC_port_base+2), (unsigned int) 0);
  79.  
  80.    return(SUCCESS);
  81.    }  /* end init_comm_eb030() */
  82.  
  83.  
  84. /*
  85. ** This function is used to send a message to the EB030.
  86. ** If the message is successfully sent, a zero is
  87. ** returned.  If the message was not sendable, a -1
  88. ** is returned.
  89. **
  90. ** Also note that this function does endian conversion on the
  91. ** returned message.  This is necessary because the Am29000
  92. ** target will be sending big-endian messages and the PC will
  93. ** be expecting little-endian.
  94. */
  95.  
  96. INT32
  97. msg_send_eb030(msg_ptr, PC_port_base)
  98.    union  msg_t  *msg_ptr;
  99. INT32    PC_port_base;
  100.    {
  101.    INT32    result;
  102.    INT32  message_size;
  103.  
  104. #if 0
  105. INT32  semaphore;
  106.    /* Set semaphore (EB030_RECV_BUF_PTR) to zero */
  107.    semaphore = 0;
  108.    result = Mini_write_memory((INT32) D_MEM,
  109.                               (ADDR32) EB030_RECV_BUF_PTR,
  110.                               (INT32) sizeof (INT32),
  111.                               (BYTE *) &semaphore);
  112. #endif
  113.  
  114.    /* Get size of whole message */
  115.    message_size = (msg_ptr->generic_msg).length + (2 * sizeof(INT32));
  116.  
  117.    /* Is the size of the message valid? */
  118.  
  119.    /* Do endian conversion */
  120.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  121.       endian_cvt(msg_ptr, OUTGOING_MSG);
  122.  
  123.    /* Send message */
  124.    result = Mini_write_memory((INT32) D_MEM,
  125.                               (ADDR32) EB030_SEND_BUF,
  126.                               (INT32) message_size,
  127.                               (BYTE *) msg_ptr);
  128.  
  129.    if (result != (INT32) 0)
  130.       return(FAILURE);
  131.  
  132.    /* Interrupt target (write to EB030 mailbox) */
  133.    result = outp((unsigned int) (PC_port_base+3),
  134.                  (int) 0x00);
  135.  
  136.    return(SUCCESS);
  137.  
  138.    }  /* end msg_send_eb030() */
  139.  
  140.  
  141.  
  142.  
  143. /*
  144. ** This function is used to receive a message to the EB030.
  145. ** If the message is waiting in the buffer, a zero is
  146. ** returned and the buffer pointed to by msg_ptr is filled
  147. ** in.  If no message was available, a -1 is returned.
  148. **
  149. ** Note that this function does endian conversion on the
  150. ** returned message.  This is necessary because the Am29000
  151. ** target will be sending big-endian messages and the PC will
  152. ** be expecting little-endian.
  153. */
  154.  
  155. INT32
  156. msg_recv_eb030(msg_ptr, PC_port_base, Mode)
  157.    union  msg_t  *msg_ptr;
  158. INT32    PC_port_base;
  159. INT32    Mode;
  160.    {
  161.    INT32    result;
  162.    ADDR32 recv_buf_addr;
  163.    INT32  parms_length;
  164.    INT32  header_size;
  165.    INT32  semaphore;
  166.    int      retval;
  167.  
  168.    /* Poll EB030 mailbox */
  169.    /* (If mailbox contains 0xff, a message is waiting) */
  170.    retval = inp((unsigned int) (PC_port_base+3));
  171.  
  172.    /* If no message waiting, return -1 */
  173.    if (retval != 0xff)
  174.       return (-1);
  175.  
  176.    /* Get receive buffer address */
  177.    result = Mini_read_memory ((INT32) D_MEM,
  178.                               (ADDR32) EB030_RECV_BUF_PTR,
  179.                               (INT32) sizeof (ADDR32),
  180.                               (BYTE *) &recv_buf_addr);
  181.  
  182.    if (result != (INT32) 0)
  183.       return(FAILURE);
  184.  
  185.    /* Change endian of recv_buf_addr (if necessary) */
  186.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  187.       tip_convert32((BYTE *) &recv_buf_addr);
  188.  
  189.    if (recv_buf_addr == (ADDR32) 0) {
  190.       return (FAILURE);
  191.    } else {
  192.    /* Get message header */
  193.    header_size = (INT32) (2 * sizeof(INT32));
  194.    result = Mini_read_memory ((INT32) D_MEM,
  195.                               (ADDR32) recv_buf_addr,
  196.                               (INT32) header_size,
  197.                               (BYTE *) msg_ptr);
  198.  
  199.    if (result != 0)
  200.       return(FAILURE);
  201.  
  202.    /* Get rest of message */
  203.    parms_length = (msg_ptr->generic_msg).length;
  204.  
  205.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  206.       tip_convert32((BYTE *) &parms_length);
  207.  
  208.    /* Is the size of the message valid? */
  209.  
  210.    result = Mini_read_memory ((INT32) D_MEM,
  211.                                (ADDR32) (recv_buf_addr + header_size),
  212.                                (INT32) parms_length,
  213.                                (BYTE *) &(msg_ptr->generic_msg.byte));
  214.    if (result != 0)
  215.       return(FAILURE);
  216.  
  217.    /* Do endian conversion (if necessary) */
  218.    if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
  219.       endian_cvt(msg_ptr, INCOMING_MSG);
  220.  
  221.    /* Write 0xff to EB030 mailbox */
  222.    /* (This tells EB030 that message has been received) */
  223.    retval = outp((unsigned int) (PC_port_base+3), (int) 0xff);
  224.  
  225.    /* Set semaphore (EB030_RECV_BUF_PTR) to zero */
  226.    semaphore = 0;
  227.    result = Mini_write_memory((INT32) D_MEM,
  228.                               (ADDR32) EB030_RECV_BUF_PTR,
  229.                               (INT32) sizeof (INT32),
  230.                               (BYTE *) &semaphore);
  231.  
  232.    if (result != 0)
  233.       return(FAILURE);
  234.  
  235.    return((INT32) msg_ptr->generic_msg.code);
  236.    }
  237. }  /* end msg_recv_eb030() */
  238.  
  239.  
  240.  
  241.  
  242. /*
  243. ** This function is used to reset the communication
  244. ** channel.  This is used when resyncing the host and
  245. ** target and when exiting the monitor.
  246. */
  247.  
  248. INT32
  249. exit_comm_eb030(PC_port_base, PC_mem_seg)
  250. INT32    PC_port_base;
  251. INT32    PC_mem_seg;
  252.    {
  253.      return(0);
  254.    }
  255.  
  256. INT32
  257. reset_comm_eb030(PC_port_base, PC_mem_seg)
  258. INT32    PC_port_base;
  259. INT32    PC_mem_seg;
  260.    {
  261.  
  262.    /* Set up memory window location */
  263.    outp((unsigned int) PC_port_base,
  264.                  ((int) ((PC_mem_seg >> 10) & 0x1f)));
  265.  
  266.    /* Set up window base to zero */
  267.    outp ((unsigned int) (PC_port_base+1), (unsigned int) 0);
  268.    outp ((unsigned int) (PC_port_base+2), (unsigned int) 0);
  269.  
  270.    return(0);
  271.  
  272.    }  /* end reset_comm_eb030() */
  273.  
  274.  
  275.  
  276. /*
  277. ** This function is used to "kick" the EB030.  This
  278. ** amounts to yanking the *RESET line low.  Code
  279. ** will begin execution at ROM address 0.
  280. */
  281.  
  282. void
  283. go_eb030(PC_port_base, PC_mem_seg)
  284. INT32    PC_port_base;
  285. INT32    PC_mem_seg;
  286.    {
  287.    int  result;
  288.  
  289.    /* Toggle the RESET bit in Control Port Register 0 */
  290.    result = outp((unsigned int) PC_port_base,
  291.                  ((int) ((PC_mem_seg >> 10) & 0x1f)));
  292.    result = outp((unsigned int) PC_port_base,
  293.                  ((int) (((PC_mem_seg >> 10) & 0x1f) |
  294.                  EB030_RESET)));
  295.  
  296.    }  /* end go_eb030() */
  297.  
  298.  
  299.  
  300. /*
  301. ** This function is used to write a string of bytes to
  302. ** the Am29000 memory on the EB030 board.
  303. **
  304. */
  305.  
  306. INT32
  307. write_memory_eb030(memory_space, address, data, byte_count, PC_port_base, PC_mem_seg)
  308.    INT32    memory_space;
  309.    ADDR32   address;
  310.    BYTE    *data;
  311.    INT32    byte_count;
  312.    INT32    PC_port_base;
  313.    INT32    PC_mem_seg;
  314.    {
  315.    INT32  bytes_in_window;
  316.    INT32  copy_count;
  317.  
  318.    while (byte_count > 0) {
  319.  
  320.       /* Write out low order EB030_addr bits */
  321.       outp((unsigned int) (PC_port_base+1), (int) ((address >> 14) & 0xff));
  322.       /* Write out high order EB030_addr bits I-/D-Mem are same */
  323.       outp((unsigned int) (PC_port_base+2), (int) ((address >> 22) & 0x7f));
  324.  
  325.       bytes_in_window = 0x4000 - (address & 0x3fff);
  326.       copy_count = MIN(byte_count, bytes_in_window);
  327.  
  328.       (void) memmove ((void *) ((PC_mem_seg << 16) + (address & 0x3fff)),
  329.               (void *) data,
  330.               (size_t) copy_count);
  331. #if  0
  332.       (void) movedata((unsigned int) FP_SEG(data),
  333.                       (unsigned int) FP_OFF(data),
  334.                       (unsigned int) PC_mem_seg,
  335.                       (unsigned int) (address & 0x3fff), 
  336.                       (int) copy_count);
  337. #endif
  338.  
  339.       data = data + copy_count;
  340.       address = address + copy_count;
  341.       byte_count = byte_count - copy_count;
  342.  
  343.       }  /* end while loop */
  344.  
  345.    return(SUCCESS);
  346.  
  347.    }  /* End write_memory_eb030() */
  348.  
  349.  
  350.  
  351.  
  352. /*
  353. ** This function is used to read a string of bytes from
  354. ** the Am29000 memory on the EB030 board.   A zero is
  355. ** returned if the data is read successfully, otherwise
  356. ** a -1 is returned.
  357. **
  358. */
  359.  
  360. INT32
  361. read_memory_eb030(memory_space, address, data, byte_count, PC_port_base, PC_mem_seg)
  362.    INT32    memory_space;
  363.    ADDR32   address;
  364.    BYTE    *data;
  365.    INT32    byte_count;
  366.    INT32    PC_port_base;
  367.    INT32    PC_mem_seg;
  368.    {
  369.    INT32  bytes_in_window;
  370.    INT32  copy_count;
  371.  
  372.    while (byte_count > 0) {
  373.  
  374.       /* Write out low order EB030_addr bits */
  375.       outp((unsigned int) (PC_port_base+1), (int) ((address >> 14) & 0xff));
  376.       /* Write out high order EB030_addr bits I/D are same */
  377.       outp((unsigned int) (PC_port_base+2), (int) ((address >> 22) & 0x7f));
  378.  
  379.       bytes_in_window = 0x4000 - (address & 0x3fff);
  380.       copy_count = MIN(byte_count, bytes_in_window);
  381.  
  382. #if 0
  383.       (void) memmove ((void *) data,
  384.               (void *) ((PC_mem_seg << 16) + (address & 0x3fff)),
  385.               (size_t) copy_count);
  386. #endif
  387.       (void) movedata((unsigned int) PC_mem_seg,
  388.                       (unsigned int) (address & 0x3fff), 
  389.                       (unsigned int) FP_SEG(data),
  390.                       (unsigned int) FP_OFF(data),
  391.                       (int) copy_count);
  392.  
  393.       data = data + copy_count;
  394.       address = address + copy_count;
  395.       byte_count = byte_count - copy_count;
  396.  
  397.       }  /* end while loop */
  398.  
  399.    return(SUCCESS);
  400.  
  401.    }  /* End read_memory_eb030() */
  402.  
  403. INT32
  404. fill_memory_eb030()
  405. {
  406.   return(SUCCESS);
  407. }
  408.