00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdlib.h>
00016 #ifdef VXWORKS
00017 #include <vxWorks.h>
00018 #include <logLib.h>
00019 #include <taskLib.h>
00020 #include <tickLib.h>
00021 #include <usrLib.h>
00022 #endif
00023
00024 #include "dma.h"
00025 #include "dbg_mem.h"
00026
00027 unsigned long DMA_VMEBUS_REQUEST_LEVEL = 0;
00028
00029
00030
00031
00032
00033 unsigned long MVME162_DMA_CONTROL_OPTIONS = 0;
00034
00035
00036
00037
00038
00039 unsigned long MVME162_DMA_TIMEOUT_OPTIONS = 0;
00040
00041
00042
00043
00044 struct MVME162_DMAC_COMMAND
00045 {
00046 unsigned long control_word;
00047 void *local_bus_address;
00048 void *vme_bus_address;
00049 unsigned long byte_count;
00050 void *next_command;
00051 };
00052
00053
00054 struct DMA_ADDR_INFO
00055 {
00056 int board_type;
00057 unsigned long addr;
00058 unsigned long am;
00059 int address_decoder;
00060 int ignore_dma_errors;
00061 };
00062
00063 void *dma_command_list = 0;
00064 int dma_command_started = 0;
00065 int dma_print_errors = 1;
00066
00067 void *testDMAVMEAddress = ((void *) 0x4e00000);
00068 long testDMABufSize = 0x4000;
00069 int testDMABoardType = VX_MVME162_BOARD_TYPE;
00070 static char c = 'a';
00071 void *local_data = 0;
00072 struct DMA_ADDR_INFO *testDMAinfo = 0;
00073 int MVME162_DMA_DELAY_COUNT = 1000;
00074
00075 #define MAX_MVME162_DMAC_COMMANDS (4)
00076 struct MVME162_DMAC_COMMAND
00077 mvme162_dmac_commands_list1[MAX_MVME162_DMAC_COMMANDS];
00078 struct MVME162_DMAC_COMMAND
00079 mvme162_dmac_commands_list2[MAX_MVME162_DMAC_COMMANDS];
00080 struct MVME162_DMAC_COMMAND *mvme162_dmac_commands_list =
00081 mvme162_dmac_commands_list1;
00082 int num_mvme162_dmac_commands = 0;
00083 int startCommandTicks = 0;
00084
00085
00086 int
00087 displayMemory (void *addr, int nunits, int nwidth)
00088 {
00089 int i;
00090 for (i = 0; i < nunits * nwidth / 16; i++)
00091 {
00092 switch (nwidth)
00093 {
00094 case 4:
00095 #ifdef VXWORKS
00096 logMsg (" %8.8X: %8.8X %8.8X %8.8X %8.8X\n",
00097 (((unsigned long) addr) + (i * 16)),
00098 (*(unsigned long *) (((unsigned long) addr) + (i * 16))),
00099 (*(unsigned long *)
00100 (((unsigned long) addr) + (i * 16 + 4))),
00101 (*(unsigned long *)
00102 (((unsigned long) addr) + (i * 16) + 8)),
00103 (*(unsigned long *)
00104 (((unsigned long) addr) + (i * 16) + 12)), 0);
00105 #else
00106 return -1;
00107 #endif
00108 break;
00109
00110 default:
00111 return -1;
00112 }
00113 }
00114 return 0;
00115 }
00116
00117 int
00118 setTestDMAData (char c)
00119 {
00120 if (0 == local_data)
00121 {
00122 local_data = (void *) DEBUG_MALLOC (testDMABufSize);
00123 }
00124 memset (local_data, c, testDMABufSize);
00125 }
00126
00127 int dma_switch = 0;
00128
00129 int
00130 testDMA ()
00131 {
00132 unsigned long ticks = 0;
00133 #ifdef VXWORKS
00134 ULONG startTicks = tickGet ();
00135 #endif
00136 if (dma_switch)
00137 {
00138 if (mvme162_dmac_commands_list == mvme162_dmac_commands_list1)
00139 {
00140 mvme162_dmac_commands_list = mvme162_dmac_commands_list2;
00141 }
00142 else
00143 {
00144 mvme162_dmac_commands_list = mvme162_dmac_commands_list1;
00145 }
00146 }
00147 printf ("c=%c\n", c);
00148 setTestDMAData (c);
00149 c++;
00150 if (c > 'z')
00151 {
00152 c = 'a';
00153 }
00154
00155 dma_command_started = 0;
00156
00157 #ifdef VERBOSE
00158 displayMemory ((void *) 0xfff40030, 8, 4);
00159 displayMemory (mvme162_dmac_commands_list, 8, 4);
00160 #ifdef VXWORKS
00161 logMsg (" getDMAInfo %X %d\n", (int) dma_command_list, dma_command_started,
00162 0, 0, 0, 0);
00163 #endif
00164 #endif
00165 if (0 == testDMAinfo)
00166 {
00167 testDMAinfo =
00168 getDMAInfo (testDMABoardType, ((unsigned long) testDMAVMEAddress));
00169 }
00170 if (0 == testDMAinfo)
00171 {
00172 return -1;
00173 }
00174 #ifdef VERBOSE
00175 displayMemory ((void *) 0xfff40030, 8, 4);
00176 displayMemory (mvme162_dmac_commands_list, 8, 4);
00177 #ifdef VXWORKS
00178 logMsg (" checkForDMADone %X %d\n", (int) dma_command_list,
00179 dma_command_started, 0, 0, 0, 0);
00180 #endif
00181 #endif
00182 taskDelay (1);
00183 taskLock ();
00184 if (!checkForDMADone (testDMAinfo))
00185 {
00186 #ifdef VXWORKS
00187 logMsg (" DMA not Done. %X %d\n", (int) dma_command_list,
00188 dma_command_started, 0, 0, 0, 0);
00189 #endif
00190 displayMemory ((void *) 0xfff40030, 8, 4);
00191 taskUnlock ();
00192 return -1;
00193 }
00194 #ifdef VERBOSE
00195 displayMemory ((void *) 0xfff40030, 8, 4);
00196 displayMemory (mvme162_dmac_commands_list, 8, 4);
00197 #ifdef VXWORKS
00198 logMsg (" DMACLearScheduledTransfersList %X %d\n", (int) dma_command_list,
00199 dma_command_started, 0, 0, 0, 0);
00200 #endif
00201 #endif
00202 if (DMAClearScheduledTransfersList (testDMAinfo) < 0)
00203 {
00204 #ifdef VXWORKS
00205 logMsg (" Can't clear scheduled DMA transfer list. %X %d\n",
00206 (int) dma_command_list, dma_command_started, 0, 0, 0, 0);
00207 #endif
00208 freeDMAInfo (testDMAinfo);
00209 testDMAinfo = 0;
00210 taskUnlock ();
00211 return -1;
00212 }
00213 #ifdef VERBOSE
00214 displayMemory ((void *) 0xfff40030, 8, 4);
00215 displayMemory (mvme162_dmac_commands_list, 8, 4);
00216 #ifdef VXWORKS
00217 logMsg (" DMASheduleLocalToVMETransfer %X %d\n", (int) dma_command_list,
00218 dma_command_started, 0, 0, 0, 0);
00219 #endif
00220 #endif
00221 if (DMAScheduleLocalToVMETransfer
00222 (testDMAinfo, testDMAVMEAddress, local_data, testDMABufSize) < 0)
00223 {
00224 #ifdef VXWORKS
00225 logMsg (" Can't schedule DMA transfer. %X %d\n", (int) dma_command_list,
00226 dma_command_started, 0, 0, 0, 0);
00227 #endif
00228 freeDMAInfo (testDMAinfo);
00229 testDMAinfo = 0;
00230 taskUnlock ();
00231 return -1;
00232 }
00233 #ifdef VERBOSE
00234 displayMemory ((void *) 0xfff40030, 8, 4);
00235 displayMemory (mvme162_dmac_commands_list, 8, 4);
00236 #ifdef VXWORKS
00237 logMsg (" DMAStartTransfers %X %d\n", (int) dma_command_list,
00238 dma_command_started, 0, 0, 0, 0);
00239 #endif
00240 #endif
00241 if (DMAStartTransfers (testDMAinfo) < 0)
00242 {
00243 #ifdef VXWORKS
00244 logMsg (" Can't start DMA transfer. %X %d\n", (int) dma_command_list,
00245 dma_command_started, 0, 0, 0, 0);
00246 #endif
00247 freeDMAInfo (testDMAinfo);
00248 testDMAinfo = 0;
00249 taskUnlock ();
00250 return -1;
00251 }
00252 #ifdef VERBOSE
00253 displayMemory ((void *) 0xfff40030, 8, 4);
00254 displayMemory (mvme162_dmac_commands_list, 8, 4);
00255 #ifdef VXWORKS
00256 logMsg (" checkForDMADone %X %d\n", (int) dma_command_list,
00257 dma_command_started, 0, 0, 0, 0);
00258 #endif
00259 #endif
00260 while (ticks < 100)
00261 {
00262 switch (checkForDMADone (testDMAinfo))
00263 {
00264 case 0:
00265 #ifdef VERBOSE
00266 displayMemory ((void *) 0xfff40030, 8, 4);
00267 displayMemory (mvme162_dmac_commands_list, 8, 4);
00268 #endif
00269 break;
00270
00271 case 1:
00272 #ifdef VERBOSE
00273 displayMemory ((void *) 0xfff40030, 8, 4);
00274 displayMemory (mvme162_dmac_commands_list, 8, 4);
00275 #endif
00276 printf ("*((char *)0x%X)=%c\n", testDMAVMEAddress,
00277 *((char *) testDMAVMEAddress));
00278 taskUnlock ();
00279 return ticks;
00280
00281 default:
00282 displayMemory ((void *) 0xfff40000, 64, 4);
00283 displayMemory (mvme162_dmac_commands_list, 8, 4);
00284 taskUnlock ();
00285 return -1;
00286 }
00287 #ifdef VXWORKS
00288 ticks = tickGet () - startTicks;
00289 #else
00290 ticks++;
00291 #endif
00292 }
00293 #ifdef VERBOSE
00294 displayMemory ((void *) 0xfff40030, 8, 4);
00295 displayMemory (mvme162_dmac_commands_list, 8, 4);
00296 taskUnlock ();
00297 #ifdef VXWORKS
00298 logMsg ("\ntestDMA finish\n", 0, 0, 0, 0, 0, 0);
00299 #endif
00300 #endif
00301 printf ("*((char *)0x%X)=%c\n", testDMAVMEAddress,
00302 *((char *) testDMAVMEAddress));
00303 return ticks;
00304 }
00305
00306 unsigned long orig_data = 0;
00307 char orig_data_char;
00308
00309 int mvme162_dma_init (struct DMA_ADDR_INFO *info);
00310
00311 struct DMA_ADDR_INFO *
00312 getDMAInfo (int board_type, unsigned long addr)
00313 {
00314 struct DMA_ADDR_INFO *info = 0;
00315 unsigned long vme_bus_enable_control_reg;
00316 unsigned long io_control_reg;
00317 unsigned long a1;
00318 unsigned long enda1;
00319 unsigned long starta1;
00320 int tries = 0;
00321 int addr_found = 0;
00322 unsigned long ticks = 0;
00323 #ifdef VXWORKS
00324 ULONG startTicks = tickGet ();
00325 #endif
00326 info =
00327 (struct DMA_ADDR_INFO *) DEBUG_MALLOC (sizeof (struct DMA_ADDR_INFO));
00328 if (0 == info)
00329 {
00330 return ((struct DMA_ADDR_INFO *) 0);
00331 }
00332 info->board_type = board_type;
00333 info->addr = addr;
00334 switch (board_type)
00335 {
00336 case VX_MVME162_BOARD_TYPE:
00337 if (0 == info)
00338 {
00339 return 0;
00340 }
00341 if (addr & 3)
00342 {
00343 return 0;
00344 }
00345 info->address_decoder = 0;
00346 info->am = 0;
00347 info->ignore_dma_errors = 1;
00348 if (num_mvme162_dmac_commands < 1)
00349 {
00350 memset (mvme162_dmac_commands_list, 0,
00351 sizeof (struct MVME162_DMAC_COMMAND) *
00352 MAX_MVME162_DMAC_COMMANDS);
00353 num_mvme162_dmac_commands = 0;
00354 }
00355
00356 vme_bus_enable_control_reg =
00357 (0x0f0000 & *((unsigned long *) 0xFFF4002C));
00358 if (vme_bus_enable_control_reg & 0x10000)
00359 {
00360
00361 a1 = *((unsigned long *) 0xFFF40014);
00362 enda1 = (0xFFFF0000 & a1);
00363 starta1 = ((0x0000FFFF & a1) << 16);
00364 if (addr > starta1 && addr < enda1)
00365 {
00366 info->address_decoder = 1;
00367
00368 info->am = 0x3f & *((unsigned long *) 0xfff40028);
00369 #ifdef VXWORKS
00370 taskDelay (1);
00371 #endif
00372 addr_found = 1;
00373 }
00374 }
00375 if (vme_bus_enable_control_reg & 0x20000 && !addr_found)
00376 {
00377
00378 a1 = *((unsigned long *) 0xFFF40018);
00379 enda1 = (0xFFFF0000 & a1);
00380 starta1 = ((0x0000FFFF & a1) << 16);
00381 if (addr > starta1 && addr < enda1)
00382 {
00383 info->address_decoder = 2;
00384
00385 info->am = 0x3f & (*((unsigned long *) 0xfff40028) >> 8);
00386 #ifdef VXWORKS
00387 taskDelay (1);
00388 #endif
00389 addr_found = 1;
00390 }
00391 }
00392 if (vme_bus_enable_control_reg & 0x40000 && !addr_found)
00393 {
00394
00395 a1 = *((unsigned long *) 0xFFF4001C);
00396 enda1 = (0xFFFF0000 & a1);
00397 starta1 = ((0x0000FFFF & a1) << 16);
00398 if (addr > starta1 && addr < enda1)
00399 {
00400 info->address_decoder = 1;
00401
00402 info->am = 0x3f & (*((unsigned long *) 0xfff40028) >> 16);
00403 #ifdef VXWORKS
00404 taskDelay (1);
00405 #endif
00406 addr_found = 1;
00407 }
00408 }
00409 if (vme_bus_enable_control_reg & 0x80000 && !addr_found)
00410 {
00411
00412 a1 = *((unsigned long *) 0xFFF40020);
00413 enda1 = (0xFFFF0000 & a1);
00414 starta1 = ((0x0000FFFF & a1) << 16);
00415 if (addr > starta1 && addr < enda1)
00416 {
00417 info->address_decoder = 1;
00418
00419 info->am = 0x3f & (*((unsigned long *) 0xfff40028) >> 24);
00420 #ifdef VXWORKS
00421 taskDelay (1);
00422 #endif
00423 addr_found = 1;
00424 }
00425 }
00426
00427 if ((addr & (0xff << 24)) == (0xf0 << 24))
00428 {
00429 io_control_reg = *((unsigned long *) 0xfff4002c);
00430 if (io_control_reg & (1 << 15))
00431 {
00432 addr_found = 1;
00433 info->address_decoder = 6;
00434 info->am = 0x0c;
00435 }
00436 }
00437 if (addr_found)
00438 {
00439 while (!mvme162_dma_init (info) && tries > 10)
00440 {
00441 #ifdef VXWORKS
00442 taskDelay (1);
00443 #endif
00444 tries++;
00445 }
00446 return info;
00447 }
00448
00449
00450 DEBUG_FREE (info);
00451 return 0;
00452
00453 default:
00454 break;
00455 }
00456 return info;
00457 }
00458
00459 int
00460 mvme162_dma_init (struct DMA_ADDR_INFO *info)
00461 {
00462 int retval = 0;
00463 unsigned long dmac_status;
00464 unsigned long addr = info->addr;
00465 unsigned long ticks = 0;
00466 #ifdef VXWORKS
00467 ULONG startTicks = tickGet ();
00468 #endif
00469 #ifdef VXWORKS
00470 taskLock ();
00471 #endif
00472 orig_data = *((unsigned long *) addr);
00473 *((unsigned long *) addr) = ~orig_data;
00474 dma_print_errors = 0;
00475 while (!checkForDMADone (info) && ticks < 10)
00476 {
00477 #ifdef VXWORKS
00478 ticks = tickGet () - startTicks;
00479 #else
00480 ticks++;
00481 #endif
00482 }
00483 DMAClearScheduledTransfersList (info);
00484 DMAScheduleLocalToVMETransfer (info, (void *) addr, &orig_data, 4);
00485 DMAStartTransfers (info);
00486 while (!checkForDMADone (info) && ticks < 10)
00487 {
00488 #ifdef VXWORKS
00489 ticks = tickGet () - startTicks;
00490 #else
00491 ticks++;
00492 #endif
00493 }
00494 dma_print_errors = 1;
00495
00496 dmac_status = *((unsigned long *) 0xFFF40048);
00497 #ifdef VXWORKS
00498 taskUnlock ();
00499 #endif
00500 retval = ((dmac_status & 0x7f) == 1)
00501 && (orig_data == *((unsigned long *) addr));
00502 if (!retval)
00503 {
00504 *((unsigned long *) addr) == orig_data;
00505 }
00506 return retval;
00507 }
00508
00509 void
00510 freeDMAInfo (struct DMA_ADDR_INFO *info)
00511 {
00512 if (0 != info)
00513 {
00514 DMAClearScheduledTransfersList (info);
00515 DEBUG_FREE (info);
00516 }
00517 }
00518
00519 int
00520 checkForDMADone (struct DMA_ADDR_INFO *info)
00521 {
00522 unsigned long dmac_status;
00523 unsigned long dmac_control_word;
00524 unsigned long dmac_byte_counter;
00525 unsigned long dmac_table_address_counter;
00526 int done = 0;
00527 int error = 0;
00528 if (info == 0)
00529 {
00530 return 0;
00531 }
00532 switch (info->board_type)
00533 {
00534 case VX_MVME162_BOARD_TYPE:
00535
00536 dmac_status = *((unsigned long *) 0xFFF40048);
00537 done = dmac_status & 1;
00538 error = dmac_status & 0x7e;
00539 if (!done && !error && !dma_command_started)
00540 {
00541
00542 dmac_control_word = *((unsigned long *) 0xfff40030);
00543
00544 if (dmac_control_word & (1 << 5))
00545 {
00546
00547 dmac_table_address_counter = *((unsigned long *) 0xfff40044);
00548
00549
00550 dmac_byte_counter = *((unsigned long *) 0xfff40040);
00551 return (((dmac_table_address_counter & 0x3) != 0)
00552 && (dmac_byte_counter == 0));
00553 }
00554 else
00555 {
00556
00557 dmac_byte_counter = *((unsigned long *) 0xfff40040);
00558 return (dmac_byte_counter == 0);
00559 }
00560 }
00561 if (error)
00562 {
00563 if (!dma_command_started || info->ignore_dma_errors)
00564 {
00565 return 1;
00566 }
00567 #ifdef VXWORKS
00568 if (dma_print_errors)
00569 {
00570 logMsg ("DMA error 0x%X -- %s %s\n", error,
00571 (int) ((error & 0x2) ? "(VMEbus ERR)" : ""),
00572 (int) ((error & 0x4) ? "(Command Table ERR)" : ""), 0,
00573 0, 0);
00574 if (error & 0x8)
00575 logMsg ("(DLTO - DMA Local Bus Timeout ERR)\n", 0, 0, 0, 0, 0,
00576 0);
00577 if (error & 0x10)
00578 logMsg ("(DLOB - DMA Offboard ERR)\n", 0, 0, 0, 0, 0, 0);
00579 if (error & 0x20)
00580 logMsg ("(DLPE - DMA Parity ERR)\n", 0, 0, 0, 0, 0, 0);
00581 if (error & 0x40)
00582 logMsg ("(DLBE - DMA Unknown ERR)\n", 0, 0, 0, 0, 0, 0);
00583 }
00584 #endif
00585
00586 *((unsigned long *) 0xfff40040) = 0;
00587 dma_command_started = 0;
00588 return -1;
00589 }
00590 if (done || error)
00591 {
00592 dma_command_started = 0;
00593 }
00594 return done;
00595
00596 default:
00597 break;
00598 }
00599 return 0;
00600 }
00601
00602 int
00603 DMAScheduleLocalToVMETransfer (struct DMA_ADDR_INFO *info, void *vme_dest,
00604 void *local_src, unsigned long bytes)
00605 {
00606 struct MVME162_DMAC_COMMAND *mvme162_cmd = 0;
00607 void **next_cmd;
00608
00609 if (info == 0)
00610 {
00611 return -1;
00612 }
00613 switch (info->board_type)
00614 {
00615 case VX_MVME162_BOARD_TYPE:
00616 mvme162_cmd =
00617 (struct MVME162_DMAC_COMMAND *)
00618 &(mvme162_dmac_commands_list[num_mvme162_dmac_commands]);
00619 num_mvme162_dmac_commands++;
00620 mvme162_cmd->control_word = 0;
00621
00622 mvme162_cmd->control_word |= (1 << 9) | (1 << 10) | (1 << 11);
00623 mvme162_cmd->control_word &= 0xFFFF;
00624 mvme162_cmd->control_word &= ~0x3f;
00625 mvme162_cmd->control_word |= info->am;
00626 mvme162_cmd->local_bus_address = local_src;
00627 mvme162_cmd->vme_bus_address = vme_dest;
00628 mvme162_cmd->byte_count = bytes;
00629 mvme162_cmd->next_command = (void *) 3;
00630 if (dma_command_list == 0
00631 || (((unsigned long) dma_command_list) & 3) != 0)
00632 {
00633 dma_command_list = mvme162_cmd;
00634
00635 *((unsigned long *) 0xfff40044) = (unsigned long) dma_command_list;
00636 }
00637 else
00638 {
00639 next_cmd =
00640 &((struct MVME162_DMAC_COMMAND *) dma_command_list)->next_command;
00641 while (*next_cmd != 0 && (((unsigned long) (*next_cmd)) & 3) == 0)
00642 {
00643 next_cmd =
00644 &((struct MVME162_DMAC_COMMAND *) (*next_cmd))->next_command;
00645 }
00646 *next_cmd = mvme162_cmd;
00647 }
00648 return 0;
00649
00650 default:
00651 break;
00652 }
00653 return -1;
00654 }
00655
00656 int
00657 DMAScheduleVMEToLocalTransfer (struct DMA_ADDR_INFO *info, void *local_dest,
00658 void *vme_src, unsigned long bytes)
00659 {
00660 struct MVME162_DMAC_COMMAND *mvme162_cmd = 0;
00661 void **next_cmd;
00662 unsigned long am = 0;
00663
00664 if (info == 0)
00665 {
00666 return -1;
00667 }
00668 switch (info->board_type)
00669 {
00670 case VX_MVME162_BOARD_TYPE:
00671 if (num_mvme162_dmac_commands >= MAX_MVME162_DMAC_COMMANDS)
00672 {
00673 return -1;
00674 }
00675 mvme162_cmd =
00676 (struct MVME162_DMAC_COMMAND *)
00677 &(mvme162_dmac_commands_list[num_mvme162_dmac_commands]);
00678 num_mvme162_dmac_commands++;
00679 mvme162_cmd->control_word = *((unsigned long *) 0xFFF40034);
00680
00681 mvme162_cmd->control_word |= (1 << 10) | (1 << 11);
00682
00683 mvme162_cmd->control_word &= ~(1 << 9);
00684 mvme162_cmd->control_word &= ~(0x3f);
00685 mvme162_cmd->control_word |= info->am;
00686 mvme162_cmd->local_bus_address = local_dest;
00687 mvme162_cmd->vme_bus_address = vme_src;
00688 mvme162_cmd->byte_count = bytes;
00689 mvme162_cmd->next_command = (void *) 3;
00690 if (dma_command_list == 0
00691 || (((unsigned long) dma_command_list) & 3) != 0)
00692 {
00693 dma_command_list = mvme162_cmd;
00694
00695 *((unsigned long *) 0xfff40044) = (unsigned long) dma_command_list;
00696 }
00697 else
00698 {
00699 next_cmd =
00700 &((struct MVME162_DMAC_COMMAND *) dma_command_list)->next_command;
00701 while (*next_cmd != 0 && (((unsigned long) (*next_cmd)) & 3) == 0)
00702 {
00703 next_cmd =
00704 &((struct MVME162_DMAC_COMMAND *) (*next_cmd))->next_command;
00705 }
00706 *next_cmd = mvme162_cmd;
00707 }
00708 return 0;
00709
00710 default:
00711 break;
00712 }
00713 return -1;
00714 }
00715
00716 int
00717 DMASingleLocalToVMETransfer (struct DMA_ADDR_INFO *info, void *vme_dest,
00718 void *local_src, unsigned long bytes)
00719 {
00720 unsigned long dmac_control_word = 0;
00721
00722 if (info == 0)
00723 {
00724 return -1;
00725 }
00726 dma_command_started = 1;
00727 switch (info->board_type)
00728 {
00729 case VX_MVME162_BOARD_TYPE:
00730
00731 *((unsigned long *) 0xfff40044) = 0;
00732
00733
00734 *((unsigned long *) 0xfff40038) = (unsigned long) local_src;
00735
00736
00737 *((unsigned long *) 0xfff4003c) = (unsigned long) vme_dest;
00738
00739
00740 *((unsigned long *) 0xfff40040) = bytes;
00741
00742
00743 dmac_control_word = *((unsigned long *) 0xfff40034);
00744
00745 dmac_control_word |= (1 << 11) | (1 << 10) | (1 << 9);
00746
00747 dmac_control_word &= ~(1 << 15);
00748 dmac_control_word &= ~(0x3f);
00749 dmac_control_word |= info->am;
00750 *((unsigned long *) 0xfff40034) = dmac_control_word;
00751
00752
00753 dmac_control_word = *((unsigned long *) 0xfff40030);
00754
00755 dmac_control_word |= (1 << 6);
00756
00757 dmac_control_word &= ~(1 << 13) & ~(1 << 5);
00758
00759 *((unsigned long *) 0xfff40048) = (1 << 11);
00760 *((unsigned long *) 0xfff40030) = dmac_control_word;
00761 return 0;
00762
00763 default:
00764 break;
00765 }
00766 return -1;
00767 }
00768
00769
00770 int
00771 DMASingleVMEToLocalTransfer (struct DMA_ADDR_INFO *info, void *local_dest,
00772 void *vme_src, unsigned long bytes)
00773 {
00774 unsigned long dmac_control_word = 0;
00775 unsigned long am = 0;
00776
00777 if (info == 0)
00778 {
00779 return -1;
00780 }
00781 dma_command_started = 1;
00782 switch (info->board_type)
00783 {
00784 case VX_MVME162_BOARD_TYPE:
00785
00786 *((unsigned long *) 0xfff40044) = 0;
00787
00788
00789 *((unsigned long *) 0xfff40038) = (unsigned long) local_dest;
00790
00791
00792 *((unsigned long *) 0xfff4003c) = (unsigned long) vme_src;
00793
00794
00795 *((unsigned long *) 0xfff40040) = bytes;
00796
00797
00798 dmac_control_word = *((unsigned long *) 0xfff40034);
00799
00800 dmac_control_word |= (1 << 11) | (1 << 10);
00801
00802 dmac_control_word &= ~(1 << 15) & ~(1 << 9);
00803 dmac_control_word &= ~(0x3f);
00804 dmac_control_word |= info->am;
00805 *((unsigned long *) 0xfff40034) = dmac_control_word;
00806
00807
00808 dmac_control_word = *((unsigned long *) 0xfff40030);
00809
00810 dmac_control_word |= (1 << 6);
00811
00812 dmac_control_word &= ~(1 << 13) & ~(1 << 5);
00813
00814 *((unsigned long *) 0xfff40048) = (1 << 11);
00815 *((unsigned long *) 0xfff40030) = dmac_control_word;
00816 return 0;
00817
00818 default:
00819 break;
00820 }
00821 return -1;
00822 }
00823
00824 int
00825 DMAStartTransfers (struct DMA_ADDR_INFO *info)
00826 {
00827 unsigned long dmac_control_word = 0;
00828 unsigned long dmac_timeout_reg = 0;
00829 unsigned long lvreql;
00830 int i = 0;
00831
00832 if (info == 0)
00833 {
00834 return -1;
00835 }
00836 if (!checkForDMADone (info))
00837 {
00838 return -1;
00839 }
00840 dma_command_started = 1;
00841 switch (info->board_type)
00842 {
00843 case VX_MVME162_BOARD_TYPE:
00844 if (dma_command_list == 0
00845 || (((unsigned long) dma_command_list) & 3) != 0)
00846 {
00847 return -1;
00848 }
00849
00850 *((unsigned long *) 0xfff40044) = (unsigned long) dma_command_list;
00851
00852
00853 dmac_control_word = *((unsigned long *) 0xfff40030);
00854
00855
00856 lvreql = (dmac_control_word & (3 << 8)) >> 8;
00857 dmac_control_word &= ~(0xff);
00858
00859
00860
00861
00862 dmac_control_word |=
00863 (1 << 5) | MVME162_DMA_CONTROL_OPTIONS | (0x3 &
00864 DMA_VMEBUS_REQUEST_LEVEL);
00865
00866 dmac_control_word &= ~(1 << 13);
00867
00868 dmac_control_word &= ~(1 << 7) & ~(1 << 6);
00869
00870 *((unsigned long *) 0xfff40048) = (1 << 11);
00871
00872
00873 *((unsigned long *) 0xfff40040) = 0;
00874
00875 *((unsigned long *) 0xfff40030) = dmac_control_word;
00876
00877 *((unsigned long *) 0xfff40040) = 0;
00878
00879 dmac_timeout_reg = *((unsigned long *) 0xfff4004c);
00880 dmac_timeout_reg &= ~(0xff << 16);
00881 dmac_timeout_reg |= MVME162_DMA_TIMEOUT_OPTIONS;
00882 *((unsigned long *) 0xfff4004c) = dmac_timeout_reg;
00883
00884 if (*((unsigned long *) 0xfff40044) !=
00885 ((unsigned long) dma_command_list)
00886 || *((unsigned long *) 0xfff40030) != dmac_control_word)
00887 {
00888 return -1;
00889 }
00890
00891 dmac_control_word |= (1 << 6);
00892 *((unsigned long *) 0xfff40030) = dmac_control_word;
00893 #ifdef VXWORKS
00894 startCommandTicks = tickGet ();
00895 #endif
00896 return 0;
00897
00898 default:
00899 break;
00900 }
00901 return -1;
00902 }
00903
00904 int
00905 DMAClearScheduledTransfersList (struct DMA_ADDR_INFO *info)
00906 {
00907 void *cmd_ptr;
00908 void *last_cmd_ptr;
00909 unsigned long dmac_control_word;
00910 unsigned long ticks = 0;
00911 #ifdef VXWORKS
00912 ULONG startTicks = tickGet ();
00913 #endif
00914
00915 if (info == 0)
00916 {
00917 return -1;
00918 }
00919
00920 dma_command_started = 0;
00921 switch (info->board_type)
00922 {
00923 case VX_MVME162_BOARD_TYPE:
00924
00925
00926
00927
00928
00929
00930
00931 dmac_control_word = *((unsigned long *) 0xfff40030);
00932
00933 dmac_control_word |= (1 << 7);
00934
00935 dmac_control_word &= ~(1 << 6);
00936 *((unsigned long *) 0xfff40030) = dmac_control_word;
00937
00938 while (*((unsigned long *) 0xfff40040) > 0)
00939 {
00940
00941 if (*((unsigned long *) 0xfff40048) & 0x7f)
00942 {
00943 break;
00944 }
00945 #ifdef VXWORKS
00946 ticks = tickGet () - startTicks;
00947 #else
00948 ticks++;
00949 #endif
00950 if (ticks > 100)
00951 {
00952 #ifdef VXWORKS
00953 displayMemory ((void *) 0xfff40030, 8, 4);
00954 #endif
00955 *((unsigned long *) 0xfff40044) = 0x3;
00956 *((unsigned long *) 0xfff40040) = 0;
00957 return -1;
00958 }
00959 }
00960
00961 *((unsigned long *) 0xfff40044) = 0x3;
00962 memset (mvme162_dmac_commands_list, 0,
00963 sizeof (struct MVME162_DMAC_COMMAND) *
00964 MAX_MVME162_DMAC_COMMANDS);
00965 num_mvme162_dmac_commands = 0;
00966 dma_command_list = 0;
00967 break;
00968
00969 default:
00970 break;
00971 }
00972 return 0;
00973 }