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

iopm.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ALIGN_DOWN(address, amt)   ((ULONG)(address) & ~(( amt ) - 1))
#define ALIGN_UP(address, amt)   (ALIGN_DOWN( (address + (amt) - 1), (amt) ))

Functions

VOID KiSetIoMap (IN PKIPI_CONTEXT SignalDone, IN PVOID MapSource, IN PVOID MapNumber, IN PVOID Parameter3)
VOID KiLoadIopmOffset (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
BOOLEAN Ke386SetIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN Ke386QueryIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN Ke386IoSetAccessProcess (PKPROCESS Process, ULONG MapNumber)
VOID Ke386SetIOPL (IN PKPROCESS Process)


Define Documentation

#define ALIGN_DOWN address,
amt   )     ((ULONG)(address) & ~(( amt ) - 1))
 

Definition at line 36 of file i386/iopm.c.

#define ALIGN_UP address,
amt   )     (ALIGN_DOWN( (address + (amt) - 1), (amt) ))
 

Definition at line 37 of file i386/iopm.c.


Function Documentation

BOOLEAN Ke386IoSetAccessProcess PKPROCESS  Process,
ULONG  MapNumber
 

Definition at line 318 of file i386/iopm.c.

References _KPROCESS::ActiveProcessors, FALSE, KeGetCurrentPrcb, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLoadIopmOffset(), KiLockContextSwap, KiPcr, KiUnlockContextSwap, NULL, TRUE, and USHORT.

00324 : 00325 00326 Set the i/o access map which controls user mode i/o access 00327 for a particular process. 00328 00329 Arguments: 00330 00331 Process - Pointer to kernel process object describing the 00332 process which for which a map is to be set. 00333 00334 MapNumber - Number of the map to set. Value of map is 00335 defined by Ke386IoSetAccessProcess. Setting MapNumber 00336 to IO_ACCESS_MAP_NONE will disallow any user mode i/o 00337 access from the process. 00338 00339 Return Value: 00340 00341 TRUE if success, FALSE if failure (illegal MapNumber) 00342 00343 --*/ 00344 00345 { 00346 00347 USHORT MapOffset; 00348 KIRQL OldIrql; 00349 PKPRCB Prcb; 00350 KAFFINITY TargetProcessors; 00351 00352 // 00353 // Reject illegal requests 00354 // 00355 00356 if (MapNumber > IOPM_COUNT) { 00357 return FALSE; 00358 } 00359 00360 MapOffset = KiComputeIopmOffset(MapNumber); 00361 00362 // 00363 // Acquire the context swap lock so a context switch will not occur. 00364 // 00365 00366 KiLockContextSwap(&OldIrql); 00367 00368 // 00369 // Store new offset in process object, compute current set of 00370 // active processors for process, if this cpu is one, set IOPM. 00371 // 00372 00373 Process->IopmOffset = MapOffset; 00374 00375 TargetProcessors = Process->ActiveProcessors; 00376 Prcb = KeGetCurrentPrcb(); 00377 if (TargetProcessors & Prcb->SetMember) { 00378 KiPcr()->TSS->IoMapBase = MapOffset; 00379 } 00380 00381 // 00382 // Compute set of active processors other than this one, if non-empty 00383 // IPI them to load their IOPMs, wait for them. 00384 // 00385 00386 #if !defined(NT_UP) 00387 00388 TargetProcessors = TargetProcessors & ~Prcb->SetMember; 00389 if (TargetProcessors != 0) { 00390 KiIpiSendPacket(TargetProcessors, 00391 KiLoadIopmOffset, 00392 NULL, 00393 NULL, 00394 NULL); 00395 00396 KiIpiStallOnPacketTargets(TargetProcessors); 00397 } 00398 00399 #endif 00400 00401 // 00402 // Restore IRQL and unlock the context swap lock. 00403 // 00404 00405 KiUnlockContextSwap(OldIrql); 00406 return TRUE; 00407 }

BOOLEAN Ke386QueryIoAccessMap ULONG  MapNumber,
PKIO_ACCESS_MAP  IoAccessMap
 

Definition at line 235 of file i386/iopm.c.

References FALSE, KiLockContextSwap, KiPcr, KiUnlockContextSwap, and TRUE.

00242 : 00243 00244 The specified i/o access map will be dumped into the buffer. 00245 map 0 is a constant, but will be dumped anyway. 00246 00247 Arguments: 00248 00249 MapNumber - Number of access map to set. map 0 is fixed. 00250 00251 IoAccessMap - Pointer to buffer (64K bits, 8K bytes) which 00252 is to receive the definition of the access map. 00253 Must be in non-paged pool. 00254 00255 Return Value: 00256 00257 TRUE if successful. FALSE if failure (attempt to query a map 00258 which does not exist) 00259 00260 --*/ 00261 00262 { 00263 00264 ULONG i; 00265 PVOID Map; 00266 KIRQL OldIrql; 00267 PUCHAR p; 00268 00269 // 00270 // Reject illegal requests 00271 // 00272 00273 if (MapNumber > IOPM_COUNT) { 00274 return FALSE; 00275 } 00276 00277 // 00278 // Acquire the context swap lock so a context switch will not occur. 00279 // 00280 00281 KiLockContextSwap(&OldIrql); 00282 00283 // 00284 // Copy out the map 00285 // 00286 00287 if (MapNumber == IO_ACCESS_MAP_NONE) { 00288 00289 // 00290 // no access case, simply return a map of all 1s 00291 // 00292 00293 p = (PUCHAR)IoAccessMap; 00294 for (i = 0; i < IOPM_SIZE; i++) { 00295 p[i] = (UCHAR)-1; 00296 } 00297 00298 } else { 00299 00300 // 00301 // normal case, just copy the bits 00302 // 00303 00304 Map = (PVOID)&(KiPcr()->TSS->IoMaps[MapNumber-1].IoMap); 00305 RtlMoveMemory((PVOID)IoAccessMap, Map, IOPM_SIZE); 00306 } 00307 00308 // 00309 // Restore IRQL and unlock the context swap lock. 00310 // 00311 00312 KiUnlockContextSwap(OldIrql); 00313 return TRUE; 00314 }

BOOLEAN Ke386SetIoAccessMap ULONG  MapNumber,
PKIO_ACCESS_MAP  IoAccessMap
 

Definition at line 80 of file i386/iopm.c.

References FALSE, KeActiveProcessors, KeGetCurrentPrcb, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiPcr, KiSetIoMap(), KiUnlockContextSwap, NULL, and TRUE.

00087 : 00088 00089 The specified i/o access map will be set to match the 00090 definition specified by IoAccessMap (i.e. enable/disable 00091 those ports) before the call returns. The change will take 00092 effect on all processors. 00093 00094 Ke386SetIoAccessMap does not give any process enhanced I/O 00095 access, it merely defines a particular access map. 00096 00097 Arguments: 00098 00099 MapNumber - Number of access map to set. Map 0 is fixed. 00100 00101 IoAccessMap - Pointer to bitvector (64K bits, 8K bytes) which 00102 defines the specified access map. Must be in 00103 non-paged pool. 00104 00105 Return Value: 00106 00107 TRUE if successful. FALSE if failure (attempt to set a map 00108 which does not exist, attempt to set map 0) 00109 00110 --*/ 00111 00112 { 00113 00114 PKPROCESS CurrentProcess; 00115 KIRQL OldIrql; 00116 PKPRCB Prcb; 00117 PVOID pt; 00118 KAFFINITY TargetProcessors; 00119 00120 // 00121 // Reject illegal requests 00122 // 00123 00124 if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE)) { 00125 return FALSE; 00126 } 00127 00128 // 00129 // Acquire the context swap lock so a context switch will not occur. 00130 // 00131 00132 KiLockContextSwap(&OldIrql); 00133 00134 // 00135 // Compute set of active processors other than this one, if non-empty 00136 // IPI them to set their maps. 00137 // 00138 00139 Prcb = KeGetCurrentPrcb(); 00140 00141 #if !defined(NT_UP) 00142 00143 TargetProcessors = KeActiveProcessors & ~Prcb->SetMember; 00144 if (TargetProcessors != 0) { 00145 KiIpiSendPacket(TargetProcessors, 00146 KiSetIoMap, 00147 IoAccessMap, 00148 (PVOID)MapNumber, 00149 NULL); 00150 } 00151 00152 #endif 00153 00154 // 00155 // Copy the IOPM map and load the map for the current process. 00156 // 00157 00158 pt = &(KiPcr()->TSS->IoMaps[MapNumber-1].IoMap); 00159 RtlMoveMemory(pt, (PVOID)IoAccessMap, IOPM_SIZE); 00160 CurrentProcess = Prcb->CurrentThread->ApcState.Process; 00161 KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset; 00162 00163 // 00164 // Wait until all of the target processors have finished copying the 00165 // new map. 00166 // 00167 00168 #if !defined(NT_UP) 00169 00170 if (TargetProcessors != 0) { 00171 KiIpiStallOnPacketTargets(TargetProcessors); 00172 } 00173 00174 #endif 00175 00176 // 00177 // Restore IRQL and unlock the context swap lock. 00178 // 00179 00180 KiUnlockContextSwap(OldIrql); 00181 return TRUE; 00182 }

VOID Ke386SetIOPL IN PKPROCESS  Process  ) 
 

Definition at line 457 of file i386/iopm.c.

References ALIGN_UP, _KTHREAD::ApcState, CONTEXT_CONTROL, _KTHREAD::InitialStack, _KTHREAD::Iopl, KeContextFromKframes(), KeContextToKframes(), KeGetCurrentThread, NULL, _KAPC_STATE::Process, and UserMode.

Referenced by NtSetInformationProcess().

00463 : 00464 00465 Gives IOPL to the specified process. 00466 00467 All threads created from this point on will get IOPL. The current 00468 process will get IOPL. Must be called from context of thread and 00469 process that are to have IOPL. 00470 00471 Iopl (to be made a boolean) in KPROCESS says all 00472 new threads to get IOPL. 00473 00474 Iopl (to be made a boolean) in KTHREAD says given 00475 thread to get IOPL. 00476 00477 N.B. If a kernel mode only thread calls this procedure, the 00478 result is (a) poinless and (b) will break the system. 00479 00480 Arguments: 00481 00482 Process - Pointer to the process == IGNORED!!! 00483 00484 Return Value: 00485 00486 none 00487 00488 --*/ 00489 00490 { 00491 00492 PKTHREAD Thread; 00493 PKPROCESS Process2; 00494 PKTRAP_FRAME TrapFrame; 00495 CONTEXT Context; 00496 00497 // 00498 // get current thread and Process2, set flag for IOPL in both of them 00499 // 00500 00501 Thread = KeGetCurrentThread(); 00502 Process2 = Thread->ApcState.Process; 00503 00504 Process2->Iopl = 1; 00505 Thread->Iopl = 1; 00506 00507 // 00508 // Force IOPL to be on for current thread 00509 // 00510 00511 TrapFrame = (PKTRAP_FRAME)((PUCHAR)Thread->InitialStack - 00512 ALIGN_UP(sizeof(KTRAP_FRAME),KTRAP_FRAME_ALIGN) - 00513 sizeof(FX_SAVE_AREA)); 00514 00515 Context.ContextFlags = CONTEXT_CONTROL; 00516 KeContextFromKframes(TrapFrame, 00517 NULL, 00518 &Context); 00519 00520 Context.EFlags |= (EFLAGS_IOPL_MASK & -1); // IOPL == 3 00521 00522 KeContextToKframes(TrapFrame, 00523 NULL, 00524 &Context, 00525 CONTEXT_CONTROL, 00526 UserMode); 00527 00528 return; 00529 } }

VOID KiLoadIopmOffset IN PKIPI_CONTEXT  SignalDone,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 

Definition at line 413 of file i386/iopm.c.

References KeGetCurrentPrcb, KiIpiSignalPacketDone(), and KiPcr.

Referenced by Ke386IoSetAccessProcess().

00422 : 00423 00424 Edit IopmBase of Tss to match that of currently running process. 00425 00426 Arguments: 00427 00428 Argument - actually a pointer to a KIPI_LOAD_IOPM_OFFSET structure 00429 ReadyFlag - Pointer to flag to be set once we are done 00430 00431 Return Value: 00432 00433 none 00434 00435 --*/ 00436 00437 { 00438 00439 PKPROCESS CurrentProcess; 00440 PKPRCB Prcb; 00441 00442 // 00443 // Update IOPM field in TSS from current process 00444 // 00445 00446 Prcb = KeGetCurrentPrcb(); 00447 CurrentProcess = Prcb->CurrentThread->ApcState.Process; 00448 KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset; 00449 KiIpiSignalPacketDone(SignalDone); 00450 return; 00451 }

VOID KiSetIoMap IN PKIPI_CONTEXT  SignalDone,
IN PVOID  MapSource,
IN PVOID  MapNumber,
IN PVOID  Parameter3
 

Definition at line 188 of file i386/iopm.c.

References KeGetCurrentPrcb, KiIpiSignalPacketDone(), and KiPcr.

Referenced by Ke386SetIoAccessMap().

00196 : 00197 00198 copy the specified map into this processor's TSS. 00199 This procedure runs at IPI level. 00200 00201 Arguments: 00202 00203 Argument - actually a pointer to a KIPI_SET_IOPM structure 00204 ReadyFlag - pointer to flag to set once setiopm has completed 00205 00206 Return Value: 00207 00208 none 00209 00210 --*/ 00211 00212 { 00213 00214 PKPROCESS CurrentProcess; 00215 PKPRCB Prcb; 00216 PVOID pt; 00217 00218 // 00219 // Copy the IOPM map and load the map for the current process. 00220 // 00221 00222 Prcb = KeGetCurrentPrcb(); 00223 pt = &(KiPcr()->TSS->IoMaps[((ULONG) MapNumber)-1].IoMap); 00224 RtlMoveMemory(pt, MapSource, IOPM_SIZE); 00225 CurrentProcess = Prcb->CurrentThread->ApcState.Process; 00226 KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset; 00227 KiIpiSignalPacketDone(SignalDone); 00228 return; 00229 }


Generated on Sat May 15 19:44:20 2004 for test by doxygen 1.3.7