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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [utils/] [amd-udi/] [montip/] [lcb29k.c] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
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
 

powered by: WebSVN 2.1.0

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