OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [utils/] [amd-udi/] [montip/] [pceb.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
static char _[] = "@(#)pceb.c   5.18 93/07/30 16:40:31, 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
 **
30
 **       This file defines functions which initialize and access the
31
 **       the PCEB 29K board.
32
 **
33
 *****************************************************************************
34
 */
35
 
36
 
37
#include <stdio.h>
38
#include <memory.h>
39
#include "messages.h"
40
#include "pceb.h"
41
#include "memspcs.h"
42
#include "macros.h"
43
#include "tdfunc.h"
44
#include "mtip.h"
45
 
46
#include <dos.h>
47
#include <conio.h>
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 PCEB to the value defined by the values in
56
** the file PCEB.h.
57
*/
58
 
59
/*ARGSUSED*/
60
INT32
61
init_comm_pceb(PC_port_base, PC_mem_seg)
62
INT32   PC_port_base;
63
INT32   PC_mem_seg;
64
   {
65
 
66
   /*** check for existence of the board ***/
67
 
68
   /* Set up PCCNF and reset processor */
69
   outp((unsigned int) (PC_port_base + PCEB_PCCNF_OFFSET),
70
        ((int) (PC_mem_seg & 0x7000) >> 10));
71
   outp((unsigned int) (PC_port_base + PCEB_PC229K_OFFSET),
72
        (int) (PCEB_LB_END | PCEB_WINENA | PCEB_S_HALT));
73
 
74
   return(0);
75
   }
76
 
77
 
78
/*
79
** This function is used to send a message to the PCEB.
80
** If the message is successfully sent, a zero is
81
** returned.  If the message was not sendable, a -1
82
** is returned.
83
**
84
** Also note that this function does endian conversion on the
85
** returned message.  This is necessary because the Am29000
86
** target will be sending big-endian messages and the PC will
87
** be expecting little-endian.
88
*/
89
 
90
INT32
91
msg_send_pceb(msg_ptr, PC_port_base)
92
   union  msg_t  *msg_ptr;
93
   INT32        PC_port_base;
94
   {
95
   INT32    result;
96
   int    pc229k;
97
   INT32  message_size;
98
   INT32        semaphore;
99
   INT32        result3;
100
 
101
         /* Set semaphore (PCEB_RECV_BUF_PTR) to zero */
102
           semaphore = (INT32) 0;
103
           result3 = Mini_write_memory ((INT32)   D_MEM,
104
                                      (ADDR32) PCEB_RECV_BUF_PTR,
105
                                      (INT32)  sizeof(INT32),
106
                                      (BYTE *) &semaphore);
107
   /* Get size of whole message */
108
   message_size = (msg_ptr->generic_msg).length + (2 * sizeof(INT32));
109
 
110
   /* Do endian conversion */
111
   if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
112
      endian_cvt(msg_ptr, OUTGOING_MSG);
113
 
114
   /* Send message */
115
   result = Mini_write_memory ((INT32)  D_MEM,
116
                              (ADDR32) PCEB_SEND_BUF,
117
                              (INT32)  message_size,
118
                              (BYTE *) msg_ptr);
119
 
120
   /* Interrupt target (write to pceb mailbox) */
121
   pc229k = (PCEB_P_REQ | PCEB_WINENA | PCEB_LB_END | PCEB_S_NORMAL);
122
   outp((unsigned int) (PC_port_base + PCEB_PC229K_OFFSET),
123
        (int) pc229k);
124
 
125
   /* Did everything go ok? */
126
   if (result != 0)
127
      return(-1);
128
      else
129
         return(0);
130
 
131
   }  /* end msg_send_pceb() */
132
 
133
 
134
 
135
 
136
/*
137
** This function is used to receive a message to the PCEB.
138
** If the message is waiting in the buffer, the message Code is
139
** returned and the buffer pointed to by msg_ptr is filled
140
** in.  If no message was available, a -1 is returned.
141
**
142
** Note that this function does endian conversion on the
143
** returned message.  This is necessary because the Am29000
144
** target will be sending big-endian messages and the PC will
145
** be expecting little-endian.
146
*/
147
 
148
INT32
149
msg_recv_pceb(msg_ptr, PC_port_base, Mode)
150
   union  msg_t  *msg_ptr;
151
   INT32  PC_port_base;
152
   INT32        Mode;
153
   {
154
   INT32    result1;
155
   INT32    result2;
156
   INT32    result3;
157
   ADDR32 recv_buf_addr;
158
   INT32  parms_length;
159
   INT32  header_size;
160
   INT32  semaphore;
161
 
162
   /* Get receive buffer address */
163
   result1 = Mini_read_memory ((INT32)  D_MEM,
164
                              (ADDR32) PCEB_RECV_BUF_PTR,
165
                              (INT32)  sizeof(ADDR32),
166
                              (BYTE *) &recv_buf_addr);
167
 
168
   /* Change endian of recv_buf_addr */
169
   if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
170
      tip_convert32((BYTE *) &recv_buf_addr);
171
 
172
   /* Return if there is no message */
173
   if (recv_buf_addr == 0) {
174
      return(-1);
175
      } else {
176
         /* Get message header */
177
         header_size = (INT32) (2 * sizeof(INT32));
178
         result1 = Mini_read_memory ((INT32)  D_MEM,
179
                                    (ADDR32) recv_buf_addr,
180
                                    (INT32)  header_size,
181
                                    (BYTE *) msg_ptr);
182
 
183
         /* Get rest of message */
184
         parms_length = (msg_ptr->generic_msg).length;
185
         if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
186
            tip_convert32((BYTE *) &parms_length);
187
         result2 = Mini_read_memory ((INT32)  D_MEM,
188
                                    (ADDR32) (recv_buf_addr + header_size),
189
                                    (INT32)  parms_length,
190
                                    (BYTE *) &(msg_ptr->generic_msg.byte));
191
 
192
         /* Do endian conversion */
193
         if (tip_target_config.TipEndian != tip_target_config.P29KEndian)
194
            endian_cvt(msg_ptr, INCOMING_MSG);
195
 
196
         /* Set semaphore (PCEB_RECV_BUF_PTR) to zero */
197
           semaphore = (INT32) 0;
198
           result3 = Mini_write_memory ((INT32)   D_MEM,
199
                                      (ADDR32) PCEB_RECV_BUF_PTR,
200
                                      (INT32)  sizeof(INT32),
201
                                      (BYTE *) &semaphore);
202
      }
203
 
204
   /* Did everything go ok? */
205
   if ((result1 != (INT32) 0) ||
206
       (result2 != (INT32) 0) ||
207
       (result3 != (INT32) 0))
208
         return(-1);
209
      else
210
         return(msg_ptr->generic_msg.code);
211
 
212
   }  /* end msg_recv_pceb() */
213
 
214
 
215
 
216
 
217
/*
218
** This function is used to close the communication
219
** channel.  This is used when resyncing the host and
220
** target and when exiting the monitor.
221
*/
222
 
223
INT32
224
exit_comm_pceb(PC_port_base, PC_mem_seg)
225
INT32   PC_port_base;
226
INT32   PC_mem_seg;
227
   {
228
     return (0);
229
   }
230
 
231
INT32
232
reset_comm_pceb(PC_port_base, PC_mem_seg)
233
INT32   PC_port_base;
234
INT32   PC_mem_seg;
235
   {
236
 
237
   return(0);
238
 
239
   }  /* end reset_comm_pceb() */
240
 
241
 
242
 
243
/*
244
** This function is used to "kick" the PCEB.  This
245
** amounts to yanking the *RESET line low.  Code
246
** will begin execution at ROM address 0.
247
*/
248
 
249
void
250
go_pceb(PC_port_base, PC_mem_seg)
251
INT32   PC_port_base;
252
INT32   PC_mem_seg;
253
   {
254
   int  setup;
255
 
256
   /* Reset processor */
257
   setup = (PCEB_LB_END | PCEB_WINENA);
258
 
259
   outp((unsigned int) (PC_port_base + PCEB_PC229K_OFFSET),
260
        (int) (setup | PCEB_S_RESET | PCEB_S_HALT));
261
 
262
   outp((unsigned int) (PC_port_base + PCEB_PC229K_OFFSET),
263
        (int) (setup | PCEB_S_RESET | PCEB_S_NORMAL));
264
 
265
   outp((unsigned int) (PC_port_base + PCEB_PC229K_OFFSET),
266
        (int ) (setup | PCEB_S_NORMAL));
267
 
268
   }  /* end go_pceb() */
269
 
270
 
271
 
272
 
273
 
274
 
275
/*
276
** This function is used to write a string of bytes to
277
** the Am29000 memory on the PCEB board.
278
**
279
** For more information on the PCEB interface, see
280
** Chapter 5 of the "PCEB User's Manual".
281
**
282
** Note:  This function aligns all 16 1K byte windows to make
283
** a single 16K byte window on a 1K boundary.
284
*/
285
 
286
INT32
287
write_memory_pceb(memory_space, address, data, byte_count, PC_port_base,
288
                  PC_mem_seg)
289
   INT32    memory_space;
290
   ADDR32   address;
291
   BYTE    *data;
292
   INT32    byte_count;
293
   INT32        PC_port_base;
294
   INT32        PC_mem_seg;
295
   {
296
   INT32  i;
297
   ADDR32 temp_address;
298
   INT32  bytes_in_window;
299
   INT32  copy_count;
300
 
301
   while (byte_count > 0) {
302
 
303
      /* Set up a single, contiguous 16K window (on a 1K boundary) */
304
      temp_address = address;
305
      for (i=0; i<16; i=i+1) {
306
         /* Write out low PCEB addr bits */
307
         outp((unsigned int) (PC_port_base+(INT32) (2*i)),
308
              (int) ((temp_address >> 10) & 0xff));
309
 
310
         /* Write out high PCEB addr bits */
311
         outp((unsigned int) (PC_port_base+(INT32) (2*i)+(INT32) 1),
312
              (int) ((temp_address >> 18) & 0x1f));
313
         temp_address = temp_address + (ADDR32) 0x400;
314
         }  /* end for */
315
 
316
      bytes_in_window = (INT32) 0x4000 - (address & 0x3ff);
317
      copy_count = (byte_count < bytes_in_window) ? byte_count : bytes_in_window;
318
 
319
      (void) movedata((unsigned int) FP_SEG(data),
320
                      (unsigned int) FP_OFF(data),
321
                      (unsigned int) PC_mem_seg,
322
                      (unsigned int) (address & 0x3ff),
323
                      (int) copy_count);
324
 
325
      data = data + copy_count;
326
      address = address + copy_count;
327
      byte_count = byte_count - copy_count;
328
 
329
      }  /* end while loop */
330
 
331
   return(0);
332
 
333
   }  /* End write_memory_pceb() */
334
 
335
 
336
 
337
 
338
/*
339
** This function is used to read a string of bytes from
340
** the Am29000 memory on the PCEB board.   A zero is
341
** returned if the data is read successfully, otherwise
342
** a -1 is returned.
343
**
344
** For more information on the PCEB interface, see
345
** Chapter 5 of the "PCEB User's Manual".
346
**
347
** Note:  This function aligns all 16 1K byte windows to make
348
** a single 16K byte window on a 1K boundary.
349
*/
350
 
351
INT32
352
read_memory_pceb(memory_space, address, data, byte_count, PC_port_base,
353
                 PC_mem_seg)
354
   INT32    memory_space;
355
   ADDR32   address;
356
   BYTE    *data;
357
   INT32    byte_count;
358
   INT32        PC_port_base;
359
   INT32        PC_mem_seg;
360
   {
361
   INT32  i;
362
   ADDR32 temp_address;
363
   INT32  bytes_in_window;
364
   INT32  copy_count;
365
 
366
   while (byte_count > 0) {
367
 
368
      /* Set up a single, contiguous 16K window (on a 1K boundary) */
369
      temp_address = address;
370
      for (i=0; i<16; i=i+1) {
371
         /* Write out low PCEB addr bits */
372
         outp((unsigned int) (PC_port_base+(2*i)),
373
              (int) ((temp_address >> 10) & 0xff));
374
 
375
         /* Write out high PCEB addr bits */
376
         outp((unsigned int) (PC_port_base+(2*i)+(INT32) 1),
377
              (int) ((temp_address >> 18) & 0x1f));
378
         temp_address = temp_address + (ADDR32) 0x400;
379
         }  /* end for */
380
 
381
      bytes_in_window = (INT32) 0x4000 - (address & 0x3ff);
382
      copy_count = (byte_count < bytes_in_window) ? byte_count : bytes_in_window;
383
 
384
      (void) movedata((unsigned int) PC_mem_seg,
385
                      (unsigned int) (address & 0x3ff),
386
                      (unsigned int) FP_SEG(data),
387
                      (unsigned int) FP_OFF(data),
388
                      (int) copy_count);
389
 
390
      data = data + copy_count;
391
      address = address + copy_count;
392
      byte_count = byte_count - copy_count;
393
 
394
      }  /* end while loop */
395
 
396
   return(0);
397
 
398
   }  /* End read_memory_pceb() */
399
 
400
INT32
401
fill_memory_pceb()
402
{
403
  return(0);
404
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.