00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifdef EXTERN_C_STD_HEADERS
00013 extern "C"
00014 {
00015 #endif
00016
00017 #include <string.h>
00018 #include <stddef.h>
00019 #include <stdlib.h>
00020 #include <ctype.h>
00021 #include <math.h>
00022
00023 #ifdef VXWORKS
00024 #include "vxWorks.h"
00025 #include "sysLib.h"
00026 #include "taskLib.h"
00027 #include "semLib.h"
00028 #include "semSmLib.h"
00029 #include "objLib.h"
00030 #include "vme.h"
00031 #endif
00032
00033 #ifdef EXTERN_C_STD_HEADERS
00034 }
00035 #endif
00036
00037
00038
00039 #ifdef VXWORKS
00040 extern "C"
00041 {
00042 #ifndef POWERPC
00043 #include "spinlock.h"
00044 #endif
00045 #include "bus_lock.h"
00046 #include "dma.h"
00047 }
00048 #endif
00049
00050 #include "cms.hh"
00051 #include "globmem.hh"
00052 #include "timer.hh"
00053 #include "rcs_prnt.hh"
00054
00055 #define SEM_DELAY_EPSILON (1.0E-6)
00056 #define DEFAULT_SEM_DELAY (1.0E-3)
00057 #define SEM_CHECK_TIME_EPSILON (1.0E-7)
00058
00059 #if defined(WIN32) && defined(USE_BIT3)
00060 #include "btapi.h"
00061 #endif
00062
00063
00064 unsigned long (*get_physical_address_func) (char *)
00065 = (unsigned long (*)(char *)) NULL;
00066
00067
00068
00069 static int
00070 convert2lower (char *dest, char *src, int len)
00071 {
00072 int i;
00073 for (i = 0; i < len; i++)
00074 {
00075 if (src[i] == 0)
00076 {
00077 dest[i] = 0;
00078 return i;
00079 }
00080 dest[i] = tolower (src[i]);
00081 }
00082 return i;
00083 }
00084
00085 static int
00086 convert2upper (char *dest, char *src, int len)
00087 {
00088 int i;
00089 for (i = 0; i < len; i++)
00090 {
00091 if (src[i] == 0)
00092 {
00093 dest[i] = 0;
00094 return i;
00095 }
00096 dest[i] = toupper (src[i]);
00097 }
00098 return i;
00099 }
00100
00101
00102
00103 #ifdef VXWORKS
00104 int RCS_BOARD_TYPE = UNKNOWN_BOARD_TYPE;
00105 int usrSmObjInitInitialized = 0;
00106 int VxMP_Option_Installed = 0;
00107 int dma_being_used = 0;
00108 #endif
00109
00110
00111
00112 GLOBMEM::GLOBMEM (char *bufline, char *procline, int set_to_server,
00113 int set_to_master):
00114 CMS (bufline, procline, set_to_server)
00115 {
00116 int address_space_code = 0;
00117 RCS_TIMER timer (1.0);
00118 char *address_equation;
00119 char *semdelay_equation;
00120 physical_address = 0;
00121 skip_area = 0;
00122 local_locks = (char *) NULL;
00123 physmem_handle = (PHYSMEM_HANDLE *) NULL;
00124 sem_delay = DEFAULT_SEM_DELAY;
00125 half_size = size / 2;
00126 half_offset = size / 2;
00127 #ifdef VXWORKS
00128 board_type = RCS_BOARD_TYPE;
00129 use_dma = 0;
00130 bl_info = 0;
00131 dma_info = 0;
00132 #endif
00133 lock_bus = 0;
00134
00135 char *board_type_eq = NULL;
00136 #ifdef VXWORKS
00137 if (NULL != (board_type_eq = sysModel ()))
00138 {
00139 if (!strncmp (board_type_eq, "MVME162", 7))
00140 {
00141 board_type = VX_MVME162_BOARD_TYPE;
00142 }
00143 }
00144 #endif
00145
00146 #ifdef VXWORKS
00147 if (NULL != (board_type_eq = strstr (buflineupper, "BD_TYPE=")))
00148 {
00149 board_type_eq += 8;
00150 if (!strncmp (board_type_eq, "MVME162", 7))
00151 {
00152 board_type = VX_MVME162_BOARD_TYPE;
00153 }
00154 }
00155
00156 if (NULL != (board_type_eq = strstr (proclineupper, "BD_TYPE=")))
00157 {
00158 board_type_eq += 8;
00159 if (!strncmp (board_type_eq, "MVME162", 7))
00160 {
00161 board_type = VX_MVME162_BOARD_TYPE;
00162 }
00163 }
00164
00165 #endif
00166
00167
00168 #ifdef VXWORKS
00169
00170 if (NULL != strstr (buflineupper, "LOCK_BUS"))
00171 {
00172 if (board_type == UNKNOWN_BOARD_TYPE)
00173 {
00174 rcs_print_error
00175 ("Can not use lock_bus option with unknown board type.\n");
00176 }
00177 else
00178 {
00179 lock_bus = 1;
00180 total_connections = 0;
00181 }
00182 }
00183 lock_task = 1;
00184 if (NULL != strstr (buflineupper, "NO_TASK_LOCK"))
00185 {
00186 lock_task = 0;
00187 }
00188 if (NULL != strstr (proclineupper, "NO_TASK_LOCK"))
00189 {
00190 lock_task = 0;
00191 }
00192
00193 use_test_and_set=1;
00194 if (NULL != strstr (buflineupper, "NO_TEST_AND_SET"))
00195 {
00196 use_test_and_set = 0;
00197 }
00198
00199 if (NULL != strstr (proclineupper, "USE_DMA"))
00200 {
00201 if (board_type == UNKNOWN_BOARD_TYPE)
00202 {
00203 rcs_print_error
00204 ("Can not use lock_bus option with unknown board type.\n");
00205 }
00206 else
00207 {
00208 use_dma = 1;
00209 }
00210 }
00211 #endif
00212
00213 if (total_connections <= connection_number && !lock_bus)
00214 {
00215 rcs_print_error
00216 ("GLOBMEM: connection number(%d) must be less than total connections (%d).\n",
00217 connection_number, total_connections);
00218 status = CMS_CONFIG_ERROR;
00219 return;
00220 }
00221
00222 address_type = INVALID_ADDRESS_TYPE;
00223 convert2upper (address_type_name, ProcessName, CMS_CONFIG_LINELEN);
00224 strcat (address_type_name, "_ADDR=");
00225 if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00226 {
00227 physical_address =
00228 get_physical_address (address_equation + strlen (address_type_name));
00229 address_type = PROCESS_SPECIFIC_ADDRESS;
00230 }
00231 if (address_type == INVALID_ADDRESS_TYPE)
00232 {
00233 convert2upper (address_type_name, ProcessHost, CMS_CONFIG_LINELEN);
00234 strcat (address_type_name, "_ADDR=");
00235 if (NULL !=
00236 (address_equation = strstr (buflineupper, address_type_name)))
00237 {
00238 physical_address =
00239 get_physical_address (address_equation +
00240 strlen (address_type_name));
00241 address_type = HOST_SPECIFIC_ADDRESS;
00242 }
00243 }
00244 #if defined(VXWORKS) || defined(linuxVME)
00245 if (address_type == INVALID_ADDRESS_TYPE)
00246 {
00247 strcpy (address_type_name, "VME_ADDR=");
00248 if (NULL !=
00249 (address_equation = strstr (buflineupper, address_type_name)))
00250 {
00251 physical_address =
00252 get_physical_address (address_equation +
00253 strlen (address_type_name));
00254 address_type = VME_ADDRESS;
00255 strcpy (address_type_name, "VME_CODE=");
00256 address_space_code = 0;
00257 if (NULL !=
00258 (address_equation = strstr (buflineupper, address_type_name)))
00259 {
00260 address_space_code = (unsigned long)
00261 strtol (address_equation + strlen (address_type_name),
00262 (char **) NULL, 0);
00263 }
00264 }
00265 }
00266 #endif
00267 #if defined(MSDOS) || defined(WIN32) || defined(_WINDOWS)
00268 if (address_type == INVALID_ADDRESS_TYPE)
00269 {
00270 strcpy (address_type_name, "EISA_ADDR=");
00271 if (NULL !=
00272 (address_equation = strstr (buflineupper, address_type_name)))
00273 {
00274 physical_address =
00275 get_physical_address (address_equation +
00276 strlen (address_type_name));
00277 address_type = EISA_ADDRESS;
00278 }
00279 }
00280
00281 if (address_type == INVALID_ADDRESS_TYPE)
00282 {
00283 strcpy (address_type_name, "ISA_ADDR=");
00284 if (NULL !=
00285 (address_equation = strstr (buflineupper, address_type_name)))
00286 {
00287 physical_address =
00288 get_physical_address (address_equation +
00289 strlen (address_type_name));
00290 address_type = ISA_ADDRESS;
00291 }
00292 }
00293
00294 if (address_type == INVALID_ADDRESS_TYPE)
00295 {
00296 strcpy (address_type_name, "PCI_ADDR=");
00297 if (NULL !=
00298 (address_equation = strstr (buflineupper, address_type_name)))
00299 {
00300 physical_address =
00301 get_physical_address (address_equation +
00302 strlen (address_type_name));
00303 address_type = PCI_ADDRESS;
00304 }
00305 }
00306 #endif
00307 if (address_type == INVALID_ADDRESS_TYPE)
00308 {
00309 strcpy (address_type_name, "GENERIC_ADDR=");
00310 if (NULL !=
00311 (address_equation = strstr (buflineupper, address_type_name)))
00312 {
00313 physical_address =
00314 get_physical_address (address_equation +
00315 strlen (address_type_name));
00316 address_type = GENERIC_ADDRESS;
00317 }
00318 }
00319
00320 #if defined(USE_BIT3) && defined(WIN32)
00321 unit = 0;
00322 remote_address = 0;
00323 bt_type = BT_DEV_DEFAULT;
00324 bt_use_mmap = 0;
00325
00326
00327 if (physical_address > 0)
00328 {
00329 remote_address = physical_address;
00330 }
00331
00332 strcpy (address_type_name, "BIT3_OFFSET=");
00333 if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00334 {
00335 physical_address = remote_address =
00336 get_physical_address (address_equation + strlen (address_type_name));
00337 address_type = GENERIC_ADDRESS;
00338 }
00339
00340 strcpy (address_type_name, "BIT3_UNIT=");
00341 if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00342 {
00343 unit = strtol (address_equation + strlen (address_type_name), NULL, 0);
00344 }
00345
00346 if (NULL != strstr (buflineupper, "BIT3_USE_MMAP"))
00347 {
00348 bt_use_mmap = 1;
00349 }
00350
00351
00352 bt_status = bt_open (&btd,
00353 bt_gen_name (unit, bt_type, &devname[0],
00354 BT_MAX_DEV_NAME), BT_RD | BT_WR);
00355 if (BT_SUCCESS != bt_status)
00356 {
00357 bt_perror (btd, bt_status, "Could not open the Bit3 device. ");
00358 status = CMS_MISC_ERROR;
00359 return;
00360 }
00361
00362
00363 bt_status = bt_clrerr (btd);
00364 if (BT_SUCCESS != bt_status)
00365 {
00366 bt_perror (btd, bt_status,
00367 "Could not clear errors from the Bit3 device. ");
00368 (void) bt_close (btd);
00369 status = CMS_MISC_ERROR;
00370 return;
00371 }
00372
00373 #if 0
00374
00375 bt_status = bt_set_info (btd, BT_INFO_SWAP, BT_SWAP_NONE);
00376 if (BT_SUCCESS != bt_status)
00377 {
00378 bt_perror (btd, bt_status,
00379 "Could not set BT_INFO_SWAP to BT_SWAP_NONE ");
00380 (void) bt_close (btd);
00381 status = CMS_MISC_ERROR;
00382 return;
00383 }
00384 #endif
00385
00386 if (!bt_use_mmap)
00387 {
00388 physmem_handle = new PHYSMEM_HANDLE (btd, remote_address, size, 0);
00389 }
00390 else
00391 {
00392
00393 bt_status = bt_mmap (btd, &remote_p, remote_address, size,
00394 BT_RD | BT_WR, BT_SWAP_DEFAULT);
00395 if (BT_SUCCESS != bt_status)
00396 {
00397 bt_perror (btd, bt_status,
00398 "Could not memory map the Bit3 device. ");
00399 (void) bt_close (btd);
00400 status = CMS_MISC_ERROR;
00401 return;
00402 }
00403 physical_address = (unsigned long) remote_p;
00404
00405 physmem_handle = new PHYSMEM_HANDLE ();
00406 physmem_handle->size = size;
00407 physmem_handle->local_address = (char *) physical_address;
00408 physmem_handle->swap_mode = 1;
00409 physmem_handle->using_bit3 = 1;
00410 }
00411
00412 #endif
00413
00414
00415
00416
00417 if (address_type == INVALID_ADDRESS_TYPE)
00418 {
00419 rcs_print_error ("GLOBMEM: No applicable address specified.\n");
00420 status = CMS_CONFIG_ERROR;
00421 return;
00422 }
00423
00424 #ifndef USE_BIT3
00425 if (0 == physical_address)
00426 {
00427 rcs_print_error ("GLOBMEM: physical address is zero.\n");
00428 status = CMS_CONFIG_ERROR;
00429 return;
00430 }
00431 #endif
00432
00433
00434 #ifdef VXWORKS
00435 if (lock_bus)
00436 {
00437 bl_info = getBusLockInfo (board_type, physical_address);
00438 if (NULL == bl_info)
00439 {
00440 rcs_print_error
00441 ("Can't get bus lock info for board type %d, and address 0x%X\n",
00442 board_type, physical_address);
00443 status = CMS_CONFIG_ERROR;
00444 return;
00445 }
00446 }
00447
00448 if (use_dma)
00449 {
00450 dma_info = getDMAInfo (board_type, physical_address);
00451 if (NULL == dma_info)
00452 {
00453 rcs_print_error
00454 ("Can't get DMA info for board type %d, and address 0x%X\n",
00455 board_type, physical_address);
00456 status = CMS_CONFIG_ERROR;
00457 use_dma = 0;
00458 return;
00459 }
00460 }
00461
00462 if (use_dma && lock_bus)
00463 {
00464 rcs_print_error
00465 ("GLOBMEM: Can't use DMA and use the bus lock for mutual exclusion.\n");
00466 status = CMS_CONFIG_ERROR;
00467 use_dma = 0;
00468 return;
00469 }
00470
00471 if (use_dma && neutral)
00472 {
00473 rcs_print_error ("GLOBMEM:: Can't use DMA with neutral buffers.\n");
00474 status = CMS_CONFIG_ERROR;
00475 use_dma = 0;
00476 return;
00477 }
00478
00479 if (use_dma && queuing_enabled)
00480 {
00481 rcs_print_error ("GLOBMEM: Can't use DMA with queued buffers.\n");
00482 status = CMS_CONFIG_ERROR;
00483 use_dma = 0;
00484 return;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 if (use_dma)
00497 {
00498 dma_being_used = 1;
00499 }
00500
00501 #endif
00502
00503 #if !defined(USE_BIT3) || !defined(WIN32)
00504
00505 physmem_handle = new PHYSMEM_HANDLE (physical_address,
00506 address_space_code, size);
00507
00508 #endif
00509
00510 if (1 == set_to_master)
00511 {
00512 is_local_master = 1;
00513 }
00514 else if (-1 == set_to_master)
00515 {
00516 is_local_master = 0;
00517 }
00518
00519 if (NULL != (semdelay_equation = strstr (proclineupper, "SEMDELAY=")))
00520 {
00521 sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00522 }
00523 else if (NULL != (semdelay_equation = strstr (buflineupper, "SEMDELAY=")))
00524 {
00525 sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00526 }
00527
00528
00529 if (is_local_master)
00530 {
00531 physmem_handle->memsetf (0, 0, size);
00532 }
00533 local_locks = (char *) NULL;
00534 int remainder;
00535 if (split_buffer)
00536 {
00537 remainder = (physical_address + total_connections + 2) % 4;
00538 skip_area = total_connections + 2;
00539 }
00540 else
00541 {
00542 remainder = (physical_address + total_connections) % 4;
00543 skip_area = total_connections;
00544 }
00545 if (remainder)
00546 {
00547 skip_area += (4 - remainder);
00548 }
00549 local_locks = (char *) malloc ((long) total_connections);
00550
00551 #ifdef VXWORKS
00552 bsem = 0;
00553 #endif
00554
00555 if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
00556 {
00557 if (is_local_master)
00558 {
00559 physmem_handle->write (BufferName, 31);
00560 #ifdef VXWORKS
00561 if (NULL != strstr (buflineupper, "BSEM"))
00562 {
00563 if (VxMP_Option_Installed)
00564 {
00565 #if 0
00566 if (!usrSmObjInitInitialized)
00567 {
00568 if (OK == usrSmObjInit (NULL))
00569 {
00570 usrSmObjInitInitialized = 1;
00571 }
00572 else
00573 {
00574 rcs_print_error ("usrSmObjInit error %d %s",
00575 errno, strerror (errno));
00576 }
00577 }
00578 if (usrSmObjInitInitialized)
00579 {
00580 physmem_handle->offset = 32;
00581 bsem = semBSmCreate (0, SEM_EMPTY);
00582 void *glob_bsem = smObjLocalToGlobal ((void *) bsem);
00583 physmem_handle->write (&glob_bsem, sizeof (void *));
00584 }
00585 #endif
00586 }
00587 }
00588 #endif
00589 }
00590 else
00591 {
00592 char buf_name_check[32];
00593 physmem_handle->read (buf_name_check, 31);
00594 buf_name_check[31] = 0;
00595 if (buf_name_check[0] != BufferName[0]
00596 && !isalnum (buf_name_check[0]))
00597 {
00598 rcs_print_error
00599 ("GLOBMEM: buffer not initialized, start master.\n");
00600 status = CMS_NO_MASTER_ERROR;
00601 return;
00602 }
00603 if (strncmp (buf_name_check, BufferName, 31))
00604 {
00605 rcs_print_error
00606 ("GLOBMEM: Buffers %s and %s may have conflicting addresses..\n",
00607 buf_name_check, BufferName);
00608 status = CMS_MISC_ERROR;
00609 return;
00610 }
00611 #ifdef VXWORKS
00612 if (NULL != strstr (buflineupper, "BSEM"))
00613 {
00614 if (VxMP_Option_Installed)
00615 {
00616 #if 0
00617 if (!usrSmObjInitInitialized)
00618 {
00619 if (OK == usrSmObjInit (NULL))
00620 {
00621 usrSmObjInitInitialized = 1;
00622 }
00623 else
00624 {
00625 rcs_print_error ("usrSmObjInit error %d %s",
00626 errno, strerror (errno));
00627 }
00628 }
00629 if (usrSmObjInitInitialized)
00630 {
00631 physmem_handle->offset = 32;
00632 void *glob_bsem = NULL;
00633 physmem_handle->read (&glob_bsem, sizeof (void *));
00634 bsem = (SEM_ID) smObjGlobalToLocal (glob_bsem);
00635 }
00636 #endif
00637 }
00638 }
00639 #endif
00640 }
00641 skip_area += 36;
00642 physical_address += 36;
00643 }
00644
00645 if (total_subdivisions <= 0)
00646 {
00647 total_subdivisions = 1;
00648 }
00649
00650 if (split_buffer)
00651 {
00652 if (neutral)
00653 {
00654 max_message_size =
00655 (size_without_diagnostics / 2) - skip_area - encoded_header_size;
00656 max_encoded_message_size =
00657 size_without_diagnostics - skip_area - total_connections -
00658 encoded_header_size;
00659 guaranteed_message_space = max_message_size / 4;
00660 }
00661 else
00662 {
00663 max_message_size =
00664 (size_without_diagnostics / 2) - skip_area - sizeof (CMS_HEADER);
00665 max_encoded_message_size = 4 * max_message_size;
00666 guaranteed_message_space = max_message_size;
00667 }
00668 }
00669 else
00670 {
00671 subdiv_size =
00672 (size_without_diagnostics - skip_area) / total_subdivisions;
00673 subdiv_size -= (subdiv_size % 4);
00674 if (neutral)
00675 {
00676 max_message_size = subdiv_size - encoded_header_size;
00677 max_encoded_message_size = subdiv_size - encoded_header_size;
00678 guaranteed_message_space = max_message_size / 4;
00679 }
00680 else
00681 {
00682 max_message_size = subdiv_size - sizeof (CMS_HEADER);
00683 max_encoded_message_size = 4 * max_message_size;
00684 guaranteed_message_space = max_message_size;
00685 }
00686 }
00687
00688 if (enc_max_size > 0 && enc_max_size < max_encoded_message_size)
00689 {
00690 max_encoded_message_size = enc_max_size;
00691 }
00692
00693 handle_to_global_data = physmem_handle;
00694 fast_mode = split_buffer && !neutral && !queuing_enabled &&
00695 timeout < SEM_CHECK_TIME_EPSILON && timeout >= 0.0;
00696 #ifdef VXWORKS
00697 my_lock = (char *) physical_address + connection_number;
00698 toggle_bit_address = (char *) physical_address + total_connections;
00699 was_read_address = (char *) physical_address + total_connections + 1;
00700 #endif
00701
00702
00703
00704
00705 #if 0
00706 rcs_print ("GLOBMEM: size = %ld\n", size);
00707 rcs_print ("GLOBMEM: size = %ld\n", size);
00708 rcs_print ("GLOBMEM: total_connections = %ld\n", total_connections);
00709 rcs_print ("GLOBMEM: skip_area = %d\n", skip_area);
00710 rcs_print ("GLOBMEM: max_message_size = %ld\n", max_message_size);
00711 rcs_print ("GLOBMEM: max_encoded_message_size = %ld\n",
00712 max_encoded_message_size);
00713 rcs_print ("GLOBMEM: guaranteed_message_space = %ld\n", max_message_size);
00714 #endif
00715 }
00716
00717
00718 GLOBMEM::~GLOBMEM ()
00719 {
00720
00721 #if defined(WIN32) && defined(USE_BIT3)
00722
00723 if (bt_use_mmap)
00724 {
00725
00726 bt_status = bt_unmmap (btd, remote_p, size);
00727 if (BT_SUCCESS != bt_status)
00728 {
00729 bt_perror (btd, bt_status, "Could not release the memory map. ");
00730 (void) bt_close (btd);
00731 return;
00732 }
00733 }
00734
00735
00736 bt_status = bt_chkerr (btd);
00737 if (BT_SUCCESS != bt_status)
00738 {
00739 bt_perror (btd, bt_status, "Memory mapped read failed. ");
00740 (void) bt_close (btd);
00741 return;
00742 }
00743
00744
00745 bt_status = bt_close (btd);
00746 if (BT_SUCCESS != bt_status)
00747 {
00748 bt_perror (btd, bt_status, "Could not close the Bit3 device. ");
00749 return;
00750 }
00751
00752 #endif
00753
00754 if (NULL != physmem_handle)
00755 {
00756 if (delete_totally)
00757 {
00758 physmem_handle->memsetf (0, 0, size);
00759 }
00760 delete physmem_handle;
00761 physmem_handle = (PHYSMEM_HANDLE *) NULL;
00762 }
00763 if (NULL != local_locks)
00764 {
00765 free (local_locks);
00766 local_locks = (char *) NULL;
00767 }
00768 #ifdef VXWORKS
00769 if (NULL != bl_info)
00770 {
00771 freeBusLockInfo (bl_info);
00772 }
00773 if (NULL != dma_info)
00774 {
00775 freeDMAInfo (dma_info);
00776 dma_being_used = 0;
00777 }
00778 #endif
00779 }
00780
00781 unsigned long
00782 GLOBMEM::get_physical_address (char *_address_string)
00783 {
00784 if (NULL != get_physical_address_func)
00785 {
00786 return (get_physical_address_func (_address_string));
00787 }
00788 if (NULL == _address_string)
00789 {
00790 return (0);
00791 }
00792 if (isdigit (_address_string[0]))
00793 {
00794 return ((unsigned long) strtoul (_address_string, (char **) NULL, 0));
00795 }
00796
00797
00798
00799 #if 0
00800
00801
00802 char *bit3_str = "BIT3DP(";
00803 long bit3_str_len = strlen (bit3_str);
00804
00805
00806 if (strlen (_address_string) >= bit3_str_len)
00807 {
00808 if (!memcmp (_address_string, bit3_str, bit3_str_len))
00809 {
00810 long board_number;
00811 char *second_arg;
00812 long offset;
00813 if (isdigit (_address_string[5]))
00814 {
00815 board_number = strtol (_address_string + 5, &second_arg, 0);
00816 if (',' == second_arg[0])
00817 {
00818 offset = strtol (second_arg + 1, NULL, 0);
00819 }
00820 else
00821 {
00822 offset = 0;
00823 }
00824 }
00825 else
00826 {
00827 board_number = 0;
00828 offset = 0;
00829 }
00830 return (get_bit3_dp_address (board_number, offset, size));
00831 }
00832 }
00833
00834 bit3_str = "BIT3RR(";
00835 bit3_str_len = strlen (bit3_str);
00836
00837
00838 if (strlen (_address_string) >= bit3_str_len)
00839 {
00840 if (!memcmp (_address_string, bit3_str, bit3_str_len))
00841 {
00842 long board_number;
00843 char *second_arg;
00844 long offset;
00845 if (isdigit (_address_string[5]))
00846 {
00847 board_number = strtol (_address_string + 5, &second_arg, 0);
00848 if (',' == second_arg[0])
00849 {
00850 offset = strtol (second_arg + 1, NULL, 0);
00851 }
00852 else
00853 {
00854 offset = 0;
00855 }
00856 }
00857 else
00858 {
00859 board_number = 0;
00860 offset = 0;
00861 }
00862 return (get_bit3_rr_address (board_number, offset, size));
00863 }
00864 }
00865 #endif
00866
00867
00868 return (0);
00869 }
00870
00871
00872
00873
00874 CMS_STATUS
00875 GLOBMEM::main_access (void *_user_data)
00876 {
00877 if ((blocking_timeout > 1e-6 || blocking_timeout < -1e-6))
00878 {
00879 rcs_print_error (" Can not call blocking_read when using GLOBMEM.\n");
00880 return (status = CMS_NO_BLOCKING_SEM_ERROR);
00881 }
00882
00883
00884 char was_read_byte;
00885 write_just_completed = 0;
00886 read_only = ((internal_access_type == CMS_CHECK_IF_READ_ACCESS) ||
00887 (internal_access_type == CMS_READ_ACCESS) ||
00888 (internal_access_type == CMS_PEEK_ACCESS));
00889
00890 #ifdef VXWORKS
00891 if (use_dma)
00892 {
00893 int dma_status = checkForDMADone (dma_info);
00894 double time_diff = 0;
00895 double start_time = 0;
00896 if (timeout > 1e-6)
00897 {
00898 start_time = etime ();
00899 }
00900 while (1 != dma_status)
00901 {
00902 if (dma_status < 0)
00903 {
00904 status = CMS_MISC_ERROR;
00905 return (status);
00906 }
00907 time_diff = etime () - start_time;
00908 if (time_diff >= (timeout / 2))
00909 {
00910 rcs_print_error ("Timed out waiting for DMA Ready!\n");
00911 status = CMS_TIMED_OUT;
00912 return (status);
00913 }
00914 dma_status = checkForDMADone (dma_info);
00915 }
00916 }
00917 #endif
00918
00919
00920 if (get_access () == -1)
00921 {
00922 return (status);
00923 }
00924
00925 physmem_handle->offset = 0;
00926
00927
00928 internal_access (physmem_handle, _user_data);
00929
00930
00931 if (!read_only && status > 0)
00932 {
00933 write_just_completed = 1;
00934 }
00935
00936 if (release_access () == -1)
00937 {
00938 return (status);
00939 }
00940 if (split_buffer && !read_only)
00941 {
00942 was_read_byte = 0;
00943 if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
00944 {
00945 physmem_handle->offset = total_connections + 37;
00946 }
00947 else
00948 {
00949 physmem_handle->offset = total_connections + 1;
00950 }
00951 if (-1 == physmem_handle->write (&was_read_byte, 1))
00952 {
00953 rcs_print_error ("GLOBMEM: can not set was read flag.\n");
00954 release_access ();
00955 return (status = CMS_MISC_ERROR);
00956 }
00957 }
00958 return (status);
00959 }
00960
00961
00962 int
00963 GLOBMEM::get_access ()
00964 {
00965 #ifdef VXWORKS
00966 register char *ptr;
00967 register char *base = (char *) physical_address;
00968 #endif
00969 char write_char;
00970 double start_time, time;
00971 int semaphores_clear = 1;
00972
00973 if (physmem_handle == NULL)
00974 {
00975 rcs_print_error ("GLOBMEM: No handle to physical memory.\n");
00976 status = CMS_MISC_ERROR;
00977 return (-1);
00978 }
00979
00980 #ifdef VXWORKS
00981 if(use_test_and_set)
00982 {
00983 char *tas_address = physmem_handle->local_address + 36;
00984 if(timeout > 0)
00985 {
00986 start_time = etime();
00987 }
00988 while(1)
00989 {
00990 if(vxTas(tas_address) == TRUE)
00991 {
00992
00993 return 0;
00994 }
00995 if(timeout > 0)
00996 {
00997 if(etime() - start_time > timeout)
00998 {
00999 status = CMS_TIMED_OUT;
01000 return(-1);
01001 }
01002 }
01003 else if(timeout == 0)
01004 {
01005 status = CMS_TIMED_OUT;
01006 return -1;
01007 }
01008 if(sem_delay > SEM_DELAY_EPSILON)
01009 {
01010 esleep(sem_delay);
01011 }
01012 }
01013 }
01014 #endif
01015
01016
01017 #ifdef VXWORKS
01018 if (lock_task)
01019 {
01020 taskLock ();
01021 }
01022 #endif
01023
01024 #ifdef VXWORKS
01025 if (lock_bus)
01026 {
01027 return enableBusLock (bl_info);
01028 }
01029 #endif
01030 if (read_only)
01031 {
01032 if (split_buffer)
01033 {
01034 char four = 4;
01035 physmem_handle->offset = connection_number + 36;
01036 if (-1 == physmem_handle->write (&four, 1))
01037 {
01038 status = CMS_MISC_ERROR;
01039 rcs_print_error
01040 ("GLOBMEM: Error occured while reading physical memory.\n");
01041 return (-1);
01042 }
01043 physmem_handle->offset = total_connections + 36;
01044 if (-1 == physmem_handle->read (&toggle_bit, 1))
01045 {
01046 status = CMS_MISC_ERROR;
01047 rcs_print_error
01048 ("GLOBMEM: Error occured while reading physical memory.\n");
01049 return (-1);
01050 }
01051 write_char = 2 + toggle_bit;
01052 }
01053 else
01054 {
01055 write_char = 2;
01056 }
01057 }
01058 else
01059 {
01060 physmem_handle->offset = total_connections + 36;
01061 if (-1 == physmem_handle->read (&toggle_bit, 1))
01062 {
01063 status = CMS_MISC_ERROR;
01064 rcs_print_error
01065 ("GLOBMEM: Error occured while reading physical memory.\n");
01066 return (-1);
01067 }
01068 write_char = 1;
01069 }
01070
01071 #ifdef VXWORKS
01072 ptr = base + connection_number;
01073 *ptr = write_char;
01074 #else
01075 physmem_handle->offset = connection_number + 36;
01076 if (-1 == physmem_handle->write (&write_char, 1))
01077 {
01078 status = CMS_MISC_ERROR;
01079 release_access ();
01080 rcs_print_error
01081 ("GLOBMEM: Error occured while writing to physical memory.\n");
01082 return (-1);
01083 }
01084 #endif
01085 if (split_buffer && read_only)
01086 {
01087 return 0;
01088 }
01089 #ifdef VXWORKS
01090 memcpy (local_locks, base, total_connections);
01091 #else
01092 physmem_handle->offset = 36;
01093 if (-1 == physmem_handle->read (local_locks, total_connections))
01094 {
01095 status = CMS_MISC_ERROR;
01096 release_access ();
01097 rcs_print_error
01098 ("GLOBMEM: Error occured while reading physical memory.\n");
01099 return (-1);
01100 }
01101 #endif
01102 semaphores_clear = 1;
01103 for (int i = 0; i < total_connections; i++)
01104 {
01105 if (0 != local_locks[i])
01106 {
01107 if (i != connection_number &&
01108 !(read_only && local_locks[i] > 1) &&
01109 !(split_buffer && 2 + toggle_bit == local_locks[i]))
01110 {
01111 semaphores_clear = 0;
01112 break;
01113 }
01114 }
01115 }
01116 if (semaphores_clear)
01117 {
01118 return 0;
01119 }
01120
01121 time = start_time = etime ();
01122 do
01123 {
01124 if (split_buffer)
01125 {
01126 physmem_handle->offset = total_connections + 36;
01127 if (-1 == physmem_handle->read (&toggle_bit, 1))
01128 {
01129 status = CMS_MISC_ERROR;
01130 release_access ();
01131 rcs_print_error
01132 ("GLOBMEM: Error occured while reading physical memory.\n");
01133 return (-1);
01134 }
01135 }
01136 #ifdef VXWORKS
01137 memcpy (local_locks, base, total_connections);
01138 #else
01139 physmem_handle->offset = 36;
01140 if (-1 == physmem_handle->read (local_locks, total_connections))
01141 {
01142 status = CMS_MISC_ERROR;
01143 release_access ();
01144 rcs_print_error
01145 ("GLOBMEM: Error occured while reading physical memory.\n");
01146 return (-1);
01147 }
01148 #endif
01149 semaphores_clear = 1;
01150 for (int i = 0; i < total_connections; i++)
01151 {
01152 if (0 != local_locks[i])
01153 {
01154 if (i != connection_number &&
01155 !(read_only && local_locks[i] > 1) &&
01156 !(split_buffer && 2 + toggle_bit == local_locks[i]))
01157 {
01158 semaphores_clear = 0;
01159 break;
01160 }
01161 }
01162 }
01163 if (semaphores_clear)
01164 {
01165 return (0);
01166 }
01167 if (fabs (timeout) < SEM_CHECK_TIME_EPSILON)
01168 {
01169 break;
01170 }
01171 if (sem_delay > SEM_DELAY_EPSILON)
01172 {
01173 release_access ();
01174 #ifdef VXWORKS
01175 if (lock_task)
01176 {
01177 taskUnlock ();
01178 }
01179 #endif
01180 esleep (sem_delay);
01181 #ifdef VXWORKS
01182 if (lock_task)
01183 {
01184 taskLock ();
01185 }
01186 #endif
01187 if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01188 {
01189 physmem_handle->offset = connection_number + 36;
01190 }
01191 else
01192 {
01193 physmem_handle->offset = connection_number;
01194 }
01195 if (-1 == physmem_handle->write (&write_char, 1))
01196 {
01197 status = CMS_MISC_ERROR;
01198 release_access ();
01199 rcs_print_error
01200 ("GLOBMEM: Error occured while writing to physical memory.\n");
01201 return (-1);
01202 }
01203 }
01204 time = etime ();
01205 }
01206 while (time - start_time < timeout || timeout < 0);
01207
01208 status = CMS_TIMED_OUT;
01209 release_access ();
01210 rcs_print_error
01211 ("GLOBMEM: Timed out after %lf seconds waiting for access to %s at %lf.\n",
01212 time - start_time, BufferName, time);
01213 return (-1);
01214 }
01215
01216 int
01217 GLOBMEM::release_access ()
01218 {
01219 char zero = 0;
01220 if (NULL == physmem_handle)
01221 {
01222 status = CMS_MISC_ERROR;
01223 return (-1);
01224 }
01225
01226
01227
01228 #ifdef VXWORKS
01229 if (lock_bus)
01230 {
01231 return disableBusLock (bl_info);
01232 }
01233 #endif
01234
01235 #ifdef VXWORKS
01236 if(use_test_and_set)
01237 {
01238 long * tas_address = (long *)
01239 ((char *) physmem_handle->local_address + 36);
01240 *tas_address = 0;
01241 return 0;
01242 }
01243 #endif
01244
01245 if (split_buffer &&
01246 (internal_access_type == CMS_WRITE_ACCESS ||
01247 internal_access_type == CMS_WRITE_IF_READ_ACCESS) &&
01248 status > 0 && write_just_completed)
01249 {
01250 toggle_bit = !toggle_bit;
01251 if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01252 {
01253 physmem_handle->offset = total_connections + 36;
01254 }
01255 else
01256 {
01257 physmem_handle->offset = total_connections;
01258 }
01259 if (-1 == physmem_handle->write (&toggle_bit, 1))
01260 {
01261 rcs_print_error
01262 ("GLOBMEM: Error occured while reading physical memory.\n");
01263 status = CMS_MISC_ERROR;
01264 return (-1);
01265 }
01266 }
01267 if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01268 {
01269 physmem_handle->offset = connection_number + 36;
01270 }
01271 else
01272 {
01273 physmem_handle->offset = connection_number;
01274 }
01275 if (-1 == physmem_handle->write (&zero, 1))
01276 {
01277 rcs_print_error
01278 ("GLOBMEM: Error occured while writing to physical memory.\n");
01279 rcs_print_error ("GLOBMEM: Can not release physical memory.\n");
01280 status = CMS_MISC_ERROR;
01281 return (-1);
01282 }
01283 #ifdef VXWORKS
01284 if (lock_task)
01285 {
01286 taskUnlock ();
01287 }
01288 #endif
01289
01290 return (0);
01291 }
01292
01293 static unsigned long zero = 0;
01294 static unsigned long one = 0x01010101;
01295
01296 #ifdef VXWORKS
01297
01298 int
01299 GLOBMEM::check_if_transfers_complete ()
01300 {
01301 if (!use_dma)
01302 {
01303 return 1;
01304 }
01305 else
01306 {
01307 return checkForDMADone (dma_info);
01308 }
01309 }
01310
01311 CMS_STATUS
01312 GLOBMEM::write (void *user_data)
01313 {
01314 register char *ptr;
01315 register char current_lock;
01316 register int semaphores_clear;
01317 char was_read_byte = 0;
01318
01319 if (use_dma)
01320 {
01321 int dma_status = checkForDMADone (dma_info);
01322 double time_diff = 0;
01323 double start_time = 0;
01324 if (timeout > 1e-6)
01325 {
01326 start_time = etime ();
01327 }
01328 while (1 != dma_status)
01329 {
01330 if (dma_status < 0)
01331 {
01332 status = CMS_MISC_ERROR;
01333 return (status);
01334 }
01335 time_diff = etime () - start_time;
01336 if (time_diff >= (timeout / 2))
01337 {
01338 rcs_print_error ("Timed out waiting for DMA Ready!");
01339 status = CMS_TIMED_OUT;
01340 return (status);
01341 }
01342 dma_status = checkForDMADone (dma_info);
01343 }
01344 if (DMAClearScheduledTransfersList (dma_info) < 0)
01345 {
01346 rcs_print_error ("DMAClearScheduledTransfers error.\n");
01347 status = CMS_MISC_ERROR;
01348 return (status);
01349 }
01350
01351 disable_final_write_raw_for_dma = 1;
01352 if (get_access () < 0)
01353 {
01354 return (status);
01355 }
01356 read_only = 0;
01357 if (split_buffer)
01358 {
01359 toggle_bit = *toggle_bit_address;
01360 if (internal_access_type == CMS_WRITE_IF_READ_ACCESS)
01361 {
01362 if (min_compatible_version > 2.58
01363 || min_compatible_version < 1e-6)
01364 {
01365 physmem_handle->offset = total_connections + 37;
01366 }
01367 else
01368 {
01369 physmem_handle->offset = total_connections + 1;
01370 }
01371 physmem_handle->read (&was_read_byte, 1);
01372 header.was_read = (was_read_byte == toggle_bit + 1);
01373 if (!header.was_read)
01374 {
01375 status = CMS_WRITE_WAS_BLOCKED;
01376 release_access ();
01377 return (status);
01378 }
01379 internal_access_type = CMS_WRITE_ACCESS;
01380 }
01381 if (read_only == toggle_bit)
01382 {
01383 physmem_handle->offset = skip_area;
01384 physmem_handle->size = half_size;
01385 }
01386 else
01387 {
01388 physmem_handle->offset = half_offset;
01389 physmem_handle->size = size;
01390 }
01391 }
01392 else
01393 {
01394 physmem_handle->offset = skip_area;
01395 physmem_handle->size = size;
01396 }
01397 write_raw (user_data);
01398 if (DMAScheduleLocalToVMETransfer
01399 (dma_info,
01400 (void
01401 *) ((unsigned long) (physmem_handle->local_address +
01402 physmem_handle->offset +
01403 sizeof (CMS_HEADER))), user_data,
01404 header.in_buffer_size) < 0)
01405 {
01406 rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01407 status = CMS_MISC_ERROR;
01408 return (status);
01409 }
01410 if (split_buffer)
01411 {
01412 toggle_bit = !toggle_bit;
01413 if (toggle_bit)
01414 {
01415 if (DMAScheduleLocalToVMETransfer
01416 (dma_info, toggle_bit_address, &one, 1) < 0)
01417 {
01418 rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01419 status = CMS_MISC_ERROR;
01420 return (status);
01421 }
01422 }
01423 else
01424 {
01425 if (DMAScheduleLocalToVMETransfer
01426 (dma_info, toggle_bit_address, &zero, 1) < 0)
01427 {
01428 rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01429 status = CMS_MISC_ERROR;
01430 return (status);
01431 }
01432 }
01433
01434 }
01435 if (DMAScheduleLocalToVMETransfer (dma_info, my_lock, &zero, 1) < 0)
01436 {
01437 rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01438 status = CMS_MISC_ERROR;
01439 return (status);
01440 }
01441 if (DMAStartTransfers (dma_info))
01442 {
01443 rcs_print_error ("DMAStartTransfers error.");
01444 status = CMS_MISC_ERROR;
01445 return (status);
01446 }
01447 return (status);
01448 }
01449
01450 if (fast_mode)
01451 {
01452 if (lock_bus)
01453 {
01454 enableBusLock (bl_info);
01455 toggle_bit = *toggle_bit_address;
01456 }
01457 else
01458 {
01459 *my_lock = 1;
01460 toggle_bit = *toggle_bit_address;
01461
01462 semaphores_clear = 1;
01463 ptr = (char *) physical_address;
01464 for (; ptr < toggle_bit_address; ptr++)
01465 {
01466 if (0 != (current_lock = *ptr))
01467 {
01468 if (ptr != my_lock && !(2 + toggle_bit == current_lock))
01469 {
01470 semaphores_clear = 0;
01471 break;
01472 }
01473 }
01474 }
01475 if (!semaphores_clear)
01476 {
01477 *my_lock = 0;
01478 status = CMS_TIMED_OUT;
01479 return (status);
01480 }
01481 }
01482
01483 if (!toggle_bit)
01484 {
01485 physmem_handle->offset = skip_area;
01486 physmem_handle->size = half_size;
01487 }
01488 else
01489 {
01490 physmem_handle->offset = half_offset;
01491 physmem_handle->size = size;
01492 }
01493
01494
01495 write_raw (user_data);
01496
01497
01498 if (status > 0)
01499 {
01500 *was_read_address = 0;
01501 *toggle_bit_address = !toggle_bit;
01502 }
01503 if (lock_bus)
01504 {
01505 disableBusLock (bl_info);
01506 }
01507 else
01508 {
01509 *my_lock = 0;
01510 }
01511 if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01512 {
01513 if (OK != semFlush (bsem))
01514 {
01515 rcs_print_error ("semFlush returned ERROR. %d %s\n",
01516 errno, strerror (errno));
01517 }
01518 }
01519 return (status);
01520 }
01521 internal_access_type = CMS_WRITE_ACCESS;
01522 main_access (user_data);
01523 if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01524 {
01525 if (OK != semFlush (bsem))
01526 {
01527 rcs_print_error ("semFlush returned ERROR. %d %s\n",
01528 errno, strerror (errno));
01529 }
01530 }
01531 return (status);
01532 }
01533
01534
01535
01536 CMS_STATUS
01537 GLOBMEM::write_if_read (void *user_data)
01538 {
01539 register char *ptr;
01540 register char current_lock;
01541 register int semaphores_clear;
01542 if (fast_mode)
01543 {
01544 if (lock_bus)
01545 {
01546 enableBusLock (bl_info);
01547 toggle_bit = *toggle_bit_address;
01548 }
01549 else
01550 {
01551 *my_lock = 1;
01552 toggle_bit = *toggle_bit_address;
01553
01554 semaphores_clear = 1;
01555 ptr = (char *) physical_address;
01556 for (; ptr < toggle_bit_address; ptr++)
01557 {
01558 if (0 != (current_lock = *ptr))
01559 {
01560 if (ptr != my_lock && !(2 + toggle_bit == current_lock))
01561 {
01562 semaphores_clear = 0;
01563 break;
01564 }
01565 }
01566 }
01567 if (!semaphores_clear)
01568 {
01569 *my_lock = 0;
01570 status = CMS_TIMED_OUT;
01571 return (status);
01572 }
01573 }
01574
01575 if (!toggle_bit)
01576 {
01577 physmem_handle->offset = skip_area;
01578 physmem_handle->size = half_size;
01579 }
01580 else
01581 {
01582 physmem_handle->offset = half_offset;
01583 physmem_handle->size = size;
01584 }
01585
01586 if (!(*was_read_address))
01587 {
01588 *my_lock = 0;
01589 return (status = CMS_WRITE_WAS_BLOCKED);
01590 }
01591
01592
01593 write (user_data);
01594
01595
01596 if (status > 0)
01597 {
01598 *was_read_address = 0;
01599 *toggle_bit_address = !toggle_bit;
01600 }
01601 if (lock_bus)
01602 {
01603 disableBusLock (bl_info);
01604 }
01605 else
01606 {
01607 *my_lock = 0;
01608 }
01609 return (status);
01610 }
01611 internal_access_type = CMS_WRITE_IF_READ_ACCESS;
01612 main_access (user_data);
01613 if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01614 {
01615 if (OK != semFlush (bsem))
01616 {
01617 rcs_print_error ("semFlush returned ERROR. %d %s\n",
01618 errno, strerror (errno));
01619 }
01620 }
01621 return (status);
01622 }
01623
01624 static int bread_not_implemented_error_printed = 0;
01625 CMS_STATUS
01626 GLOBMEM::blocking_read (double btimeout)
01627 {
01628 if (btimeout < 1e-6 && btimeout > -1e-6)
01629 {
01630 return read ();
01631 }
01632 if (!bread_not_implemented_error_printed)
01633 {
01634 rcs_print_error ("BLOCKING READ NOT IMPLEMENTED FOR GLOBMEM.\n");
01635 bread_not_implemented_error_printed = 1;
01636 }
01637 status = CMS_NO_IMPLEMENTATION_ERROR;
01638 #if 0
01639 register char *ptr;
01640 register char current_lock;
01641 register int semaphores_clear;
01642 if (fast_mode)
01643 {
01644 *my_lock = 4;
01645 *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01646 if (toggle_bit)
01647 {
01648 physmem_handle->offset = skip_area;
01649 physmem_handle->size = half_size;
01650 }
01651 else
01652 {
01653 physmem_handle->offset = half_offset;
01654 physmem_handle->size = size;
01655 }
01656
01657
01658 read_raw ();
01659
01660 *my_lock = 0;
01661 if (status == CMS_READ_OLD && ((int) bsem) > 0 && btimeout > 1e-6
01662 || btimeout < -1e-6)
01663 {
01664 int ticks = (int) (btimeout * sysClkRateGet ());
01665 if (btimeout < 0)
01666 {
01667 ticks = WAIT_FOREVER;
01668 }
01669 if (OK != semTake (bsem, ticks))
01670 {
01671 if (ticks > 0 && errno == S_objLib_OBJ_TIMEOUT)
01672 {
01673 status = CMS_TIMED_OUT;
01674 return (status);
01675 }
01676 else
01677 {
01678 rcs_print_error ("semTake returned ERROR. %d %s",
01679 errno, strerror (errno));
01680 status = CMS_MISC_ERROR;
01681 return (status);
01682 }
01683 }
01684 *my_lock = 4;
01685 *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01686 if (toggle_bit)
01687 {
01688 physmem_handle->offset = skip_area;
01689 physmem_handle->size = half_size;
01690 }
01691 else
01692 {
01693 physmem_handle->offset = half_offset;
01694 physmem_handle->size = size;
01695 }
01696
01697
01698 read_raw ();
01699
01700 *my_lock = 0;
01701 }
01702 return (status);
01703 }
01704 internal_access_type = CMS_READ_ACCESS;
01705 main_access (data);
01706 if (status == CMS_READ_OLD && bsem > 0 && btimeout > 1e-6
01707 || btimeout < -1e-6)
01708 {
01709 int ticks = (int) (btimeout * sysClkRateGet ());
01710 if (btimeout < 0)
01711 {
01712 ticks = WAIT_FOREVER;
01713 }
01714 if (OK != semTake (bsem, ticks))
01715 {
01716 if (ticks > 0 && errno == S_objLib_OBJ_TIMEOUT)
01717 {
01718 status = CMS_TIMED_OUT;
01719 return (status);
01720 }
01721 else
01722 {
01723 rcs_print_error ("semTake returned ERROR. %d %s",
01724 errno, strerror (errno));
01725 status = CMS_MISC_ERROR;
01726 return (status);
01727 }
01728 }
01729 main_access (data);
01730 }
01731 #endif
01732 return (status);
01733 }
01734
01735 CMS_STATUS
01736 GLOBMEM::read ()
01737 {
01738 if (fast_mode)
01739 {
01740 if (lock_bus)
01741 {
01742 enableBusLock (bl_info);
01743 toggle_bit = *toggle_bit_address;
01744 }
01745 else
01746 {
01747 *my_lock = 4;
01748 *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01749 }
01750
01751 if (toggle_bit)
01752 {
01753 physmem_handle->offset = skip_area;
01754 physmem_handle->size = half_size;
01755 }
01756 else
01757 {
01758 physmem_handle->offset = half_offset;
01759 physmem_handle->size = size;
01760 }
01761
01762
01763 read_raw ();
01764
01765 if (lock_bus)
01766 {
01767 disableBusLock (bl_info);
01768 }
01769 else
01770 {
01771 *my_lock = 0;
01772 }
01773 return (status);
01774 }
01775 internal_access_type = CMS_READ_ACCESS;
01776 main_access (data);
01777 return (status);
01778 }
01779
01780 CMS_STATUS
01781 GLOBMEM::peek ()
01782 {
01783 if (fast_mode)
01784 {
01785 if (lock_bus)
01786 {
01787 enableBusLock (bl_info);
01788 toggle_bit = *toggle_bit_address;
01789 }
01790 else
01791 {
01792 *my_lock = 4;
01793 *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01794 }
01795
01796 if (toggle_bit)
01797 {
01798 physmem_handle->offset = skip_area;
01799 physmem_handle->size = half_size;
01800 }
01801 else
01802 {
01803 physmem_handle->offset = half_offset;
01804 physmem_handle->size = size;
01805 }
01806
01807
01808 read_raw ();
01809
01810 if (lock_bus)
01811 {
01812 disableBusLock (bl_info);
01813 }
01814 else
01815 {
01816 *my_lock = 0;
01817 }
01818 return (status);
01819 }
01820 internal_access_type = CMS_PEEK_ACCESS;
01821 main_access (data);
01822 return (status);
01823 }
01824
01825 #endif