Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

abiosc.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 abiosc.c 00008 00009 Abstract: 00010 00011 This module implements ABIOS support C routines for i386 NT. 00012 00013 Author: 00014 00015 Shie-Lin Tzong (shielint) 20-May-1991 00016 00017 Environment: 00018 00019 Boot loader privileged, FLAT mode. 00020 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ki.h" 00027 #pragma hdrstop 00028 #include "abios.h" 00029 00030 extern PKCOMMON_DATA_AREA KiCommonDataArea; 00031 extern BOOLEAN KiAbiosPresent; 00032 00033 // 00034 // The reason of having these variables defined in here is to isolate 00035 // ABIOS from current system. 00036 // 00037 00038 // 00039 // KiNumberFreeSelectors defines the number of available selectors for 00040 // ABIOS specific drivers. This number should be the same accross all 00041 // the processors. 00042 // 00043 00044 static USHORT KiNumberFreeSelectors = 0; 00045 00046 // 00047 // KiFreeGdtListHead points to the head of free GDT list on the processor 0. 00048 // 00049 00050 static PKFREE_GDT_ENTRY KiFreeGdtListHead = 0L; 00051 00052 // 00053 // Logica Id Table to control the ownership of logical Id. 00054 // 00055 00056 PKLID_TABLE_ENTRY KiLogicalIdTable; 00057 00058 // 00059 // KiAbiosGdt[] defines the Starting address of GDT for each processor. 00060 // 00061 00062 ULONG KiAbiosGdt[MAXIMUM_PROCESSORS]; 00063 00064 // 00065 // SpinLock for accessing GDTs 00066 // 00067 00068 KSPIN_LOCK KiAbiosGdtLock; 00069 00070 // 00071 // Spinlock for accessing Logical Id Table 00072 // 00073 00074 KSPIN_LOCK KiAbiosLidTableLock; 00075 00076 // 00077 // KiStack16GdtEntry defines the address of the gdt entry for 16 bit stack. 00078 // 00079 00080 ULONG KiStack16GdtEntry; 00081 00082 VOID 00083 KiInitializeAbiosGdtEntry ( 00084 OUT PKGDTENTRY GdtEntry, 00085 IN ULONG Base, 00086 IN ULONG Limit, 00087 IN USHORT Type 00088 ) 00089 00090 /*++ 00091 00092 Routine Description: 00093 00094 This function initializes a GDT entry for abios specific code. Base, 00095 Limit, and Type (code, data) are set according to parameters. All other 00096 fields of the entry are set to match standard system values. 00097 00098 N.B. The BIG and GRANULARITY are always set to 0. 00099 00100 Arguments: 00101 00102 GdtEntry - GDT descriptor to be filled in. 00103 00104 Base - Linear address of the first byte mapped by the selector. 00105 00106 Limit - Size of the selector in BYTE. 00107 00108 Type - Code or Data. All code selectors are marked readable, 00109 all data selectors are marked writeable. 00110 00111 Return Value: 00112 00113 Pointer to the GDT entry. 00114 00115 --*/ 00116 00117 { 00118 GdtEntry->LimitLow = (USHORT)(Limit & 0xffff); 00119 GdtEntry->BaseLow = (USHORT)(Base & 0xffff); 00120 GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((Base & 0xff0000) >> 16); 00121 GdtEntry->HighWord.Bits.Type = Type; 00122 GdtEntry->HighWord.Bits.Dpl = 0; 00123 GdtEntry->HighWord.Bits.Pres = 1; 00124 GdtEntry->HighWord.Bits.LimitHi = (Limit & 0xf0000) >> 16; 00125 GdtEntry->HighWord.Bits.Sys = 0; 00126 GdtEntry->HighWord.Bits.Reserved_0 = 0; 00127 GdtEntry->HighWord.Bits.Default_Big = 0; 00128 GdtEntry->HighWord.Bits.Granularity = 0; 00129 GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((Base & 0xff000000) >> 24); 00130 } 00131 00132 ULONG 00133 KiI386SelectorBase ( 00134 IN USHORT Selector 00135 ) 00136 00137 /*++ 00138 00139 Routine Description: 00140 00141 This function returns the base address of the specified GDT selector. 00142 00143 Arguments: 00144 00145 Selector - Supplies the desired selector. 00146 00147 Return Value: 00148 00149 SelectorBase - Return the base address of the specified selector; 00150 (return -1L if invalid selector) 00151 00152 00153 --*/ 00154 00155 { 00156 PKGDTENTRY GdtEntry; 00157 00158 00159 GdtEntry = (PKGDTENTRY)(KiAbiosGetGdt() + Selector); 00160 if (GdtEntry->HighWord.Bits.Pres) { 00161 return ((ULONG)GdtEntry->BaseLow | 00162 (ULONG)GdtEntry->HighWord.Bytes.BaseMid << 16 | 00163 (ULONG)GdtEntry->HighWord.Bytes.BaseHi << 24); 00164 } else { 00165 return (ULONG)(-1L); 00166 } 00167 } 00168 00169 NTSTATUS 00170 KeI386GetLid( 00171 IN USHORT DeviceId, 00172 IN USHORT RelativeLid, 00173 IN BOOLEAN SharedLid, 00174 IN PDRIVER_OBJECT DriverObject, 00175 OUT PUSHORT LogicalId 00176 ) 00177 00178 /*++ 00179 00180 Routine Description: 00181 00182 This function searches Device Blocks and Common Data Area for the 00183 Logical Id matching the specified Device Id. 00184 00185 N.B. (WARNING shielint) To speed the search, this routine ASSUMES that 00186 the LIDs with the same Device ID always appear consecutively in the 00187 Common Data Area. IBM ABIOS doc does not explicitly specify this. 00188 But from the way ABIOS initializes Device Block and Function Transfer 00189 Table, I think the assumption is true. 00190 00191 Arguments: 00192 00193 DeviceId - Desired Device Id. 00194 00195 RelativeLid - Specifies the Nth logical Id for this device Id. A value 00196 of 0 indicates the first available Lid. 00197 00198 SharedLid - A boolean value indicates if it is a shared or exclusively 00199 owned logical Id. 00200 00201 DriverObject - Supplies a 32-bit flat pointer of the requesting device 00202 driver's driver object. The DriverObject is used to establish 00203 the ownership of the desired LID. 00204 00205 LogicalId - A pointer to a variable which will receive the Lid. 00206 00207 Return Value: 00208 00209 STATUS_SUCCESS - If the requested LID is available. 00210 00211 STATUS_ABIOS_NOT_PRESENT - If there is no ABIOS support in the system. 00212 00213 STATUS_ABIOS_LID_NOT_EXIST - If the specified LID does not exist. 00214 00215 STATUS_ABIOS_LID_ALREADY_OWNED - If the caller requests an exclusively 00216 owned LID. 00217 00218 --*/ 00219 00220 { 00221 PKDB_FTT_SECTION CdaPointer; 00222 PKDEVICE_BLOCK DeviceBlock; 00223 USHORT Lid, RelativeLidCount = 1; 00224 ULONG Owner; 00225 USHORT Increment; 00226 KIRQL OldIrql; 00227 NTSTATUS Status; 00228 00229 if (!KiAbiosPresent) { 00230 return STATUS_ABIOS_NOT_PRESENT; 00231 } 00232 00233 if (SharedLid) { 00234 Owner = LID_NO_SPECIFIC_OWNER; 00235 Increment = 1; 00236 } else { 00237 Owner = (ULONG)DriverObject; 00238 Increment = 0; 00239 } 00240 00241 // 00242 // If the Logical Id Table hasn't been created yet, create it now. 00243 // 00244 if (KiLogicalIdTable==NULL) { 00245 KiLogicalIdTable = ExAllocatePoolWithTag(NonPagedPool, 00246 NUMBER_LID_TABLE_ENTRIES * 00247 sizeof(KLID_TABLE_ENTRY), 00248 ' eK'); 00249 if (KiLogicalIdTable == NULL) { 00250 return(STATUS_NO_MEMORY); 00251 } 00252 RtlZeroMemory(KiLogicalIdTable, NUMBER_LID_TABLE_ENTRIES*sizeof(KLID_TABLE_ENTRY)); 00253 } 00254 00255 // 00256 // For each Lid defined in Common Data Area, we check if it has non 00257 // empty device block and function transfer table. If yes, we proceed 00258 // to check the device id. Otherwise, we skip the Lid. 00259 // 00260 00261 CdaPointer = (PKDB_FTT_SECTION)KiCommonDataArea + 2; 00262 Status = STATUS_ABIOS_LID_NOT_EXIST; 00263 00264 ExAcquireSpinLock(&KiAbiosLidTableLock, &OldIrql); 00265 00266 for (Lid = 2; Lid < KiCommonDataArea->NumberLids; Lid++) { 00267 if (CdaPointer->DeviceBlock.Selector != 0 && 00268 CdaPointer->FunctionTransferTable.Selector != 0) { 00269 00270 DeviceBlock = (PKDEVICE_BLOCK)(KiI386SelectorBase( 00271 CdaPointer->DeviceBlock.Selector) 00272 + (CdaPointer->DeviceBlock.Offset)); 00273 if (DeviceBlock->DeviceId == DeviceId) { 00274 if (RelativeLid == RelativeLidCount || RelativeLid == 0) { 00275 if (KiLogicalIdTable[Lid].Owner == 0L) { 00276 KiLogicalIdTable[Lid].Owner = Owner; 00277 KiLogicalIdTable[Lid].OwnerCount += Increment; 00278 *LogicalId = Lid; 00279 Status = STATUS_SUCCESS; 00280 } else if (KiLogicalIdTable[Lid].Owner == LID_NO_SPECIFIC_OWNER) { 00281 if (SharedLid) { 00282 *LogicalId = Lid; 00283 KiLogicalIdTable[Lid].OwnerCount += Increment; 00284 Status = STATUS_SUCCESS; 00285 } else { 00286 Status = STATUS_ABIOS_LID_ALREADY_OWNED; 00287 } 00288 } else if (KiLogicalIdTable[Lid].Owner == (ULONG)DriverObject) { 00289 *LogicalId = Lid; 00290 Status = STATUS_SUCCESS; 00291 } else if (RelativeLid != 0) { 00292 Status = STATUS_ABIOS_LID_ALREADY_OWNED; 00293 } 00294 break; 00295 } else { 00296 RelativeLidCount++; 00297 } 00298 } 00299 } 00300 CdaPointer++; 00301 } 00302 00303 ExReleaseSpinLock(&KiAbiosLidTableLock, OldIrql); 00304 return Status; 00305 } 00306 00307 NTSTATUS 00308 KeI386ReleaseLid( 00309 IN USHORT LogicalId, 00310 IN PDRIVER_OBJECT DriverObject 00311 ) 00312 00313 /*++ 00314 00315 Routine Description: 00316 00317 This function releases a logical Id. This routine is called at ABIOS 00318 device driver destallation or termination. 00319 00320 Arguments: 00321 00322 LogicalId - Logical Id to be released. 00323 00324 DriverObject - Supplies a 32-bit flat pointer of the requesting device 00325 driver's driver object. The DriverObject is used to check 00326 the ownership of the specified LID. 00327 00328 Return Value: 00329 00330 STATUS_SUCCESS - If the requested LID is released. 00331 00332 STATUS_ABIOS_NOT_PRESENT - If there is no ABIOS support in the system. 00333 00334 STATUS_ABIOS_NOT_LID_OWNER - If the caller does not own the LID. 00335 00336 --*/ 00337 00338 { 00339 KIRQL OldIrql; 00340 NTSTATUS Status; 00341 00342 if (!KiAbiosPresent) { 00343 return STATUS_ABIOS_NOT_PRESENT; 00344 } 00345 00346 ExAcquireSpinLock(&KiAbiosLidTableLock, &OldIrql); 00347 00348 if (KiLogicalIdTable[LogicalId].Owner == (ULONG)DriverObject) { 00349 KiLogicalIdTable[LogicalId].Owner = 0L; 00350 Status = STATUS_SUCCESS; 00351 } else if (KiLogicalIdTable[LogicalId].Owner == LID_NO_SPECIFIC_OWNER) { 00352 KiLogicalIdTable[LogicalId].OwnerCount--; 00353 if (KiLogicalIdTable[LogicalId].OwnerCount == 0L) { 00354 KiLogicalIdTable[LogicalId].Owner = 0L; 00355 } 00356 Status = STATUS_SUCCESS; 00357 } else { 00358 Status = STATUS_ABIOS_NOT_LID_OWNER; 00359 } 00360 00361 ExReleaseSpinLock(&KiAbiosLidTableLock, OldIrql); 00362 00363 return Status; 00364 } 00365 00366 NTSTATUS 00367 KeI386AbiosCall( 00368 IN USHORT LogicalId, 00369 IN PDRIVER_OBJECT DriverObject, 00370 IN PUCHAR RequestBlock, 00371 IN USHORT EntryPoint 00372 ) 00373 00374 /*++ 00375 00376 Routine Description: 00377 00378 This function calls an ABIOS service routine on behave of device driver 00379 using Operating System Transfer Convension. 00380 00381 Arguments: 00382 00383 LogicalId - Logical Id for the call. 00384 00385 DriverObject - Supplies a 32-bit flat pointer of the requesting device 00386 driver's driver object. The DriverObject is used to verify 00387 the ownership of the desired LID. 00388 00389 RequestBlock - A 16:16 (selector:offset) pointer to the request block. 00390 00391 EntryPoint - Specifies which ABIOS entry point: 00392 00393 0 - Start Routine 00394 1 - Interrupt Routine 00395 2 - Timeout Routine 00396 00397 Return Value: 00398 00399 STATUS_SUCCESS - If no error. 00400 00401 STATUS_ABIOS_NOT_PRESENT - If there is no ABIOS support in the system. 00402 00403 STATUS_ABIOS_INVALID_COMMAND - if the specified entry point is not supported. 00404 00405 STATUS_ABIOS_INVALID_LID - If the Lid specified is invalid. 00406 00407 STATUS_ABIOS_NOT_LID_OWNER - If the caller does not own this Lid. 00408 00409 (Note that the request specific ABIOS returned code is in RequestBlock.) 00410 00411 --*/ 00412 00413 { 00414 00415 KABIOS_POINTER FuncTransferTable; 00416 KABIOS_POINTER DeviceBlock; 00417 KABIOS_POINTER AbiosFunction; 00418 PKFUNCTION_TRANSFER_TABLE FttPointer; 00419 00420 if (!KiAbiosPresent) { 00421 return STATUS_ABIOS_NOT_PRESENT; 00422 } 00423 00424 if (LogicalId >= KiCommonDataArea->NumberLids) { 00425 return STATUS_ABIOS_INVALID_LID; 00426 } else if (KiLogicalIdTable[LogicalId].Owner != (ULONG)DriverObject && 00427 KiLogicalIdTable[LogicalId].Owner != LID_NO_SPECIFIC_OWNER) { 00428 return STATUS_ABIOS_NOT_LID_OWNER; 00429 } else if (EntryPoint > 2) { 00430 return STATUS_ABIOS_INVALID_COMMAND; 00431 } 00432 00433 FuncTransferTable = ((PKDB_FTT_SECTION)KiCommonDataArea + LogicalId)-> 00434 FunctionTransferTable; 00435 DeviceBlock = ((PKDB_FTT_SECTION)KiCommonDataArea + LogicalId)->DeviceBlock; 00436 FttPointer = (PKFUNCTION_TRANSFER_TABLE)(KiI386SelectorBase(FuncTransferTable.Selector) + 00437 (ULONG)FuncTransferTable.Offset); 00438 AbiosFunction = FttPointer->CommonRoutine[EntryPoint]; 00439 KiI386CallAbios(AbiosFunction, 00440 DeviceBlock, 00441 FuncTransferTable, 00442 *(PKABIOS_POINTER)&RequestBlock 00443 ); 00444 00445 return STATUS_SUCCESS; 00446 } 00447 00448 NTSTATUS 00449 KeI386AllocateGdtSelectors( 00450 OUT PUSHORT SelectorArray, 00451 IN USHORT NumberOfSelectors 00452 ) 00453 00454 /*++ 00455 00456 Routine Description: 00457 00458 This function allocates a set of GDT selectors for a device driver to use. 00459 Usually this allocation is performed at device driver initialization time 00460 to reserve the selectors for later use. 00461 00462 Arguments: 00463 00464 SelectorArray - Supplies a pointer to an array of USHORT to be filled 00465 in with the GDT selectors allocated. 00466 00467 NumberOfSelectors - Specifies the number of selectors to be allocated. 00468 00469 Return Value: 00470 00471 STATUS_SUCCESS - If the requested selectors are allocated. 00472 00473 STATUS_ABIOS_SELECTOR_NOT_AVAILABLE - if systen can not allocate the number 00474 of selectors requested. 00475 00476 --*/ 00477 00478 { 00479 PKFREE_GDT_ENTRY GdtEntry; 00480 KIRQL OldIrql; 00481 00482 if (KiNumberFreeSelectors >= NumberOfSelectors) { 00483 ExAcquireSpinLock(&KiAbiosGdtLock, &OldIrql); 00484 00485 // 00486 // The Free Gdt link list is maintained on Processor 0's GDT ONLY. 00487 // Because the 'selector' is an offset to the beginning of GDT and 00488 // it should be the same accross all the processors. 00489 // 00490 00491 KiNumberFreeSelectors -= NumberOfSelectors; 00492 GdtEntry = KiFreeGdtListHead; 00493 while (NumberOfSelectors != 0) { 00494 *SelectorArray++ = (USHORT)((ULONG)GdtEntry - KiAbiosGdt[0]); 00495 GdtEntry = GdtEntry->Flink; 00496 NumberOfSelectors--; 00497 } 00498 KiFreeGdtListHead = GdtEntry; 00499 ExReleaseSpinLock(&KiAbiosGdtLock, OldIrql); 00500 return STATUS_SUCCESS; 00501 } else { 00502 return STATUS_ABIOS_SELECTOR_NOT_AVAILABLE; 00503 } 00504 } 00505 00506 NTSTATUS 00507 KeI386ReleaseGdtSelectors( 00508 OUT PUSHORT SelectorArray, 00509 IN USHORT NumberOfSelectors 00510 ) 00511 00512 /*++ 00513 00514 Routine Description: 00515 00516 This function releases a set of GDT selectors for a device driver. 00517 Usually this function is called at device driver termination or 00518 deinstallation time. 00519 00520 Arguments: 00521 00522 SelectorArray - Supplies a pointer to an array of USHORT selectors 00523 to be freed. 00524 00525 NumberOfSelectors - Specifies the number of selectors to be released. 00526 00527 Return Value: 00528 00529 STATUS_SUCCESS - If the requested LID is released. 00530 00531 --*/ 00532 { 00533 PKFREE_GDT_ENTRY GdtEntry; 00534 KIRQL OldIrql; 00535 ULONG Gdt; 00536 00537 ExAcquireSpinLock(&KiAbiosGdtLock, &OldIrql); 00538 00539 // 00540 // The Free Gdt link list is maintained on Processor 0's GDT ONLY. 00541 // Because the 'selector' is an offset to the beginning of GDT and 00542 // it should be the same accross all the processors. 00543 // 00544 00545 KiNumberFreeSelectors += NumberOfSelectors; 00546 Gdt = KiAbiosGdt[0]; 00547 while (NumberOfSelectors != 0) { 00548 GdtEntry = (PKFREE_GDT_ENTRY)(Gdt + *SelectorArray++); 00549 GdtEntry->Flink = KiFreeGdtListHead; 00550 KiFreeGdtListHead = GdtEntry; 00551 NumberOfSelectors--; 00552 } 00553 ExReleaseSpinLock(&KiAbiosGdtLock, OldIrql); 00554 return STATUS_SUCCESS; 00555 } 00556 00557 NTSTATUS 00558 KeI386FlatToGdtSelector( 00559 IN ULONG SelectorBase, 00560 IN USHORT Length, 00561 IN USHORT Selector 00562 ) 00563 00564 /*++ 00565 00566 Routine Description: 00567 00568 This function converts a 32-bit flat address to a GDT selector-offset 00569 pair. The segment set up is always 16-bit ring 0 data segment. 00570 00571 Arguments: 00572 00573 SelectorBase - Supplies 32 bit flat address to be set as the base address 00574 of the desired selector. 00575 00576 Length - Supplies the Length of the segment. The Length is a 16 bit value 00577 and zero means 64KB. 00578 00579 Selector - Supplies the selector to be set up. 00580 00581 Return Value: 00582 00583 STATUS_SUCCESS - If the requested LID is released. 00584 00585 STATUS_ABIOS_NOT_PRESENT - If there is no ABIOS support in the system. 00586 00587 STATUS_ABIOS_INVALID_SELECTOR - If the selector supplied is invalid. 00588 00589 00590 --*/ 00591 00592 { 00593 PKGDTENTRY GdtEntry, GdtEntry1; 00594 KIRQL OldIrql; 00595 ULONG i; 00596 00597 if (!KiAbiosPresent) { 00598 return STATUS_ABIOS_NOT_PRESENT; 00599 } 00600 if (Selector < RESERVED_GDT_ENTRIES * sizeof(KGDTENTRY)) { 00601 return STATUS_ABIOS_INVALID_SELECTOR; 00602 } else { 00603 ExAcquireSpinLock(&KiAbiosGdtLock, &OldIrql); 00604 GdtEntry = (PKGDTENTRY)(KiAbiosGdt[0] + Selector); 00605 GdtEntry->LimitLow = (USHORT)(Length - 1); 00606 GdtEntry->BaseLow = LOWWORD(SelectorBase); 00607 GdtEntry->HighWord.Bytes.BaseMid = LOWBYTE(HIGHWORD(SelectorBase)); 00608 GdtEntry->HighWord.Bytes.BaseHi = HIGHBYTE(HIGHWORD(SelectorBase)); 00609 GdtEntry->HighWord.Bits.Pres = 1; 00610 GdtEntry->HighWord.Bits.Type = TYPE_DATA; 00611 GdtEntry->HighWord.Bits.Dpl = DPL_SYSTEM; 00612 for (i = 1; i < (ULONG)KeNumberProcessors; i++) { 00613 GdtEntry1 = (PKGDTENTRY)(KiAbiosGdt[i] + Selector); 00614 *GdtEntry1 = *GdtEntry; 00615 } 00616 ExReleaseSpinLock(&KiAbiosGdtLock, OldIrql); 00617 return STATUS_SUCCESS; 00618 } 00619 } 00620 00621 VOID 00622 Ki386InitializeGdtFreeList ( 00623 PKFREE_GDT_ENTRY EndOfGdt 00624 ) 00625 00626 /*++ 00627 00628 Routine Description: 00629 00630 This function initializes gdt free list by linking all the unused gdt 00631 entries to a free list. 00632 00633 Arguments: 00634 00635 EndOfGdt - Supplies the ending address of desired GDT. 00636 00637 Return Value: 00638 00639 None. 00640 00641 --*/ 00642 { 00643 PKFREE_GDT_ENTRY GdtEntry; 00644 00645 GdtEntry = EndOfGdt - 1; 00646 KiFreeGdtListHead = (PKFREE_GDT_ENTRY)0; 00647 while (GdtEntry != (PKFREE_GDT_ENTRY)KiAbiosGetGdt() + 00648 RESERVED_GDT_ENTRIES - 1) { 00649 if (GdtEntry->Present == 0) { 00650 GdtEntry->Flink = KiFreeGdtListHead; 00651 KiFreeGdtListHead = GdtEntry; 00652 KiNumberFreeSelectors++; 00653 } 00654 GdtEntry--; 00655 } 00656 } 00657 00658 VOID 00659 KiInitializeAbios ( 00660 IN UCHAR Processor 00661 ) 00662 00663 /*++ 00664 00665 Routine Description: 00666 00667 This function initializes gdt free list and sets up selector for 00668 KiI386AbiosCall (16-bit code). 00669 00670 Arguments: 00671 00672 Processor - the processor who performs the initialization. 00673 00674 Return Value: 00675 00676 None. 00677 00678 --*/ 00679 00680 { 00681 00682 ULONG GdtLength; 00683 PKGDTENTRY AliasGdtSelectorEntry; 00684 PKFREE_GDT_ENTRY EndOfGdt; 00685 00686 // 00687 // First check if abios is recognized by osloader. 00688 // 00689 00690 KiCommonDataArea = KeLoaderBlock->u.I386.CommonDataArea; 00691 00692 // 00693 // NOTE For now we want to disable ABIOS support on MP. 00694 // 00695 00696 if (KiCommonDataArea == NULL || Processor != 0) { 00697 KiAbiosPresent = FALSE; 00698 } else { 00699 KiAbiosPresent = TRUE; 00700 } 00701 00702 // 00703 // Initialize the spinlocks for accessing GDTs and Lid Table. 00704 // 00705 00706 KeInitializeSpinLock( &KiAbiosGdtLock ); 00707 KeInitializeSpinLock( &KiAbiosLidTableLock ); 00708 00709 // 00710 // Determine the starting and ending addresses of GDT. 00711 // 00712 00713 KiAbiosGdt[Processor] = KiAbiosGetGdt(); 00714 00715 AliasGdtSelectorEntry = (PKGDTENTRY)(KiAbiosGetGdt() + KGDT_GDT_ALIAS); 00716 GdtLength = 1 + (ULONG)(AliasGdtSelectorEntry->LimitLow) + 00717 (ULONG)(AliasGdtSelectorEntry->HighWord.Bits.LimitHi << 16); 00718 EndOfGdt = (PKFREE_GDT_ENTRY)(KiAbiosGetGdt() + GdtLength); 00719 00720 // 00721 // Prepare selector for 16 bit stack segment 00722 // 00723 00724 KiStack16GdtEntry = KiAbiosGetGdt() + KGDT_STACK16; 00725 00726 KiInitializeAbiosGdtEntry( 00727 (PKGDTENTRY)KiStack16GdtEntry, 00728 0L, 00729 0xffff, 00730 TYPE_DATA 00731 ); 00732 00733 // 00734 // Establish the addressability of Common Data Area selector. 00735 // 00736 00737 KiInitializeAbiosGdtEntry( 00738 (PKGDTENTRY)(KiAbiosGetGdt() + KGDT_CDA16), 00739 (ULONG)KiCommonDataArea, 00740 0xffff, 00741 TYPE_DATA 00742 ); 00743 00744 // 00745 // Set up 16-bit code selector for KiI386AbiosCall 00746 // 00747 00748 KiInitializeAbiosGdtEntry( 00749 (PKGDTENTRY)(KiAbiosGetGdt() + KGDT_CODE16), 00750 (ULONG)&KiI386CallAbios, 00751 (ULONG)&KiEndOfCode16 - (ULONG)&KiI386CallAbios - 1, 00752 0x18 // TYPE_CODE 00753 ); 00754 00755 // 00756 // Link all the unused GDT entries to our GDT free list. 00757 // 00758 00759 if (Processor == 0) { 00760 Ki386InitializeGdtFreeList(EndOfGdt); 00761 } 00762 }

Generated on Sat May 15 19:39:12 2004 for test by doxygen 1.3.7