#include "rcs_defs.hh"#include "_physmem.h"#include <string.h>Include dependency graph for _physmem.c:

Go to the source code of this file.
Functions | |
| int | read_physmem (unsigned long source, void *destination, long bytes) |
| int | write_physmem (unsigned long destination, void *source, long bytes) |
| int | move_physmem (unsigned long target, unsigned long source, long bcount) |
|
||||||||||||||||
|
Definition at line 44 of file _physmem.c. 00045 {
00046
00047 #ifndef WIN32
00048 #ifdef _WINDOWS
00049
00050 LPBYTE lpDestination;
00051 LPBYTE lpSource;
00052 WORD wSelector;
00053 int i;
00054
00055 lpDestination = (LPBYTE) destination;
00056 lpSource = create_ptr_to_physmem (source, bytes, &wSelector);
00057
00058 if (NULL == lpSource || NULL == lpDestination)
00059 {
00060 return (-1);
00061 }
00062
00063
00064 for (i = 0; i < bytes; i++)
00065 {
00066 lpDestination[i] = lpSource[i];
00067 }
00068 if (wSelector)
00069 {
00070 FreeSelector (wSelector);
00071 }
00072 return (i);
00073 #else
00074 char far *ptr_to_destination;
00075 char far *ptr_to_source;
00076 unsigned long physical_source_address;
00077 unsigned long physical_destination_address;
00078 unsigned long temp_segment, temp_offset;
00079 static char two_bytes[2];
00080 char far *ptr_to_two_bytes;
00081 int i;
00082
00083 if (((unsigned long) destination) < 0x100000UL)
00084 {
00085 ptr_to_source = (char far *)
00086 ((source & 0xf) + ((source & 0xffff0L) << 16));
00087 ptr_to_destination = (char far *) destination;
00088 for (i = 0; i < bytes; i++)
00089 {
00090 ptr_to_destination[i] = ptr_to_source[i];
00091 }
00092 return (i);
00093 }
00094 else
00095 {
00096 physical_source_address = source;
00097 temp_segment = (((unsigned long) destination) & 0xffff0000L) >> 16;
00098 temp_offset = ((unsigned long) destination) & 0x0000ffffL;
00099 physical_destination_address = (temp_segment << 4) + temp_offset;
00100 if (0 == (bytes % 2))
00101 {
00102 return (move_physmem (physical_destination_address,
00103 physical_source_address, bytes));
00104 }
00105 else
00106 {
00107 if (bytes > 1)
00108 {
00109 if (-1 == move_physmem (physical_destination_address,
00110 physical_source_address, bytes))
00111 {
00112 return -1;
00113 }
00114 }
00115 ptr_to_two_bytes = (char far *) two_bytes;
00116 temp_segment =
00117 (((unsigned long) ptr_to_two_bytes) & 0xffff0000L) >> 16;
00118 temp_offset = ((unsigned long) ptr_to_two_bytes) & 0x0000ffffL;
00119 physical_source_address = source + bytes - 1;
00120 physical_destination_address = (temp_segment << 4) + temp_offset;
00121 if (-1 == move_physmem (physical_destination_address,
00122 physical_source_address, 2))
00123 {
00124 return -1;
00125 }
00126 ((char *) destination)[bytes - 1] = (char) two_bytes[0];
00127 return (0);
00128 }
00129 }
00130 #endif
00131 #endif
00132 return (-1); /* No Applicable PLATFORM */
00133 }
|
|
||||||||||||||||
|
Definition at line 136 of file _physmem.c. 00137 {
00138 #ifndef WIN32
00139 #ifdef _WINDOWS
00140
00141 LPBYTE lpDestination;
00142 LPBYTE lpSource;
00143 WORD wSelector;
00144 DWORD max_size;
00145 int i;
00146
00147 lpDestination = create_ptr_to_physmem (destination, bytes, &wSelector);
00148 lpSource = (LPBYTE) source;
00149
00150 if (NULL == lpSource || NULL == lpDestination)
00151 {
00152 return (-1);
00153 }
00154
00155
00156 for (i = 0; i < bytes; i++)
00157 {
00158 lpDestination[i] = lpSource[i];
00159 }
00160
00161 if (wSelector)
00162 {
00163 FreeSelector (wSelector);
00164 }
00165 return (i);
00166 #else
00167 char far *ptr_to_destination;
00168 char far *ptr_to_source;
00169 unsigned long physical_source_address;
00170 unsigned long physical_destination_address;
00171 unsigned long temp_segment, temp_offset;
00172 int i;
00173 static char two_bytes[2];
00174 char far *ptr_to_two_bytes;
00175
00176 if (destination < 0x100000UL)
00177 {
00178 ptr_to_source = (char far *) source;
00179 ptr_to_destination = (char far *)
00180 ((destination & 0xf) + ((destination & 0xffff0L) << 16));
00181 for (i = 0; i < bytes; i++)
00182 {
00183 ptr_to_destination[i] = ptr_to_source[i];
00184 }
00185 return (i);
00186 }
00187 else
00188 {
00189 temp_segment = (((unsigned long) source) & 0xffff0000L) >> 16;
00190 temp_offset = ((unsigned long) source) & 0x0000ffffL;
00191 physical_source_address = (temp_segment << 4) + temp_offset;
00192 physical_destination_address = destination;
00193 if (0 == (bytes % 2))
00194 {
00195 return (move_physmem (physical_destination_address,
00196 physical_source_address, bytes));
00197 }
00198 else
00199 {
00200 if (bytes > 1)
00201 {
00202 if (-1 == move_physmem (physical_destination_address,
00203 physical_source_address, bytes))
00204 {
00205 return -1;
00206 }
00207 }
00208 two_bytes[0] = ((char *) source)[bytes - 1];
00209 ptr_to_two_bytes = (char far *) two_bytes;
00210 temp_segment =
00211 (((unsigned long) ptr_to_two_bytes) & 0xffff0000L) >> 16;
00212 temp_offset = ((unsigned long) ptr_to_two_bytes) & 0x0000ffffL;
00213 physical_destination_address = destination + bytes - 1;
00214 physical_source_address = (temp_segment << 4) + temp_offset;
00215 if (-1 == move_physmem (physical_destination_address,
00216 physical_source_address, 2))
00217 {
00218 return -1;
00219 }
00220 return (0);
00221 }
00222 }
00223 #endif
00224 #endif
00225 return (-1); /* No Applicable PLATFORM */
00226 }
|
|
||||||||||||||||
|
Definition at line 439 of file _physmem.c. Referenced by read_physmem(), and write_physmem().
00440 {
00441 static initialized = 0; /* Has the CPU been checked. */
00442 static unsigned char addrln = 0; /* Number of addr. lines CPU drives */
00443 unsigned char gdt[48]; /* Global Descriptor Table,see below */
00444 unsigned char far *g_p = gdt; /* Pointer to GDT loaded into SI & ES */
00445
00446 #ifdef __BORLANDC__
00447 union REGS r; /* Structure of INTEL registers */
00448 struct SREGS s; /* Structure of INTEL segment reg's */
00449 #endif
00450 #ifdef _MSC_VER
00451 union _REGS r; /* Structure of INTEL registers */
00452 struct _SREGS s; /* Structure of INTEL segment reg's */
00453 #endif
00454
00455 /* Movphy can not transfer more than (32K - 1) words */
00456 if (bcount >= 0x7ffffL)
00457 {
00458 fprintf (stderr, "\nTransfer length too large.\n");
00459 return (-1);
00460 }
00461
00462 /*****************************************************************************
00463 **
00464 ** Identify system processor type and its addressing capability.
00465 **
00466 *****************************************************************************/
00467
00468 if (!initialized)
00469 {
00470 /*lint -e122 */
00471 #ifdef __BORLANDC__
00472 asm
00473 {
00474 #else
00475 __asm
00476 {
00477 #endif
00478 /* 8086 CPU check */
00479 /* Bits 12-15 are always set on the 8086 processor. */
00480 pushf; /* Save EFLAGS. */
00481 pop bx; /* Store EFLAGS in BX */
00482 mov ax, 0f ffh; /* clear bits 12-15 */
00483 and ax, bx; /* in EFLAGS */
00484 push ax; /* Store new EFLAGS value on stack. */
00485 popf; /* Replace current EFLAGS value. */
00486 pushf; /* Set new EFLAGS. */
00487 pop ax; /* Store new EFLAGS in AX. */
00488 and ax, 0f 000 h; /* If bits 12-15 are set, then the */
00489 cmp ax, 0f 000 h; /* CPU is an 8086/8088. */
00490 mov addrln, 20; /* Set the number of address lines */
00491 /* for a 8086/8088. */
00492 je nodescriptors;
00493
00494
00495 /* 80286 CPU check */
00496 /* Bits 12-15 are always clear on the 80286 processor. */
00497
00498 or bx, 0f 000 h; /* Try to set bits 12-15 */
00499 push bx; /* */
00500 popf; /* */
00501 pushf; /* */
00502 pop ax; /* */
00503 and ax, 0f 000 h; /* If bits 12-15 are cleared, then */
00504 /* the CPU is an 80286 */
00505 mov addrln, 24; /* Set the number of address lines */
00506 /* for a 80286. */
00507 jz descriptors; /* */
00508
00509
00510 /* Otherwise it is an i386 or later CPU with 32 bit addressing. */
00511 mov addrln, 32; /* Set the number of address lines */
00512 /* for either a i386 or later CPU's. */
00513 }
00514 /*lint +e122 */
00515
00516
00517 nodescriptors:
00518 if (addrln < 24)
00519 {
00520 fprintf (stderr,
00521 "\nThis system does not support protected mode.\n");
00522 return (-1);
00523 }
00524
00525 /* For i286 check against A24 address limit. */
00526 descriptors:
00527 if ((addrln < 32) && (source >= (1UL << 24) || target >= (1UL << 24)))
00528 {
00529 fprintf (stderr, "\nA24 Address out of bounds.\n");
00530 return (-1);
00531 }
00532 initialized = 1;
00533 }
00534
00535 /*****************************************************************************
00536 **
00537 ** Format of descriptors
00538 **
00539 ** Offset Size Description
00540 **
00541 ** 00h 2 Bytes Bits 0-15 of the segment limit.
00542 **
00543 ** 02h 3 Bytes Bits 0-23 of physical address.
00544 **
00545 ** 05h 1 Byte i386 & i486 Access flags:
00546 ** 9Ah = Code segment.
00547 ** 92h = Writable data segment.
00548 ** 90h = Read only data segment.
00549 **
00550 ** 80286 Access flags:
00551 ** 9Bh = Code segment.
00552 ** 93h = Writable data segment.
00553 ** 91h = Read only data segment.
00554 **
00555 ** 06h 2 Bytes Reserved on an 80286, must be zero.
00556 **
00557 ** A32 Processors Only.
00558 ** 06h 1 Byte Bits 0-3 are the upper 4 bits of the
00559 ** segment limit. Bits 4-7 are set to zero.
00560 ** Please note that this byte is not supported
00561 ** by Interrupt 0x15 Function 0x87.
00562 **
00563 ** A32 Processors Only.
00564 ** 07h 1 Byte Bits 24-32 of physical address.
00565 **
00566 *****************************************************************************/
00567
00568 memset (gdt, '\0', sizeof (gdt)); /* Zero out global descripter table */
00569
00570 /* Descripter 2: Source */
00571 gdt[16] = (unsigned char) bcount;
00572 gdt[17] = (unsigned char) (bcount >> 8);
00573 gdt[18] = (unsigned char) source;
00574 gdt[19] = (unsigned char) (source >> 8);
00575 gdt[20] = (unsigned char) (source >> 16);
00576
00577 if (addrln < 32)
00578 {
00579 gdt[21] = 0x93; /* A24 Access flag */
00580 }
00581 else
00582 {
00583 gdt[21] = 0x92; /* A32 Access flag */
00584 gdt[23] = (unsigned char) (source >> 24);
00585 }
00586
00587 /* Descripter 3: Target */
00588 gdt[24] = (unsigned char) bcount;
00589 gdt[25] = (unsigned char) (bcount >> 8);
00590 gdt[26] = (unsigned char) target;
00591 gdt[27] = (unsigned char) (target >> 8);
00592 gdt[28] = (unsigned char) (target >> 16);
00593
00594 if (addrln < 32)
00595 {
00596 gdt[29] = 0x93; /* A24 Access flag */
00597 }
00598 else
00599 {
00600 gdt[29] = 0x92; /* A32 Access flag */
00601 gdt[31] = (unsigned char) (target >> 24);
00602 }
00603
00604 r.h.ah = 0x87;
00605 r.x.cx = (int) (bcount / 2);
00606 s.es = (((unsigned long) g_p) & 0xffff0000L) >> 16;
00607 r.x.si = ((unsigned long) g_p) & 0x0000ffffL;
00608
00609 #ifdef __BORLANDC__
00610 int86x (0x15, &r, &r, &s);
00611 #endif
00612
00613 #ifdef _MSC_VER
00614 (void) _int86x (0x15, &r, &r, &s);
00615 #endif
00616
00617 if (r.h.ah)
00618 {
00619 switch (r.h.ah)
00620 {
00621 case 1:
00622 /* RAM parity error occurred */
00623 fprintf (stderr,
00624 "\nData transfer failed. A RAM parity error occurred.\n");
00625 break;
00626
00627 case 2:
00628 /* Exception interrupt error occurred */
00629 fprintf (stderr,
00630 "\nData transfer failed. Exception interrupt error occurred.\n");
00631 break;
00632
00633 case 3:
00634 /* Gating address line 20 failed during switch to protected mode */
00635 fprintf (stderr,
00636 "\nData transfer failed. Gate address line 20 failed.\n");
00637 break;
00638
00639 default:
00640 /* Unknown reason-word count > 32767 */
00641 fprintf (stderr,
00642 "\nData transfer failed. Reason unknown, possibly word count > 32767.\n");
00643 break;
00644 }
00645 return (-1);
00646 }
00647
00648
00649 return (bcount);
00650 }
|
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001