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.

Functions

BOOLEAN KiIA32SetPortMemory (PKPROCESS Process)
BOOLEAN KeIA32SetIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN KeIA32QueryIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN KeIA32IoSetAccessProcess (PKPROCESS Process, ULONG MapNumber)
BOOLEAN KeIA32PortIsAccessable (PKPROCESS Process, ULONG Port, ULONG Size)

Variables

PKIO_ACCESS_MAP VdmIoMaps [IOPM_COUNT]


Function Documentation

BOOLEAN KeIA32IoSetAccessProcess PKPROCESS  Process,
ULONG  MapNumber
 

Definition at line 227 of file ia64/iopm.c.

References FALSE, and KiIA32SetPortMemory().

00233 : 00234 00235 Set the i/o access map which controls user mode i/o access 00236 for a particular process. 00237 00238 Arguments: 00239 00240 Process - Pointer to kernel process object describing the 00241 process which for which a map is to be set. 00242 00243 MapNumber - Number of the map to set. Value of map is 00244 defined by KeIA32IoSetAccessProcess. Setting MapNumber 00245 to IO_ACCESS_MAP_NONE will disallow any user mode i/o 00246 access from the process. 00247 00248 Return Value: 00249 00250 TRUE if success, FALSE if failure (illegal MapNumber) 00251 00252 --*/ 00253 00254 { 00255 // 00256 // Reject illegal requests 00257 // 00258 00259 if (MapNumber > IOPM_COUNT) { 00260 return FALSE; 00261 } 00262 00263 // 00264 // Store new offset in process object, compute current set of 00265 // active processors for process, if this cpu is one, set IOPM. 00266 // 00267 00268 Process->IOCurMap = MapNumber; 00269 if (Process->IOCurMap == IO_ACCESS_MAP_NONE) { 00270 // 00271 // BUGBUG: Need to set the EFLAGS.iopl back to 0 for this process 00272 // And all its threads? 00273 // 00274 } 00275 else { 00276 // 00277 // BUGBUG: Need to set the EFLAGS.iopl to 3 for this process 00278 // And all its threads? 00279 // 00280 } 00281 00282 return (KiIA32SetPortMemory(Process)); 00283 }

BOOLEAN KeIA32PortIsAccessable PKPROCESS  Process,
ULONG  Port,
ULONG  Size
 

Definition at line 287 of file ia64/iopm.c.

References ASSERT, FALSE, Size, and VdmIoMaps.

00294 : 00295 00296 Checks to see if a particular port is accessable by a particular process 00297 00298 Arguments: 00299 00300 Process - Pointer to kernel process object 00301 00302 Port - port number to check 00303 00304 Size - size of access (1, 2 or 4 bytes) 00305 00306 Return Value: 00307 00308 TRUE if port is accessable, false if port is not 00309 00310 --*/ 00311 { 00312 ULONG byte; 00313 ULONG bit; 00314 ULONG val; 00315 ULONG ToTest; 00316 PUCHAR ioBits; 00317 00318 if (Process->IOCurMap == IO_ACCESS_MAP_NONE) { 00319 return FALSE; 00320 } 00321 00322 // 00323 // Make sure everything is legit... 00324 // 00325 ASSERT (Process->IOCurMap <= IOPM_COUNT); 00326 ASSERT (Port < (64 * 1024)); 00327 ASSERT((Size == 1) || (Size == 2) || (Size == 4)); 00328 00329 ioBits = VdmIoMaps[Process->IOCurMap - 1]; 00330 00331 // 00332 // Get the byte to be tested 00333 // 00334 byte = Port >> 3; 00335 00336 // 00337 // This handles boundary conditions... 00338 // 00339 ToTest = ioBits[byte] | (ioBits[byte + 1] << 8); 00340 00341 // 00342 // And get the specific bit 00343 // 00344 bit = Port & 0x07; 00345 00346 // 00347 // Really want Size to be 1, 2, or 3 so we can use it for shifting and 00348 // we want val to be a mask for the port access 00349 // (2^Size -1 == mask for size of port access)... 00350 // 00351 if (Size == 4) { 00352 val = 7 << bit; 00353 } 00354 else { 00355 val = ((1 << Size) - 1) << bit; 00356 } 00357 00358 return (! (ToTest & val)); 00359 }

BOOLEAN KeIA32QueryIoAccessMap ULONG  MapNumber,
PKIO_ACCESS_MAP  IoAccessMap
 

Definition at line 156 of file ia64/iopm.c.

References ASSERT, FALSE, NULL, TRUE, and VdmIoMaps.

00163 : 00164 00165 The specified i/o access map will be dumped into the buffer. 00166 map 0 is a constant, but will be dumped anyway. 00167 00168 Arguments: 00169 00170 MapNumber - Number of access map to set. map 0 is fixed. 00171 00172 IoAccessMap - Pointer to buffer (64K bits, 8K bytes) which 00173 is to receive the definition of the access map. 00174 Must be in non-paged pool. 00175 00176 Return Value: 00177 00178 TRUE if successful. FALSE if failure (attempt to query a map 00179 which does not exist) 00180 00181 --*/ 00182 00183 { 00184 PVOID Map; 00185 KIRQL OldIrql; 00186 00187 // 00188 // Reject illegal requests 00189 // 00190 00191 if (MapNumber > IOPM_COUNT) { 00192 return FALSE; 00193 } 00194 00195 // 00196 // BUGBUG: Do we care if a context switch occurs? What if someone 00197 // else is modifying map N? (just an issue with MP systems...) 00198 // 00199 00200 // 00201 // Copy out the map 00202 // 00203 00204 if (MapNumber == IO_ACCESS_MAP_NONE) { 00205 00206 // 00207 // no access case, simply return a map of all 1s 00208 // 00209 RtlFillMemory((PVOID) IoAccessMap, IOPM_SIZE, 0x0ff); 00210 00211 } else { 00212 00213 // 00214 // normal case, just copy the bits 00215 // 00216 00217 Map = VdmIoMaps[MapNumber-1]; 00218 ASSERT(Map != NULL); 00219 RtlMoveMemory((PVOID)IoAccessMap, Map, IOPM_SIZE); 00220 } 00221 00222 return TRUE; 00223 }

BOOLEAN KeIA32SetIoAccessMap ULONG  MapNumber,
PKIO_ACCESS_MAP  IoAccessMap
 

Definition at line 48 of file ia64/iopm.c.

References ExAllocatePool, FALSE, KiIA32SetPortMemory(), KiLockContextSwap, KiUnlockContextSwap, NonPagedPool, NULL, PsGetCurrentProcess, and VdmIoMaps.

00055 : 00056 00057 The specified i/o access map will be set to match the 00058 definition specified by IoAccessMap (i.e. enable/disable 00059 those ports) before the call returns. The change will take 00060 effect on all processors. 00061 00062 KeIA32SetIoAccessMap does not give any process enhanced I/O 00063 access, it merely defines a particular access map. 00064 00065 Arguments: 00066 00067 MapNumber - Number of access map to set. Map 0 is fixed. 00068 00069 IoAccessMap - Pointer to bitvector (64K bits, 8K bytes) which 00070 defines the specified access map. Must be in 00071 non-paged pool. 00072 00073 Return Value: 00074 00075 TRUE if successful. FALSE if failure (attempt to set a map 00076 which does not exist, attempt to set map 0) 00077 00078 --*/ 00079 00080 { 00081 00082 PKPROCESS CurrentProcess; 00083 KIRQL OldIrql; 00084 PVOID pt; 00085 PUCHAR p; 00086 ULONG i; 00087 BOOLEAN res; 00088 00089 // 00090 // Reject illegal requests 00091 // 00092 00093 if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE)) { 00094 return FALSE; 00095 } 00096 00097 // 00098 // If the map N hasn't been allocated, then allocate it now. 00099 // Don't need to ever free this since it is a system wide 00100 // resource... Once allocated, stays till reboot. 00101 // This implies we might want to allocate it early, but we can 00102 // deal with that later... 00103 // 00104 00105 if (VdmIoMaps[MapNumber - 1] == NULL) { 00106 // Allocate a little extra to handle wrap-around... 00107 p = (PUCHAR) ExAllocatePool(NonPagedPool, PIOPM_SIZE); 00108 if (p == NULL) { 00109 return FALSE; 00110 } 00111 00112 // 00113 // And set it all to "no-access" 00114 // (and don't forget the little extra) 00115 // 00116 RtlFillMemory((PVOID) p, PIOPM_SIZE, 0x0ff); 00117 00118 VdmIoMaps[MapNumber - 1] = p; 00119 } 00120 00121 // 00122 // Acquire the context swap lock so a context switch will not occur. 00123 // 00124 // BUGBUG: Is this really needed? 00125 // 00126 00127 KiLockContextSwap(&OldIrql); 00128 00129 // 00130 // Copy the IOPM map and load the map for the current process. 00131 // 00132 00133 pt = VdmIoMaps[MapNumber-1]; 00134 RtlMoveMemory(pt, (PVOID)IoAccessMap, IOPM_SIZE); 00135 CurrentProcess = PsGetCurrentProcess(); 00136 00137 CurrentProcess->IOCurMap = MapNumber; 00138 00139 // 00140 // BUGBUG: Need to set the EFLAGS.iopl to 3 for this process 00141 // and all threads in the process as well? 00142 // 00143 00144 res = KiIA32SetPortMemory(CurrentProcess); 00145 00146 // 00147 // Restore IRQL and unlock the context swap lock. 00148 // 00149 00150 KiUnlockContextSwap(OldIrql); 00151 return res; 00152 }

BOOLEAN KiIA32SetPortMemory PKPROCESS  Process  ) 
 

Definition at line 363 of file ia64/iopm.c.

References TRUE, and VdmIoMaps.

Referenced by KeIA32IoSetAccessProcess(), and KeIA32SetIoAccessMap().

00368 : 00369 00370 Based on the IO access allowed for a particular process, set the memory 00371 map accordingly... 00372 00373 Arguments: 00374 00375 Process - Pointer to kernel process object 00376 00377 Return Value: 00378 00379 TRUE if able to setup the memory pages 00380 00381 Notes: 00382 It would be a lot faster to use a bit searching algorithm 00383 looking for the first 0 bit (accessible) instead of 00384 doing 8192 calls to the memory system... Of course, we may 00385 do this infrequently enough that it may not matter... 00386 00387 --*/ 00388 { 00389 PUCHAR ioBits; 00390 ULONG i; 00391 PVOID VirtualPort; 00392 00393 if (Process->IOCurMap == IO_ACCESS_MAP_NONE) { 00394 // Unmap all of the IOBASE memory? 00395 // Or set them all as Inaccesable? 00396 00397 return TRUE; 00398 } 00399 00400 ioBits = VdmIoMaps[Process->IOCurMap - 1]; 00401 00402 for (i = 0; i < IOPM_SIZE; i++) { 00403 // VirtualPort = (i << SHIFT_8K) + IOBASE; 00404 if ((*ioBits & 0x000f) == 0) { 00405 // These four ports can be set read/writable 00406 // Call memory manager to set read/writable + IO special 00407 } 00408 else { 00409 // Call memory manager to set as inaccessable/unmap 00410 } 00411 00412 // VirtualPort = (i << SHIFT_8K) + IOBASE + (4K_PAGE); 00413 if ((*ioBits++ & 0x00f0) == 0) { 00414 // These four ports can be set read/writable 00415 // Call memory manager to set read/writable + IO special 00416 } 00417 else { 00418 // Call memory manager to set as inaccessable/unmap 00419 } 00420 } 00421 00422 return TRUE; 00423 } }


Variable Documentation

PKIO_ACCESS_MAP VdmIoMaps[IOPM_COUNT] [static]
 

Definition at line 44 of file ia64/iopm.c.

Referenced by KeIA32PortIsAccessable(), KeIA32QueryIoAccessMap(), KeIA32SetIoAccessMap(), and KiIA32SetPortMemory().


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