OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains4x.git] / utils / amd-udi / montip / eb030.c
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 }