#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 } |