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

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