└── boot └── environ ├── app ├── bootmgr │ ├── bcd.c │ ├── bmbgdisp.c │ ├── bootmgr.c │ ├── bootmgr.h │ ├── display.c │ ├── efi │ │ ├── entry.c │ │ └── util.c │ ├── error.c │ ├── fvedisp.c │ └── resume.c ├── lib │ └── charge │ │ ├── battery.c │ │ ├── battery.h │ │ ├── charge.c │ │ ├── chargelib.c │ │ ├── chargelib.h │ │ ├── chargelibex.h │ │ ├── efibattery.c │ │ ├── efiusbfn.c │ │ ├── efiusbfndescriptor.c │ │ ├── efiusbfnsupport.c │ │ ├── efiwrappers.c │ │ ├── efiwrappers.h │ │ ├── graphics.c │ │ ├── graphics.h │ │ ├── usbfn.h │ │ └── usbfnsupport.h └── osloader │ ├── arm │ ├── armentry.c │ ├── armxfer.asm │ ├── detect.c │ └── osxferc.c │ ├── bootstat.c │ ├── config.c │ ├── debug.c │ ├── display.c │ ├── efi │ ├── fwconfig.c │ ├── fwupdate.c │ ├── osfirmw.c │ └── sbootfw.c │ ├── entropy.c │ ├── error.c │ ├── fipsmode.c │ ├── ldrblock.c │ ├── load.c │ ├── mcupdate.c │ ├── osbgdisp.c │ ├── osextens.c │ ├── oskstack.c │ ├── osloader.c │ ├── osloader.h │ ├── registry.c │ ├── resmcntx.c │ ├── schema.c │ ├── si.c │ └── utility.c └── lib ├── arch ├── arm │ ├── archapi.c │ ├── ctxarm.c │ ├── ioaccess.c │ ├── transita.asm │ ├── transitc.c │ └── vector.asm ├── context.c └── efi │ └── ctxefiarm.c ├── firmware └── efi │ ├── efiapi.c │ ├── efiblock.c │ ├── eficon.c │ ├── efidebug.c │ ├── efifw.c │ ├── efiinit.c │ ├── efilib.c │ ├── efipci.c │ ├── efiprot.c │ ├── efipxe.c │ ├── efirng.c │ ├── efisc.c │ ├── efitcg.c │ └── efitree.c ├── io ├── device │ ├── blkcache.c │ ├── block.h │ ├── blockapi.c │ ├── device.c │ ├── device.h │ ├── disk.h │ ├── diskapi.c │ ├── efi │ │ ├── block.c │ │ ├── disk.c │ │ └── partition.c │ ├── locate.c │ ├── partapi.c │ ├── partition.h │ └── ramapi.c └── file │ ├── fatboot.c │ ├── fatboot.h │ ├── file.c │ ├── file.h │ ├── ntfsboot.c │ ├── ntfsboot.h │ ├── wimboot.c │ ├── wimboot.h │ └── wimintegrity.c ├── misc ├── archack.c ├── bsdlog.c ├── efi │ ├── image.c │ └── time.c ├── hash.c ├── imgapp.c ├── imgload.c ├── libapi.c ├── loader.c ├── log.c ├── pdsup.c ├── resource.c ├── status.c ├── string.c ├── table.c ├── time_cmn.c └── utility.c ├── mm ├── arm │ ├── procuarm.c │ ├── procuarm.h │ └── tranapp.c ├── blkalloc.c ├── efi │ └── memory.c ├── malloc.c ├── memdesc.c ├── memutils.c ├── pagalloc.c ├── translat.c └── transmin.c └── platform ├── efi └── eficfg.c ├── pciconfig.c └── platinit.c /boot/environ/app/bootmgr/efi/entry.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | entry.c 8 | 9 | Abstract: 10 | 11 | This module contains the entry point for the Windows Boot Manager on 12 | an EFI platform. 13 | 14 | Environment: 15 | 16 | Boot. 17 | 18 | --*/ 19 | 20 | // ------------------------------------------------------------------- Includes 21 | 22 | #include "bootmgr.h" 23 | 24 | // ------------------------------------------------------------------ Functions 25 | 26 | EFI_STATUS 27 | EFIAPI 28 | EfiEntry ( 29 | __in EFI_HANDLE ImageHandle, 30 | __in struct _EFI_SYSTEM_TABLE *SystemTable 31 | ) 32 | 33 | /*++ 34 | 35 | Routine Description: 36 | 37 | The entry point for the Windows Boot Manager on an EFI platform. 38 | 39 | Arguments: 40 | 41 | ImageHandle - Firmware allocated handle for the Boot Manager's image. 42 | 43 | SystemTable - A pointer to the EFI system table. 44 | 45 | Returns: 46 | 47 | STATUS_SUCCESS when successful. 48 | STATUS_INVALID_PARAMETER when unable to initialize boot application 49 | input data structure. 50 | 51 | Any other error is possible when the Boot Manager fails. 52 | 53 | --*/ 54 | 55 | { 56 | 57 | PBOOT_APPLICATION_PARAMETERS InputParameters; 58 | NTSTATUS Status; 59 | 60 | // 61 | // All boot environment applications have a common input data structure. 62 | // Since this application was loaded as an EFI Application, we need 63 | // to create our expected input data structure. 64 | // 65 | 66 | InputParameters = EfiInitCreateInputParameters(ImageHandle, SystemTable); 67 | if (InputParameters == NULL) { 68 | Status = STATUS_INVALID_PARAMETER; 69 | goto EntryEnd; 70 | } 71 | 72 | // 73 | // Transfer execution to the boot application's firmware independent 74 | // entry point. 75 | // 76 | 77 | Status = BmMain(InputParameters); 78 | 79 | EntryEnd: 80 | return EfiGetEfiStatusCode(Status); 81 | } 82 | 83 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/battery.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | battery.h 8 | 9 | Abstract: 10 | 11 | Common header for the battery subsystem 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | 18 | --*/ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | // 25 | // Are we above threshold? 26 | // 27 | #define IS_ABOVE_THRESHOLD( _t_, _b_) ( _b_ >= _t_) 28 | 29 | // 30 | // Timeout value during threshold charging, in seconds 31 | // 32 | #define THRESHOLD_TIMEOUT ( 300 * SECONDS ) 33 | 34 | // 35 | // Default battery threshold value for booting into the main OS 36 | // 37 | #define BATTERY_CHARGING_BOOT_THRESHOLD ( 10 ) 38 | 39 | // 40 | // The OEM should not set a threshold limit more than this value 41 | // 42 | #define BATTERY_CHARGING_BOOT_THRESHOLD_LIMIT ( 50 ) 43 | 44 | // 45 | // Minimum allowed Rated Capacity of the battery in mAh 46 | // 47 | #define MINIMUM_BATTERY_RATED_CAPACITY ( 100 ) 48 | 49 | // 50 | // Maximum allowed Rated Capacity of the battery in mAh 51 | // 52 | #define MAXIMUM_BATTERY_RATED_CAPACITY ( 10000 ) 53 | 54 | // 55 | // Skip charging threshold value 56 | // 57 | #define BATTERY_SKIP_CHARGING ( 0xFF ) 58 | 59 | // 60 | // From the UEFI Battery Charging functional spec (last updated March 8 61 | // 2013), we have the following cases: 62 | // * Charging Downstream Port -> 1.5A 63 | // * Standard Downstream Port -> 500mA 64 | // * Standard Downstream Port (3.0) -> 900mA 65 | // * Dedicated Charging Port -> 1.5A 66 | // * Suspended Port -> 100mA 67 | // These current values are in mA 68 | // 69 | #define CURRENT_CHARGING_DOWNSTREAM ( 1500 ) 70 | #define CURRENT_STANDARD_DOWNSTREAM ( 500 ) 71 | #define CURRENT_STANDARD_DOWNSTREAM_30 ( 900 ) 72 | #define CURRENT_DEDICATED_CHARGING ( 1500 ) 73 | #define CURRENT_SUSPENDED ( CURRENT_STANDARD_DOWNSTREAM ) 74 | 75 | 76 | // 77 | // MIN and MAX values we expect from the battery protocol 78 | // 79 | #define CHARGE_MAX ( 100 ) 80 | #define CHARGE_MIN ( 0 ) 81 | 82 | // 83 | // Default UNKNOWN values for certain metrics 84 | // 85 | #define UNKNOWN_CURRENT_INTO_BATTERY ( -8888 ) 86 | #define UNKNOWN_VOLTAGE_ACROSS_BATTERY_TERMINALS ( 0 ) 87 | #define UNKNOWN_VOLTAGE_OVER_USB_CABLE ( 0 ) 88 | #define UNKNOWN_CURRENT_THROUGH_USB_CABLE ( 0 ) 89 | #define UNKNOWN_BATTERY_TEMPERATURE ( -8888 ) 90 | 91 | // 92 | // Charge timeout 93 | // 94 | // #define CHARGE_TIMEOUT_ENABLED 95 | #undef CHARGE_TIMEOUT_ENABLED 96 | 97 | // 98 | // Time in seconds about how often the battery will be 99 | // polled to get an update about the state of charge 100 | // This is in seconds 101 | // 102 | #define BATTERY_POLL_INTERVAL ( 50 ) 103 | 104 | #define IS_POLL_TIME( __x__ ) ( __x__ % (BATTERY_POLL_INTERVAL) == 0 ) 105 | 106 | 107 | // 108 | // This is the delta to be applied on top of the threshold retrieved from the BCD 109 | // when the phone determines it needs to boot into the Update OS 110 | // 111 | #define UPDATE_OS_THRESHOLD_DELTA ( 8 ) 112 | 113 | #define GET_UPDATE_OS_THRESHOLD( __x__ ) ( __x__ + UPDATE_OS_THRESHOLD_DELTA) 114 | 115 | // 116 | // Continue loop counter limit 117 | // 118 | #define SANITY_CHECK_LOOP_LIMIT ( 1 ) 119 | 120 | // 121 | // Scancode for the power button 122 | // Open issue: this should be changed to BL_SCAN_SUSPEND once 123 | // the changes make to mobilecore 124 | // 125 | #define POWER_BUTTON ( BL_SCAN_SUSPEND ) 126 | 127 | #define POWER_BUTTON_LONG_PRESS_DELAY ( 2 * SECONDS ) 128 | 129 | #define CHARGE_PAUSE_DELAY ( 300 * SECONDS ) 130 | 131 | // Overrides 132 | 133 | #define DEFAULT_BATTERY_CHARGING_MODE ( FALSE ) 134 | #define DEFAULT_CONNECTED_TO_SOURCE ( FALSE ) 135 | #define IS_GOING_TO_BATTERY_CHARGING_MODE ( FALSE ) 136 | 137 | // 138 | // This UI is calculated as an index into the ChargeGraphics array. 139 | // The array is a sequence of [ NOPLUG, PLUG ] elements, starting from 140 | // BATTERY_0 (empty battery), i.e [BATTERY_0, BATTERY_PLUG_0]. 141 | // Each duple following that is an increase of 10% of the battery. 142 | // 143 | // The UI is based on the Main OS System Tray data model available at: 144 | // \src\media\shell\product\shellevents\systemtraydatamodel.cpp 145 | // 146 | // In particular, this is the mapping: 147 | // 148 | // Battery % Image Level Index [PLUG, NOPLUG] 149 | // [0] BATTERY_0 [0,1] 150 | // [1,9] BATTERY_1 [2,3] 151 | // [10,19] BATTERY_2 [4,5] 152 | // [20,29] BATTERY_3 [6,7] 153 | // [30,39] BATTERY_4 [8,9] 154 | // [40,49] BATTERY_5 [10,11] 155 | // [50,59] BATTEYR_6 [12,13] 156 | // [60,69] BATTERY_7 [14,15] 157 | // [70,79] BATTERY_8 [16,17] 158 | // [80,89] BATTERY_9 [18,19] 159 | // [90,99] BATTERY_10 [20,21] 160 | // [100] BATTERY_11 [22,23] 161 | // 162 | // N.B. the case of 0 needs to be handled separately. For all other cases, 163 | // the following macro will work. 164 | // 165 | #define CHARGING_UI_NOPLUG( _b_ ) ( ( _b_ / 10 + 1 ) * 2 ) 166 | #define CHARGING_UI_PLUG( _b_ ) ( ( _b_ / 10 + 1 ) * 2 + 1 ) 167 | 168 | 169 | 170 | #define CONVERT_TO_CYCLES(__Seconds__, __Frequency__) \ 171 | (__Seconds__ * (__Frequency__ / (1000 * 1000))); 172 | 173 | 174 | // 175 | // Different states that the charging application 176 | // can be in 177 | // 178 | typedef enum _CHARGE_STATE 179 | { 180 | StateDefault, 181 | StateChargingUntilThreshold, 182 | StateBatteryChargingMode, 183 | StateUserInvokedChargeUntilThreshold 184 | } CHARGE_STATE; 185 | 186 | 187 | // 188 | // This enum is used to translate from platform-specific operation status into 189 | // charge app specific status 190 | // 191 | typedef enum _CHARGE_STATUS 192 | { 193 | None = 0, 194 | Success, 195 | Overheat, 196 | VoltageOutOfRange, 197 | CurrentOutOfRange, 198 | Timeout, 199 | Aborted, 200 | DeviceError, 201 | ExtremeCold, 202 | ChargingNotSupported, 203 | BatteryNotDetected, 204 | SourceNotDetected, 205 | SourceVoltageInvalid, 206 | SourceCurrentInvalid, 207 | RequestShutdown, 208 | RequestReboot, 209 | Pause 210 | 211 | } CHARGE_STATUS; 212 | 213 | 214 | 215 | NTSTATUS Sleep( UINT32 time ); 216 | 217 | NTSTATUS BatteryChargingProtocolInit(); 218 | 219 | NTSTATUS UpdateBatteryStatus(); 220 | 221 | NTSTATUS ChargeBattery(UINT32 MaximumCurrent, UINT32 TargetStateOfCharge); 222 | 223 | NTSTATUS Charge(UINT32 StateOfCharge, CHARGE_STATE State); 224 | 225 | NTSTATUS BatteryEventHandler(); 226 | 227 | NTSTATUS CloseCompletionTokenEvent(); 228 | 229 | NTSTATUS DestroyBatterySubsystem(); 230 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/chargelib.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | chargelib.c 8 | 9 | Abstract: 10 | 11 | Support functions for the charge app in EFI 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | 18 | --*/ 19 | 20 | #include "chargelib.h" 21 | 22 | // 23 | // Global to keep track of whether or not the USB protocol has been initialized 24 | // 25 | BOOLEAN UsbInit = FALSE; 26 | 27 | // 28 | // The boot device is used to query into 29 | // 30 | PBOOT_ENVIRONMENT_DEVICE ChargeBootDevice = NULL; 31 | 32 | // 33 | // Global for Battery threshold. 34 | // Battery levels below this should block booting to main os 35 | // Default it max limit 36 | // 37 | UINT32 Threshold = BATTERY_CHARGING_BOOT_THRESHOLD_LIMIT; 38 | 39 | 40 | NTSTATUS Initialize() 41 | /*++ 42 | 43 | Routine Description: 44 | 45 | Initialize display and Battery Charging protocol 46 | 47 | Arguments: 48 | 49 | None 50 | 51 | Return Value: 52 | 53 | NT status code. 54 | 55 | --*/ 56 | { 57 | NTSTATUS Status; 58 | 59 | // 60 | // Query boot device here so we can open the device & graphics file 61 | // 62 | Status = BlGetApplicationOptionDevice( BCDE_LIBRARY_TYPE_APPLICATION_DEVICE, 63 | &ChargeBootDevice, 64 | NULL); 65 | 66 | // Update provisioned permissions for various functionality 67 | UpdateProvisionedPermissions(); 68 | 69 | // 70 | // Initialize the display 71 | // 72 | Status = BlpDisplayInitialize((ULONG)0); 73 | if (!NT_SUCCESS(Status)) 74 | { 75 | return Status; 76 | } 77 | 78 | ConsoleSetCursor(0, 0); 79 | LinesPrinted = 0; 80 | 81 | // 82 | // Initialize the graphics subsystem. This will set up the ChargeGraphics 83 | // data structure 84 | // 85 | Status = InitGraphicsSubsystem(); 86 | if (!NT_SUCCESS(Status)) 87 | { 88 | return Status; 89 | } 90 | 91 | // 92 | // Initialize the Battery Charging Protocol on EFI systems. Does nothing on 93 | // PCAT 94 | // 95 | Status = BatteryChargingProtocolInit(); 96 | if (!NT_SUCCESS(Status)) 97 | { 98 | return Status; 99 | } 100 | 101 | return Status; 102 | 103 | } 104 | 105 | 106 | 107 | NTSTATUS DisplayErrorAndShutDown(DISPLAY_SCREEN DisplayScreen, UINT32 Delay) 108 | /*++ 109 | 110 | Routine Description: 111 | 112 | This function will display the DisplayScreen for Delay amount of time 113 | and then shut down the device 114 | 115 | Arguments: 116 | 117 | DisplayScreen: The display screen to show 118 | 119 | Delay: Amount of time to show it for. Please use macros defined 120 | in chargelib.h for unit of time 121 | 122 | Return Value: 123 | 124 | NT status code. 125 | 126 | --*/ 127 | { 128 | // 129 | // Display the UI 130 | // 131 | DisplayUI(DisplayScreen); 132 | 133 | // 134 | // Stall 135 | // 136 | Sleep(Delay); 137 | 138 | // 139 | // Shutdown. We do not expect this to fail 140 | // 141 | BlFwShutdown(); 142 | 143 | // 144 | // We do not expect to reach here 145 | // 146 | return STATUS_UNSUCCESSFUL; 147 | } 148 | 149 | 150 | 151 | NTSTATUS DisplayErrorAndStall(DISPLAY_SCREEN DisplayScreen) 152 | /*++ 153 | 154 | Routine Description: 155 | 156 | This will show an error screen and stall the device forever 157 | 158 | Arguments: 159 | 160 | DisplayScreen: The display screen to show 161 | 162 | Return Value: 163 | 164 | NT status code. 165 | 166 | --*/ 167 | { 168 | NTSTATUS Status; 169 | 170 | // 171 | // Ensure screen is ON 172 | // 173 | Status = TurnScreenOn(); 174 | if (!NT_SUCCESS(Status)) 175 | { 176 | goto End; 177 | } 178 | 179 | // 180 | // Display the screen 181 | // 182 | Status = DisplayUI(DisplayScreen); 183 | if(!NT_SUCCESS(Status)) 184 | { 185 | goto End; 186 | } 187 | 188 | // 189 | // Stall forever 190 | // 191 | for(;;) 192 | {} 193 | 194 | End: 195 | return Status; 196 | } 197 | 198 | 199 | 200 | NTSTATUS GetOemBatteryChargingMode(BOOLEAN *BatteryChargingMode) 201 | /*++ 202 | 203 | Routine Description: 204 | 205 | The Boot Charging app supports a "Battery Charging" mode, also called 206 | "OFF" charging mode. This is an OEM configurable, optional, mode. 207 | The OEM can set a flag in the BCD to enable or disable this mode. 208 | 209 | Read the BCD flag and return the BOOLEAN 210 | 211 | Arguments: 212 | 213 | BatteryChargingMode: Allocated memory block that will receive the 214 | boolean 215 | 216 | Return Value: 217 | 218 | NT status code. 219 | 220 | --*/ 221 | 222 | { 223 | NTSTATUS Status; 224 | BOOLEAN RetVal; 225 | 226 | if(NULL == BatteryChargingMode) 227 | { 228 | return STATUS_INVALID_PARAMETER; 229 | } 230 | 231 | // 232 | // Read the flag from the BCD 233 | // 234 | Status = BlGetApplicationOptionBoolean(BCDE_OEM_CHARGING_MODE_ENABLED, 235 | &RetVal ); 236 | // 237 | // If there are some errors, or if the flag is not defined, default it to 238 | // FALSE 239 | // 240 | if(!NT_SUCCESS(Status)) 241 | { 242 | RetVal = FALSE; 243 | } 244 | 245 | *BatteryChargingMode = RetVal; 246 | 247 | return Status; 248 | } 249 | 250 | 251 | 252 | NTSTATUS GetOemBatteryBootThreshold(UINT32 *Threshold) 253 | /*++ 254 | 255 | Routine Description: 256 | 257 | The threshold to boot into the main OS is configurable by the OEM as 258 | different devices will have different thresholds to boot into the OS 259 | 260 | Read that value from the BCD and return it 261 | 262 | Arguments: 263 | 264 | Threshold: Allocated block that will receive the threshold 265 | 266 | Return Value: 267 | 268 | NT status code. 269 | 270 | --*/ 271 | { 272 | NTSTATUS Status; 273 | ULONGLONG RetVal; 274 | 275 | if(NULL == Threshold) 276 | { 277 | return STATUS_INVALID_PARAMETER; 278 | } 279 | 280 | // 281 | // Read the value from the BCD 282 | // 283 | Status = BlGetApplicationOptionInteger(BCDE_OEM_CHARGING_BOOT_THRESHOLD, 284 | &RetVal ); 285 | 286 | // 287 | // If there is an error reading the flag or if it is not defined, 288 | // use the default value defined within the Boot Charging app 289 | // 290 | if(!NT_SUCCESS(Status)) 291 | { 292 | RetVal = BATTERY_CHARGING_BOOT_THRESHOLD; 293 | } 294 | 295 | // 296 | // For FRE builds, make sure that the threshold is not too high to avoid 297 | // being stuck in threshold charging mode 298 | // 299 | BLOCK_FRE 300 | ( 301 | *Threshold = (UINT32) RetVal; 302 | ) 303 | 304 | // 305 | // For CHK builds, just return the value as it is. It is useful to debug 306 | // threshold charging mode by setting the threshold to be very high 307 | // 308 | BLOCK_CHK 309 | ( 310 | *Threshold = (UINT32) RetVal; 311 | ) 312 | 313 | return Status; 314 | } 315 | 316 | 317 | 318 | NTSTATUS DestroyChargeLibraryBuffers() 319 | /*++ 320 | 321 | Routine Description: 322 | 323 | Free memory consumed by the various subsystems 324 | 325 | Arguments: 326 | 327 | None 328 | 329 | Return Value: 330 | 331 | NT status code. 332 | 333 | --*/ 334 | { 335 | 336 | NTSTATUS Status = STATUS_SUCCESS; 337 | NTSTATUS TempStatus = STATUS_SUCCESS; 338 | 339 | // 340 | // Get the last error value of a series of functions. 341 | // 342 | 343 | TempStatus = DestroyBatterySubsystem(); 344 | Status = TempStatus != STATUS_SUCCESS ? TempStatus : Status; 345 | 346 | TempStatus = DestroyGraphicsSubsystem(); 347 | Status = TempStatus != STATUS_SUCCESS ? TempStatus : Status; 348 | 349 | 350 | return Status; 351 | } 352 | 353 | NTSTATUS UpdateProvisionedPermissions() 354 | /*++ 355 | 356 | Routine Description: 357 | 358 | Updates provisioned permissions for various functionality 359 | and sets their corresponding flags for later use. 360 | 361 | Arguments: 362 | 363 | None. 364 | 365 | Return Value: 366 | 367 | NT status code. 368 | 369 | --*/ 370 | { 371 | NTSTATUS Status = STATUS_SUCCESS; 372 | DEVICE_ID BootDeviceID = INVALID_DEVICE_ID; 373 | FILE_ID UEFIChargingLogToDisplayFileID = INVALID_FILE_ID; 374 | 375 | UEFIChargingLogToDisplay = FALSE; 376 | 377 | CHARGING_LOGGING("charge: Updating provisioned permissions...\r\n"); 378 | 379 | Status = BlDeviceOpen(ChargeBootDevice, OPEN_READ_WRITE, &BootDeviceID); 380 | if (!NT_SUCCESS(Status)) 381 | { 382 | CHARGING_LOGGING("charge: Boot device not found\r\n"); 383 | goto UpdateProvisionedPermissionsEnd; 384 | } 385 | 386 | // Check for permission to show certain helpful log messages on the phone's screen 387 | Status = BlFileOpen(BootDeviceID, UEFI_CHARGING_LOG_TO_DISPLAY, OPEN_READ, &UEFIChargingLogToDisplayFileID); 388 | if (!NT_SUCCESS(Status)) 389 | { 390 | CHARGING_LOGGING("charge: UEFIChargingLogToDisplay.txt not found\r\n"); 391 | UEFIChargingLogToDisplay = FALSE; 392 | } 393 | else 394 | { 395 | CHARGING_LOGGING("charge: Found UEFIChargingLogToDisplay.txt\r\n"); 396 | UEFIChargingLogToDisplay = TRUE; 397 | } 398 | 399 | UpdateProvisionedPermissionsEnd: 400 | 401 | // 402 | // Log all results, close all file handles that were successfully opened, 403 | // then close the boot device handle if it was successfully opened. 404 | // 405 | 406 | CHARGING_LOGGING("charge: UEFIChargingLogToDisplay %d\r\n", UEFIChargingLogToDisplay); 407 | 408 | if (UEFIChargingLogToDisplayFileID != INVALID_FILE_ID) 409 | { 410 | BlFileClose(UEFIChargingLogToDisplayFileID); 411 | } 412 | 413 | if (BootDeviceID != INVALID_DEVICE_ID) 414 | { 415 | BlDeviceClose(BootDeviceID); 416 | } 417 | 418 | return Status; 419 | } 420 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/chargelib.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | chargelib.h 8 | 9 | Abstract: 10 | 11 | Internal header for the Boot Battery Charging application. 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // 26 | // Boot Charging Application Subsystems 27 | // 28 | #include "usbfn.h" 29 | #include "battery.h" 30 | #include "graphics.h" 31 | 32 | #define CHARGE_DEBUG_LOG 33 | 34 | #ifdef CHARGE_DEBUG_LOG 35 | #define ChargeLogPrint BootLogPrint 36 | #else 37 | #define ChargeLogPrint(...) ((void) 0) 38 | #endif 39 | 40 | BOOLEAN UEFIChargingLogToDisplay; 41 | BOOLEAN RenderTimeExpired; 42 | 43 | // Only going to print a specific number of lines 44 | int LinesPrinted; 45 | #define MAX_LINES_TO_PRINT 12 46 | 47 | // Take parameters in same order as used by BlDisplaySetCursorPosition for 48 | // consistency, but SIMPLE_TEXT_OUTPUT_INTERFACE.SetCursorPosition takes them 49 | // in swapped. As this is a macro, all the symbols it contains will be found 50 | // at run time just fine, as long as the right header files are included. 51 | #define EfiSetCursor(_VR, _HC) \ 52 | if (BlpArchQueryCurrentContextType() != ExecutionContextFirmware) \ 53 | { \ 54 | BlpArchSwitchContext(ExecutionContextFirmware); \ 55 | EfiConOut->SetCursorPosition(EfiST->ConOut, (_HC), (_VR)); \ 56 | BlpArchSwitchContext(ExecutionContextApplication); \ 57 | } \ 58 | else \ 59 | { \ 60 | EfiConOut->SetCursorPosition(EfiST->ConOut, (_HC), (_VR)); \ 61 | } 62 | 63 | #define PcatSetCursor(_VR, _HC) ((void) 0) 64 | 65 | #ifdef ConsoleSetCursor 66 | #undef ConsoleSetCursor 67 | #endif 68 | 69 | #ifdef EFI 70 | #define ConsoleSetCursor EfiSetCursor 71 | #endif 72 | 73 | #ifdef PCAT 74 | #define ConsoleSetCursor PcatSetCursor 75 | #endif 76 | 77 | #define LOG_TO_DISPLAY(__S__,...) \ 78 | if (RenderTimeExpired == FALSE && UEFIChargingLogToDisplay != FALSE) \ 79 | { \ 80 | if (++LinesPrinted > MAX_LINES_TO_PRINT) \ 81 | { \ 82 | LinesPrinted = 0; \ 83 | ConsoleSetCursor(0, 0); \ 84 | BlDisplayClearScreen(); \ 85 | } \ 86 | ConsolePrint(L ## __S__, __VA_ARGS__); \ 87 | } 88 | 89 | #define CHARGING_LOGGING(__S__,...) \ 90 | DebugConsolePrint(L ## __S__, __VA_ARGS__); \ 91 | ChargeLogPrint(__S__, __VA_ARGS__); \ 92 | LOG_TO_DISPLAY(__S__, __VA_ARGS__) 93 | 94 | #define BOOLIFY(expr) (!!(expr)) 95 | 96 | #define MILLI_SECONDS ( 1000 ) 97 | #define SECONDS ( 1000 * MILLI_SECONDS ) 98 | 99 | 100 | // 101 | // The log file 102 | // 103 | #define CHARGE_LOG_FILE_NAME L"\\Windows\\System32\\CHARGELOG.txt" 104 | 105 | // 106 | // Functionality files 107 | // 108 | #define UEFI_CHARGING_LOG_TO_DISPLAY L"\\Windows\\System32\\boot\\UEFIChargingLogToDisplay.txt" 109 | 110 | // ---------------------------------------------------------------------------- 111 | // 112 | // Charge Library Function Prototypes 113 | // 114 | // ---------------------------------------------------------------------------- 115 | 116 | NTSTATUS Initialize(); 117 | 118 | NTSTATUS DisplayErrorAndShutDown(DISPLAY_SCREEN DisplayScreen, UINT32 Delay); 119 | 120 | NTSTATUS DisplayErrorAndStall(DISPLAY_SCREEN DisplayScreen); 121 | 122 | NTSTATUS GetConnectedToPowerSource(BOOLEAN *ConnectedToPowerSource); 123 | 124 | NTSTATUS GetOemBatteryChargingMode(BOOLEAN *BatteryChargingMode); 125 | 126 | NTSTATUS GetOemBatteryBootThreshold(UINT32 *Threshold); 127 | 128 | NTSTATUS DestroyChargeLibraryBuffers(); 129 | 130 | NTSTATUS UpdateProvisionedPermissions(); 131 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/chargelibex.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) Microsoft. All rights reserved. 3 | // 4 | 5 | #pragma once 6 | #include 7 | 8 | typedef enum 9 | { 10 | StartChargeType_NormalOperation, // normal charging for normal boot 11 | StartChargeType_UserInvoked, // charge to threshold before doing a special operation like reset 12 | StartChargeType_DrainBattery, // DEBUG mode to drain the battery for testing 13 | StartChargeType_IgnoreFlags, // DEBUG mode to ignore flags that prevent or extend charging 14 | StartChargeType_MAXTYPES 15 | } StartChargeType; 16 | 17 | NTSTATUS StartCharge (StartChargeType ChargeType); 18 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/efiwrappers.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efiwrappers.h 8 | 9 | --*/ 10 | 11 | #pragma once 12 | 13 | #include "chargelib.h" 14 | #include "usbfnsupport.h" 15 | #include 16 | #include 17 | 18 | //----------------------------------------------------------------------------- 19 | // General Wrappers 20 | //----------------------------------------------------------------------------- 21 | 22 | 23 | 24 | //----------------------------------------------------------------------------- 25 | // EFI UsbFn Protocol Wrappers 26 | //----------------------------------------------------------------------------- 27 | 28 | NTSTATUS EfiUsbFnEventHandler( 29 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 30 | EFI_USBFN_MESSAGE *Message, 31 | UINTN *PayloadSize, 32 | EFI_USBFN_MESSAGE_PAYLOAD *Payload 33 | ); 34 | 35 | NTSTATUS EfiUsbFnConfigureEnableEndpoints( 36 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 37 | EFI_USB_DEVICE_INFO *DeviceInfo 38 | ); 39 | 40 | NTSTATUS EfiUsbFnDetectPort( 41 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 42 | EFI_USBFN_PORT_TYPE *PortType 43 | ); 44 | 45 | NTSTATUS EfiUsbFnAllocateTransferBuffer( 46 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 47 | UINTN Size, 48 | VOID **Buffer 49 | ); 50 | 51 | NTSTATUS EfiUsbFnFreeTransferBuffer( 52 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 53 | VOID *Buffer 54 | ); 55 | 56 | NTSTATUS EfiUsbFnGetEndpointMaxPacketSize( 57 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 58 | EFI_USB_ENDPOINT_TYPE EndpointType, 59 | EFI_USB_BUS_SPEED BusSpeed, 60 | UINT16 *MaxPacketSize 61 | ); 62 | 63 | NTSTATUS EfiUsbFnGetMaxTransferSize( 64 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 65 | UINTN *MaxTransferSize 66 | ); 67 | 68 | NTSTATUS EfiUsbFnGetDeviceInfo( 69 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 70 | EFI_USBFN_DEVICE_INFO_ID Id, 71 | UINTN *BufferSize, 72 | VOID *Buffer 73 | ); 74 | 75 | NTSTATUS EfiUsbFnGetVendorIdProductId( 76 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 77 | UINT16 *Vid, 78 | UINT16 *Pid 79 | ); 80 | 81 | NTSTATUS EfiUsbFnAbortTransfer( 82 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 83 | UINT8 EndpointIndex, 84 | EFI_USBFN_ENDPOINT_DIRECTION Direction 85 | ); 86 | 87 | NTSTATUS EfiUsbFnTransfer( 88 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 89 | UINT8 EndpointIndex, 90 | EFI_USBFN_ENDPOINT_DIRECTION Direction, 91 | UINTN *BufferSize, 92 | VOID *Buffer 93 | ); 94 | 95 | NTSTATUS EfiUsbFnGetEndpointStallState( 96 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 97 | UINT8 EndpointIndex, 98 | EFI_USBFN_ENDPOINT_DIRECTION Direction, 99 | BOOLEAN *State 100 | ); 101 | 102 | NTSTATUS EfiUsbFnSetEndpointStallState( 103 | EFI_USBFN_IO_PROTOCOL *EfiUsbFnProtocol, 104 | UINT8 EndpointIndex, 105 | EFI_USBFN_ENDPOINT_DIRECTION Direction, 106 | BOOLEAN State 107 | ); 108 | 109 | //----------------------------------------------------------------------------- 110 | // EFI Battery Charging Protocol wrappers 111 | //----------------------------------------------------------------------------- 112 | 113 | NTSTATUS EfiBatteryChargingGetBatteryStatus( 114 | EFI_BATTERY_CHARGING_PROTOCOL *EfiBatteryChargingProtocol, 115 | UINT32 *StateOfCharge, 116 | UINT32 *RatedCapacity, 117 | INT32 *CurrentIntoBattery 118 | ); 119 | 120 | NTSTATUS EfiBatteryChargingChargeBattery( 121 | EFI_BATTERY_CHARGING_PROTOCOL *EfiBatteryChargingProtocol, 122 | UINT32 MaximumCurrent, 123 | UINT32 TargetStateOfCharge, 124 | EFI_BATTERY_CHARGING_COMPLETION_TOKEN *CompletionToken 125 | ); 126 | 127 | NTSTATUS EfiBatteryChargingGetBatteryInformation( 128 | EFI_BATTERY_CHARGING_PROTOCOL *EfiBatteryChargingProtocol, 129 | UINT32 *StateOfCharge, 130 | INT32 *CurrentIntoBattery, 131 | UINT32 *BatteryTerminalVoltage, 132 | INT32 *BatteryTemperature, 133 | UINT32 *USBCableVoltage, 134 | UINT32 *USBCableCurrent 135 | ); 136 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/graphics.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) Microsoft. All rights reserved. 3 | // 4 | 5 | #pragma once 6 | #include 7 | 8 | #include 9 | 10 | 11 | NTSTATUS BlpDisplayInitialize (ULONG Flags); 12 | 13 | // 14 | // This enum is used to index into the CHARGE_IMAGE array 15 | // 16 | typedef enum _DISPLAY_SCREEN 17 | { 18 | BATTERY_0 = 0, // 0 19 | BATTERY_PLUG_0, // 1 20 | BATTERY_1, // 2 21 | BATTERY_PLUG_1, // 3 22 | BATTERY_2, // 4 23 | BATTERY_PLUG_2, // 5 24 | BATTERY_3, // 6 25 | BATTERY_PLUG_3, // 7 26 | BATTERY_4, // 8 27 | BATTERY_PLUG_4, // 9 28 | BATTERY_5, // 10 29 | BATTERY_PLUG_5, // 11 30 | BATTERY_6, // 12 31 | BATTERY_PLUG_6, // 13 32 | BATTERY_7, // 14 33 | BATTERY_PLUG_7, // 15 34 | BATTERY_8, // 16 35 | BATTERY_PLUG_8, // 17 36 | BATTERY_9, // 18 37 | BATTERY_PLUG_9, // 19 38 | BATTERY_10, // 20 39 | BATTERY_PLUG_10, // 21 40 | BATTERY_11, // 22 41 | BATTERY_PLUG_11, // 23 42 | BATTERY_1_RED, // 24 43 | BATTERY_PLUG_1_RED, // 25 44 | BATTERY_UNKNOWN, // 26 45 | BATTERY_LAST // 27 46 | 47 | } DISPLAY_SCREEN; 48 | 49 | // 50 | // This stores the Path of an image and its in memory buffer 51 | // 52 | typedef struct _CHARGE_IMAGE 53 | { 54 | PWSTR Path; 55 | PVOID Buffer; 56 | 57 | } CHARGE_IMAGE; 58 | 59 | 60 | 61 | #define GRAPHICS_DIR L"\\Windows\\System32\\boot\\ui\\boot.battery." 62 | #define GRAPHICS_FILE_EXT L".bmpx" 63 | #define GRAPHICS_PATH(__x__) GRAPHICS_DIR __x__ GRAPHICS_FILE_EXT 64 | 65 | #define SET_IMAGE(_w_, _x_, _y_) { _w_[_x_].Path = GRAPHICS_PATH(_y_); _w_[_x_].Buffer = NULL; } 66 | 67 | 68 | // 69 | // Time to delay the BATTERY_UNKNOWN screen before shutdown 70 | // 71 | #define BATTERY_ERROR_DELAY ( 8 * SECONDS ) 72 | 73 | // 74 | // Time to show the Low Battery UI before turning off the device 75 | // 76 | #define LOW_BATTERY_TURNOFF_DELAY ( 5 * SECONDS ) 77 | 78 | 79 | // 80 | // Time delay between alternating images 81 | // 82 | #define ANIMATION_DELAY ( 1 * SECONDS ) 83 | 84 | // 85 | // Screen timeout 86 | // 87 | #define SCREEN_TIMEOUT_DELAY ( 10 * SECONDS ) 88 | 89 | 90 | NTSTATUS DisplayInfo(); 91 | 92 | NTSTATUS DisplayUI(DISPLAY_SCREEN Screen); 93 | 94 | NTSTATUS DisplayAlternatingUI(DISPLAY_SCREEN ScreenA, DISPLAY_SCREEN ScreenB); 95 | 96 | NTSTATUS DisplayControl(); 97 | 98 | NTSTATUS InitGraphicsSubsystem(); 99 | 100 | NTSTATUS DestroyGraphicsSubsystem(); 101 | 102 | NTSTATUS TurnScreenOn(); 103 | 104 | NTSTATUS TurnScreenOff(); 105 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/usbfn.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | usbfn.h 8 | 9 | Abstract: 10 | 11 | This header file is inspired by the SimpleWinphoneIo interface. 12 | Exposes supported functionality for initializing the USBFn interface which 13 | will be consumed by the USB subsystem of the Boot Charging application 14 | 15 | Environment: 16 | 17 | Boot 18 | 19 | --*/ 20 | 21 | 22 | #pragma once 23 | 24 | #include "chargelib.h" 25 | #include 26 | 27 | // 28 | // Timeout before we can decide for sure what our connection 29 | // status is 30 | // 31 | #define USB_CONNECT_TIMEOUT ( 7 * SECONDS ) 32 | #define USB_ENUMERATION_TIMEOUT ( 5 * SECONDS ) 33 | 34 | NTSTATUS UsbFnProtocolInit(); 35 | 36 | NTSTATUS UsbFnEnumerate(); 37 | 38 | NTSTATUS GetUsbFnConnectionToHost(BOOLEAN *ConnectedToHost); 39 | 40 | NTSTATUS UsbFnEnumerateIfConnected(BOOLEAN *ConnectedToHost); 41 | 42 | NTSTATUS GetUsbConnectedToCharger(BOOLEAN *ConnectedToHost); 43 | 44 | NTSTATUS GetCurrentConnectionStatus(BOOLEAN *CurrentConnectionStatus); 45 | 46 | NTSTATUS DetectPort(); 47 | -------------------------------------------------------------------------------- /boot/environ/app/lib/charge/usbfnsupport.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | usbfnsupport.h 8 | 9 | Abstract: 10 | 11 | This header and usbfnsupport.c were ported from SimpleWinphoneIO 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | 18 | --*/ 19 | 20 | #pragma once 21 | 22 | #include "chargelib.h" 23 | #include 24 | #include 25 | #include 26 | #include "efiwrappers.h" 27 | 28 | 29 | 30 | #define EFI_USB_MAXIMUM_PACKET_SIZE (16376) //16K-8 31 | 32 | // 33 | // UsbFnIo interface 34 | // 35 | extern EFI_USBFN_IO_PROTOCOL *EfiUsbProtocol; 36 | 37 | // 38 | // Maximum transfer size 39 | // 40 | extern UINTN cMaxTransferSize; 41 | 42 | // 43 | // USB string descriptors 44 | // 45 | #define USBSERIALNUM_DEFAULT L"FFFFFFFFFFFF" 46 | #define MANUFACTURER_DEFAULT L"Microsoft" 47 | #define PRODUCT_DEFAULT L"Microsoft Simple IO Device" 48 | 49 | 50 | // 51 | // Internal transfer status 52 | // 53 | typedef enum _TRANSFER_STATUS 54 | { 55 | TransferStatusNone, 56 | TransferStatusOngoing, 57 | TransferStatusComplete, 58 | TransferStatusAborted 59 | } TRANSFER_STATUS; 60 | 61 | 62 | 63 | #define CONTROL_ENDPT 0 // Control endpoint 64 | #define BULKOUT_ENDPT 1 // Logical bulkout endpoint 65 | #define BULKIN_ENDPT 2 // Logical bulkin endpoint 66 | #define MAX_ENDPT CONTROL_ENDPT 67 | 68 | 69 | #define MAX_MSGBUF_SIZE (64) 70 | #define MAX_RXBUF_SIZE (cMaxTransferSize) 71 | 72 | #define EFIMSG_ERROR dprintf 73 | #define EFIMSG_VERBOSE dprintf 74 | #define EFIMSG_WARN dprintf 75 | #define EFIMSG_TRACE dprintf 76 | 77 | // Length from starting of USB_CONFIGURATION_DESCRIPTOR_TYPE to end (50) 78 | #define CONFIGDESC_LEN 42 79 | // Device (class) specific request 80 | #define SET_CONTROL_LINE_STATE 0x22 81 | // No message ever recvd on EP0 82 | #define EP0_MAX_MSG_RECV_BUFFER 4 83 | 84 | 85 | 86 | typedef volatile struct 87 | { 88 | UINT8* pbBuffer; 89 | UINT32 cbRequested; 90 | UINT32 cbCompleted; 91 | TRANSFER_STATUS status; 92 | } EPTransfer; 93 | 94 | 95 | 96 | 97 | extern UINT64 gIoReadWriteTimeoutIn100ns; 98 | 99 | extern EPTransfer cEpTransfers[]; 100 | extern EFI_USBFN_MESSAGE_PAYLOAD *cUsbFnMsgPayload; 101 | extern UINT8 *cRxBuffer; 102 | extern EFI_USB_BUS_SPEED cBusSpeed; 103 | 104 | #define EfiCopyMemory(_Destination, _Source, _Length) \ 105 | EfiBS->CopyMem(_Destination, _Source, _Length) 106 | 107 | 108 | 109 | #include 110 | typedef struct _USB_DEVICE_REQUEST { 111 | UCHAR bmRequestType; 112 | UCHAR bRequest; 113 | USHORT wValue; 114 | USHORT wIndex; 115 | USHORT wLength; 116 | } USB_DEVICE_REQUEST, *PUSB_DEVICE_REQUEST; 117 | typedef USB_DEVICE_REQUEST const * PCUSB_DEVICE_REQUEST; 118 | #include 119 | // 120 | #include 121 | 122 | // 123 | // HID constants 124 | // 125 | #define HID_GET_REPORT 0x01 126 | #define HID_GET_IDLE 0x02 127 | #define HID_GET_PROTOCOL 0x03 128 | #define HID_SET_REPORT 0x09 129 | #define HID_SET_IDLE 0x0A 130 | #define HID_SET_PROTOCOL 0x0B 131 | #define HID_DESCRIPTOR_TYPE_REPORT 0x22 132 | #define USB_HID_DESCRIPTOR_TYPE 0x21 133 | 134 | 135 | typedef struct _EFI_USB_HID_DESCRIPTOR 136 | { 137 | UCHAR bLength; 138 | UCHAR bDescriptorType; 139 | USHORT bcdHID; 140 | UCHAR bCountryCode; 141 | UCHAR bNumDescriptors; 142 | UCHAR bClassDescriptorType; 143 | USHORT wDescriptorLength; 144 | } EFI_USB_HID_DESCRIPTOR; 145 | 146 | // 147 | // This is to extend the USBFN spec to include HID 148 | // 149 | typedef struct _EFI_USB_HID_CONFIG_INFO 150 | { 151 | EFI_USB_CONFIG_DESCRIPTOR ConfigDescriptor; 152 | EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 153 | EFI_USB_HID_DESCRIPTOR HidDescriptor; 154 | EFI_USB_ENDPOINT_DESCRIPTOR EndpointInterruptIn; 155 | 156 | } EFI_USB_HID_CONFIG_INFO; 157 | 158 | 159 | 160 | #include 161 | 162 | #include 163 | typedef struct _USB_STRING_RESPONSE 164 | { 165 | // 166 | // Reference: USB Spec 2.0 Section 9.6.7 167 | // 168 | // String descriptors use UNICODE encodings and might support multiple 169 | // languages. The UNICODE string descriptor is *not* NULL terminated. The 170 | // string length is computed by subtracting two from the value of the first 171 | // byte of the descriptor. 172 | // 173 | // Above indicates that maximum size of the string can only be 253 bytes or 174 | // 126 wide characters. 175 | // 176 | USB_STRING_DESCRIPTOR hdr; 177 | UINT8 reserved[(MAXIMUM_USB_STRING_LENGTH - sizeof(WCHAR) - 2) / sizeof(UCHAR)]; 178 | } USB_STRING_RESPONSE; 179 | #include 180 | 181 | EFI_STATUS 182 | EventHandler( 183 | void 184 | ); 185 | 186 | EFI_STATUS 187 | GetChargerEndpointMaxPacketSize( 188 | void 189 | ); 190 | 191 | void 192 | ChargerIssueTransfer( 193 | UINT8 EndpointIndex, 194 | EFI_USBFN_ENDPOINT_DIRECTION Direction, 195 | UINT8 *pData, 196 | UINT32 cbData 197 | ); 198 | 199 | EFI_STATUS 200 | ConfigureEnableEndpoints( 201 | EFI_USBFN_IO_PROTOCOL *EfiUsbProtocol 202 | ); 203 | 204 | EFI_STATUS 205 | AllocBuffers( 206 | void 207 | ); 208 | 209 | EFI_STATUS 210 | FreeBuffers( 211 | void 212 | ); 213 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/arm/armentry.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | armentry.c 8 | 9 | Abstract: 10 | 11 | This module contains the entry point for an ARM OS Loader. 12 | 13 | Environment: 14 | 15 | Boot. 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "osloader.h" 22 | 23 | 24 | //--------------------------------------------------------------------- Defines 25 | 26 | //#define DBG_NEW_TRANSPORT 1 27 | 28 | 29 | // ------------------------------------------------------------------ Functions 30 | 31 | NTSTATUS 32 | OslMain ( 33 | __in PBOOT_APPLICATION_PARAMETERS Parameters 34 | ) 35 | 36 | /*++ 37 | 38 | Routine Description: 39 | 40 | Entry point for the x86-64 BIOS Boot OS Loader. 41 | 42 | Arguments: 43 | 44 | Parameters - Incoming parameters to the OS loader, including firmware 45 | specific handles and an allocated memory descriptor list. 46 | 47 | Return Value: 48 | 49 | Error code if fatal failure is experienced. 50 | 51 | --*/ 52 | 53 | { 54 | 55 | LIBRARY_PARAMETERS LibraryParameters; 56 | PBOOT_APPLICATION_RETURN_ARGUMENTS ReturnArgs; 57 | ULONG ReturnFlags; 58 | NTSTATUS Status; 59 | 60 | ReturnArgs = Add2Ptr(Parameters, Parameters->ReturnArgumentOffset); 61 | ReturnArgs->Version = BOOT_APPLICATION_RETURN_ARGUMENTS_VERSION; 62 | 63 | // 64 | // Initialize the boot environment library. 65 | // 66 | 67 | LibraryParameters = BlGetDefaultLibraryParameters(); 68 | LibraryParameters.FontDirectory = OSLOADER_DEFAULT_FONT_DIRECTORY; 69 | LibraryParameters.TranslationType = VA_TRANSLATION_TYPE_DEFAULT; 70 | LibraryParameters.HeapAllocationAttributes = 71 | MEMORY_ATTRIBUTE_ALLOCATION_KSEG; 72 | 73 | LibraryParameters.Flags |= LF_SVN_CHAIN_CHECK_SELF; 74 | LibraryParameters.Flags |= LF_NO_TCG_LOG_WRITETHROUGH; 75 | 76 | #ifdef DBG_NEW_TRANSPORT 77 | 78 | LibraryParameters.Flags |= LF_DEBUG_TRANSPORT; 79 | 80 | #endif 81 | 82 | // 83 | // Set the number of descriptors required to 512. This should be 84 | // sufficient to load ~1GB file 85 | // 86 | 87 | LibraryParameters.NumberOfDynamicDescriptors = 512; 88 | Status = BlInitializeLibrary(Parameters, &LibraryParameters); 89 | if (!NT_SUCCESS(Status)) { 90 | ReturnArgs->ReturnStatus = Status; 91 | return Status; 92 | } 93 | 94 | #ifdef DBG_NEW_TRANSPORT 95 | 96 | LibraryParameters = BlGetCurrentLibraryParameters(); 97 | LibraryParameters.Flags |= 98 | LF_BOOT_OPTIONS_INITIALIZED | LF_REINITIALIZE; 99 | 100 | Status = BlInitializeLibrary(Parameters, &LibraryParameters); 101 | 102 | #endif 103 | 104 | // 105 | // Call the OS Loader's Architecture and Platform independent entry point. 106 | // 107 | 108 | Status = OslpMain(&ReturnFlags); 109 | 110 | // 111 | // The loader has returned control. Record the information about why this 112 | // occurred and return to the boot manager. 113 | // 114 | 115 | ReturnArgs->ReturnStatus = Status; 116 | ReturnArgs->Flags = ReturnFlags; 117 | BlDestroyLibrary(); 118 | return Status; 119 | } 120 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/arm/armxfer.asm: -------------------------------------------------------------------------------- 1 | ;++ 2 | ; 3 | ; Copyright (c) Microsoft Corporation 4 | ; 5 | ; Module Name: 6 | ; 7 | ; armxfer.asm 8 | ; 9 | ; Abstract: 10 | ; 11 | ; ASM routines for transitioning control between the OS Loader and the 12 | ; OS Kernel. 13 | ; 14 | ; Environment: 15 | ; 16 | ; Boot Environment 17 | ; 18 | ;-- 19 | 20 | #include 21 | 22 | 23 | IMPORT OslArchKernelStack 24 | EXPORT OslArmTransferToKernel 25 | 26 | TEXTAREA 27 | 28 | ;++ 29 | ; 30 | ; VOID 31 | ; OslArmTransferToKernel ( 32 | ; IN PLOADER_PARAMETER_BLOCK LoaderBlock, 33 | ; IN PVOID KernelEntryPoint 34 | ; ); 35 | ; 36 | ; RoutineDescription - 37 | ; 38 | ; This routine will transfer execution from the OS loader to the kernel. 39 | ; 40 | ; Arguments: 41 | ; 42 | ; LoaderBlock (r0) - A pointer to the kernel's input parameter structure. 43 | ; 44 | ; KernelEntryPoint (r1) - Linear address to the kernel's entry point. 45 | ; 46 | ; Return Value: 47 | ; 48 | ; None. 49 | ; 50 | ;-- 51 | LEAF_ENTRY OslArmTransferToKernel 52 | 53 | ldr r2, =OslArchKernelStack ; Grab the kernel stack 54 | ldr sp, [r2] ; switch stacks 55 | bx r1 ; jump to the kernel 56 | 57 | LEAF_END OslArmTransferToKernel 58 | 59 | END 60 | 61 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/arm/detect.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | detect.c 8 | 9 | Abstract: 10 | 11 | This module contains code for detecting the appropriate kernel and hal 12 | type for an ARM system. 13 | 14 | Environment: 15 | 16 | Boot. 17 | 18 | Revision History: 19 | 20 | --*/ 21 | 22 | // ------------------------------------------------------------------- Includes 23 | 24 | #include "osloader.h" 25 | #include "acpitabl.h" 26 | 27 | // ---------------------------------------------------------------- Definitions 28 | 29 | #define ARM_KERNEL_NAME L"ntoskrnl.exe" 30 | #define ARM_HAL_NAME L"hal.dll" 31 | 32 | // ------------------------------------------------------------------ Functions 33 | 34 | NTSTATUS 35 | OslArchDetectKernelHal ( 36 | __inout PUNICODE_STRING KernelName, 37 | __inout PUNICODE_STRING HalName 38 | ) 39 | 40 | /*++ 41 | 42 | Routine Description: 43 | 44 | Determines the kernal and hal most appropriate for the executing 45 | platform. 46 | 47 | Memory will be allocated to hold the strings for the kernel and hal 48 | filename. The caller is responsible for freeing the memory. 49 | 50 | Arguments: 51 | 52 | KernelName - The name of the kernel to load. 53 | 54 | HalName - The name of the hal to load. 55 | 56 | Return Value: 57 | 58 | STATUS_SUCCESS when successful. 59 | STATUS_NO_MEMORY when a memory allocation fails. 60 | 61 | --*/ 62 | 63 | { 64 | 65 | BOOLEAN BoolRet; 66 | 67 | BoolRet = BlAppendUnicodeToString(KernelName, ARM_KERNEL_NAME); 68 | if (BoolRet == FALSE) { 69 | return STATUS_NO_MEMORY; 70 | } 71 | 72 | BoolRet = BlAppendUnicodeToString(HalName, ARM_HAL_NAME); 73 | if (BoolRet == FALSE) { 74 | return STATUS_NO_MEMORY; 75 | } 76 | 77 | return STATUS_SUCCESS; 78 | } 79 | 80 | NTSTATUS 81 | OslArchDetectUpdateLibrary ( 82 | __inout PUNICODE_STRING UpdateLibrary 83 | ) 84 | 85 | /*++ 86 | 87 | Routine Description: 88 | 89 | Determines the most appropriate microcode update library for the executing 90 | platform. This module does not check for the existence of the update 91 | library. This check is left to the caller to perform. 92 | 93 | Memory will be allocated to hold the string for the microcode update library 94 | filename. The caller is responsible for freeing the memory. 95 | 96 | Arguments: 97 | 98 | UpdateLibrary - Supplies a UNICODE_STRING that will be used to return the 99 | name of the update library to load. 100 | 101 | Return Value: 102 | 103 | STATUS_SUCCESS when successful. 104 | STATUS_NO_MEMORY when a memory allocation fails. 105 | STATUS_NOT_SUPPORTED if CPUID is not supported on this CPU. 106 | 107 | --*/ 108 | 109 | { 110 | UNREFERENCED_PARAMETER(UpdateLibrary); 111 | 112 | return STATUS_NOT_SUPPORTED; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/fipsmode.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | fipsmode.c 8 | 9 | Abstract: 10 | 11 | This module contains a routine for checking the FIPS mode flag in winload. 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | 19 | // 20 | // ------------------------------------------------------------------- Includes 21 | // 22 | 23 | #include "osloader.h" 24 | 25 | // 26 | // ---------------------------------------------------------------- Definitions 27 | // 28 | 29 | #define SYSTEM_KEY_NAME L"System" 30 | #define CURRENT_CONTROL_SET_KEY_NAME L"CurrentControlSet" 31 | #define CONTROL_KEY_NAME L"Control" 32 | #define LSA_KEY_NAME L"Lsa" 33 | #define FIPS_ALGORITHM_POLICY_KEY_NAME L"FipsAlgorithmPolicy" 34 | #define FIPS_MODE_VALUE_NAME L"Enabled" 35 | #define FIPS_MODE_MDM_VALUE_NAME L"MDMEnabled" 36 | 37 | #define POLICIES_KEY_NAME L"Policies" 38 | #define MICROSOFT_KEY_NAME L"Microsoft" 39 | #define CRYPTOGRAPHY_KEY_NAME L"Cryptography" 40 | #define CONFIGURATION_KEY_NAME L"Configuration" 41 | #define SELFTEST_ALGORITHMS_VALUE_NAME L"SelfTestAlgorithms" 42 | 43 | 44 | VOID 45 | OslCheckFipsMode ( 46 | __in ULONG HiveHandle, 47 | __in BOOLEAN bImcHiveHandle, 48 | __out PBOOLEAN pbFipsModeEnabled 49 | ) 50 | 51 | /*++ 52 | 53 | Routine Description: 54 | 55 | This routine checks if the flag is set in 4 registry keys and 56 | if one of them is set it returns TRUE. 57 | 58 | The 4 registry keys are: 59 | BCRYPT_CFG_FIPS_MODE_KEY: 60 | \HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\Enabled (DWORD) 61 | BCRYPT_CFG_LEGACY_FIPS_MODE_KEY: 62 | \HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy (DWORD) 63 | BCRYPT_MDM_FIPS_MODE_KEY: 64 | \HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\MDMEnabled (DWORD) 65 | BCRYPT_CRYPTO_CONFIG_KEY: 66 | \HKLM\SYSTEM\CurrentControlSet\Policies\Microsoft\Cryptography\Configuration\SelfTestAlgorithms (DWORD) 67 | 68 | Arguments: 69 | 70 | HiveHandle - Supplies a handle to the system hive or the IMC hive 71 | 72 | bImcHiveHandle - flag that is set if we got the IMC hive handle 73 | 74 | pbFipsModeEnabled - Supplies a pointer to a BOOLEAN that receives 75 | the results of the registry check. 76 | 77 | Return Value: 78 | 79 | None 80 | 81 | --*/ 82 | 83 | { 84 | NTSTATUS Status = STATUS_SUCCESS; 85 | 86 | // Registry cells 87 | PCM_KEY_NODE RootCell = NULL; 88 | PCM_KEY_NODE SystemCell = NULL; 89 | PCM_KEY_NODE CurrentControlSetCell = NULL; 90 | PCM_KEY_NODE ControlCell = NULL; 91 | PCM_KEY_NODE LsaCell = NULL; 92 | PCM_KEY_NODE FipsAlgorithmPolicyCell = NULL; 93 | PCM_KEY_NODE PoliciesCell = NULL; 94 | PCM_KEY_NODE MicrosoftCell = NULL; 95 | PCM_KEY_NODE CryptographyCell = NULL; 96 | PCM_KEY_NODE ConfigurationCell = NULL; 97 | 98 | 99 | // Registry results 100 | DWORD dwResult = 0; 101 | ULONG DataLength = 0; 102 | ULONG Type = 0; 103 | 104 | if (bImcHiveHandle) 105 | { 106 | // 107 | // IMC Hive 108 | // 109 | 110 | // RootCell 111 | RootCell = OslGetRootCell(HiveHandle); 112 | 113 | // System 114 | if (RootCell != NULL) 115 | { 116 | OslGetSubkey(HiveHandle, 117 | RootCell, 118 | SYSTEM_KEY_NAME, 119 | &SystemCell); 120 | } 121 | 122 | // CurrentControlSet 123 | if (SystemCell != NULL) 124 | { 125 | OslGetSubkey(HiveHandle, 126 | SystemCell, 127 | CURRENT_CONTROL_SET_KEY_NAME, 128 | &CurrentControlSetCell); 129 | } 130 | } 131 | else 132 | { 133 | // System Hive 134 | 135 | // CurrentControlSet 136 | OslGetSubkey(HiveHandle, 137 | NULL, 138 | NULL, 139 | &CurrentControlSetCell); 140 | } 141 | 142 | // 143 | // Key: \HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy 144 | // Value: Enabled (DWORD) 145 | // 146 | 147 | // Control 148 | if (CurrentControlSetCell != NULL) 149 | { 150 | OslGetSubkey(HiveHandle, 151 | CurrentControlSetCell, 152 | CONTROL_KEY_NAME, 153 | &ControlCell); 154 | } 155 | 156 | // Lsa 157 | if (ControlCell != NULL) 158 | { 159 | OslGetSubkey(HiveHandle, 160 | ControlCell, 161 | LSA_KEY_NAME, 162 | &LsaCell); 163 | } 164 | 165 | // FipsAlgorithmPolicy 166 | if (LsaCell != NULL) 167 | { 168 | OslGetSubkey(HiveHandle, 169 | LsaCell, 170 | FIPS_ALGORITHM_POLICY_KEY_NAME, 171 | &FipsAlgorithmPolicyCell); 172 | } 173 | 174 | // Enabled 175 | if (FipsAlgorithmPolicyCell != NULL) 176 | { 177 | DataLength = sizeof(dwResult); 178 | Status = OslGetValue(HiveHandle, 179 | FipsAlgorithmPolicyCell, 180 | FIPS_MODE_VALUE_NAME, 181 | &Type, 182 | &DataLength, 183 | (PBYTE)&dwResult); 184 | } 185 | 186 | 187 | if( NT_SUCCESS(Status) && 188 | (FipsAlgorithmPolicyCell != NULL) && 189 | Type == REG_DWORD && 190 | DataLength == sizeof(DWORD) && 191 | dwResult != 0) 192 | { 193 | // if the flag is set don't check the other locations 194 | goto OslCheckFipsModeEnd; 195 | } 196 | else 197 | { 198 | dwResult = 0; 199 | } 200 | 201 | // MDMEnabled 202 | if (FipsAlgorithmPolicyCell != NULL) 203 | { 204 | DataLength = sizeof(dwResult); 205 | Status = OslGetValue(HiveHandle, 206 | FipsAlgorithmPolicyCell, 207 | FIPS_MODE_MDM_VALUE_NAME, 208 | &Type, 209 | &DataLength, 210 | (PBYTE)&dwResult); 211 | } 212 | 213 | 214 | if( NT_SUCCESS(Status) && 215 | (FipsAlgorithmPolicyCell != NULL) && 216 | Type == REG_DWORD && 217 | DataLength == sizeof(DWORD) && 218 | dwResult != 0) 219 | { 220 | // if the flag is set don't check the other locations 221 | goto OslCheckFipsModeEnd; 222 | } 223 | else 224 | { 225 | dwResult = 0; 226 | } 227 | 228 | // 229 | // Key: \HKLM\System\CurrentControlSet\Control\Lsa 230 | // Value: FipsAlgorithmPolicy (DWORD) 231 | // 232 | 233 | // FipsAlgorithmPolicy 234 | if (LsaCell != NULL) 235 | { 236 | DataLength = sizeof(dwResult); 237 | Status = OslGetValue(HiveHandle, 238 | LsaCell, 239 | FIPS_ALGORITHM_POLICY_KEY_NAME, // Value name same as key name 240 | &Type, 241 | &DataLength, 242 | (PBYTE)&dwResult); 243 | } 244 | 245 | 246 | if( NT_SUCCESS(Status) && 247 | (LsaCell != NULL) && 248 | Type == REG_DWORD && 249 | DataLength == sizeof(DWORD) && 250 | dwResult != 0) 251 | { 252 | // if the flag is set don't check the other locations 253 | goto OslCheckFipsModeEnd; 254 | } 255 | else 256 | { 257 | dwResult = 0; 258 | } 259 | 260 | // 261 | // Key: \HKLM\SYSTEM\CurrentControlSet\Policies\Microsoft\Cryptography\Configuration 262 | // Value: SelfTestAlgorithms (DWORD) 263 | // 264 | 265 | // Policies 266 | if (CurrentControlSetCell != NULL) 267 | { 268 | OslGetSubkey(HiveHandle, 269 | CurrentControlSetCell, 270 | POLICIES_KEY_NAME, 271 | &PoliciesCell); 272 | } 273 | 274 | // Microsoft 275 | if (PoliciesCell != NULL) 276 | { 277 | OslGetSubkey(HiveHandle, 278 | PoliciesCell, 279 | MICROSOFT_KEY_NAME, 280 | &MicrosoftCell); 281 | } 282 | 283 | // Cryptography 284 | if (MicrosoftCell != NULL) 285 | { 286 | OslGetSubkey(HiveHandle, 287 | MicrosoftCell, 288 | CRYPTOGRAPHY_KEY_NAME, 289 | &CryptographyCell); 290 | } 291 | 292 | // Configuration 293 | if (CryptographyCell != NULL) 294 | { 295 | OslGetSubkey(HiveHandle, 296 | CryptographyCell, 297 | CONFIGURATION_KEY_NAME, 298 | &ConfigurationCell); 299 | } 300 | 301 | // SelfTestAlgorithms 302 | if (ConfigurationCell != NULL) 303 | { 304 | DataLength = sizeof(dwResult); 305 | Status = OslGetValue(HiveHandle, 306 | ConfigurationCell, 307 | SELFTEST_ALGORITHMS_VALUE_NAME, 308 | &Type, 309 | &DataLength, 310 | (PBYTE)&dwResult); 311 | } 312 | 313 | if( NT_SUCCESS(Status) && 314 | (ConfigurationCell != NULL) && 315 | Type == REG_DWORD && 316 | DataLength == sizeof(DWORD) && 317 | dwResult != 0) 318 | { 319 | // if the flag is set don't check the other locations 320 | goto OslCheckFipsModeEnd; 321 | } 322 | else 323 | { 324 | dwResult = 0; 325 | } 326 | 327 | OslCheckFipsModeEnd: 328 | 329 | *pbFipsModeEnabled = (dwResult!=0); 330 | 331 | } 332 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/mcupdate.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | mcupdate.c 8 | 9 | Abstract: 10 | 11 | Routines required to load microcode update on boot processor. 12 | 13 | Environment: 14 | 15 | Boot Environment. 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "osloader.h" 22 | #include "mcupdate.h" 23 | 24 | #pragma warning( disable : 4055 ) 25 | 26 | // -------------------------------------------------------------------- Globals 27 | 28 | PMCUPDATEMICROCODEFUNC McpUpdateMicrocodeFunc = NULL; 29 | 30 | // ----------------------------------------------------------------- Prototypes 31 | 32 | typedef 33 | NTSTATUS 34 | (*PMCUPDATEENTRYPOINT)( 35 | __out PMCUPDATE_FUNCTIONS ExportedFunctions, 36 | __in PMCUPDATE_DLL_DEPENDENCIES ImportedFunctions 37 | ); 38 | 39 | NTSTATUS 40 | McpUpdateInitialize ( 41 | __in PLOADER_PARAMETER_BLOCK LoaderBlock 42 | ); 43 | 44 | PKLDR_DATA_TABLE_ENTRY 45 | McpUpdateFindDataTableEntry ( 46 | __in PLIST_ENTRY DataTableEntryList 47 | ); 48 | 49 | PVOID 50 | McpMemoryLockStub ( 51 | __in PVOID UnusedParam 52 | ); 53 | 54 | VOID 55 | McpMemoryLockByHandleStub ( 56 | __in PVOID UnusedParam 57 | ); 58 | 59 | NTSTATUS 60 | McpMemoryUnlockStub ( 61 | __in PVOID UnusedParam 62 | ); 63 | 64 | NTSTATUS 65 | McpUpdateMicrocode ( 66 | VOID 67 | ); 68 | 69 | ULONG 70 | McpReadPciConfig ( 71 | __in ULONG BusNumber, 72 | __in ULONG SlotNumber, 73 | __out_bcount(Length) PVOID Buffer, 74 | __in ULONG Offset, 75 | __in ULONG Length 76 | ); 77 | 78 | // ------------------------------------------------------------------ Functions 79 | 80 | NTSTATUS 81 | OslLoadMicrocode ( 82 | __in PLOADER_PARAMETER_BLOCK LoaderBlock 83 | ) 84 | 85 | /*++ 86 | 87 | Routine Description: 88 | 89 | This routine will initialize the internal structures required to perform 90 | microcode update and then triggers application of microcode update. 91 | 92 | Arguments: 93 | 94 | LoaderBlock - A pointer to the loader parameter block. 95 | 96 | Return Value: 97 | 98 | NT status code. 99 | 100 | --*/ 101 | 102 | { 103 | NTSTATUS Status; 104 | 105 | Status = McpUpdateInitialize(LoaderBlock); 106 | if (!NT_SUCCESS(Status)) { 107 | goto LoadMicrocodeExit; 108 | } 109 | 110 | // 111 | // Update the processor microcode now. 112 | // 113 | 114 | McpUpdateMicrocode(); 115 | 116 | LoadMicrocodeExit: 117 | 118 | return Status; 119 | } 120 | 121 | 122 | NTSTATUS 123 | McpUpdateInitialize ( 124 | __in PLOADER_PARAMETER_BLOCK LoaderBlock 125 | ) 126 | 127 | /*++ 128 | 129 | Routine Description: 130 | 131 | This function initializes the microcode update architecture. It should be 132 | called before any attempt is made to update microcode from a loaded 133 | microcode update DLL. 134 | 135 | Arguments: 136 | 137 | LoaderBlock - A pointer to the loader parameter block. 138 | 139 | Return Value: 140 | 141 | NT status code. 142 | 143 | --*/ 144 | 145 | { 146 | PKLDR_DATA_TABLE_ENTRY DataTableEntry; 147 | PMCUPDATEENTRYPOINT EntryPoint; 148 | MCUPDATE_FUNCTIONS Functions; 149 | PLIST_ENTRY LoadedModuleList; 150 | NTSTATUS Status; 151 | MCUPDATE_DLL_DEPENDENCIES UpdateDllImportedFunctions; 152 | 153 | Status = STATUS_SUCCESS; 154 | DataTableEntry = NULL; 155 | 156 | McpUpdateMicrocodeFunc = NULL; 157 | 158 | // 159 | // Initialize the function dependencies for the update dll. 160 | // 161 | 162 | UpdateDllImportedFunctions.ReadPciConfig = McpReadPciConfig; 163 | UpdateDllImportedFunctions.LockPagableCodeSection = McpMemoryLockStub; 164 | UpdateDllImportedFunctions.LockPagableDataSection = McpMemoryLockStub; 165 | UpdateDllImportedFunctions.LockPagableSectionByHandle = 166 | McpMemoryLockByHandleStub; 167 | UpdateDllImportedFunctions.UnlockPagableImageSection = 168 | (PMCUPDATE_UNLOCK_PAGABLE_IMAGE_SECTION) McpMemoryUnlockStub; 169 | 170 | // 171 | // Determine whether a microcode update module has been loaded. If one has 172 | // been loaded, then determine the entry point and call it. This will yield 173 | // pointers to the functions required to perform microcode update. These 174 | // pointers must be stored for use when microcode update is required. 175 | // 176 | 177 | if (LoaderBlock == NULL) { 178 | ASSERT(FALSE); 179 | goto InitializeEnd; 180 | } 181 | 182 | LoadedModuleList = &LoaderBlock->LoadOrderListHead; 183 | DataTableEntry = McpUpdateFindDataTableEntry(LoadedModuleList); 184 | 185 | // 186 | // If microcode update module was not loaded nothing needs to be done. 187 | // 188 | 189 | if (DataTableEntry == NULL) { 190 | goto InitializeEnd; 191 | } 192 | 193 | EntryPoint = (PMCUPDATEENTRYPOINT)DataTableEntry->EntryPoint; 194 | 195 | Status = (NTSTATUS)EntryPoint(&Functions, &UpdateDllImportedFunctions); 196 | 197 | if (!NT_SUCCESS(Status)) { 198 | goto InitializeEnd; 199 | } 200 | 201 | McpUpdateMicrocodeFunc = Functions.MicrocodeFunc; 202 | 203 | InitializeEnd: 204 | 205 | return Status; 206 | } 207 | 208 | 209 | PKLDR_DATA_TABLE_ENTRY 210 | McpUpdateFindDataTableEntry ( 211 | __in PLIST_ENTRY DataTableEntryList 212 | ) 213 | 214 | /*++ 215 | 216 | Routine Description: 217 | 218 | This routine traverses the provided data table entry list in search of the 219 | entry for the microcode update library. 220 | 221 | Arguments: 222 | 223 | DataTableEntryList - Linked list of LDR_DATA_TABLE_ENTRYs. 224 | 225 | Return Value: 226 | 227 | A pointer to the data table entry for the specified image. 228 | 229 | NULL if there does not exist an entry for the image. 230 | 231 | --*/ 232 | 233 | { 234 | UNICODE_STRING CompareName = RTL_CONSTANT_STRING (L"mcupdate.dll"); 235 | PUNICODE_STRING EntryName; 236 | PKLDR_DATA_TABLE_ENTRY Entry; 237 | PLIST_ENTRY Index; 238 | 239 | // 240 | // Walk the specified loaded image list until the requested image is found, 241 | // or the end of the loaded image list is reached. 242 | // 243 | 244 | for (Index = DataTableEntryList->Flink; 245 | Index != DataTableEntryList; 246 | Index = Index->Flink) { 247 | 248 | Entry = CONTAINING_RECORD(Index, 249 | KLDR_DATA_TABLE_ENTRY, 250 | InLoadOrderLinks); 251 | 252 | EntryName = &Entry->BaseDllName; 253 | 254 | if (EntryName->Length != CompareName.Length) { 255 | continue; 256 | } 257 | 258 | if (_wcsicmp(EntryName->Buffer, CompareName.Buffer) == 0) { 259 | return Entry; 260 | } 261 | } 262 | 263 | return NULL; 264 | } 265 | 266 | 267 | PVOID 268 | McpMemoryLockStub ( 269 | __in PVOID UnusedParam 270 | ) 271 | { 272 | UNREFERENCED_PARAMETER(UnusedParam); 273 | 274 | return NULL; 275 | } 276 | 277 | 278 | VOID 279 | McpMemoryLockByHandleStub ( 280 | __in PVOID UnusedParam 281 | ) 282 | { 283 | UNREFERENCED_PARAMETER(UnusedParam); 284 | } 285 | 286 | NTSTATUS 287 | McpMemoryUnlockStub ( 288 | __in PVOID UnusedParam 289 | ) 290 | { 291 | UNREFERENCED_PARAMETER(UnusedParam); 292 | 293 | return STATUS_SUCCESS; 294 | } 295 | 296 | 297 | NTSTATUS 298 | McpUpdateMicrocode ( 299 | VOID 300 | ) 301 | 302 | /*++ 303 | 304 | Routine Description: 305 | 306 | This routine performs the microcode update. 307 | 308 | Arguments: 309 | 310 | None. 311 | 312 | Return Value: 313 | 314 | NT status code. 315 | 316 | --*/ 317 | 318 | { 319 | NTSTATUS Status; 320 | 321 | Status = STATUS_SUCCESS; 322 | 323 | if (McpUpdateMicrocodeFunc != NULL) { 324 | Status = McpUpdateMicrocodeFunc(MC_UPDATE_RESIDENT, 0); 325 | } 326 | 327 | return Status; 328 | } 329 | 330 | 331 | ULONG 332 | McpReadPciConfig ( 333 | __in ULONG BusNumber, 334 | __in ULONG SlotNumber, 335 | __out_bcount(Length) PVOID Buffer, 336 | __in ULONG Offset, 337 | __in ULONG Length 338 | ) 339 | 340 | /*++ 341 | 342 | Routine Description: 343 | 344 | This routine is provided so that the microcode update module can access PCI 345 | configuration space to obtain information to assist in its decision making 346 | flow. The microcode update module is only permitted to access configuration 347 | space on bus 0, and then only the first 256 bytes of each device. 348 | 349 | Arguments: 350 | 351 | BusNumber - Supplies the bus number to be accessed. This is currently 352 | to bus 0. 353 | 354 | Slot - Supplies the slot number (device/function number) of the device to 355 | access. 356 | 357 | Buffer - Supplies the space to store the data. 358 | 359 | Offset - Supplies the offset into configuration space to access. 360 | 361 | Length - Supplies a count in bytes of the maximum amount to return. 362 | 363 | Return Value: 364 | 365 | Lenght of the PCI config space read.into the given Buffer. 366 | 367 | -*/ 368 | 369 | { 370 | NTSTATUS Status; 371 | PCI_CONFIG_ADDRESS DeviceAddress; 372 | PCI_SLOT_NUMBER Slot; 373 | 374 | Status = STATUS_SUCCESS; 375 | 376 | // 377 | // The microcode update module is only permitted to access configuration 378 | // space on bus 0, and then only the first 256 bytes of each device. 379 | // 380 | 381 | if (BusNumber > 0) { 382 | return 0; 383 | } 384 | 385 | if (Length + Offset > 256 ) { 386 | if (Offset > 256) { 387 | return 0; 388 | } 389 | 390 | Length = 256 - Offset; 391 | } 392 | 393 | Slot.u.AsULONG = SlotNumber; 394 | 395 | DeviceAddress.Segment = 0; 396 | DeviceAddress.Bus = (UCHAR)BusNumber; 397 | DeviceAddress.Device = (UCHAR)Slot.u.bits.DeviceNumber; 398 | DeviceAddress.Function = (UCHAR)Slot.u.bits.FunctionNumber; 399 | 400 | Status = BlPltReadPciConfig(&DeviceAddress, 401 | Buffer, 402 | Offset, 403 | Length); 404 | 405 | if (!NT_SUCCESS(Status)) { 406 | Length = 0; 407 | } 408 | 409 | return Length; 410 | } 411 | 412 | 413 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/oskstack.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | oskstack.c 8 | 9 | Abstract: 10 | 11 | NTOS Kernel stack support. 12 | 13 | Environment: 14 | 15 | Boot Environment. 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "osloader.h" 22 | #include 23 | 24 | // ------------------------------------------------------------------ Functions 25 | 26 | #if defined(_X86_) || defined (_AMD64_) 27 | 28 | #define ROUNDUP64(x) (((x) + 63) & ~63) 29 | 30 | 31 | ULONG 32 | OslpArchDetectXSaveAreaSize ( 33 | __inout PLOADER_PARAMETER_BLOCK LoaderBlock 34 | ) 35 | 36 | /*++ 37 | 38 | Routine Description: 39 | 40 | Determines the footprint of the FXSAVE (or XSAVE, if available) buffer, 41 | including all available features. 42 | 43 | N.B. Determining footprint of the FXSAVE (or XSAVE) buffer is done 44 | during kernel initialization also. 45 | 46 | Arguments: 47 | 48 | None. 49 | 50 | Return Value: 51 | 52 | Size of the FXSAVE/XSAVE buffer. 53 | 54 | --*/ 55 | 56 | { 57 | 58 | ULONG64 ConfigAllowedFeatures; 59 | ULONG ConfigExtendedStateFlags; 60 | ULONG64 CpuEnabledUserFeatures; 61 | ULONG64 CpuEnabledSupervisorFeatures; 62 | ULONG64 CpuEnabledAllFeatures; 63 | CPUID_INFO CpuInfo; 64 | ULONG Index; 65 | ULONG XSaveSize; 66 | 67 | // 68 | // Check if XSAVE is even supported. 69 | // 70 | 71 | XSaveSize = FIELD_OFFSET(XSAVE_AREA, Header); 72 | CpuEnabledUserFeatures = 0; 73 | CpuEnabledSupervisorFeatures = 0; 74 | BlArchCpuId(0x1, 0, &CpuInfo); 75 | if ((CpuInfo.Ecx & (1UL << 26)) == 0) { 76 | goto calc_complete; 77 | } 78 | 79 | // 80 | // XSAVE is supported. Determine the user and supervisor features enabled. 81 | // 82 | 83 | XSaveSize += sizeof(XSAVE_AREA_HEADER); 84 | ConfigAllowedFeatures = LoaderBlock->Extension->XsaveAllowedFeatures; 85 | ConfigExtendedStateFlags = LoaderBlock->Extension->XsaveFlags; 86 | 87 | BlArchCpuId(0xd, 0, &CpuInfo); 88 | CpuEnabledUserFeatures = ((ULONG64)(CpuInfo.Eax)) | 89 | (((ULONG64)(CpuInfo.Edx)) << 32); 90 | 91 | CpuEnabledUserFeatures = CpuEnabledUserFeatures & (ConfigAllowedFeatures | XSTATE_MASK_LEGACY); 92 | 93 | // 94 | // If XSAVEC/XSAVES are supported and has been enabled, retrieve the 95 | // supervisor features available, and calculate size of XSAVE buffer in 96 | // compacted format. 97 | // 98 | 99 | BlArchCpuId(0xd, 1, &CpuInfo); 100 | if (((CpuInfo.Eax & (1UL << 1)) && (CpuInfo.Eax & (1UL << 3))) && 101 | ((ConfigExtendedStateFlags & XSAVE_FLAG_ENABLE_XSAVEC) != 0)) { 102 | 103 | CpuEnabledSupervisorFeatures = ((ULONG64)(CpuInfo.Ecx)) | 104 | (((ULONG64)(CpuInfo.Edx)) << 32); 105 | 106 | CpuEnabledSupervisorFeatures = CpuEnabledSupervisorFeatures & ConfigAllowedFeatures; 107 | CpuEnabledAllFeatures = CpuEnabledUserFeatures | CpuEnabledSupervisorFeatures; 108 | for (Index = XSTATE_GSSE; Index < MAXIMUM_XSTATE_FEATURES; Index += 1) { 109 | if ((CpuEnabledAllFeatures & (1ui64 << Index)) != 0) { 110 | BlArchCpuId(0xd, Index, &CpuInfo); 111 | 112 | // 113 | // Checking if ECX[1] is set to 1. This indicates if the start offset of the state 114 | // in the XSAVE buffer should be aligned to a 64 byte boundary. 115 | // 116 | 117 | if ((CpuInfo.Ecx & XSTATE_ALIGN_MASK) != 0) { 118 | XSaveSize = ROUNDUP64(XSaveSize); 119 | } 120 | 121 | XSaveSize += CpuInfo.Eax; 122 | } 123 | } 124 | 125 | goto calc_complete; 126 | } 127 | 128 | // 129 | // If XSAVE is supported, but not XSAVEC/XSAVES, calculate size of XSAVE 130 | // buffer in legacy format. 131 | // 132 | 133 | for (Index = XSTATE_GSSE; Index < MAXIMUM_XSTATE_FEATURES; Index += 1) { 134 | if (CpuEnabledUserFeatures & (1ui64 << Index)) { 135 | BlArchCpuId(0xd, Index, &CpuInfo); 136 | if (XSaveSize < CpuInfo.Ebx + CpuInfo.Eax) { 137 | XSaveSize = CpuInfo.Ebx + CpuInfo.Eax; 138 | } 139 | } 140 | } 141 | 142 | calc_complete: 143 | 144 | LoaderBlock->Extension->XsaveAllowedFeatures = CpuEnabledUserFeatures | 145 | CpuEnabledSupervisorFeatures; 146 | 147 | return XSaveSize; 148 | } 149 | 150 | VOID 151 | OslReadXsaveRegistryValues( 152 | __in ULONG SystemHiveHandle, 153 | __out PLOADER_PARAMETER_BLOCK LoaderBlock 154 | ) 155 | { 156 | 157 | ULONG64 AllowedFeatures; 158 | ULONG ExtendedStateFlags; 159 | 160 | // 161 | // N.B. These values are filled in for Xbox System OS in 162 | // %BaseDir%\xbox\lnm\bldtools\makevbi\paramblk.cpp: 163 | // VbiBuildLoaderParameterBlock. 164 | // 165 | 166 | if (!OslGetExtendedStateAllowedFeatures(SystemHiveHandle, 167 | &AllowedFeatures)) { 168 | 169 | // 170 | // If AllowedFeatures registry value is not defined, Allow x87, SSE, AVX 171 | // MPX and AVX512. 172 | // 173 | 174 | AllowedFeatures = XSTATE_MASK_LEGACY | 175 | XSTATE_MASK_AVX | 176 | XSTATE_MASK_MPX | 177 | XSTATE_MASK_AVX512; 178 | 179 | } else { 180 | AllowedFeatures &= XSTATE_MASK_ALLOWED; 181 | AllowedFeatures |= XSTATE_MASK_LEGACY; 182 | } 183 | 184 | if (!OslGetExtendedStateFlags(SystemHiveHandle, &ExtendedStateFlags)) { 185 | 186 | // 187 | // If Flags registry value is not defined, assume xsaveopt and xsavec 188 | // are allowed. 189 | // 190 | 191 | ExtendedStateFlags = XSAVE_FLAG_ENABLE_XSAVEOPT | 192 | XSAVE_FLAG_ENABLE_XSAVEC; 193 | 194 | } 195 | 196 | // 197 | // C requires OPT 198 | // 199 | 200 | if ((ExtendedStateFlags & XSAVE_FLAG_ENABLE_XSAVEOPT) == 0) { 201 | ExtendedStateFlags &= ~XSAVE_FLAG_ENABLE_XSAVEC; 202 | } 203 | 204 | #if defined(_AMD64_) 205 | 206 | if (OslArchHvlInitialized() != FALSE) { 207 | AllowedFeatures &= HV_X64_XSAVE_SUPPORTED_FEATURES; 208 | } 209 | 210 | #endif 211 | 212 | LoaderBlock->Extension->XsaveFlags = ExtendedStateFlags; 213 | LoaderBlock->Extension->XsaveAllowedFeatures = AllowedFeatures; 214 | 215 | return; 216 | } 217 | 218 | #endif 219 | 220 | ULONG 221 | OslDetermineKernelStackSize ( 222 | __inout PLOADER_PARAMETER_BLOCK LoaderBlock 223 | ) 224 | 225 | /*++ 226 | 227 | Routine Description: 228 | 229 | Determines the footprint of the FXSAVE (or XSAVE, if available) buffer, 230 | including all available features. 231 | 232 | Arguments: 233 | 234 | None. 235 | 236 | Return Value: 237 | 238 | Size of the FXSAVE/XSAVE buffer. 239 | 240 | --*/ 241 | 242 | { 243 | 244 | #if defined(_X86_) || defined (_AMD64_) 245 | 246 | ULONG StackSize; 247 | ULONG XSaveSize; 248 | 249 | XSaveSize = OslpArchDetectXSaveAreaSize(LoaderBlock); 250 | if (XSaveSize <= XSTATE_STACK_NEW_PAGE_THRESHOLD) { 251 | return KERNEL_STACK_SIZE; 252 | } 253 | 254 | StackSize = KERNEL_STACK_SIZE; 255 | StackSize += ALIGN_RANGE_UP(XSaveSize - XSTATE_STACK_NEW_PAGE_THRESHOLD, 256 | PAGE_SIZE); 257 | 258 | ASSERT(StackSize > KERNEL_STACK_SIZE); 259 | 260 | if (StackSize > (KERNEL_LARGE_STACK_SIZE - PAGE_SIZE)) { 261 | return (KERNEL_LARGE_STACK_SIZE - PAGE_SIZE); 262 | } 263 | 264 | return StackSize; 265 | 266 | #else 267 | 268 | UNREFERENCED_PARAMETER(LoaderBlock); 269 | 270 | return KERNEL_STACK_SIZE; 271 | 272 | #endif 273 | 274 | } 275 | 276 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/resmcntx.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | resmcntx.c 8 | 9 | Abstract: 10 | 11 | Implementation of resume context support for passing information 12 | between the loader and resume boot applications. 13 | 14 | Environment: 15 | 16 | Boot Environment. 17 | 18 | --*/ 19 | 20 | // 21 | // ------------------------------------------------------------------- Includes 22 | // 23 | 24 | #include "osloader.h" 25 | 26 | // 27 | // -------------------------------------------------------------------- Globals 28 | // 29 | 30 | PRESUME_CONTEXT ResumeContext = NULL; 31 | 32 | // 33 | // ---------------------------------------------------------- Private Functions 34 | // 35 | 36 | ULONG 37 | OslpGetBootFootPrintSize ( 38 | __in DEVICE_ID OsDeviceId 39 | ); 40 | 41 | // 42 | // ------------------------------------------------------------------ Functions 43 | // 44 | 45 | NTSTATUS 46 | OslDestroyResumeContext ( 47 | VOID 48 | ) 49 | 50 | /*++ 51 | 52 | Routine Description: 53 | 54 | This routine destroys the resume context in cases where the loader fails. 55 | 56 | Arguments: 57 | 58 | None. 59 | 60 | Return Value: 61 | 62 | NT status code. 63 | 64 | --*/ 65 | 66 | { 67 | 68 | GENERIC_BUFFER PersistentData; 69 | GUID ResumeContextGUID = RESUME_CONTEXT_GUID; 70 | NTSTATUS Status; 71 | 72 | Status = STATUS_SUCCESS; 73 | if (ResumeContext != NULL) { 74 | BlInitGenericBuffer(&PersistentData, 75 | ResumeContext, 76 | ResumeContext->Size); 77 | 78 | Status = BlPdFreeData(NULL, &ResumeContextGUID, &PersistentData); 79 | ResumeContext = NULL; 80 | } 81 | 82 | return Status; 83 | } 84 | 85 | NTSTATUS 86 | OslInitializeResumeContext ( 87 | VOID 88 | ) 89 | 90 | /*++ 91 | 92 | Routine Description: 93 | 94 | This routine creates the resume context that gets passed to the resume 95 | application during resume from hibernate. 96 | 97 | Arguments: 98 | 99 | None. 100 | 101 | Return Value: 102 | 103 | NT status code. 104 | 105 | --*/ 106 | 107 | { 108 | 109 | PMEMORY_DESCRIPTOR Descriptor; 110 | LIST_ENTRY MemoryMap; 111 | GENERIC_BUFFER MemoryMapDescriptors; 112 | PLIST_ENTRY NextEntry; 113 | GENERIC_BUFFER PersistentData; 114 | GUID ResumeContextGUID = RESUME_CONTEXT_GUID; 115 | PMEMORY_DESCRIPTOR ResumeDescriptor; 116 | NTSTATUS Status; 117 | 118 | BlInitGenericBuffer(&MemoryMapDescriptors, NULL, 0); 119 | BlInitGenericBuffer(&PersistentData, NULL, 0); 120 | 121 | // 122 | // Obtain a copy of the firmware memory map. Get the non-coalesced version 123 | // so all firmware runtime regions get their own descriptor. 124 | // 125 | 126 | Status = BlMmGetMemoryMap(&MemoryMap, 127 | &MemoryMapDescriptors, 128 | MEMORYMAP_TYPE_FIRMWARE_NOT_COALESCED, 129 | MDL_FLAGS_ALLOCATE_DESCRIPTORS); 130 | 131 | if (!NT_SUCCESS(Status)) { 132 | goto InitializeResumeContextEnd; 133 | } 134 | 135 | // 136 | // Allocate a persistent buffer for the resume context. 137 | // 138 | 139 | PersistentData.DataSize = FIELD_OFFSET(RESUME_CONTEXT, PhysicalMemoryMap) + 140 | MemoryMapDescriptors.DataSize; 141 | 142 | Status = BlPdAllocateData(NULL, 143 | &ResumeContextGUID, 144 | MEMORY_ATTRIBUTE_ALLOCATION_KSEG, 145 | &PersistentData); 146 | 147 | if (!NT_SUCCESS(Status)) { 148 | goto InitializeResumeContextEnd; 149 | } 150 | 151 | // 152 | // Initialize the resume context and determine the size of boot code and 153 | // data regions. 154 | // 155 | 156 | ResumeContext = PersistentData.Buffer; 157 | RtlZeroMemory(ResumeContext, PersistentData.DataSize); 158 | ResumeContext->Revision = RESUME_CONTEXT_VERSION; 159 | ResumeContext->Size = PersistentData.DataSize; 160 | ResumeDescriptor = ResumeContext->PhysicalMemoryMap; 161 | NextEntry = MemoryMap.Flink; 162 | while (NextEntry != &MemoryMap) { 163 | Descriptor = CONTAINING_RECORD(NextEntry, 164 | MEMORY_DESCRIPTOR, 165 | ListEntry); 166 | 167 | ResumeDescriptor->BasePage = Descriptor->BasePage; 168 | ResumeDescriptor->PageCount = Descriptor->PageCount; 169 | ResumeDescriptor->MemoryType = Descriptor->MemoryType; 170 | ResumeContext->PhysicalMemoryMapCount += 1; 171 | ResumeDescriptor += 1; 172 | NextEntry = NextEntry->Flink; 173 | } 174 | 175 | ASSERT(ResumeContext->PhysicalMemoryMapCount != 0); 176 | 177 | InitializeResumeContextEnd: 178 | if (!NT_SUCCESS(Status) && (PersistentData.Buffer != NULL)) { 179 | NT_VERIFY( 180 | NT_SUCCESS( 181 | BlPdFreeData(NULL, &ResumeContextGUID, &PersistentData))); 182 | } 183 | 184 | if (MemoryMapDescriptors.Buffer != NULL) { 185 | BlMmFreeHeap(MemoryMapDescriptors.Buffer); 186 | } 187 | 188 | return Status; 189 | } 190 | 191 | NTSTATUS 192 | OslInitializeResumePages ( 193 | __in DEVICE_ID OsDeviceId, 194 | __out PULONG ResumePages 195 | ) 196 | 197 | /*++ 198 | 199 | Routine Description: 200 | 201 | This routine determines the number of resume pages that are required to 202 | resume from hibernate. This value will be passed to the power manager 203 | thru the loader block. 204 | 205 | Arguments: 206 | 207 | OsDeviceId - Supplies the device ID for the OS device. 208 | 209 | ResumePages - Supplies an integer buffer which receives the page count. 210 | 211 | Return Value: 212 | 213 | NT status code. 214 | 215 | --*/ 216 | 217 | { 218 | 219 | ULONGLONG BootServicesPages; 220 | PMEMORY_DESCRIPTOR Descriptor; 221 | ULONG Index; 222 | ULONG Size; 223 | 224 | if (ResumeContext == NULL) { 225 | return STATUS_UNSUCCESSFUL; 226 | } 227 | 228 | // 229 | // For EFI systems the boot services memory regions increase the scratch 230 | // space requirement as they must also persist until the final stage of 231 | // the resume process. Determine the size of the boot services memory 232 | // regions. 233 | // 234 | 235 | BootServicesPages = 0; 236 | Descriptor = ResumeContext->PhysicalMemoryMap; 237 | for (Index = 0; 238 | Index < ResumeContext->PhysicalMemoryMapCount; 239 | Index += 1) { 240 | 241 | if ((Descriptor->MemoryType == MEMORY_TYPE_BOOT_SERVICE_CODE)) { 242 | BootServicesPages += Descriptor->PageCount; 243 | } 244 | 245 | Descriptor += 1; 246 | } 247 | 248 | Size = OslpGetBootFootPrintSize(OsDeviceId); 249 | *ResumePages = Size >> PAGE_SHIFT; 250 | *ResumePages += (ULONG)BootServicesPages; 251 | return STATUS_SUCCESS; 252 | } 253 | 254 | // 255 | // ---------------------------------------------------------- Private Functions 256 | // 257 | 258 | ULONG 259 | OslpGetBootFootPrintSize ( 260 | __in DEVICE_ID OsDeviceId 261 | ) 262 | 263 | /*++ 264 | 265 | Routine Description: 266 | 267 | This routine determines the boot environment foot print size. 268 | 269 | Arguments: 270 | 271 | OsDeviceId - Supplies the device ID for the OS device. 272 | 273 | Return Value: 274 | 275 | ULONG - Size of boot environment foot print (in bytes). 276 | 277 | --*/ 278 | 279 | { 280 | UNREFERENCED_PARAMETER(OsDeviceId); 281 | 282 | return BOOT_ENVIRONMENT_FOOTPRINT_BASE_SIZE; 283 | } 284 | 285 | -------------------------------------------------------------------------------- /boot/environ/app/osloader/schema.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | schema.c 8 | 9 | Abstract: 10 | 11 | Implementation of the Windows composible API set schema. 12 | 13 | --*/ 14 | 15 | #include "osloader.h" 16 | 17 | NTSTATUS 18 | OslpLoadApiSetSchemaImage ( 19 | _In_ DEVICE_ID OsDeviceId, 20 | _In_ PWSTR ImagePath, 21 | _Outptr_result_bytebuffer_(*SchemaDataSize) PVOID *SchemaData, 22 | _Out_ ULONG *SchemaDataSize, 23 | _Inout_ PLIST_ENTRY LoadedImageList, 24 | _Outptr_ PKLDR_DATA_TABLE_ENTRY *DataTableEntry 25 | ); 26 | 27 | VOID 28 | OslpUnloadApiSetSchemaImage ( 29 | _Inout_ PKLDR_DATA_TABLE_ENTRY DataTableEntry 30 | ); 31 | 32 | PVOID OslApiSetSecureSchema; 33 | PVOID OslApiSetSchema; 34 | ULONG OslApiSetSchemaSize; 35 | 36 | NTSTATUS 37 | OslLoadApiSetSchema ( 38 | _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, 39 | _In_ ULONG SystemHiveHandle, 40 | _Inout_ PUNICODE_STRING OsFilePath, 41 | _In_ DEVICE_ID OsDeviceId 42 | ) 43 | 44 | /*++ 45 | 46 | Routine Description: 47 | 48 | This routine loads the API set schema. 49 | 50 | Arguments: 51 | 52 | LoaderBlock - A pointer to the loader parameter block. 53 | 54 | OsFilePath - The file path to the Operating System directory. 55 | 56 | OsDeviceId - Handle to the device containing the Operating System. 57 | 58 | Return Value: 59 | 60 | NTSTATUS code. 61 | 62 | --*/ 63 | 64 | { 65 | BOOLEAN BoolRet; 66 | PKLDR_DATA_TABLE_ENTRY DataTableEntry; 67 | PAPI_SET_SCHEMA_EXTENSION_NODE Entry; 68 | PLIST_ENTRY Extensions; 69 | USHORT OsFilePathLength; 70 | PLIST_ENTRY Node; 71 | NTSTATUS Status; 72 | PVOID Schema; 73 | PVOID SchemaData; 74 | ULONG SchemaDataSize; 75 | ULONG SchemaSize; 76 | BOOLEAN Sealed; 77 | 78 | DataTableEntry = NULL; 79 | Schema = NULL; 80 | 81 | // 82 | // Construct the path to the base apiset schema file and load it. 83 | // 84 | 85 | OsFilePathLength = OsFilePath->Length; 86 | BoolRet = BlAppendUnicodeToString(OsFilePath, APISET_SCHEMA_NAME); 87 | if (BoolRet == FALSE) { 88 | Status = STATUS_NO_MEMORY; 89 | goto OslLoadApiSetSchemaEnd; 90 | } 91 | 92 | Status = OslpLoadApiSetSchemaImage(OsDeviceId, 93 | OsFilePath->Buffer, 94 | &SchemaData, 95 | &SchemaDataSize, 96 | &LoaderBlock->LoadOrderListHead, 97 | &DataTableEntry); 98 | 99 | if (!NT_SUCCESS(Status)) { 100 | goto OslLoadApiSetSchemaEnd; 101 | } 102 | 103 | OsFilePath->Buffer[OsFilePathLength / sizeof(WCHAR)] = UNICODE_NULL; 104 | OsFilePath->Length = OsFilePathLength; 105 | 106 | // 107 | // Allocate a buffer and copy the base schema into it, and then unload the 108 | // image. 109 | // 110 | 111 | SchemaSize = SchemaDataSize; 112 | Schema = BlMmAllocateHeap(SchemaSize); 113 | if (Schema == NULL) { 114 | Status = STATUS_NO_MEMORY; 115 | goto OslLoadApiSetSchemaEnd; 116 | } 117 | 118 | RtlCopyMemory(Schema, SchemaData, SchemaSize); 119 | OslpUnloadApiSetSchemaImage(DataTableEntry); 120 | 121 | // 122 | // Save the schema data to global variables for use by the OS loader, and 123 | // to the loader parameter block for later use by the kernel. 124 | // 125 | 126 | OslApiSetSchema = Schema; 127 | OslApiSetSchemaSize = SchemaSize; 128 | LoaderBlock->Extension->ApiSetSchema = Schema; 129 | LoaderBlock->Extension->ApiSetSchemaSize = SchemaSize; 130 | 131 | // 132 | // If the schema is sealed, then ignore any registered API set schema 133 | // extensions. Composition will not be attempted. 134 | // 135 | 136 | Sealed = ApiSetIsSchemaSealed(Schema); 137 | if (Sealed != FALSE) { 138 | goto OslLoadApiSetSchemaEnd; 139 | } 140 | 141 | // 142 | // Obtain the list of schema extensions that must be loaded for composition 143 | // and then add the extensions into the base schema. 144 | // 145 | 146 | Extensions = &LoaderBlock->Extension->ApiSetSchemaExtensions; 147 | Status = OslHiveGetApiSetSchemaExtensions(SystemHiveHandle, Extensions); 148 | if (!NT_SUCCESS(Status)) { 149 | goto OslLoadApiSetSchemaEnd; 150 | } 151 | 152 | for (Node = Extensions->Flink; Node != Extensions; Node = Node->Flink) { 153 | Entry = CONTAINING_RECORD(Node, API_SET_SCHEMA_EXTENSION_NODE, Links); 154 | 155 | // 156 | // Load the next API set schema extension image. Note that if this 157 | // fails, we should still attempt to boot. The entry in the list shows 158 | // the failure so that the kernel can report it later. 159 | // 160 | 161 | BoolRet = BlAppendUnicodeToString(OsFilePath, Entry->FileName.Buffer); 162 | if (BoolRet == FALSE) { 163 | Status = STATUS_NO_MEMORY; 164 | goto OslLoadApiSetSchemaEnd; 165 | } 166 | 167 | Status = OslpLoadApiSetSchemaImage(OsDeviceId, 168 | OsFilePath->Buffer, 169 | &SchemaData, 170 | &SchemaDataSize, 171 | &LoaderBlock->LoadOrderListHead, 172 | &DataTableEntry); 173 | 174 | OsFilePath->Buffer[OsFilePathLength / sizeof(WCHAR)] = UNICODE_NULL; 175 | OsFilePath->Length = OsFilePathLength; 176 | if (!NT_SUCCESS(Status)) { 177 | Entry->Status = Status; 178 | continue; 179 | } 180 | 181 | // 182 | // Process the API set schema extension data. There is no need to unpack 183 | // the data into a buffer, as it will not be modified and will no longer 184 | // be needed once it has been added into the schema. If this fails, then 185 | // boot will continue so that the error can be reported by the OS. Note 186 | // that in the case of failure, the module remains loaded so that it can 187 | // be examined. 188 | // 189 | 190 | Status = 191 | ApiSetComposeSchema((PAPI_SET_NAMESPACE *)&OslApiSetSchema, 192 | &OslApiSetSchemaSize, 193 | SchemaData, 194 | SchemaDataSize); 195 | 196 | if (!NT_SUCCESS(Status)) { 197 | Entry->Status = Status; 198 | continue; 199 | } 200 | 201 | OslpUnloadApiSetSchemaImage(DataTableEntry); 202 | } 203 | 204 | LoaderBlock->Extension->ApiSetSchema = OslApiSetSchema; 205 | LoaderBlock->Extension->ApiSetSchemaSize = OslApiSetSchemaSize; 206 | Status = STATUS_SUCCESS; 207 | 208 | OslLoadApiSetSchemaEnd: 209 | return Status; 210 | } 211 | 212 | NTSTATUS 213 | OslpLoadApiSetSchemaImage ( 214 | _In_ DEVICE_ID OsDeviceId, 215 | _In_ PWSTR ImagePath, 216 | _Outptr_result_bytebuffer_(*SchemaDataSize) PVOID *SchemaData, 217 | _Out_ ULONG *SchemaDataSize, 218 | _Inout_ PLIST_ENTRY LoadedImageList, 219 | _Outptr_ PKLDR_DATA_TABLE_ENTRY *DataTableEntry 220 | ) 221 | 222 | /*++ 223 | 224 | Routine Description: 225 | 226 | This routine will load the specified API set schema data file, returning the 227 | location and size of the schema data. 228 | 229 | N.B. The caller should take care to only access this data while the data file 230 | remains loaded. 231 | 232 | Arguments: 233 | 234 | OsDeviceId - Supplies the device ID for the Windows boot partition. 235 | 236 | ImagePath - Supplies a pointer to the name of the API set schema file. 237 | 238 | LoaderBlock - Supplies a pointer to the loader parameter block. 239 | 240 | SchemaData - Supplies a location in which a pointer to the schema data is 241 | returned. 242 | 243 | SchemaDataSize - Supllies a location in which the size of the schema data is 244 | returned. 245 | 246 | LoadedImageList - Supplies a pointer to the load image list head. The loaded 247 | schema image will be added to the list. 248 | 249 | Return Value: 250 | 251 | NTSTATUS code. 252 | 253 | --*/ 254 | 255 | { 256 | 257 | PKLDR_DATA_TABLE_ENTRY LoadedModule; 258 | PIMAGE_SECTION_HEADER Section; 259 | NTSTATUS Status; 260 | 261 | Status = OslLoadImage(OsDeviceId, 262 | OSL_MEMORY_TYPE_SYSTEM_CODE, 263 | ImagePath, 264 | NULL, 265 | NULL, 266 | NULL, 267 | 0, 268 | LoadedImageList, 269 | &LoadedModule, 270 | 0, 271 | 0, 272 | IMAGE_FLAGS_NONE, 273 | OSL_IMAGE_FLAGS_APISET_SCHEMA, 274 | NULL); 275 | 276 | if (!NT_SUCCESS(Status)) { 277 | goto OslpLoadApiSetSchemaImageEnd; 278 | } 279 | 280 | // 281 | // Find the section that contains the schema data. 282 | // 283 | 284 | Section = BlImgFindSection(LoadedModule->DllBase, 285 | LoadedModule->SizeOfImage, 286 | API_SET_SECTION_NAME); 287 | 288 | if (Section == NULL) { 289 | OslpUnloadApiSetSchemaImage(LoadedModule); 290 | Status = STATUS_INVALID_IMAGE_FORMAT; 291 | goto OslpLoadApiSetSchemaImageEnd; 292 | } 293 | 294 | // 295 | // Return the location and size of the schema data. The caller must ony 296 | // access this data while the image is still loaded. 297 | // 298 | 299 | *SchemaData = Add2Ptr(LoadedModule->DllBase, Section->VirtualAddress); 300 | *SchemaDataSize = Section->Misc.VirtualSize; 301 | *DataTableEntry = LoadedModule; 302 | 303 | OslpLoadApiSetSchemaImageEnd: 304 | return Status; 305 | } 306 | 307 | VOID 308 | OslpUnloadApiSetSchemaImage ( 309 | _Inout_ PKLDR_DATA_TABLE_ENTRY DataTableEntry 310 | ) 311 | 312 | /*++ 313 | 314 | Routine Description: 315 | 316 | This routine will unload the specified image. 317 | 318 | Arguments: 319 | 320 | DataTableEntry - Supplies a pointer to the loaded module data table entry 321 | returned when the module was loaded. 322 | 323 | Return Value: 324 | 325 | None. 326 | 327 | --*/ 328 | 329 | { 330 | 331 | BlLdrUnloadImage(DataTableEntry); 332 | return; 333 | } 334 | 335 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/arm/ioaccess.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | ioaccess.c 8 | 9 | Abstract: 10 | 11 | This module contains ARM stubs for I/O port access. ARM doe 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | 19 | // 20 | // ------------------------------------------------------------------- Includes 21 | // 22 | 23 | #include 24 | 25 | UCHAR 26 | BL_READ_PORT_UCHAR ( 27 | __in PUCHAR Port 28 | ) 29 | 30 | /*++ 31 | 32 | Routine Description: 33 | 34 | Reads a byte from the specified I/O port. 35 | 36 | Arguments: 37 | 38 | Port - Supplies the port address from which to read. 39 | 40 | Return Value: 41 | 42 | The byte read from the specified port. 43 | 44 | --*/ 45 | 46 | { 47 | UCHAR PortData; 48 | 49 | UNREFERENCED_PARAMETER(Port); 50 | 51 | ASSERT(FALSE); 52 | 53 | PortData = (UCHAR)-1; 54 | 55 | return PortData; 56 | } 57 | 58 | VOID 59 | BL_WRITE_PORT_UCHAR ( 60 | __in PUCHAR Port, 61 | __in UCHAR Value 62 | ) 63 | 64 | /*++ 65 | 66 | Routine Description: 67 | 68 | Writes a byte to the specified I/O port. 69 | 70 | Arguments: 71 | 72 | Port - Supplies the port address to which to write. 73 | 74 | Value - The value to be written to the I/O port. 75 | 76 | Return Value: 77 | 78 | None. 79 | 80 | --*/ 81 | 82 | { 83 | UNREFERENCED_PARAMETER(Port); 84 | UNREFERENCED_PARAMETER(Value); 85 | 86 | ASSERT(FALSE); 87 | 88 | return; 89 | } 90 | 91 | USHORT 92 | BL_READ_PORT_USHORT ( 93 | __in PUSHORT Port 94 | ) 95 | 96 | /*++ 97 | 98 | Routine Description: 99 | 100 | Reads a word from the specified I/O port. 101 | 102 | Arguments: 103 | 104 | Port - Supplies the port address from which to read. 105 | 106 | Return Value: 107 | 108 | The word read from the specified port. 109 | 110 | --*/ 111 | 112 | { 113 | 114 | USHORT PortData; 115 | 116 | UNREFERENCED_PARAMETER(Port); 117 | 118 | ASSERT(FALSE); 119 | 120 | PortData = (USHORT)-1; 121 | 122 | return PortData; 123 | } 124 | 125 | VOID 126 | BL_WRITE_PORT_USHORT ( 127 | __in PUSHORT Port, 128 | __in USHORT Value 129 | ) 130 | 131 | /*++ 132 | 133 | Routine Description: 134 | 135 | Writes a word to the specified I/O port. 136 | 137 | Arguments: 138 | 139 | Port - Supplies the port address to which to write. 140 | 141 | Value - The value to be written to the I/O port. 142 | 143 | Return Value: 144 | 145 | None. 146 | 147 | --*/ 148 | 149 | { 150 | 151 | UNREFERENCED_PARAMETER(Port); 152 | UNREFERENCED_PARAMETER(Value); 153 | 154 | ASSERT(FALSE); 155 | 156 | return; 157 | } 158 | 159 | ULONG 160 | BL_READ_PORT_ULONG ( 161 | __in PULONG Port 162 | ) 163 | 164 | /*++ 165 | 166 | Routine Description: 167 | 168 | Reads a dword from the specified I/O port. 169 | 170 | Arguments: 171 | 172 | Port - Supplies the port address from which to read. 173 | 174 | Return Value: 175 | 176 | The dword read from the specified port. 177 | 178 | --*/ 179 | 180 | { 181 | 182 | ULONG PortData; 183 | 184 | UNREFERENCED_PARAMETER(Port); 185 | 186 | ASSERT(FALSE); 187 | 188 | PortData = (ULONG)-1; 189 | 190 | return PortData; 191 | } 192 | 193 | VOID 194 | BL_WRITE_PORT_ULONG ( 195 | __in PULONG Port, 196 | __in ULONG Value 197 | ) 198 | 199 | /*++ 200 | 201 | Routine Description: 202 | 203 | Writes a dword to the specified I/O port. 204 | 205 | Arguments: 206 | 207 | Port - Supplies the port address to which to write. 208 | 209 | Value - The value to be written to the I/O port. 210 | 211 | Return Value: 212 | 213 | None. 214 | 215 | --*/ 216 | 217 | { 218 | 219 | UNREFERENCED_PARAMETER(Port); 220 | UNREFERENCED_PARAMETER(Value); 221 | 222 | ASSERT(FALSE); 223 | 224 | return; 225 | } 226 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/arm/transita.asm: -------------------------------------------------------------------------------- 1 | ;++ 2 | ; 3 | ; Copyright (C) Microsoft. All rights reserved. 4 | ; 5 | ; Module Name: 6 | ; 7 | ; transita.asm 8 | ; 9 | ; Abstract: 10 | ; 11 | ; ASM routines for transitioning control between boot applications. 12 | ; 13 | ;-- 14 | 15 | 16 | #include 17 | 18 | TEXTAREA 19 | 20 | ;++ 21 | ; 22 | ; BOOLEAN 23 | ; BlpArchQueryInterruptStatus ( 24 | ; VOID 25 | ; ); 26 | ; 27 | ; Routine Description: 28 | ; 29 | ; This routines queries the status of interrupts on the system. 30 | ; 31 | ; Arguments: 32 | ; 33 | ; None. 34 | ; 35 | ; Return Value: 36 | ; 37 | ; FALSE if interrupts are globally disabled. 38 | ; 39 | ; TRUE if interrupts are globally enabled. 40 | ; 41 | ;-- 42 | 43 | LEAF_ENTRY BlpArchQueryInterruptStatus 44 | 45 | READ_CPSR r1 ; get cpsr 46 | tst r1, #CPSRC_INT ; are interrupts enabled? 47 | 48 | ; 49 | ; N.B. These assignments look backwards but CPSRC_INT is a 50 | ; interrupt disable bit rather than traditional enable bit. 51 | ; 52 | 53 | movne r0, #FALSE ; if ne, ints were disabled 54 | moveq r0, #TRUE ; if eq, ints were enabled 55 | bx lr 56 | 57 | LEAF_END BlpArchQueryInterruptStatus 58 | 59 | ;++ 60 | ; 61 | ; VOID 62 | ; BlpArchTransferToApplicationState 63 | ; __in PBOOT_APPLICATION_ENTRYPOINT EntryRoutine, 64 | ; __inout PBOOT_APPLICATION_PARAMETERS EntryParameters, 65 | ; __in PVOID Stack, 66 | ; ) 67 | ; 68 | ; Routine Description: 69 | ; 70 | ; This routine will transfer control to an ARM boot application. 71 | ; 72 | ; Arguments: 73 | ; 74 | ; EntryRoutine A pointer to the entry routine for the new boot application. 75 | ; 76 | ; EntryParameters - A pointer to the entry parameters for the new 77 | ; boot application. 78 | ; 79 | ; Stack - A pointer to memory allocated for the new boot 80 | ; application's stack. 81 | ; 82 | ; Return Value: 83 | ; 84 | ; None. 85 | ; 86 | ;-- 87 | NESTED_ENTRY BlpArchTransferToApplicationState 88 | PROLOG_PUSH {r4, lr} 89 | 90 | mov r4, sp ; save incoming stack 91 | cps #CPSRM_SVC ; go to svc mode 92 | 93 | mov sp, r2 ; switch to new stack 94 | mov r2, r0 95 | mov r0, r1 96 | blx r2 97 | 98 | mov sp, r4 99 | 100 | EPILOG_POP {r4, pc} 101 | NESTED_END BlpArchTransferToApplicationState 102 | 103 | END 104 | 105 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/arm/transitc.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | transitc.c 8 | 9 | Abstract: 10 | 11 | This module contains ARM specific code for the transitioning of control 12 | between boot applications. 13 | 14 | Environment: 15 | 16 | Boot 17 | 18 | --*/ 19 | 20 | // 21 | // ------------------------------------------------------------------- Includes 22 | // 23 | 24 | #include 25 | #include "context.h" 26 | 27 | // 28 | // -------------------------------------------------------------------- Globals 29 | // 30 | 31 | VOID 32 | BlpArchTransferToApplicationState ( 33 | __in PBOOT_APPLICATION_ENTRYPOINT EntryRoutine, 34 | __inout PBOOT_APPLICATION_PARAMETERS EntryParameters, 35 | __in PVOID Stack 36 | ); 37 | 38 | PEXECUTION_CONTEXT 39 | ArchGetContext ( 40 | __in EXECUTION_CONTEXT_TYPE ContextType 41 | ); 42 | 43 | VOID 44 | ArchSetInitialContext ( 45 | __in PEXECUTION_CONTEXT Context 46 | ); 47 | 48 | VOID 49 | ArchSwitchContext ( 50 | __in PEXECUTION_CONTEXT NewContext, 51 | __in_opt PEXECUTION_CONTEXT CurrentContext 52 | ); 53 | 54 | // 55 | // ------------------------------------------------------------------ Functions 56 | // 57 | 58 | DECLSPEC_NOINLINE 59 | NTSTATUS 60 | BlpArchTransferToEfiBootApplication ( 61 | __in PBOOT_APPLICATION_ENTRYPOINT EntryRoutine, 62 | __inout PBOOT_APPLICATION_PARAMETERS EntryParameters, 63 | __in PVOID ApplicationContext, 64 | __in PVOID Stack 65 | ) 66 | 67 | /*++ 68 | 69 | Routine Description: 70 | 71 | Transfers exeuction to an EFI boot application. 72 | 73 | Arguments: 74 | 75 | EntryRoutine - Pointer to the entry point for the x64 boot application. 76 | 77 | EntryParameters - Input parameters for the boot application to start. 78 | 79 | ApplicationContext - Supplies a pointer to the context to instantiate. 80 | 81 | Stack - Allocated stack for the boot application. 82 | 83 | Return Value: 84 | 85 | The return status of the loaded application. 86 | 87 | --*/ 88 | 89 | { 90 | 91 | PEXECUTION_CONTEXT PreviousContext; 92 | PBOOT_APPLICATION_RETURN_ARGUMENTS ReturnArguments; 93 | NTSTATUS Status; 94 | 95 | // 96 | // If the debugger is currently connected, stop it. That way the 97 | // new boot application can start a new session. 98 | // 99 | 100 | BlBdStop(); 101 | 102 | // 103 | // Capture the current context in case we return from the 104 | // application. 105 | // 106 | 107 | PreviousContext = ArchGetCurrentContext(); 108 | ArchSwitchContext(ApplicationContext, PreviousContext); 109 | 110 | // 111 | // Transfer control. 112 | // 113 | 114 | BlpArchTransferToApplicationState(EntryRoutine, 115 | EntryParameters, 116 | Stack); 117 | 118 | // 119 | // Resume previous context 120 | // 121 | 122 | ArchSwitchContext(PreviousContext, ApplicationContext); 123 | 124 | // 125 | // Resume the boot debugger, if it was formerly connected. 126 | // 127 | 128 | BlBdStart(); 129 | 130 | // 131 | // A boot application's returned the status is contained within the 132 | // input parameter structure. 133 | // 134 | 135 | ReturnArguments = Add2Ptr(EntryParameters, 136 | EntryParameters->ReturnArgumentOffset); 137 | 138 | if (ReturnArguments->Version >= 1) { 139 | Status = ReturnArguments->ReturnStatus; 140 | 141 | } else { 142 | 143 | Status = STATUS_SUCCESS; 144 | } 145 | 146 | return Status; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/arm/vector.asm: -------------------------------------------------------------------------------- 1 | ; title "CPU and coprocessor primatives" 2 | ;++ 3 | ; 4 | ; Copyright (C) Microsoft. All rights reserved. 5 | ; 6 | ; Module Name: 7 | ; 8 | ; vector.asm 9 | ; 10 | ; Abstract: 11 | ; 12 | ; This module implements the ARM exception vector table which can 13 | ; be located at 0x00000000 or 0xFFFF0000. The NT loader initialize 14 | ; the processor such that the vector table appears at 15 | ; 0xFFFF0000. 16 | ; 17 | ; The vector table itself consists of a room for a single 18 | ; instruction per vector. This instruction will load the PC via a 19 | ; PC-relative load from a nearby array of vectors which will 20 | ; contain the real OS exception entry points. 21 | ; 22 | ; Environment: 23 | ; 24 | ; Kernel mode only. 25 | ; 26 | ;-- 27 | 28 | #include "ksarm.h" 29 | 30 | 31 | AREA |.text|,ALIGN=5,CODE,READONLY 32 | 33 | EXPORT ArchStubExceptionVectors 34 | 35 | ; 36 | ; This set of stub exception vectors each invokes an endless loop. It 37 | ; is intended to be installed when the boot loader debugger is not 38 | ; active or before switching to a new application. 39 | ; 40 | 41 | ALIGN 32 ; 32-byte alignment required 42 | 43 | ArchStubExceptionVectors 44 | ArchResetException 45 | b ArchResetException 46 | nop 47 | ArchUndefinedException 48 | b ArchUndefinedException 49 | nop 50 | ArchSWIException 51 | b ArchSWIException 52 | nop 53 | ArchPrefetchException 54 | b ArchPrefetchException 55 | nop 56 | ArchDataException 57 | b ArchDataException 58 | nop 59 | ArchUnusedException 60 | b ArchUnusedException 61 | nop 62 | ArchIrqException 63 | b ArchIrqException 64 | nop 65 | ArchFiqException 66 | b ArchFiqException 67 | nop 68 | 69 | END 70 | 71 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/context.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | context.c 8 | 9 | Abstract: 10 | 11 | This module implements architecture-independent execution context 12 | manipulation routines. 13 | 14 | Environment: 15 | 16 | Boot 17 | 18 | --*/ 19 | 20 | // ------------------------------------------------------------------- Includes 21 | 22 | #include "arch.h" 23 | 24 | // -------------------------------------------------------------------- Globals 25 | 26 | // 27 | // Define storage for the two possible execution contexts. 28 | // 29 | 30 | EXECUTION_CONTEXT FirmwareExecutionContext; 31 | EXECUTION_CONTEXT ApplicationExecutionContext; 32 | 33 | // 34 | // Define the current execution context for the boot application. 35 | // 36 | 37 | PEXECUTION_CONTEXT CurrentExecutionContext; 38 | 39 | // ------------------------------------------------------------------ Functions 40 | 41 | NTSTATUS 42 | ArchInitializeContexts ( 43 | VOID 44 | ) 45 | 46 | /*++ 47 | 48 | Routine Description: 49 | 50 | This routine initializes the firmware and application execution contexts 51 | for the boot application. 52 | 53 | Arguments: 54 | 55 | None. 56 | 57 | Return Value: 58 | 59 | NTSTATUS code. 60 | 61 | --*/ 62 | 63 | { 64 | 65 | NTSTATUS ApplicationStatus; 66 | NTSTATUS FirmwareStatus; 67 | ULONG FirmwareSupported; 68 | 69 | // 70 | // Initialize global execution contexts. 71 | // 72 | 73 | CurrentExecutionContext = NULL; 74 | FirmwareExecutionContext.ContextType = ExecutionContextFirmware; 75 | ApplicationExecutionContext.ContextType = ExecutionContextApplication; 76 | 77 | // 78 | // If an application execution context is supported, then the 79 | // application should run in its own context. 80 | // 81 | 82 | ApplicationStatus = ArchInitializeContext(&ApplicationExecutionContext); 83 | if (NT_SUCCESS(ApplicationStatus)) { 84 | CurrentExecutionContext = &ApplicationExecutionContext; 85 | } 86 | 87 | // 88 | // Initialize the firmware execution contexts, if supported. 89 | // 90 | 91 | FirmwareSupported = 92 | CHECK_FLAG(BlPlatformFlags, FW_FLAGS_EXECUTION_CONTEXT_SUPPORTED); 93 | 94 | if (FirmwareSupported != 0) { 95 | FirmwareStatus = ArchInitializeContext(&FirmwareExecutionContext); 96 | if (!NT_SUCCESS(FirmwareStatus)) { 97 | return FirmwareStatus; 98 | } 99 | 100 | // 101 | // If a firmware context is supported but the application context is not 102 | // supported, then the application should run in the firmware's context. 103 | // 104 | // Additionally, ensure that the firmware context is set. Some 105 | // applications can be launched with their own page tables and GDT/IDT, 106 | // and with interrupts disabled, but need to run in the firmware's 107 | // context. This will set them back to the firmare's context. 108 | // 109 | 110 | if (!NT_SUCCESS(ApplicationStatus)) { 111 | CurrentExecutionContext = &FirmwareExecutionContext; 112 | } 113 | } 114 | 115 | ASSERT(CurrentExecutionContext != NULL); 116 | ArchSetInitialContext(CurrentExecutionContext); 117 | 118 | return STATUS_SUCCESS; 119 | } 120 | 121 | VOID 122 | BlpArchSwitchContext ( 123 | __in EXECUTION_CONTEXT_TYPE ContextType 124 | ) 125 | 126 | /*++ 127 | 128 | Routine Description: 129 | 130 | This routine transitions a boot application to execute within the 131 | specified execution context. On return, the application will be running 132 | in the new context. 133 | 134 | Arguments: 135 | 136 | ContextType - Supplies the type of the target execution context to switch 137 | the boot application to. 138 | 139 | Return Value: 140 | 141 | None. 142 | 143 | --*/ 144 | 145 | { 146 | 147 | PEXECUTION_CONTEXT NewContext; 148 | 149 | BlpInterfaceEnter(InterfaceArch); 150 | NewContext = ArchGetContext(ContextType); 151 | 152 | // 153 | // Switch to the target execution context if the application is not already 154 | // executing within it. 155 | // 156 | 157 | if (BlpArchQueryCurrentContextType() != ContextType) { 158 | ArchSwitchContext(NewContext, CurrentExecutionContext); 159 | CurrentExecutionContext = NewContext; 160 | } 161 | 162 | BlpInterfaceExit(InterfaceArch); 163 | return; 164 | } 165 | 166 | EXECUTION_CONTEXT_TYPE 167 | BlpArchQueryCurrentContextType ( 168 | VOID 169 | ) 170 | 171 | /*++ 172 | 173 | Routine Description: 174 | 175 | This routine returns the current execution context type for the boot 176 | application. 177 | 178 | Arguments: 179 | 180 | None. 181 | 182 | Return Value: 183 | 184 | EXECUTION_CONTEXT_TYPE - Type of the execution context within which the boot 185 | application is currently running. 186 | 187 | --*/ 188 | 189 | { 190 | 191 | BlpInterfaceEnter(InterfaceArch); 192 | 193 | ASSERT(CurrentExecutionContext != NULL); 194 | 195 | BlpInterfaceExit(InterfaceArch); 196 | return CurrentExecutionContext->ContextType; 197 | } 198 | 199 | PEXECUTION_CONTEXT 200 | ArchGetContext ( 201 | __in EXECUTION_CONTEXT_TYPE ContextType 202 | ) 203 | 204 | /*++ 205 | 206 | Routine Description: 207 | 208 | This routine returns the execution context of the requested type. 209 | 210 | Arguments: 211 | 212 | ContextType - Supplies the type of context the caller is requesting. 213 | 214 | Return Value: 215 | 216 | PEXECUTION_CONTEXT - The execution context of the type requested. 217 | 218 | --*/ 219 | 220 | { 221 | 222 | PEXECUTION_CONTEXT Context; 223 | 224 | if (ContextType == ExecutionContextFirmware) { 225 | Context = &FirmwareExecutionContext; 226 | 227 | } else { 228 | Context = &ApplicationExecutionContext; 229 | } 230 | 231 | return Context; 232 | } 233 | 234 | PEXECUTION_CONTEXT 235 | ArchGetCurrentContext ( 236 | VOID 237 | ) 238 | 239 | /*++ 240 | 241 | Routine Description: 242 | 243 | This routine returns the current execution context. 244 | 245 | Arguments: 246 | 247 | None. 248 | 249 | Return Value: 250 | 251 | PEXECUTION_CONTEXT - The current execution context. 252 | 253 | --*/ 254 | 255 | { 256 | 257 | return CurrentExecutionContext; 258 | } 259 | 260 | #if defined(_X86_) || defined(_AMD64_) 261 | 262 | NTSTATUS 263 | ArchExecuteTransition ( 264 | __in PARCH_TRANSITION_ROUTINE TransitionRoutine, 265 | __inout PBOOT_APPLICATION_PARAMETERS EntryParameters 266 | ) 267 | 268 | /*++ 269 | 270 | Routine Description: 271 | 272 | This routine contains common X86/AMD64 transition code when launching boot 273 | application. 274 | 275 | Arguments: 276 | 277 | TransitionRoutine - Supplies architecture specific transition routine to 278 | execute final transition to the boot application being launched. 279 | 280 | EntryParameters - Supplies pointer to the input parameters for the boot 281 | application. 282 | 283 | Return Value: 284 | 285 | Status value returned by the application. 286 | 287 | --*/ 288 | 289 | { 290 | 291 | PBOOT_APPLICATION_RETURN_ARGUMENTS ReturnArguments; 292 | 293 | // 294 | // Restore processor features enabled by the boot application to their 295 | // original state. 296 | // 297 | 298 | ArchRestoreProcessorFeatures(); 299 | 300 | // 301 | // If the debugger is currently connected, stop it. That way the new boot 302 | // application can start a new session. 303 | // 304 | 305 | BlBdStop(); 306 | 307 | // 308 | // Call into architecture specific routine to transfer control. 309 | // 310 | 311 | (*TransitionRoutine)(); 312 | 313 | // 314 | // Resume the boot debugger, if it was formerly connected. 315 | // 316 | 317 | BlBdStart(); 318 | 319 | // 320 | // Enable processor features being used in the boot environment. 321 | // 322 | 323 | ArchEnableProcessorFeatures(); 324 | 325 | // 326 | // A boot application's returned the status is contained within the 327 | // input parameter structure. 328 | // 329 | 330 | ReturnArguments = Add2Ptr(EntryParameters, 331 | EntryParameters->ReturnArgumentOffset); 332 | 333 | if (ReturnArguments->Version >= 1) { 334 | return ReturnArguments->ReturnStatus; 335 | } 336 | 337 | return STATUS_SUCCESS; 338 | } 339 | 340 | #endif 341 | 342 | -------------------------------------------------------------------------------- /boot/environ/lib/arch/efi/ctxefiarm.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | ctxefiarm.c 8 | 9 | Abstract: 10 | 11 | This module implements context manipulation routines for UEFI firmware. 12 | 13 | N.B. This is only compiled on ARM/ARM64 builds. 14 | 15 | Environment: 16 | 17 | Boot 18 | 19 | --*/ 20 | 21 | // 22 | // ------------------------------------------------------------------- Includes 23 | // 24 | 25 | #include 26 | 27 | // 28 | // ------------------------------------------------------------------ Functions 29 | // 30 | 31 | NTSTATUS 32 | ArchFwInitializeFirmwareContext ( 33 | __out PEXECUTION_CONTEXT FirmwareContext 34 | ) 35 | 36 | /*++ 37 | 38 | Routine Description: 39 | 40 | This routine initializes the firmware execution context. It sets the page 41 | directory address, the address translation state, and the interrupt state 42 | for the firmware context. 43 | 44 | Arguments: 45 | 46 | FirmwareContext - Supplies a pointer to the firmware context to be 47 | initialized. 48 | 49 | Return Value: 50 | 51 | NT Status Code. 52 | 53 | --*/ 54 | 55 | { 56 | 57 | FIRMWARE_PARAMETERS UNALIGNED FirmwareBuffer; 58 | PFIRMWARE_PARAMETERS FirmwareParameters; 59 | NTSTATUS Status; 60 | 61 | // 62 | // Get the architecture parameters that were passed by the previous boot 63 | // application. 64 | // 65 | 66 | Status = BlFwGetParameters(&FirmwareBuffer); 67 | if (!NT_SUCCESS(Status)) { 68 | return Status; 69 | } 70 | 71 | FirmwareParameters = &FirmwareBuffer; 72 | 73 | // 74 | // The firmware's page tables as captured by the MM_STATE are used 75 | // when running in the firmware context. 76 | // 77 | 78 | FirmwareContext->MmState = FirmwareParameters->MmState; 79 | 80 | // 81 | // Address translation is always disabled when running in the firmware 82 | // execution context. In the ARM case, this means that the application is 83 | // running with the firmware's page tables and that everything is 1:1 84 | // mapped. 85 | // 86 | 87 | FirmwareContext->AddressTranslationEnabled = 0; 88 | 89 | // 90 | // Use firmware's exception state 91 | // 92 | 93 | FirmwareContext->ExceptionState = FirmwareParameters->ExceptionState; 94 | 95 | // 96 | // The firmware context runs with interrupts enabled. 97 | // 98 | 99 | FirmwareContext->InterruptState = FirmwareParameters->InterruptState; 100 | return STATUS_SUCCESS; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efiblock.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efiblock.c 8 | 9 | Abstract: 10 | 11 | Wrappers for EFI Block I/O Protocol routines. 12 | 13 | The BLOCK_IO_PROTOCOL interface provides functional support to read and 14 | write to a hardware device. This module provides wrappers for these 15 | functions to correctly handle cases such as whether the caller is in 16 | virtual mode, physical mode, etc. 17 | 18 | Environment: 19 | 20 | Boot 21 | 22 | --*/ 23 | 24 | // ------------------------------------------------------------------- Includes 25 | 26 | #include "bootlibp.h" 27 | 28 | // ------------------------------------------------------------------ Functions 29 | 30 | NTSTATUS 31 | EfiBlockIoReadBlocks ( 32 | __in EFI_BLOCK_IO *BlockIoInterface, 33 | __in ULONGLONG BlockNumber, 34 | __in UINTN NumberBlocks, 35 | __out VOID *Buffer 36 | ) 37 | 38 | /*++ 39 | 40 | Routine Description: 41 | 42 | Wrapper for an EFI Block I/O Interface call to read from a block i/o 43 | device. 44 | 45 | Arguments: 46 | 47 | BlockIoInterface - Block I/O device's interface. (This is a physical 48 | address pointer). 49 | 50 | BlockNumber - LBA on device to start read. 51 | 52 | NumberBlock - The number of blocks to read. 53 | 54 | Buffer - Pointer to address to store contents read from device. 55 | 56 | Return Value: 57 | 58 | STATUS_SUCCESS when successful. 59 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 60 | operation. 61 | STATUS_NO_MEDIA if there is no media in the device. 62 | STATUS_INVALID_PARAMETER if the request block number is not valid. 63 | STATUS_MEDIA_CHANGED if the underlying media has changed. 64 | 65 | --*/ 66 | 67 | { 68 | 69 | EXECUTION_CONTEXT_TYPE ContextType; 70 | ULONG BlockSize; 71 | PHYSICAL_ADDRESS BufferPa = {0}; 72 | EFI_STATUS EfiStatus; 73 | PHYSICAL_ADDRESS InterfacePa = {0}; 74 | 75 | // 76 | // If the application is running within the application execution context, 77 | // switch it to firmware execution context for making firmware the call. 78 | // Translate all virtual addresses to their respective physical addresses. 79 | // 80 | 81 | ContextType = BlpArchQueryCurrentContextType(); 82 | if (ContextType != ExecutionContextFirmware) { 83 | BlMmTranslateVirtualAddress(BlockIoInterface, &InterfacePa); 84 | BlockIoInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 85 | BlMmTranslateVirtualAddress(Buffer, &BufferPa); 86 | Buffer = (PVOID)(UINTN)BufferPa.QuadPart; 87 | BlpArchSwitchContext(ExecutionContextFirmware); 88 | } 89 | 90 | // 91 | // Use the Block I/O devices ReadBlocks implementation to read the physical 92 | // blocks from the device. 93 | // 94 | 95 | BlockSize = BlockIoInterface->Media->BlockSize; 96 | EfiStatus = BlockIoInterface->ReadBlocks(BlockIoInterface, 97 | BlockIoInterface->Media->MediaId, 98 | BlockNumber, 99 | NumberBlocks * BlockSize, 100 | Buffer); 101 | 102 | // 103 | // Restore original execution context. 104 | // 105 | 106 | if (ContextType != ExecutionContextFirmware) { 107 | BlpArchSwitchContext(ContextType); 108 | } 109 | 110 | return EfiGetNtStatusCode(EfiStatus); 111 | } 112 | 113 | NTSTATUS 114 | EfiBlockIoWriteBlocks ( 115 | __in EFI_BLOCK_IO *BlockIoInterface, 116 | __in ULONGLONG BlockNumber, 117 | __in UINTN NumberBlocks, 118 | __in VOID *Buffer 119 | ) 120 | 121 | /*++ 122 | 123 | Routine Description: 124 | 125 | Wrapper for an EFI Block I/O Interface call to write to a block i/o 126 | device. 127 | 128 | Arguments: 129 | 130 | BlockIoInterface - Block I/O device's interface. (This is a physical 131 | address pointer). 132 | 133 | BlockNumber - LBA on device to start write. 134 | 135 | NumberBlock - The number of blocks to write. 136 | 137 | Buffer - Pointer to address with contents to write to device. 138 | 139 | Return Value: 140 | 141 | STATUS_SUCCESS when successful. 142 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 143 | operation. 144 | STATUS_NO_MEDIA if there is no media in the device. 145 | STATUS_INVALID_PARAMETER if the request block number is not valid. 146 | STATUS_MEDIA_CHANGED if the underlying media has changed. 147 | 148 | --*/ 149 | 150 | { 151 | 152 | EXECUTION_CONTEXT_TYPE ContextType; 153 | ULONG BlockSize; 154 | PHYSICAL_ADDRESS BufferPa = {0}; 155 | EFI_STATUS EfiStatus; 156 | PHYSICAL_ADDRESS InterfacePa = {0}; 157 | 158 | // 159 | // If the application is running within the application execution context, 160 | // switch it to firmware execution context for making firmware the call. 161 | // Translate all virtual addresses to their respective physical addresses. 162 | // 163 | 164 | ContextType = BlpArchQueryCurrentContextType(); 165 | if (ContextType != ExecutionContextFirmware) { 166 | BlMmTranslateVirtualAddress(BlockIoInterface, &InterfacePa); 167 | BlockIoInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 168 | BlMmTranslateVirtualAddress(Buffer, &BufferPa); 169 | Buffer = (PVOID)(UINTN)BufferPa.QuadPart; 170 | BlpArchSwitchContext(ExecutionContextFirmware); 171 | } 172 | 173 | // 174 | // Use the Block I/O devices WriteBlocks implementation to write the 175 | // physical blocks to the device. 176 | // 177 | 178 | BlockSize = BlockIoInterface->Media->BlockSize; 179 | EfiStatus = BlockIoInterface->WriteBlocks(BlockIoInterface, 180 | BlockIoInterface->Media->MediaId, 181 | BlockNumber, 182 | NumberBlocks * BlockSize, 183 | Buffer); 184 | 185 | // 186 | // Restore original execution context. 187 | // 188 | 189 | if (ContextType != ExecutionContextFirmware) { 190 | BlpArchSwitchContext(ContextType); 191 | } 192 | 193 | return EfiGetNtStatusCode(EfiStatus); 194 | } 195 | 196 | NTSTATUS 197 | EfiBlockIoReset ( 198 | __in EFI_BLOCK_IO *BlockIoInterface, 199 | __in BOOLEAN ExtendedVerification 200 | ) 201 | 202 | /*++ 203 | 204 | Routine Description: 205 | 206 | Wrapper for an EFI Block I/O Interface call to reset a block i/o 207 | device. 208 | 209 | Arguments: 210 | 211 | BlockIoInterface - Block I/O device's interface. (This is a physical 212 | address pointer). 213 | 214 | ExtendedVerification - Indicates that the driver may perform a more 215 | exhaustive verification operation of the device during reset. 216 | 217 | Return Value: 218 | 219 | STATUS_SUCCESS when successful. 220 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 221 | operation. 222 | 223 | --*/ 224 | 225 | { 226 | 227 | EXECUTION_CONTEXT_TYPE ContextType; 228 | EFI_STATUS EfiStatus; 229 | PHYSICAL_ADDRESS InterfacePa = {0}; 230 | 231 | // 232 | // If the application is running within the application execution context, 233 | // switch it to firmware execution context for making firmware the call. 234 | // Translate all virtual addresses to their respective physical addresses. 235 | // 236 | 237 | ContextType = BlpArchQueryCurrentContextType(); 238 | if (ContextType != ExecutionContextFirmware) { 239 | BlMmTranslateVirtualAddress(BlockIoInterface, &InterfacePa); 240 | BlockIoInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 241 | BlpArchSwitchContext(ExecutionContextFirmware); 242 | } 243 | 244 | // 245 | // Use the Block I/O devices Reset implementation to reset the device. 246 | // 247 | 248 | EfiStatus = BlockIoInterface->Reset(BlockIoInterface, 249 | ExtendedVerification); 250 | 251 | // 252 | // Restore original execution context. 253 | // 254 | 255 | if (ContextType != ExecutionContextFirmware) { 256 | BlpArchSwitchContext(ContextType); 257 | } 258 | 259 | return EfiGetNtStatusCode(EfiStatus); 260 | } 261 | 262 | NTSTATUS 263 | EfiBlockIoFlushBlocks ( 264 | __in EFI_BLOCK_IO *BlockIoInterface 265 | ) 266 | 267 | /*++ 268 | 269 | Routine Description: 270 | 271 | Wrapper for an EFI Block I/O Interface call to flush a block i/o 272 | device. 273 | 274 | Arguments: 275 | 276 | BlockIoInterface - Block I/O device's interface. (This is a physical 277 | address pointer). 278 | 279 | Return Value: 280 | 281 | STATUS_SUCCESS when successful. 282 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 283 | operation. 284 | STATUS_NO_MEDIA if there is no media in the device. 285 | 286 | --*/ 287 | 288 | { 289 | 290 | EXECUTION_CONTEXT_TYPE ContextType; 291 | EFI_STATUS EfiStatus; 292 | PHYSICAL_ADDRESS InterfacePa = {0}; 293 | 294 | // 295 | // If the application is running within the application execution context, 296 | // switch it to firmware execution context for making firmware the call. 297 | // Translate all virtual addresses to their respective physical addresses. 298 | // 299 | 300 | ContextType = BlpArchQueryCurrentContextType(); 301 | if (ContextType != ExecutionContextFirmware) { 302 | BlMmTranslateVirtualAddress(BlockIoInterface, &InterfacePa); 303 | BlockIoInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 304 | BlpArchSwitchContext(ExecutionContextFirmware); 305 | } 306 | 307 | // 308 | // Use the Block I/O devices Flush implementation to flush pending 309 | // writes to the device. 310 | // 311 | 312 | EfiStatus = BlockIoInterface->FlushBlocks(BlockIoInterface); 313 | 314 | // 315 | // Restore original execution context. 316 | // 317 | 318 | if (ContextType != ExecutionContextFirmware) { 319 | BlpArchSwitchContext(ContextType); 320 | } 321 | 322 | return EfiGetNtStatusCode(EfiStatus); 323 | } 324 | 325 | 326 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efidebug.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efidebug.c 8 | 9 | Abstract: 10 | 11 | Wrappers for EFI Debug Port routines. 12 | 13 | All efi call must be made in physical mode. When a boot environment 14 | application runs in virtual mode, pointers need to be modified and fixed 15 | before every EFI call. Additionally firmware pointers/addresses need to be 16 | virtually mapped for the caller to read contents. The wrappers intend to 17 | hide as much of that work as possible from the caller. 18 | 19 | Environment: 20 | 21 | Boot 22 | 23 | --*/ 24 | 25 | // 26 | // ------------------------------------------------------------------- Includes 27 | // 28 | 29 | #include "bootlibp.h" 30 | 31 | // 32 | // -------------------------------------------------------- Debug Port Services 33 | // 34 | 35 | NTSTATUS 36 | EfiDebugPortReset ( 37 | __in EFI_DEBUGPORT *DebugPortInterface 38 | ) 39 | 40 | /*++ 41 | 42 | Routine Description: 43 | 44 | Wrapper for an EFI Debug Port Interface call to reset the debug port. 45 | 46 | Arguments: 47 | 48 | DebugPortInterface - Debug port interface. (This is a physical 49 | address pointer). 50 | 51 | Return Value: 52 | 53 | STATUS_SUCCESS when successful. 54 | 55 | --*/ 56 | 57 | { 58 | 59 | EXECUTION_CONTEXT_TYPE ContextType; 60 | EFI_STATUS EfiStatus; 61 | PHYSICAL_ADDRESS InterfacePa; 62 | 63 | // 64 | // If the application is running within the application execution context, 65 | // switch it to firmware execution context for making firmware the call. 66 | // Translate all virtual addresses to their respective physical addresses. 67 | // 68 | 69 | ContextType = BlpArchQueryCurrentContextType(); 70 | if (ContextType != ExecutionContextFirmware) { 71 | BlMmTranslateVirtualAddress(DebugPortInterface, &InterfacePa); 72 | DebugPortInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 73 | BlpArchSwitchContext(ExecutionContextFirmware); 74 | } 75 | 76 | // 77 | // Use the debug port protocol Reset implementation to reset debug port. 78 | // 79 | 80 | EfiStatus = DebugPortInterface->Reset(DebugPortInterface); 81 | 82 | // 83 | // Restore original execution context. 84 | // 85 | 86 | if (ContextType != ExecutionContextFirmware) { 87 | BlpArchSwitchContext(ContextType); 88 | } 89 | 90 | return EfiGetNtStatusCode(EfiStatus); 91 | } 92 | 93 | NTSTATUS 94 | EfiDebugPortWrite ( 95 | __in EFI_DEBUGPORT *DebugPortInterface, 96 | __in UINT32 Timeout, 97 | __inout UINTN *BufferSize, 98 | __in VOID *Buffer 99 | ) 100 | 101 | /*++ 102 | 103 | Routine Description: 104 | 105 | Wrapper for an EFI Debug Port Interface call to write to debug port. 106 | 107 | Arguments: 108 | 109 | DebugPortInterface - Debug port interface. (This is a physical 110 | address pointer). 111 | 112 | Timeout - timeout of the write. 113 | 114 | BufferSize - The size of the buffer. 115 | 116 | Buffer - Pointer to address to store contents write to debug port. 117 | 118 | Return Value: 119 | 120 | STATUS_SUCCESS when successful. 121 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 122 | operation. 123 | STATUS_TIMEOUT if the device reported timeout. 124 | 125 | --*/ 126 | 127 | { 128 | 129 | PHYSICAL_ADDRESS BufferPa; 130 | PHYSICAL_ADDRESS BufferSizePa; 131 | EXECUTION_CONTEXT_TYPE ContextType; 132 | EFI_STATUS EfiStatus; 133 | PHYSICAL_ADDRESS InterfacePa; 134 | 135 | // 136 | // If the application is running within the application execution context, 137 | // switch it to firmware execution context for making firmware the call. 138 | // Translate all virtual addresses to their respective physical addresses. 139 | // 140 | 141 | ContextType = BlpArchQueryCurrentContextType(); 142 | if (ContextType != ExecutionContextFirmware) { 143 | BlMmTranslateVirtualAddress(DebugPortInterface, &InterfacePa); 144 | DebugPortInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 145 | BlMmTranslateVirtualAddress(Buffer, &BufferPa); 146 | Buffer = (PVOID)(UINTN)BufferPa.QuadPart; 147 | BlMmTranslateVirtualAddress(BufferSize, &BufferSizePa); 148 | BufferSize = (PVOID)(UINTN)BufferSizePa.QuadPart; 149 | BlpArchSwitchContext(ExecutionContextFirmware); 150 | } 151 | 152 | // 153 | // Use the debug port protocol Write implementation to write the data 154 | // to debug port. 155 | // 156 | 157 | EfiStatus = DebugPortInterface->Write(DebugPortInterface, 158 | Timeout, 159 | BufferSize, 160 | Buffer); 161 | 162 | // 163 | // Restore original execution context. 164 | // 165 | 166 | if (ContextType != ExecutionContextFirmware) { 167 | BlpArchSwitchContext(ContextType); 168 | } 169 | 170 | return EfiGetNtStatusCode(EfiStatus); 171 | } 172 | 173 | NTSTATUS 174 | EfiDebugPortRead ( 175 | __in EFI_DEBUGPORT *DebugPortInterface, 176 | __in UINT32 Timeout, 177 | __inout UINTN *BufferSize, 178 | __out VOID *Buffer 179 | ) 180 | 181 | /*++ 182 | 183 | Routine Description: 184 | 185 | Wrapper for an EFI Debug Port Interface call to read from debug port. 186 | 187 | Arguments: 188 | 189 | DebugPortInterface - Debug port interface. (This is a physical 190 | address pointer). 191 | 192 | Timeout - timeout of the read. 193 | 194 | BufferSize - The size of the buffer. 195 | 196 | Buffer - Pointer to address to store contents read from debug port. 197 | 198 | Return Value: 199 | 200 | STATUS_SUCCESS when successful. 201 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 202 | operation. 203 | STATUS_TIMEOUT if the device reported timeout. 204 | 205 | --*/ 206 | 207 | { 208 | 209 | PHYSICAL_ADDRESS BufferPa; 210 | PHYSICAL_ADDRESS BufferSizePa; 211 | EXECUTION_CONTEXT_TYPE ContextType; 212 | EFI_STATUS EfiStatus; 213 | PHYSICAL_ADDRESS InterfacePa; 214 | 215 | // 216 | // If the application is running within the application execution context, 217 | // switch it to firmware execution context for making firmware the call. 218 | // Translate all virtual addresses to their respective physical addresses. 219 | // 220 | 221 | ContextType = BlpArchQueryCurrentContextType(); 222 | if (ContextType != ExecutionContextFirmware) { 223 | BlMmTranslateVirtualAddress(DebugPortInterface, &InterfacePa); 224 | DebugPortInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 225 | BlMmTranslateVirtualAddress(Buffer, &BufferPa); 226 | Buffer = (PVOID)(UINTN)BufferPa.QuadPart; 227 | BlMmTranslateVirtualAddress(BufferSize, &BufferSizePa); 228 | BufferSize = (PVOID)(UINTN)BufferSizePa.QuadPart; 229 | BlpArchSwitchContext(ExecutionContextFirmware); 230 | } 231 | 232 | // 233 | // Use the debug port protocol Read implementation to read the data 234 | // from debug port. 235 | // 236 | 237 | EfiStatus = DebugPortInterface->Read(DebugPortInterface, 238 | Timeout, 239 | BufferSize, 240 | Buffer); 241 | 242 | // 243 | // Restore original execution context. 244 | // 245 | 246 | if (ContextType != ExecutionContextFirmware) { 247 | BlpArchSwitchContext(ContextType); 248 | } 249 | 250 | return EfiGetNtStatusCode(EfiStatus); 251 | } 252 | 253 | NTSTATUS 254 | EfiDebugPortPoll ( 255 | __in EFI_DEBUGPORT *DebugPortInterface 256 | ) 257 | 258 | /*++ 259 | 260 | Routine Description: 261 | 262 | Wrapper for an EFI Debug Port Interface call to test if new data is available 263 | on debug port. 264 | 265 | Arguments: 266 | 267 | DebugPortInterface - Debug port interface. (This is a physical 268 | address pointer). 269 | 270 | Return Value: 271 | 272 | STATUS_SUCCESS when new data is available. 273 | STATUS_NOT_FOUND when there is no new data available. 274 | STATUS_IO_DEVICE_ERROR if the device reported an error when performing 275 | operation. 276 | 277 | --*/ 278 | 279 | { 280 | 281 | EXECUTION_CONTEXT_TYPE ContextType; 282 | EFI_STATUS EfiStatus; 283 | PHYSICAL_ADDRESS InterfacePa; 284 | 285 | // 286 | // If the application is running within the application execution context, 287 | // switch it to firmware execution context for making firmware the call. 288 | // Translate all virtual addresses to their respective physical addresses. 289 | // 290 | 291 | ContextType = BlpArchQueryCurrentContextType(); 292 | if (ContextType != ExecutionContextFirmware) { 293 | BlMmTranslateVirtualAddress(DebugPortInterface, &InterfacePa); 294 | DebugPortInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 295 | BlpArchSwitchContext(ExecutionContextFirmware); 296 | } 297 | 298 | // 299 | // Use the debug port protocol Poll implementation to query 300 | // data availability on debug port. 301 | // 302 | 303 | EfiStatus = DebugPortInterface->Poll(DebugPortInterface); 304 | 305 | // 306 | // Restore original execution context. 307 | // 308 | 309 | if (ContextType != ExecutionContextFirmware) { 310 | BlpArchSwitchContext(ContextType); 311 | } 312 | 313 | return EfiGetNtStatusCode(EfiStatus); 314 | } 315 | 316 | 317 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efilib.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efilib.c 8 | 9 | Abstract: 10 | 11 | Various library routines for EFI firmware boot. 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "bootlibp.h" 22 | 23 | // ------------------------------------------------------------------ Functions 24 | 25 | EFI_STATUS 26 | EfiGetEfiStatusCode ( 27 | __in NTSTATUS NtStatus 28 | ) 29 | 30 | /*++ 31 | 32 | Routine Description: 33 | 34 | This routine returns the closest equivalent EFI status code for the 35 | specified NT status code. 36 | 37 | Arguments: 38 | 39 | NtStatus - Supplies a NT status code. 40 | 41 | Return Value: 42 | 43 | EFI status code. 44 | 45 | --*/ 46 | 47 | { 48 | 49 | switch (NtStatus) { 50 | case STATUS_SUCCESS: 51 | return EFI_SUCCESS; 52 | 53 | case STATUS_DRIVER_UNABLE_TO_LOAD: 54 | return EFI_LOAD_ERROR; 55 | 56 | case STATUS_INVALID_PARAMETER: 57 | return EFI_INVALID_PARAMETER; 58 | 59 | case STATUS_NOT_SUPPORTED: 60 | return EFI_UNSUPPORTED; 61 | 62 | case STATUS_INVALID_BUFFER_SIZE: 63 | return EFI_BAD_BUFFER_SIZE; 64 | 65 | case STATUS_BUFFER_TOO_SMALL: 66 | return EFI_BUFFER_TOO_SMALL; 67 | 68 | case STATUS_IO_DEVICE_ERROR: 69 | return EFI_DEVICE_ERROR; 70 | 71 | case STATUS_MEDIA_WRITE_PROTECTED: 72 | return EFI_WRITE_PROTECTED; 73 | 74 | case STATUS_INSUFFICIENT_RESOURCES: 75 | return EFI_OUT_OF_RESOURCES; 76 | 77 | case STATUS_DISK_CORRUPT_ERROR: 78 | return EFI_VOLUME_CORRUPTED; 79 | 80 | case STATUS_DISK_FULL: 81 | return EFI_VOLUME_FULL; 82 | 83 | case STATUS_NO_MEDIA: 84 | return EFI_NO_MEDIA; 85 | 86 | case STATUS_MEDIA_CHANGED: 87 | return EFI_MEDIA_CHANGED; 88 | 89 | case STATUS_NOT_FOUND: 90 | return EFI_NOT_FOUND; 91 | 92 | case STATUS_ACCESS_DENIED: 93 | return EFI_ACCESS_DENIED; 94 | 95 | case STATUS_NO_MATCH: 96 | return EFI_NO_MAPPING; 97 | 98 | case STATUS_TIMEOUT: 99 | return EFI_TIMEOUT; 100 | 101 | case STATUS_DEVICE_NOT_READY: 102 | return EFI_NOT_STARTED; 103 | 104 | case STATUS_DEVICE_ALREADY_ATTACHED: 105 | return EFI_ALREADY_STARTED; 106 | 107 | case STATUS_REQUEST_ABORTED: 108 | return EFI_ABORTED; 109 | 110 | default: 111 | return EFI_NO_MAPPING; 112 | } 113 | } 114 | 115 | NTSTATUS 116 | EfiGetNtStatusCode ( 117 | __in EFI_STATUS EfiStatus 118 | ) 119 | 120 | /*++ 121 | 122 | Routine Description: 123 | 124 | This routine returns the closest equivalent NT status code for the 125 | specified EFI status code. 126 | 127 | Arguments: 128 | 129 | EfiStatus - Supplies an EFI status code. 130 | 131 | Return Value: 132 | 133 | NT status code. 134 | 135 | --*/ 136 | 137 | { 138 | 139 | switch (EfiStatus) { 140 | case EFI_SUCCESS: 141 | return STATUS_SUCCESS; 142 | 143 | case EFI_LOAD_ERROR: 144 | return STATUS_DRIVER_UNABLE_TO_LOAD; 145 | 146 | case EFI_INVALID_PARAMETER: 147 | return STATUS_INVALID_PARAMETER; 148 | 149 | case EFI_UNSUPPORTED: 150 | return STATUS_NOT_SUPPORTED; 151 | 152 | case EFI_BAD_BUFFER_SIZE: 153 | return STATUS_INVALID_BUFFER_SIZE; 154 | 155 | case EFI_BUFFER_TOO_SMALL: 156 | return STATUS_BUFFER_TOO_SMALL; 157 | 158 | case EFI_NOT_READY: 159 | return STATUS_NOT_FOUND; 160 | 161 | case EFI_DEVICE_ERROR: 162 | return STATUS_IO_DEVICE_ERROR; 163 | 164 | case EFI_WRITE_PROTECTED: 165 | return STATUS_MEDIA_WRITE_PROTECTED; 166 | 167 | case EFI_OUT_OF_RESOURCES: 168 | return STATUS_INSUFFICIENT_NVRAM_RESOURCES; 169 | 170 | case EFI_VOLUME_CORRUPTED: 171 | return STATUS_DISK_CORRUPT_ERROR; 172 | 173 | case EFI_VOLUME_FULL: 174 | return STATUS_DISK_FULL; 175 | 176 | case EFI_NO_MEDIA: 177 | return STATUS_NO_MEDIA; 178 | 179 | case EFI_MEDIA_CHANGED: 180 | return STATUS_MEDIA_CHANGED; 181 | 182 | case EFI_NOT_FOUND: 183 | return STATUS_NOT_FOUND; 184 | 185 | case EFI_ACCESS_DENIED: 186 | case EFI_SECURITY_VIOLATION: 187 | return STATUS_ACCESS_DENIED; 188 | 189 | case EFI_NO_RESPONSE: 190 | return STATUS_TIMEOUT; 191 | 192 | case EFI_NO_MAPPING: 193 | return STATUS_NO_MATCH; 194 | 195 | case EFI_TIMEOUT: 196 | return STATUS_TIMEOUT; 197 | 198 | case EFI_NOT_STARTED: 199 | return STATUS_DEVICE_NOT_READY; 200 | 201 | case EFI_ALREADY_STARTED: 202 | return STATUS_DEVICE_ALREADY_ATTACHED; 203 | 204 | case EFI_ABORTED: 205 | return STATUS_REQUEST_ABORTED; 206 | 207 | case EFI_ICMP_ERROR: 208 | case EFI_TFTP_ERROR: 209 | case EFI_PROTOCOL_ERROR: 210 | //case EFI_INCOMPATIBLE_VERSION: 211 | //case EFI_CRC_ERROR: 212 | default: 213 | return STATUS_UNSUCCESSFUL; 214 | } 215 | } 216 | 217 | VOID 218 | EfiPrintf ( 219 | __in PWSTR Format, 220 | ... 221 | ) 222 | 223 | /*++ 224 | 225 | Routine Description: 226 | 227 | Simple print routine. Defined as ConsolePrint and used for debug purposes 228 | when console display does not work. 229 | 230 | Arguments: 231 | 232 | Format - printf style format 233 | 234 | ... - arguments. 235 | 236 | Return Value: 237 | 238 | none 239 | 240 | --*/ 241 | 242 | { 243 | 244 | va_list Arglist; 245 | LONG Ret; 246 | ULONG Size; 247 | 248 | va_start(Arglist, Format); 249 | Size = GLOBAL_SCRATCH_BUFFER_SIZE/sizeof(WCHAR) - 1; 250 | Ret = vswprintf_s((PWCHAR)BlScratchBuffer, Size, Format, Arglist); 251 | if (Ret > 0) { 252 | ((PWCHAR)BlScratchBuffer)[Size] = L'\0'; 253 | EfiPrint((PWCHAR)BlScratchBuffer); 254 | } 255 | } 256 | 257 | EFI_DEVICE_PATH UNALIGNED * 258 | EfiGetLeafNode ( 259 | __in EFI_DEVICE_PATH UNALIGNED *DevicePath 260 | ) 261 | 262 | /*++ 263 | 264 | Routine Description: 265 | 266 | Get the last node of an EFI device path. 267 | 268 | Arguments: 269 | 270 | DevicePath - Efi device path. 271 | 272 | Return Value: 273 | 274 | A pointer to the last node in the device path. 275 | 276 | --*/ 277 | 278 | { 279 | 280 | EFI_DEVICE_PATH UNALIGNED *Dp; 281 | 282 | ASSERT(DevicePath != NULL); 283 | 284 | if (IsDevicePathEndType(DevicePath)) { 285 | return DevicePath; 286 | } 287 | 288 | // 289 | // Walk down the device path, have DevicePath lag by one node. 290 | // 291 | 292 | Dp = NextDevicePathNode(DevicePath); 293 | while (!IsDevicePathEndType(Dp)) { 294 | DevicePath = Dp; 295 | Dp = NextDevicePathNode(Dp); 296 | } 297 | 298 | return DevicePath; 299 | } 300 | 301 | HARDDRIVE_DEVICE_PATH UNALIGNED * 302 | EfiGetFirstHardDriveNode ( 303 | __in EFI_DEVICE_PATH UNALIGNED *DevicePath 304 | ) 305 | 306 | /*++ 307 | 308 | Routine Description: 309 | 310 | This routine returns the first hard drive node in an EFI device path. 311 | 312 | Arguments: 313 | 314 | DevicePath - Supplies a pointer to the first node in an EFI device path. 315 | 316 | Return Value: 317 | 318 | A pointer to the first hard drive node found. NULL if no such node was 319 | found. 320 | 321 | --*/ 322 | 323 | { 324 | 325 | EFI_DEVICE_PATH UNALIGNED *CurrentNode; 326 | 327 | ASSERT(DevicePath != NULL); 328 | 329 | CurrentNode = DevicePath; 330 | while ((CurrentNode != NULL) && 331 | (IsDevicePathEndType(CurrentNode) == FALSE)) { 332 | 333 | if ((CurrentNode->Type == MEDIA_DEVICE_PATH) && 334 | (CurrentNode->SubType == MEDIA_HARDDRIVE_DP)) { 335 | 336 | return (HARDDRIVE_DEVICE_PATH UNALIGNED *)CurrentNode; 337 | } 338 | 339 | CurrentNode = NextDevicePathNode(CurrentNode); 340 | } 341 | 342 | return NULL; 343 | } 344 | 345 | EFI_DEVICE_PATH UNALIGNED * 346 | EfiIsDevicePathParent ( 347 | __in EFI_DEVICE_PATH UNALIGNED *DevicePath1, 348 | __in EFI_DEVICE_PATH UNALIGNED *DevicePath2 349 | ) 350 | 351 | /*++ 352 | 353 | Routine Description: 354 | 355 | Determines the relationship between DevicePath1 and DevicePath2. In 356 | particular, this routine determines if either is the parent of the 357 | other. 358 | 359 | Arguments: 360 | 361 | DevicePath1 - Efi device path. 362 | 363 | DevicePath2 - Efi device path. 364 | 365 | Return Value: 366 | 367 | DevicePath1 if DevicePath2 is the child of DevicePath1. 368 | 369 | DevicePath2 if DevicePath1 is the child of DevicePath2. 370 | 371 | NULL otherwise. 372 | 373 | --*/ 374 | 375 | { 376 | 377 | EFI_DEVICE_PATH UNALIGNED *Dp1; 378 | EFI_DEVICE_PATH UNALIGNED *Dp2; 379 | UINTN Num; 380 | 381 | Dp1 = DevicePath1; 382 | Dp2 = DevicePath2; 383 | 384 | // 385 | // Iterate through the device paths comparing each node. Return from the 386 | // function if the nodes ever differ. That way, if we ever break out of 387 | // the loop, one of the two paths is the parent of the other. 388 | // 389 | 390 | while (!IsDevicePathEndType(Dp1) && !IsDevicePathEndType(Dp2)) { 391 | 392 | // 393 | // Check to make sure this node is the same for both device paths. If 394 | // not, return now. 395 | // 396 | 397 | if (DevicePathNodeLength(Dp1) != DevicePathNodeLength(Dp2)) { 398 | return NULL; 399 | } 400 | 401 | Num = RtlCompareMemory(Dp1, Dp2, DevicePathNodeLength(Dp1)); 402 | if (Num != (UINTN)DevicePathNodeLength(Dp1)) { 403 | return NULL; 404 | } 405 | 406 | // 407 | // Try the next node. 408 | // 409 | 410 | Dp1 = NextDevicePathNode(Dp1); 411 | Dp2 = NextDevicePathNode(Dp2); 412 | } 413 | 414 | // 415 | // Catch the case where DevicePath1 == DevicePath2. 416 | // 417 | 418 | if (IsDevicePathEndType(Dp1) && IsDevicePathEndType(Dp2)) { 419 | return NULL; 420 | } 421 | 422 | // 423 | // We iterated through the device path's and the are equivalent. The 424 | // non-null device path is the child. 425 | // 426 | 427 | return IsDevicePathEndType(Dp1) ? DevicePath1 : DevicePath2; 428 | } 429 | 430 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efipci.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efipci.c 8 | 9 | Abstract: 10 | 11 | Wrappers for EFI PCI Root Bridge I/O Protocol routines. 12 | 13 | The PCI Root Bridge I/O Protocol provides functional support to read and 14 | write PCI device resources beneath a root bus. This module provides 15 | wrappers for these functions to correctly handle cases such as whether the 16 | caller is in virtual mode, physical mode, etc. 17 | 18 | --*/ 19 | 20 | // ------------------------------------------------------------------- Includes 21 | 22 | #include "bootlibp.h" 23 | 24 | // ------------------------------------------------------------------ Functions 25 | 26 | NTSTATUS 27 | EfiPciAccessConfigSpace ( 28 | __in EFI_PCI_ROOT_BRIDGE_IO_INTERFACE *RootBridgeInterface, 29 | __in EFI_PCI_IO_PROTOCOL_WIDTH Width, 30 | __in UINT64 Address, 31 | __in UINTN Count, 32 | __inout PVOID Buffer, 33 | __in BOOLEAN ReadAccess 34 | ) 35 | 36 | /*++ 37 | 38 | Routine Description: 39 | 40 | This routine accesses PCI configuration space of a device using the given 41 | PCI Root Bridge I/O Interface. 42 | 43 | Arguments: 44 | 45 | RootBridgeInterface - Supplies a pointer to the PCI Root Bridge I/O 46 | Interface to use. 47 | 48 | Width - Supplies the width and access type to use. This dictates whether 49 | the address is considered to be a hardware-fill FIFO or a buffer, as 50 | well as whether the address is to be accessed in 1, 2, 4 or 8 byte 51 | chunks. 52 | 53 | Address - Supplies the PCI configuration space address to access. This is 54 | constructed with the following bit fields: 55 | 56 | Register (low byte) - 0-7 57 | Function Number - 7-15 58 | Device Number - 16-23 59 | Bus Number - 24-31 60 | Register (remaining) - 32-64 61 | 62 | The segment number of the access is fixed by the interface in use. 63 | 64 | Count - Supplies the number of transactions to issue. The total number of 65 | bytes accessed will be this value multiplied by the width indicated 66 | above. 67 | 68 | Buffer - Supplies the buffer to use to transfer data to or from the device. 69 | 70 | ReadAccess - Supplies a boolean indicating whether the access is a read 71 | or write access. 72 | 73 | Return Value: 74 | 75 | NT Status code. 76 | 77 | STATUS_SUCCESS if the access completes successfully. 78 | 79 | STATUS_INVALID_PARAMETER if the width parameter or address field are out 80 | of range for this root bus. 81 | 82 | STATUS_INSUFFICIENT_RESOURCES if the firmware encounters a resource failure. 83 | 84 | --*/ 85 | 86 | { 87 | 88 | EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM AccessRoutine; 89 | PHYSICAL_ADDRESS BufferPa; 90 | EXECUTION_CONTEXT_TYPE ContextType; 91 | EFI_STATUS EfiStatus; 92 | PHYSICAL_ADDRESS InterfacePa; 93 | 94 | // 95 | // If the application is running within the application execution context, 96 | // switch it to firmware execution context for making firmware the call. 97 | // Translate all virtual addresses to their respective physical addresses. 98 | // 99 | 100 | ContextType = BlpArchQueryCurrentContextType(); 101 | if (ContextType != ExecutionContextFirmware) { 102 | BlMmTranslateVirtualAddress(RootBridgeInterface, &InterfacePa); 103 | RootBridgeInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 104 | BlMmTranslateVirtualAddress(Buffer, &BufferPa); 105 | Buffer = (PVOID)(UINTN)BufferPa.QuadPart; 106 | BlpArchSwitchContext(ExecutionContextFirmware); 107 | } 108 | 109 | if (ReadAccess != FALSE) { 110 | AccessRoutine = RootBridgeInterface->Pci.Read; 111 | 112 | } else { 113 | AccessRoutine = RootBridgeInterface->Pci.Write; 114 | } 115 | 116 | EfiStatus = AccessRoutine(RootBridgeInterface, 117 | Width, 118 | Address, 119 | Count, 120 | Buffer); 121 | 122 | // 123 | // Restore original execution context. 124 | // 125 | 126 | if (ContextType != ExecutionContextFirmware) { 127 | BlpArchSwitchContext(ContextType); 128 | } 129 | 130 | return EfiGetNtStatusCode(EfiStatus); 131 | } 132 | 133 | NTSTATUS 134 | EfiPciGetConfiguration ( 135 | __in EFI_PCI_ROOT_BRIDGE_IO_INTERFACE *RootBridgeInterface, 136 | __out PPHYSICAL_ADDRESS Resources 137 | ) 138 | 139 | /*++ 140 | 141 | Routine Description: 142 | 143 | This routine retrieves the resource configuration from the root bus that 144 | supports the given PCI Root Bridge I/O Interface. 145 | 146 | Arguments: 147 | 148 | RootBridgeInterface - Supplies the PCI Root Bridge I/O Interface for which 149 | the resource configuration is to be retrieved. 150 | 151 | Resources - Supplies a pointer to a variable that receives the physical 152 | address of the resource configuration buffer. This physical address is 153 | to BIOS-internal memory and must be treated as read-only. The resource 154 | buffer is an array of ACPI resource descriptors terminated by an end 155 | tag. The valid length of the buffer can only be determined by walking 156 | it. 157 | 158 | N.B. If a caller of this routine is executing with virtual address 159 | translation enabled, it must either revert to physical mode to 160 | walk the buffer for the purposes of determining its length or 161 | carefully map the buffer speculatively. 162 | 163 | Return Value: 164 | 165 | --*/ 166 | 167 | { 168 | 169 | PVOID Buffer; 170 | PVOID *BufferPointer; 171 | PHYSICAL_ADDRESS BufferPointerPa; 172 | EXECUTION_CONTEXT_TYPE ContextType; 173 | EFI_STATUS EfiStatus; 174 | PHYSICAL_ADDRESS InterfacePa; 175 | NTSTATUS Status; 176 | 177 | // 178 | // If the application is running within the application execution context, 179 | // switch it to firmware execution context for making firmware the call. 180 | // Translate all virtual addresses to their respective physical addresses. 181 | // 182 | 183 | Buffer = NULL; 184 | ContextType = BlpArchQueryCurrentContextType(); 185 | if (ContextType != ExecutionContextFirmware) { 186 | BlMmTranslateVirtualAddress(RootBridgeInterface, &InterfacePa); 187 | RootBridgeInterface = (PVOID)(UINTN)InterfacePa.QuadPart; 188 | BlMmTranslateVirtualAddress(&Buffer, &BufferPointerPa); 189 | BufferPointer = (PVOID *)(UINTN)BufferPointerPa.QuadPart; 190 | BlpArchSwitchContext(ExecutionContextFirmware); 191 | 192 | } else { 193 | BufferPointer = &Buffer; 194 | } 195 | 196 | // 197 | // Call the interface configuration routine to get the resources decoded 198 | // by the root bus exposing this interface. 199 | // 200 | 201 | EfiStatus = RootBridgeInterface->Configuration(RootBridgeInterface, 202 | BufferPointer); 203 | 204 | Status = EfiGetNtStatusCode(EfiStatus); 205 | 206 | // 207 | // The configuration routine populates the buffer pointer with a physical 208 | // mode pointer to the resource configuration. 209 | // 210 | 211 | if (NT_SUCCESS(Status)) { 212 | Resources->QuadPart = (ULONG_PTR)Buffer; 213 | } 214 | 215 | // 216 | // Restore original execution context. 217 | // 218 | 219 | if (ContextType != ExecutionContextFirmware) { 220 | BlpArchSwitchContext(ContextType); 221 | } 222 | 223 | return Status; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efirng.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efirng.c 8 | 9 | Abstract: 10 | 11 | Wrappers for EFI RNG routines. 12 | 13 | All efi call must be made in physical mode. When a boot environment 14 | application runs in virtual mode, pointers need to be modified and fixed 15 | before every EFI call. Additionally firmware pointers/addresses need to be 16 | virtually mapped for the caller to read contents. The wrappers intend to 17 | hide as much of that work as possible from the caller. 18 | 19 | Environment: 20 | 21 | Boot 22 | 23 | --*/ 24 | 25 | // 26 | // ------------------------------------------------------------------- Includes 27 | // 28 | 29 | #include "bootlibp.h" 30 | 31 | // 32 | // -------------------------------------------------------------------- Pragmas 33 | // 34 | 35 | //#pragma warning(disable:4152) // Function pointer to data pointer. 36 | 37 | // 38 | // --------------------------------------------------------------- RNG Services 39 | // 40 | 41 | NTSTATUS 42 | EfiRngGetRng ( 43 | __in EFI_RNG_PROTOCOL *Protocol, 44 | __in UINTN RNGValueLength, 45 | __out_bcount(RNGValueLenth) UINT8 *RNGValue 46 | ) 47 | 48 | /*++ 49 | 50 | Routine Description: 51 | 52 | Wrapper function around the EFI RNG protocol GetRng function 53 | to take care of the virtual/physical address mappings. 54 | 55 | Arguments: 56 | 57 | Protocol - Supplies a pointer to the RNG protocol structure 58 | 59 | RNGValueLength - Supplies the size of the RNGValue buffer. 60 | 61 | RNGValue - Supplies a pointer to the buffer that receives the 62 | random bytes 63 | 64 | Return Value: 65 | 66 | STATUS_SUCCESS or error value. 67 | 68 | --*/ 69 | 70 | { 71 | 72 | EXECUTION_CONTEXT_TYPE ContextType; 73 | EFI_STATUS EfiStatus; 74 | PHYSICAL_ADDRESS Pa = {0}; 75 | EFI_RNG_PROTOCOL *ProtocolPa; 76 | UINT8 *RNGValuePa; 77 | 78 | ProtocolPa = Protocol; 79 | RNGValuePa = RNGValue; 80 | ContextType = BlpArchQueryCurrentContextType(); 81 | if (ContextType != ExecutionContextFirmware) { 82 | BlMmTranslateVirtualAddress(Protocol, &Pa); 83 | ProtocolPa = (PVOID)(ULONG_PTR)Pa.QuadPart; 84 | BlMmTranslateVirtualAddress(RNGValue, &Pa); 85 | RNGValuePa = (PVOID)(ULONG_PTR)Pa.QuadPart; 86 | BlpArchSwitchContext(ExecutionContextFirmware); 87 | } 88 | 89 | // 90 | // Make the requested service call. 91 | // 92 | 93 | EfiStatus = ProtocolPa->GetRNG( ProtocolPa, 94 | NULL, 95 | RNGValueLength, 96 | RNGValuePa ); 97 | 98 | // 99 | // Restore original execution context. 100 | // 101 | 102 | if (ContextType != ExecutionContextFirmware) { 103 | BlpArchSwitchContext(ContextType); 104 | } 105 | 106 | return EfiGetNtStatusCode(EfiStatus); 107 | } 108 | 109 | 110 | -------------------------------------------------------------------------------- /boot/environ/lib/firmware/efi/efisc.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | efisc.c 8 | 9 | Abstract: 10 | 11 | This module contains the wrapper functions to call the EFI BIOS for 12 | doing Security Commands with the storage device. 13 | 14 | Environment: 15 | 16 | Boot 17 | 18 | --*/ 19 | 20 | // 21 | // ------------------------------------------------------------------- Includes 22 | // 23 | 24 | #include "bootlibp.h" 25 | 26 | // 27 | // ------------------------------------------------------------------ Functions 28 | // 29 | 30 | NTSTATUS 31 | EfiScpReceiveData ( 32 | __in EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Interface, 33 | __in UINT32 MediaId, 34 | __in UINT64 Timeout, 35 | __in UINT8 SecurityProtocol, 36 | __in UINT16 SecurityProtocolSpecificData, 37 | __in UINTN PayloadBufferSize, 38 | __out VOID *PayloadBuffer, 39 | __out UINTN *PayloadTransferSize 40 | ) 41 | 42 | /*++ 43 | 44 | Routine Description: 45 | 46 | This routine is a wrapper for EFI_STORAGE_SECURITY_RECEIVE_DATA 47 | (aka TrustedReceive) which will return the result and data for 48 | the previous EFI_STORAGE_SECURITY_SEND_DATA call. 49 | 50 | Arguments: 51 | 52 | Interface - Supplies a pointer to the protocol interface structure. 53 | 54 | MediaId - Supplies the ID of the medium to receive data from. 55 | 56 | Timeout - Supplies the time, in 100ns units, for the execution of the 57 | security protocol command. A Timeout value of 0 means this function 58 | will wait indefinitely for the security protocol command to execute. 59 | If Timeout is greater than zero, this function will return EFI_TIMEOUT 60 | if the time required to execute the receive data command is greater 61 | than Timeout. 62 | 63 | SecurityProtocol - Supplies the value of the "Security Protocol" parameter 64 | of the security protocol command to be sent. 65 | 66 | SecurityProtocolSpecificData - Supplies the value of the "Security Protocol 67 | Specific" parameter of the security protocol command to be sent. 68 | 69 | PayloadBufferSize - Supplies the size, in bytes, of the payload data buffer. 70 | 71 | PayloadBuffer - Supplies the pointer to the destination buffer to store the 72 | security protocol command specific payload data for the security 73 | protocol command. The caller is responsible for having either implicit 74 | or explicit ownership of the buffer. 75 | 76 | PayloadTransferSize - Supplies a pointer to a variable to store the size, 77 | in bytes, of the data written to the payload data buffer. 78 | 79 | Return Value: 80 | 81 | NT Status code. 82 | 83 | --*/ 84 | 85 | { 86 | 87 | EXECUTION_CONTEXT_TYPE ContextType; 88 | EFI_STATUS EfiStatus; 89 | PHYSICAL_ADDRESS InterfacePa = {0}; 90 | PHYSICAL_ADDRESS PayloadBufferPa = {0}; 91 | PHYSICAL_ADDRESS PayloadTransferSizePa = {0}; 92 | 93 | // 94 | // If the application is running within the application execution 95 | // context, switch it to firmware execution context for making 96 | // firmware call. Translate all virtual addresses to their 97 | // respective physical addresses. 98 | // 99 | 100 | ContextType = BlpArchQueryCurrentContextType(); 101 | if (ContextType != ExecutionContextFirmware) { 102 | BlMmTranslateVirtualAddress(Interface, &InterfacePa); 103 | Interface = (EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *) 104 | (UINTN)InterfacePa.QuadPart; 105 | 106 | BlMmTranslateVirtualAddress(PayloadBuffer, &PayloadBufferPa); 107 | PayloadBuffer = (VOID *)(UINTN)PayloadBufferPa.QuadPart; 108 | 109 | BlMmTranslateVirtualAddress(PayloadTransferSize, 110 | &PayloadTransferSizePa); 111 | 112 | PayloadTransferSize = (UINTN *)(UINTN)PayloadTransferSizePa.QuadPart; 113 | BlpArchSwitchContext(ExecutionContextFirmware); 114 | } 115 | 116 | EfiStatus = Interface->ReceiveData(Interface, 117 | MediaId, 118 | Timeout, 119 | SecurityProtocol, 120 | SecurityProtocolSpecificData, 121 | PayloadBufferSize, 122 | PayloadBuffer, 123 | PayloadTransferSize); 124 | 125 | if (ContextType != ExecutionContextFirmware) { 126 | BlpArchSwitchContext(ContextType); 127 | } 128 | 129 | return EfiGetNtStatusCode(EfiStatus); 130 | } 131 | 132 | NTSTATUS 133 | EfiScpSendData ( 134 | __in EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Interface, 135 | __in UINT32 MediaId, 136 | __in UINT64 Timeout, 137 | __in UINT8 SecurityProtocol, 138 | __in UINT16 SecurityProtocolSpecificData, 139 | __in UINTN PayloadBufferSize, 140 | __in VOID *PayloadBuffer 141 | ) 142 | 143 | /*++ 144 | 145 | Routine Description: 146 | 147 | This routine is a wrapper for EFI_STORAGE_SECURITY_SEND_DATA 148 | (aka TrustedSend) which will send the payload to the device 149 | using Security Command Protocol. 150 | 151 | Arguments: 152 | 153 | Interface - Supplies a pointer to the protocol interface structure. 154 | 155 | MediaId - Supplies the ID of the medium to send data to. 156 | 157 | Timeout - Supplies the time, in 100ns units, for the execution of the 158 | security protocol command. A Timeout value of 0 means this function 159 | will wait indefinitely for the security protocol command to execute. 160 | If Timeout is greater than zero, this function will return EFI_TIMEOUT 161 | if the time required to execute the send data command is greater than 162 | Timeout. 163 | 164 | SecurityProtol - Supplies the value of the "Security Protocol" parameter 165 | of the security protocol command to be sent. 166 | 167 | SecurityProtocolSpecificData - Supplies the value of the "Security 168 | Protocol Specific" parameter of the security protocol command to be 169 | sent. 170 | 171 | PayloadBufferSize - Supplies the size, in bytes, of the payload data buffer. 172 | 173 | PayloadBuffer - Supplies a pointer to the buffer containing the security 174 | protocol command specific payload data for the security protocol 175 | command. 176 | 177 | Return Value: 178 | 179 | NT Status code. 180 | 181 | --*/ 182 | 183 | { 184 | 185 | EXECUTION_CONTEXT_TYPE ContextType; 186 | EFI_STATUS EfiStatus; 187 | PHYSICAL_ADDRESS InterfacePa = {0}; 188 | PHYSICAL_ADDRESS PayloadBufferPa = {0}; 189 | 190 | // 191 | // If the application is running within the application execution 192 | // context, switch it to firmware execution context for making 193 | // firmware call. Translate all virtual addresses to their 194 | // respective physical addresses. 195 | // 196 | 197 | ContextType = BlpArchQueryCurrentContextType(); 198 | if (ContextType != ExecutionContextFirmware) { 199 | BlMmTranslateVirtualAddress(Interface, &InterfacePa); 200 | Interface = (EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *) 201 | (UINTN)InterfacePa.QuadPart; 202 | 203 | BlMmTranslateVirtualAddress(PayloadBuffer, &PayloadBufferPa); 204 | PayloadBuffer = (VOID *)(UINTN)PayloadBufferPa.QuadPart; 205 | BlpArchSwitchContext(ExecutionContextFirmware); 206 | } 207 | 208 | EfiStatus = Interface->SendData(Interface, 209 | MediaId, 210 | Timeout, 211 | SecurityProtocol, 212 | SecurityProtocolSpecificData, 213 | PayloadBufferSize, 214 | PayloadBuffer); 215 | 216 | if (ContextType != ExecutionContextFirmware) { 217 | BlpArchSwitchContext(ContextType); 218 | } 219 | 220 | return EfiGetNtStatusCode(EfiStatus); 221 | } 222 | 223 | 224 | -------------------------------------------------------------------------------- /boot/environ/lib/io/device/device.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | device.h 8 | 9 | Abstract: 10 | 11 | Header file for boot environment device i/o. 12 | 13 | When device's are opened, an entry is created in a device table. After 14 | this, all device i/o calls are directed based on function pointers set 15 | during the specific devices open routine. 16 | 17 | This header is to be included by all device implementation of i/o (ie. 18 | console, disk, etc). It contains definitions for the routines each 19 | needs to implement and the data structures used in each. 20 | 21 | Environment: 22 | 23 | Boot. 24 | 25 | Revision History: 26 | 27 | --*/ 28 | 29 | #pragma once 30 | 31 | // ------------------------------------------------------------------- Includes 32 | 33 | #include 34 | 35 | // ------------------------------------------------- Data Structure Definitions 36 | 37 | typedef ULONG DEVICE_ATTRIBUTES; 38 | typedef DEVICE_ATTRIBUTES *PDEVICE_ATTRIBUTES; 39 | 40 | #define DEVICE_OPEN (0x01) 41 | #define DEVICE_READ (0x02) 42 | #define DEVICE_WRITE (0x04) 43 | #define DEVICE_NO_FVE (0x08) 44 | #define DEVICE_OPEN_BY_HASH (0x10) 45 | #define DEVICE_NT_DEVICE (0x20) 46 | 47 | // --------------------------------------------------------------------- Macros 48 | 49 | #define SET_DEVICE_OPEN(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_OPEN) 50 | #define SET_DEVICE_READ(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_READ) 51 | #define SET_DEVICE_WRITE(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_WRITE) 52 | #define SET_DEVICE_NO_FVE(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_NO_FVE) 53 | #define SET_DEVICE_OPEN_BY_HASH(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_OPEN_BY_HASH) 54 | #define SET_DEVICE_NT_DEVICE(_x) ((DEVICE_ATTRIBUTES)_x |= DEVICE_NT_DEVICE) 55 | 56 | #define CLEAR_DEVICE_OPEN(_x) ((DEVICE_ATTRIBUTES)_x &= ~DEVICE_OPEN) 57 | #define CLEAR_DEVICE_ATTRIBUTES(_x) ((DEVICE_ATTRIBUTES)_x = 0) 58 | 59 | #define IS_DEVICE_OPENED(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_OPEN) 60 | #define IS_DEVICE_READ_SET(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_READ) 61 | #define IS_DEVICE_WRITE_SET(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_WRITE) 62 | #define IS_DEVICE_NO_FVE_SET(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_NO_FVE) 63 | #define IS_DEVICE_OPEN_BY_HASH_SET(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_OPEN_BY_HASH) 64 | #define IS_DEVICE_NT_DEVICE(_x) ((DEVICE_ATTRIBUTES)_x & DEVICE_NT_DEVICE) 65 | #define IS_DEVICE_OPENED_FOR_READ(_x) (IS_DEVICE_OPENED(_x) && \ 66 | IS_DEVICE_READ_SET(_x)) 67 | #define IS_DEVICE_OPENED_FOR_WRITE(_x) (IS_DEVICE_OPENED(_x) && \ 68 | IS_DEVICE_WRITE_SET(_x)) 69 | 70 | // ------------------------------------------------------------ Data Structures 71 | 72 | typedef enum _OVERLAY_STATE { 73 | OverlayOpened, 74 | OverlayClosed, 75 | OverlayError 76 | } OVERLAY_STATE; 77 | 78 | typedef struct _OVERLAY_ENTRY { 79 | LARGE_INTEGER DataSourceId; 80 | PBOOT_ENVIRONMENT_DEVICE DeviceIdentifier; 81 | OVERLAY_STATE State; 82 | DEVICE_ID DeviceId; 83 | } OVERLAY_ENTRY, *POVERLAY_ENTRY; 84 | 85 | typedef struct _DEVICE_OVERLAY { 86 | ULONG OverlayCount; 87 | POVERLAY_CONFIG OverlayConfig; 88 | OVERLAY_ENTRY Entry[ANYSIZE_ARRAY]; 89 | } DEVICE_OVERLAY, *PDEVICE_OVERLAY; 90 | 91 | typedef struct _OVERLAY_INFORMATION { 92 | DEVICE_ID DeviceId; 93 | LARGE_INTEGER DataSourceId; 94 | } OVERLAY_INFORMATION, *POVERLAY_INFORMATION; 95 | 96 | typedef struct _DEVICE_ENTRY { 97 | DEVICE_ID DeviceId; 98 | PDEVICE_OVERLAY Overlay; 99 | OVERLAY_INFORMATION OverlayInfo; 100 | DEVICE_ATTRIBUTES Attributes; 101 | ULONG FilterLevel; 102 | ULONG ReferenceCount; 103 | DEVICE_FUNCTION_TABLE FunctionTable; 104 | PVOID DeviceData; 105 | PBOOT_ENVIRONMENT_DEVICE DeviceIdentifier; 106 | } DEVICE_ENTRY, *PDEVICE_ENTRY; 107 | 108 | /*++ 109 | 110 | Device Entry Description: 111 | 112 | A device entry is the internal representation for a device after it has 113 | been opened. 114 | 115 | Fields: 116 | 117 | DeviceId - The index into the global device table. 118 | 119 | Attributes - Attribute flags for the device. Includes, open, read, write. 120 | 121 | ReferenceCount - A reference count to the number of open instances of the 122 | device. 123 | 124 | FilterLevel - The Device I/O Library supports device filters by 125 | allowing a device class to open a device and then forward the open 126 | request, allowing a second device class to open the device. 127 | For the Device I/O Library to fully support this functionality, it 128 | requires an additional level of granularity when describing a device. 129 | Each device class that opens the same device will be assigned a 130 | different filter level (with the top level device class assigned 131 | level 0). 132 | 133 | FunctionTable - Function table for I/O operations on the device. 134 | 135 | DeviceData - A pointer to device specific data. Device information can 136 | be conceptualized as three different types and a device class is 137 | expected to define a data buffer as such. 138 | 139 | - Device Information : Data that would be interesting to the user and 140 | is obtained/modified using BlDeviceGetInformation and 141 | BlDeviceSetInformation. 142 | 143 | - Device Class Information : Data structures use in all devices of a 144 | common device type. The data structures are internel and are not 145 | exposed to a user in any mannar. 146 | 147 | - Firmware Data : Firmware specific information and data structures 148 | for a device, including firmware handles, paths, protocols, etc. 149 | 150 | DeviceIndentifier - A pointer to an allocated buffer which saves the 151 | device identifier for a device. N.B. This field must be an allocated 152 | buffer since it is possible for a registered device class to have 153 | an identifier larger than the defined union, BOOT_ENVIRONMENT_DEVICE. 154 | 155 | --*/ 156 | 157 | typedef struct _REGISTERED_DEVICE_CLASS { 158 | LIST_ENTRY ListEntry; 159 | DEVICE_FUNCTION_TABLE FunctionTable; 160 | } REGISTERED_DEVICE_CLASS, *PREGISTERED_DEVICE_CLASS; 161 | 162 | /*++ 163 | 164 | Registered Device Class Description : 165 | 166 | The Device I/O Manager maintains a list of device classes which have 167 | been registered with the library. If registered, the device classes' 168 | open routine will be called prior to the library attempting to open the 169 | device using well known device classes. 170 | 171 | Fields: 172 | 173 | ListEntry - List entry pointing to the previous and next entries in the 174 | linked list. 175 | 176 | FunctionTable - Registered device classes' function table. 177 | 178 | --*/ 179 | 180 | // -------------------------------------------------------------------- Globals 181 | 182 | extern const DEVICE_FUNCTION_TABLE ConsoleDeviceFunctionTable; 183 | extern const DEVICE_FUNCTION_TABLE BlockIoDeviceFunctionTable; 184 | extern const DEVICE_FUNCTION_TABLE SerialPortFunctionTable; 185 | extern const DEVICE_FUNCTION_TABLE UdpFunctionTable; 186 | extern const DEVICE_FUNCTION_TABLE VmbusDeviceFunctionTable; 187 | 188 | // ----------------------------------------------------------------- Prototypes 189 | 190 | // 191 | // Filter class initialization routines. 192 | // 193 | 194 | NTSTATUS 195 | FvebInitialize ( 196 | VOID 197 | ); 198 | 199 | NTSTATUS 200 | BlockIoPurgeCache ( 201 | VOID 202 | ); 203 | 204 | VOID 205 | BlockIoPurgeCacheByDevice ( 206 | __in PDEVICE_ENTRY DeviceEntry 207 | ); 208 | 209 | PDEVICE_ENTRY 210 | BlpDeviceGetEntry ( 211 | __in DEVICE_ID DeviceId 212 | ); 213 | 214 | NTSTATUS 215 | BlpDeviceFlush ( 216 | __in PDEVICE_ENTRY Device 217 | ); 218 | 219 | NTSTATUS 220 | BlpDeviceReset ( 221 | __in PDEVICE_ENTRY Device 222 | ); 223 | 224 | -------------------------------------------------------------------------------- /boot/environ/lib/io/device/disk.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | disk.h 8 | 9 | Abstract: 10 | 11 | Header file for disk i/o implementation. 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | 19 | #pragma once 20 | 21 | // ------------------------------------------------------------------- Includes 22 | 23 | #include 24 | #include "device.h" 25 | #include "block.h" 26 | 27 | // ----------------------------------------------------------------- Prototypes 28 | 29 | // 30 | // Routines implemented in this module. They are used to patch some of the 31 | // block i/o routines in the block i/o function table. 32 | // 33 | 34 | NTSTATUS 35 | DiskOpen ( 36 | __in PBOOT_ENVIRONMENT_DEVICE Device, 37 | __out PDEVICE_ENTRY DeviceEntry 38 | ); 39 | 40 | NTSTATUS 41 | DiskClose ( 42 | __in PDEVICE_ENTRY DeviceEntry 43 | ); 44 | 45 | NTSTATUS 46 | DiskEnumerateDeviceClass ( 47 | __in PBOOT_ENVIRONMENT_DEVICE DeviceClassIdentifier, 48 | __inout PGENERIC_BUFFER DeviceIdBuffer, 49 | __in BOOLEAN AllocateNewBuffer 50 | ); 51 | 52 | // -------------------------------------------------------- Firmware Prototypes 53 | 54 | NTSTATUS 55 | DiskFirmwareOpen ( 56 | __in PBOOT_ENVIRONMENT_DEVICE Device, 57 | __inout PDEVICE_ENTRY DeviceEntry 58 | ); 59 | 60 | NTSTATUS 61 | DiskFirmwareClose ( 62 | __in PBLOCK_IO_DEVICE BlockIoDevice 63 | ); 64 | 65 | -------------------------------------------------------------------------------- /boot/environ/lib/io/device/efi/disk.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | disk.c 8 | 9 | Abstract: 10 | 11 | Implementation of disk device i/o routines using EFI. 12 | 13 | Environment: 14 | 15 | Boot 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "disk.h" 22 | 23 | // ------------------------------------------------------------------ Functions 24 | 25 | NTSTATUS 26 | DiskFirmwareOpen ( 27 | __in PBOOT_ENVIRONMENT_DEVICE Device, 28 | __inout PDEVICE_ENTRY DeviceEntry 29 | ) 30 | 31 | /*++ 32 | 33 | Routine Description: 34 | 35 | Opens a disk device and collects information, such as disk geometry for the 36 | device. 37 | 38 | Arguments: 39 | 40 | Device - The Disk device to open and initialize. 41 | 42 | DeviceEntry - Pointer to the device entry. Will be filled with all 43 | information for the device. 44 | 45 | Return Value: 46 | 47 | STATUS_SUCCESS when successful. 48 | STATUS_NO_SUCH_DEVICE when the requested device could not be found. 49 | STATUS_NO_MEMORY if allocation fails for an internal data structure. 50 | 51 | --*/ 52 | 53 | { 54 | 55 | NTSTATUS Status; 56 | 57 | // 58 | // On EFI machines, it is easiest to process all block i/o devices at once. 59 | // They all share a common interface and can be obtained by querying for 60 | // devices that support the block i/o protocol. 61 | // 62 | 63 | Status = BlockIoFirmwareOpen(Device, DeviceEntry->DeviceData); 64 | return Status; 65 | } 66 | 67 | NTSTATUS 68 | DiskFirmwareClose ( 69 | __in PBLOCK_IO_DEVICE BlockIoDevice 70 | ) 71 | 72 | /*++ 73 | 74 | Routine Description: 75 | 76 | Closes an EFI disk device. 77 | 78 | On EFI 1.10 systems this is to call CloseProtocol to notify the EFI handle 79 | database that there the handle is no longer being used. 80 | 81 | Arguments: 82 | 83 | DeviceEntry - Block I/O device structure. 84 | 85 | Return Value: 86 | 87 | STATUS_SUCCESS when successful. 88 | STATUS_INVALID_PARAMETER if the stored firmware handle is no longer valid. 89 | STATUS_NOT_FOUND if the firmware handle no longer supports the block i/o 90 | protocol. 91 | 92 | Both error cases result in some sort of internal error (Handle is 93 | corrupted). 94 | 95 | --*/ 96 | 97 | { 98 | 99 | PDISK_INTERNAL_DATA DiskData; 100 | 101 | // 102 | // Release partition table, if allocated. 103 | // 104 | 105 | #ifdef ENABLE_PATCHED_PARTITIONS 106 | 107 | DiskData = &BlockIoDevice->InternalData.u.DiskData; 108 | if (DiskData->GptData.PartitionEntryArray != NULL) { 109 | BlMmFreeHeap(DiskData->GptData.PartitionEntryArray); 110 | DiskData->GptData.PartitionEntryArray = NULL; 111 | } 112 | 113 | #endif 114 | 115 | return EfiCloseProtocol(BlockIoDevice->FirmwareData.Handle, 116 | &EfiBlockIoProtocol, 117 | BlockIoDevice->FirmwareData.BlockIoInterface); 118 | } 119 | 120 | 121 | -------------------------------------------------------------------------------- /boot/environ/lib/io/device/partition.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 1990-1997 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | partition.h 8 | 9 | Abstract: 10 | 11 | Header file for partition i/o implementation. 12 | 13 | Author: 14 | 15 | Jamie Schwartz (jamschw) May 2003 16 | 17 | Environment: 18 | 19 | Boot. 20 | 21 | Revision History: 22 | 23 | --*/ 24 | 25 | #pragma once 26 | 27 | // ------------------------------------------------------------------- Includes 28 | 29 | #include 30 | #include "device.h" 31 | #include "block.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | // ---------------------------------------------------------------- Definitions 38 | 39 | // 40 | // For patched partitions logical byte offset is stached in Attributes field in 41 | // the partition table entry. 42 | // 43 | 44 | #define GET_PATCH_PARTITION_LOGICAL_OFFSET(_b) (((_b) >> 8) << 8) 45 | 46 | // 47 | // Size of the patched partition name in characters not including terminating 48 | // null. 49 | // 50 | 51 | #define PATCHED_PARTITION_NAME_SIZE (RTL_GUID_STRING_SIZE - 3) 52 | 53 | // 54 | // Format string for the patched partition name. 55 | // 56 | 57 | #define PATCHED_PARTITION_NAME_FORMAT L"%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x" 58 | 59 | // ----------------------------------------------------------------- Prototypes 60 | 61 | // 62 | // Routines implemented in this module. They are used to patch some of the 63 | // block i/o routines in the block i/o function table. 64 | // 65 | 66 | NTSTATUS 67 | PartitionOpen ( 68 | __in PBOOT_ENVIRONMENT_DEVICE Device, 69 | __out PDEVICE_ENTRY DeviceEntry 70 | ); 71 | 72 | NTSTATUS 73 | PartitionClose ( 74 | __in PDEVICE_ENTRY DeviceEntry 75 | ); 76 | 77 | NTSTATUS 78 | PartitionEnumerateDeviceClass ( 79 | __in PBOOT_ENVIRONMENT_DEVICE DeviceClassIdentifier, 80 | __inout PGENERIC_BUFFER DeviceIdBuffer, 81 | __in BOOLEAN AllocateNewBuffer 82 | ); 83 | 84 | // -------------------------------------------------------- Firmware Prototypes 85 | 86 | NTSTATUS 87 | PartitionFirmwareOpen ( 88 | __in PBOOT_ENVIRONMENT_DEVICE Device, 89 | __out PDEVICE_ENTRY DeviceEntry 90 | ); 91 | 92 | NTSTATUS 93 | PartitionFirmwareClose ( 94 | __in PBLOCK_IO_DEVICE BlockIoDevice 95 | ); 96 | 97 | // -------------------------------------------------------- Internal Structures 98 | 99 | typedef struct _PARTP_MBR_TRAVERSAL_CONTEXT { 100 | ULONG PartitionNumber; 101 | PMBR_PARTITION_TABLE_ENTRY MbrEntry; 102 | ULONG64 PartitionOffset; 103 | ULONG SectorSize; 104 | } PARTP_MBR_TRAVERSAL_CONTEXT, *PPARTP_MBR_TRAVERSAL_CONTEXT; 105 | 106 | /*++ 107 | 108 | MBR disk traversal context: 109 | 110 | This structure encapsulates the MBR partition information required by the 111 | callback routines invoked from the generic MBR partition traversal code. 112 | 113 | Fields: 114 | 115 | PartitionNumber - Supplies the 1-based number of this partition within 116 | the disk. 117 | 118 | MbrEntry - Supplies a pointer to the MBR partition table entry describing 119 | this partition. 120 | 121 | PartitionOffset - Supplies the offset, in bytes, of this partition within 122 | the enclosing disk. 123 | 124 | SectorSize - Supplies the sector size, in bytes, associated with the 125 | enclosing disk. 126 | 127 | --*/ 128 | 129 | #define PARTP_USE_DEVICE_ID 1 130 | #define PARTP_USE_DEVICE_ENTRY 2 131 | 132 | typedef struct _PARTP_DEVICE_HANDLE { 133 | ULONG AccessMethod; 134 | union { 135 | DEVICE_ID DeviceId; 136 | PDEVICE_ENTRY DeviceEntry; 137 | } u; 138 | } PARTP_DEVICE_HANDLE, *PPARTP_DEVICE_HANDLE; 139 | 140 | /*++ 141 | 142 | Device access handle: 143 | 144 | This structure describes a device, indicating whether it should be accessed 145 | through a standard device ID or be accessed directly through its device 146 | table entry. 147 | 148 | --*/ 149 | 150 | // -------------------------------------------------------- Internal Prototypes 151 | 152 | NTSTATUS 153 | PartpCreatePartitionDeviceEntry ( 154 | __in PBOOT_ENVIRONMENT_DEVICE Device, 155 | __deref_out PDEVICE_ENTRY *DeviceEntry 156 | ); 157 | 158 | NTSTATUS 159 | PartpOpenMbrPartition ( 160 | __in PDEVICE_ENTRY ParentDeviceEntry, 161 | __in PBOOT_ENVIRONMENT_DEVICE Device, 162 | __inout PPARTITION_DEVICE PartitionEntry 163 | ); 164 | 165 | NTSTATUS 166 | PartpOpenGptPartition ( 167 | __in PDEVICE_ENTRY ParentDeviceEntry, 168 | __in PBOOT_ENVIRONMENT_DEVICE Device, 169 | __inout PPARTITION_DEVICE PartitionEntry 170 | ); 171 | 172 | NTSTATUS 173 | PartpOpenElToritoPartition ( 174 | __in PDEVICE_ENTRY ParentDeviceEntry, 175 | __in PBOOT_ENVIRONMENT_DEVICE Device, 176 | __inout PPARTITION_DEVICE PartitionEntry 177 | ); 178 | 179 | NTSTATUS 180 | PartpEnumerateMbrPartitions ( 181 | __in DEVICE_ID ParentDeviceId, 182 | __inout PGENERIC_BUFFER DeviceIdBuffer 183 | ); 184 | 185 | NTSTATUS 186 | PartpEnumerateGptPartitions ( 187 | __in DEVICE_ID ParentDeviceId, 188 | __inout PGENERIC_BUFFER DeviceIdBuffer, 189 | __in BOOLEAN ForceFveCheck 190 | ); 191 | 192 | typedef 193 | NTSTATUS 194 | (*PARTP_MBR_TRAVERSAL_CALLBACK) ( 195 | __in PPARTP_MBR_TRAVERSAL_CONTEXT Context, 196 | __in PVOID Context1, 197 | __in PVOID Context2, 198 | __in PVOID Context3 199 | ); 200 | 201 | NTSTATUS 202 | PartpTraverseMbrPartitions ( 203 | __in PPARTP_DEVICE_HANDLE ParentDeviceHandle, 204 | __in PARTP_MBR_TRAVERSAL_CALLBACK Callback, 205 | __in PVOID Context1, 206 | __in PVOID Context2, 207 | __in PVOID Context3 208 | ); 209 | 210 | NTSTATUS 211 | PartpMatchMbrPartition ( 212 | __in PPARTP_MBR_TRAVERSAL_CONTEXT Context, 213 | __in PPARTITION_IDENTIFIER_EX PartitionIdentifier, 214 | __inout PPARTITION_DEVICE PartitionEntry, 215 | __in PVOID Context3 216 | ); 217 | 218 | NTSTATUS 219 | PartpMatchDeprecatedMbrPartition ( 220 | __in PPARTP_MBR_TRAVERSAL_CONTEXT Context, 221 | __in PPARTITION_IDENTIFIER PartitionIdentifier, 222 | __inout PPARTITION_DEVICE PartitionEntry, 223 | __in PVOID Context3 224 | ); 225 | 226 | NTSTATUS 227 | PartpCountMbrPartitions ( 228 | __in PPARTP_MBR_TRAVERSAL_CONTEXT Context, 229 | __inout PULONG RunningCounter, 230 | __in PVOID Context2, 231 | __in PVOID Context3 232 | ); 233 | 234 | NTSTATUS 235 | PartpOpenAllMbrPartitions ( 236 | __in PPARTP_MBR_TRAVERSAL_CONTEXT Context, 237 | __inout PDEVICE_ID *CurrentDeviceId, 238 | __inout PGENERIC_BUFFER DeviceIdBuffer, 239 | __inout PBOOT_ENVIRONMENT_DEVICE IdentifierTemplate 240 | ); 241 | 242 | NTSTATUS 243 | PartpOpenVirtualPartitionDevice ( 244 | __in PBOOT_ENVIRONMENT_DEVICE Device, 245 | __out PDEVICE_ENTRY DeviceEntry 246 | ); 247 | 248 | #ifdef ENABLE_PATCHED_PARTITIONS 249 | 250 | NTSTATUS 251 | PartpGetPatchInformation ( 252 | __in ULONG PartitionCount, 253 | __in ULONG PartitionEntrySize, 254 | __in PGPT_PARTITION_ENTRY PartitionEntryArray, 255 | __in ULONG BlockSize, 256 | __in LPCGUID PartitionGuid, 257 | __inout PDISK_INTERNAL_DATA DiskData 258 | ); 259 | 260 | VOID 261 | PartpReleasePatchData ( 262 | __inout PDISK_INTERNAL_DATA DiskData 263 | ); 264 | 265 | #endif 266 | 267 | #ifdef __cplusplus 268 | } 269 | #endif 270 | -------------------------------------------------------------------------------- /boot/environ/lib/io/file/file.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | file.h 8 | 9 | Abstract: 10 | 11 | Header file for boot environment file i/o. 12 | 13 | When file's are opened, an entry is created in a file table. After 14 | this, all file i/o calls are directed based on function pointers set 15 | during the specific files open routine. 16 | 17 | This header is to be included by all boot environment file system 18 | implementations (but not by any application running in the boot 19 | environment. This file contains definitions for the routines each file 20 | system must implement and the internal data structures that are used 21 | by them. 22 | 23 | Environment: 24 | 25 | boot 26 | 27 | --*/ 28 | 29 | #pragma once 30 | 31 | // ------------------------------------------------------------------- Includes 32 | 33 | #include 34 | #include "systemevents.h" 35 | 36 | // 37 | // Disable warnings for non-data types as parameters to function. 38 | // 39 | 40 | #pragma warning(disable:4218) 41 | 42 | // 43 | // Disable warnings for function/data pointer conversion. 44 | // 45 | 46 | #pragma warning(disable:4152) 47 | 48 | // ---------------------------------------------------------------- Definitions 49 | 50 | typedef ULONG FILE_ATTRIBUTES; 51 | typedef FILE_ATTRIBUTES *PFILE_ATTRIBUTES; 52 | 53 | #define BOOT_FILE_OPEN (0x00000001) 54 | #define BOOT_FILE_READ (0x00000002) 55 | #define BOOT_FILE_WRITE (0x00000004) 56 | #define BOOT_FILE_CATALOG (0x00000010) 57 | #define BOOT_FILE_DIRECTORY (0x00010000) 58 | #define BOOT_FILE_REPARSE (0x00020000) 59 | 60 | // --------------------------------------------------------------------- Macros 61 | 62 | #define SET_FILE_OPEN(_x) SET_FLAGS(_x, BOOT_FILE_OPEN) 63 | #define SET_FILE_READ(_x) SET_FLAGS(_x, BOOT_FILE_READ) 64 | #define SET_FILE_WRITE(_x) SET_FLAGS(_x, BOOT_FILE_WRITE) 65 | #define SET_FILE_CATALOG(_x) SET_FLAGS(_x, BOOT_FILE_CATALOG) 66 | #define SET_FILE_DIRECTORY(_x) SET_FLAGS(_x, BOOT_FILE_DIRECTORY) 67 | #define SET_FILE_REPARSE(_x) SET_FLAGS(_x, BOOT_FILE_REPARSE) 68 | 69 | #define CLEAR_FILE_OPEN(_x) CLEAR_FLAGS(_x, BOOT_FILE_OPEN) 70 | #define CLEAR_FILE_READ(_x) CLEAR_FLAGS(_x, BOOT_FILE_READ) 71 | #define CLEAR_FILE_WRITE(_x) CLEAR_FLAGS(_x, BOOT_FILE_WRITE) 72 | #define CLEAR_FILE_CATALOG(_x) CLEAR_FLAGS(_x, BOOT_FILE_CATALOG) 73 | #define CLEAR_FILE_DIRECTORY(_x) CLEAR_FLAGS(_x, BOOT_FILE_DIRECTORY) 74 | #define CLEAR_FILE_ATTRIBUTES(_x) ((FILE_ATTRIBUTES)_x = 0) 75 | 76 | #define IS_FILE_OPENED(_x) CHECK_FLAG(_x, BOOT_FILE_OPEN) 77 | #define IS_FILE_READ_SET(_x) CHECK_FLAG(_x, BOOT_FILE_READ) 78 | #define IS_FILE_WRITE_SET(_x) CHECK_FLAG(_x, BOOT_FILE_WRITE) 79 | #define IS_FILE_CATALOG_SET(_x) CHECK_FLAG(_x, BOOT_FILE_CATALOG) 80 | #define IS_FILE_DIRECTORY_SET(_x) CHECK_FLAG(_x, BOOT_FILE_DIRECTORY) 81 | #define IS_FILE_REPARSE_SET(_x) CHECK_FLAG(_x, BOOT_FILE_REPARSE) 82 | 83 | 84 | #define IS_FILE_OPENED_FOR_READ(_x) (IS_FILE_OPENED(_x) && \ 85 | IS_FILE_READ_SET(_x)) 86 | #define IS_FILE_OPENED_FOR_WRITE(_x) (IS_FILE_OPENED(_x) && \ 87 | IS_FILE_WRITE_SET(_x)) 88 | 89 | // ------------------------------------------------------------ Data Structures 90 | 91 | typedef struct _REGISTERED_FILESYSTEM { 92 | LIST_ENTRY ListEntry; 93 | FILESYSTEM_REGISTER_FUNCTION_TABLE FunctionTable; 94 | } REGISTERED_FILESYSTEM, *PREGISTERED_FILESYSTEM; 95 | 96 | /*++ 97 | 98 | Registered Filesystem Description : 99 | 100 | The File I/O Library maintains a list of filesystem that have been 101 | registered with the library. If registered, the mount routine for the 102 | filesystem will be called when determining the filesystem on a particular 103 | device. 104 | 105 | Fields: 106 | 107 | ListEntry - List entry pointing to the previous and next entries in the 108 | linked list. 109 | 110 | FunctionTable - Registered filesystem function table. 111 | 112 | --*/ 113 | 114 | typedef struct _FILE_ENTRY { 115 | 116 | PWCHAR FilePath; 117 | 118 | DEVICE_ID DeviceId; 119 | FILE_ID FileId; 120 | 121 | FILE_ATTRIBUTES Attributes; 122 | ULONG ReferenceCount; 123 | ULONG FilterLevel; 124 | ULONG Reserved; 125 | ULONGLONG BytesRead; 126 | ULONGLONG BytesWritten; 127 | 128 | FILESYSTEM_FUNCTION_TABLE FunctionTable; 129 | PVOID FileData; 130 | 131 | } FILE_ENTRY, *PFILE_ENTRY; 132 | 133 | /*++ 134 | 135 | File Entry Description: 136 | 137 | A file entry is the internal representation for a file, describing the 138 | file that is opened, the attribute flags the file was opened with, 139 | a function table for I/O operations, etc. 140 | 141 | Fields: 142 | 143 | FilePath - Saved copy of the file path. The buffer must be allocated 144 | when the file entry is created and freed when the file entry is 145 | destroyed. 146 | 147 | DeviceId - Index for the device the file is located. 148 | 149 | FileId - Index into a file table. 150 | 151 | Attributes - Attribute flags for the file. (Includes open/read/write). 152 | 153 | ReferenceCount - A reference count to the number of open instances of the 154 | file. 155 | 156 | FilterLevel - The File I/O Library supports filesystem filters by 157 | allowing a filesystem to mount a device and then forward the mount 158 | request, allowing a second filesystem to mount on the device. 159 | For the File I/O Library to fully support this functionality, it 160 | requires an additional level of granularity when describing a file (in 161 | addition to file name and device). Each filesystem mounted on the 162 | same device will be assigned a different filter level (with the top 163 | level filesystem assigned level 0). Therefore, a file entry can 164 | be defined for each filesystem in the stack. 165 | 166 | BytesRead - The number of bytes read from this file so far. 167 | 168 | BytesWritten - The number of bytes written to this file so far. 169 | 170 | FunctionTable - Function table for I/O operations on the file. 171 | 172 | FileData - A pointer to a file specific data buffer. (Allocated 173 | during open and freed during close). There are two types of data 174 | that are contained in this buffer, 175 | 176 | - File Information : Data that would be interesting to the user. This 177 | could very well be the information passed using BlFileGetInformation 178 | and BlFileSetInformation. 179 | 180 | - Filesystem specific information : Data unique to the underlying 181 | filesystem. 182 | 183 | The representation of the above data is dependent on the implementation 184 | of the filesystem. But it is recommended that this structure be 185 | defined as two distinct structure (one for each of the above cases). 186 | See FAT_FILE or NTFS_FILE for examples of this. 187 | 188 | --*/ 189 | 190 | // -------------------------------------------------------------------- Globals 191 | 192 | // 193 | // Function Tables for known filesystems. 194 | // 195 | 196 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE FatRegisterFunctionTable; 197 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE FppRegisterFunctionTable; 198 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE NtfsRegisterFunctionTable; 199 | #ifdef BLDR_REFS_SUPPORT 200 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE RefsRegisterFunctionTable; 201 | #endif 202 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE EtfsRegisterFunctionTable; 203 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE UdfsRegisterFunctionTable; 204 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE WimRegisterFunctionTable; 205 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE NetRegisterFunctionTable; 206 | extern const FILESYSTEM_REGISTER_FUNCTION_TABLE VmbfsRegisterFunctionTable; 207 | extern const PCFILESYSTEM_REGISTER_FUNCTION_TABLE FsTable[]; 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /boot/environ/lib/misc/efi/image.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | image.c 8 | 9 | Abstract: 10 | 11 | This module provides support for loading and starting images using 12 | EFI. 13 | 14 | Environment: 15 | 16 | Boot 17 | 18 | --*/ 19 | 20 | // ------------------------------------------------------------------- Includes 21 | 22 | #include "image.h" 23 | 24 | // -------------------------------------------------------- Firmware Prototypes 25 | 26 | NTSTATUS 27 | ImgArchEfiStartBootApplication ( 28 | __in PBOOT_APPLICATION_TRANSITION_ENTRY ApplicationEntry, 29 | __in_bcount(ImageSize) PVOID ImageBase, 30 | __in ULONG ImageSize, 31 | __in ULONG StartFlags, 32 | __out PBOOT_APPLICATION_RETURN_ARGUMENTS ReturnArgs 33 | ); 34 | 35 | // ------------------------------------------------------------------ Functions 36 | 37 | NTSTATUS 38 | ImgFwLoadBootApplication ( 39 | __in DEVICE_ID DeviceId, 40 | __in PWSTR FilePath, 41 | __in ULONG Attributes, 42 | __deref_out_bcount(*ImageSize) PVOID *ImageBase, 43 | __out PULONG ImageSize, 44 | __out_bcount_opt(MAX_HASH_LEN) PUCHAR ImageHash, 45 | __in ULONG ImageFlags, 46 | __out PULONG LoadInformation 47 | ) 48 | 49 | /*++ 50 | 51 | Routine Description: 52 | 53 | This routine will load the specified image into memory. 54 | 55 | Arguments: 56 | 57 | DeviceId - The device containing the specified boot application. 58 | 59 | FilePath - The file path for the specified boot application. 60 | 61 | Attributes - Supplies attributes of the boot entry. 62 | 63 | ImageBase - On return, contains the address of the loaded image. 64 | 65 | ImageSize - On return, contains the in-memory size of the loaded image. 66 | 67 | ImageHash - If present then on return contains the hash of the loaded image. 68 | 69 | ImageFlags - Supplies a set of image load flags that must be used during 70 | this image load. Additional load flags can be added by this routine. 71 | 72 | LoadInformation - Provides flags that describe properties of the loaded image. 73 | 74 | Return Value: 75 | 76 | STATUS_SUCCESS when successful. 77 | STATUS_NO_SUCH_DEVICE if Device is invalid. 78 | STATUS_NO_SUCH_FILE if FilePath does not exist. 79 | STATUS_INVALID_IMAGE_FORMAT if the file exists, but is neither a 80 | legacy loader or a PE boot application. 81 | 82 | --*/ 83 | 84 | { 85 | 86 | ULONG Flags; 87 | NTSTATUS Status; 88 | 89 | UNREFERENCED_PARAMETER(Attributes); 90 | 91 | // 92 | // Load the application into memory. All boot applications are PE images 93 | // and can be loaded as such. 94 | // 95 | // N.B. All boot applications need to be mapped one to one since they 96 | // can disable address translation at any time. 97 | // 98 | 99 | Flags = 100 | ImageFlags | 101 | IMAGE_FLAGS_BOOT_APPLICATION | 102 | IMAGE_FLAGS_MAP_ONE_TO_ONE | 103 | IMAGE_FLAGS_VALIDATE_MACHINE_TYPE; 104 | 105 | *ImageBase = NULL; // No preferred address. 106 | Status = BlImgLoadPEImageWithInfo(DeviceId, 107 | MEMORY_TYPE_BOOT_APPLICATION, 108 | FilePath, 109 | ImageBase, 110 | ImageSize, 111 | ImageHash, 112 | Flags, 113 | LoadInformation); 114 | 115 | return Status; 116 | } 117 | 118 | NTSTATUS 119 | ImgFwUnloadBootApplication ( 120 | __in_bcount(ImageSize) PVOID ImageBase, 121 | __in ULONG ImageSize 122 | ) 123 | 124 | /*++ 125 | 126 | Routine Description: 127 | 128 | This routine will unload a boot application loaded by 129 | ImageFirmwareLoadBootApplication. 130 | 131 | Arguments: 132 | 133 | ImageBase - Base address of the loaded image. 134 | 135 | ImageSize - Size (in bytes) of the loaded image. 136 | 137 | Return Value: 138 | 139 | STATUS_SUCCESS when successful. 140 | STATUS_MEMORY_NOT_ALLOCATED if there as an error freeing the memory 141 | allocated for the image. 142 | 143 | --*/ 144 | 145 | { 146 | 147 | NTSTATUS Status; 148 | 149 | // 150 | // Free page allocation made by BlImgLoadPEImage. 151 | // 152 | 153 | Status = BlImgUnLoadImage(ImageBase, ImageSize, IMAGE_FLAGS_NONE); 154 | if (!NT_SUCCESS(Status)) { 155 | return STATUS_MEMORY_NOT_ALLOCATED; 156 | } 157 | 158 | return STATUS_SUCCESS; 159 | } 160 | 161 | NTSTATUS 162 | ImgFwStartBootApplication ( 163 | __in PBOOT_APPLICATION_TRANSITION_ENTRY ApplicationEntry, 164 | __in_bcount(ImageSize) PVOID ImageBase, 165 | __in ULONG ImageSize, 166 | __in ULONG StartFlags, 167 | __out PBOOT_APPLICATION_RETURN_ARGUMENTS ReturnArgs 168 | ) 169 | 170 | /*++ 171 | 172 | Routine Description: 173 | 174 | This routine will transfer execution to a boot application loaded by 175 | ImageFirmwareBootApplication. 176 | 177 | Arguments: 178 | 179 | ApplicationEntry - Supplies a boot entry for the application. 180 | 181 | ImageBase - Base address of the loaded image. 182 | 183 | ImageSize - Size (in bytes) of the loaded image. 184 | 185 | StartFlags - Supplies start flags. Possible values include: 186 | 187 | IMAGE_FLAGS_ISOLATED_EXECUTION_CONTEXT - Specifies that the child 188 | application should run completely in its own execution context. 189 | 190 | ReturnArgs - Supplies a buffer for the application's return arguments. 191 | 192 | Return Value: 193 | 194 | STATUS_SUCCESS when successful. 195 | STATUS_INVALID_PARAMETER if the image type is invalid. 196 | 197 | --*/ 198 | 199 | { 200 | 201 | return ImgArchEfiStartBootApplication(ApplicationEntry, 202 | ImageBase, 203 | ImageSize, 204 | StartFlags, 205 | ReturnArgs); 206 | } 207 | 208 | -------------------------------------------------------------------------------- /boot/environ/lib/misc/status.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | status.c 8 | 9 | Abstract: 10 | 11 | This module implements Boot Environment Library API for reporting errors 12 | and status. 13 | 14 | Environment: 15 | 16 | Boot. 17 | 18 | Revision History: 19 | 20 | --*/ 21 | 22 | // ------------------------------------------------------------------- Includes 23 | 24 | #include 25 | 26 | // ---------------------------------------------------------------- Definitions 27 | 28 | #define LOCAL_SCRATCH_BUFFER_SIZE 1024 29 | 30 | // --------------------------------------------------------------------- Locals 31 | 32 | static PBL_STATUS_ERROR_FUNCTION BlpStatusErrorHandler; 33 | static BOOLEAN BlpStatusErrorInProgress; 34 | 35 | // ------------------------------------------------------------------------ API 36 | 37 | VOID 38 | BlpStatusError ( 39 | __in ULONG ErrorCode, 40 | __in ULONG_PTR ErrorParameter1, 41 | __in ULONG_PTR ErrorParameter2, 42 | __in ULONG_PTR ErrorParameter3, 43 | __in ULONG_PTR ErrorParameter4 44 | ); 45 | 46 | VOID 47 | BlStatusPrint ( 48 | __in PCWSTR Format, 49 | ... 50 | ) 51 | 52 | /*++ 53 | 54 | Routine Description: 55 | 56 | Printf style string routine for reporting status to the Boot Environment 57 | Library. 58 | 59 | N.B. This function is used to report heap corruptions. This implies that 60 | any memory allocation attempt could result in a recursive call back 61 | to this routine if the heap is corrupt. In order to avoid infinite 62 | recursion this routine must not attempt any heap allocations. 63 | 64 | Arguments: 65 | 66 | printf style arguments. 67 | 68 | Returns: 69 | 70 | None. 71 | 72 | --*/ 73 | 74 | { 75 | 76 | static CHAR AnsiBuffer[LOCAL_SCRATCH_BUFFER_SIZE]; 77 | ANSI_STRING AnsiString; 78 | va_list ArgList; 79 | LONG ReturnValue; 80 | ULONG Size; 81 | NTSTATUS Status; 82 | UNICODE_STRING UnicodeString; 83 | 84 | // 85 | // If the debugger is connected, print the formatted string to the 86 | // debugger. 87 | // 88 | 89 | if (BlBdDebuggerEnabled() != FALSE) { 90 | 91 | // 92 | // Use the global scratch buffer to initialize a UNICODE_STRING using 93 | // the caller's arguments. 94 | // 95 | 96 | ASSERT((LOCAL_SCRATCH_BUFFER_SIZE * sizeof(WCHAR)) < 97 | GLOBAL_SCRATCH_BUFFER_SIZE); 98 | 99 | va_start(ArgList, Format); 100 | Size = LOCAL_SCRATCH_BUFFER_SIZE - 1; 101 | ReturnValue = vswprintf_s((PWCHAR)BlScratchBuffer, 102 | Size, 103 | Format, 104 | ArgList); 105 | 106 | va_end(ArgList); 107 | if (ReturnValue > 0) { 108 | 109 | // 110 | // Initialize an ANSI string to pass to the debugger API. 111 | // 112 | 113 | RtlInitUnicodeString(&UnicodeString, (PWCHAR)BlScratchBuffer); 114 | AnsiString.Length = 0; 115 | AnsiString.MaximumLength = LOCAL_SCRATCH_BUFFER_SIZE; 116 | AnsiString.Buffer = AnsiBuffer; 117 | Status = RtlUnicodeStringToAnsiString(&AnsiString, 118 | &UnicodeString, 119 | FALSE); 120 | 121 | if (NT_SUCCESS(Status)) { 122 | BlBdPrint(AnsiString.Buffer); 123 | } 124 | } 125 | } 126 | 127 | return; 128 | } 129 | 130 | VOID 131 | BlStatusError ( 132 | __in ULONG ErrorCode, 133 | __in ULONG_PTR ErrorParameter1, 134 | __in ULONG_PTR ErrorParameter2, 135 | __in ULONG_PTR ErrorParameter3, 136 | __in ULONG_PTR ErrorParameter4 137 | ) 138 | 139 | /*++ 140 | 141 | Routine Description: 142 | 143 | Boot Environment Library interface for reporting an error (application 144 | or library). 145 | 146 | Arguments: 147 | 148 | ErrorCode - ULONG value indicating the reason of the error. 149 | 150 | ErrorParameter1 - Additional information for the error. 151 | 152 | ErrorParameter2 - Additional information for the error. 153 | 154 | ErrorParameter3 - Additional information for the error. 155 | 156 | ErrorParameter4 - Additional information for the error. 157 | 158 | Returns: 159 | 160 | None. 161 | 162 | --*/ 163 | 164 | { 165 | NTSTATUS Status; 166 | 167 | Status = STATUS_UNSUCCESSFUL; 168 | 169 | // 170 | // Report library errors to registered error handler, if registered. 171 | // 172 | 173 | if (ErrorCode != BL_ERROR_APPLICATION && 174 | BlpStatusErrorInProgress == FALSE && 175 | BlpStatusErrorHandler != NULL) { 176 | 177 | // 178 | // Set Error In Progress flag to protect against reentrency and 179 | // recursive calls as boot application error handlers often call 180 | // BlStatusError. 181 | // 182 | 183 | BlpStatusErrorInProgress = TRUE; 184 | Status = BlpStatusErrorHandler(ErrorCode, 185 | ErrorParameter1, 186 | ErrorParameter2, 187 | ErrorParameter3, 188 | ErrorParameter4); 189 | BlpStatusErrorInProgress = FALSE; 190 | } 191 | 192 | // 193 | // Call default error method if error handler wasn't called, or was 194 | // error handler was successful. 195 | // 196 | 197 | if (!NT_SUCCESS(Status)) { 198 | BlpStatusError(ErrorCode, 199 | ErrorParameter1, 200 | ErrorParameter2, 201 | ErrorParameter3, 202 | ErrorParameter4); 203 | } 204 | 205 | return; 206 | } 207 | 208 | VOID 209 | BlStatusRegisterErrorHandler( 210 | __in PBL_STATUS_ERROR_FUNCTION Callback 211 | ) 212 | 213 | /*++ 214 | 215 | Routine Description: 216 | 217 | Boot Environment Library interface for registering a callback that is 218 | invoked when reporting a library error. 219 | 220 | Arguments: 221 | 222 | Callback - Supplies a pointer to the callback function. 223 | 224 | Returns: 225 | 226 | None. 227 | 228 | --*/ 229 | 230 | { 231 | 232 | BlpStatusErrorHandler = Callback; 233 | return; 234 | } 235 | 236 | VOID 237 | BlStatusUnregisterErrorHandler( 238 | ) 239 | 240 | /*++ 241 | 242 | Routine Description: 243 | 244 | Boot Environment Library interface for unregistering the callback that is 245 | invoked when reporting a library error. 246 | 247 | Arguments: 248 | 249 | None. 250 | 251 | Returns: 252 | 253 | None. 254 | 255 | --*/ 256 | 257 | { 258 | 259 | BlpStatusErrorHandler = NULL; 260 | return; 261 | } 262 | 263 | VOID 264 | BlpStatusError ( 265 | __in ULONG ErrorCode, 266 | __in ULONG_PTR ErrorParameter1, 267 | __in ULONG_PTR ErrorParameter2, 268 | __in ULONG_PTR ErrorParameter3, 269 | __in ULONG_PTR ErrorParameter4 270 | ) 271 | 272 | /*++ 273 | 274 | Routine Description: 275 | 276 | Boot Environment Library interface for reporting an error (application 277 | or library). 278 | 279 | Arguments: 280 | 281 | ErrorCode - ULONG value indicating the reason of the error. 282 | 283 | ErrorParameter1 - Additional information for the error. 284 | 285 | ErrorParameter2 - Additional information for the error. 286 | 287 | ErrorParameter3 - Additional information for the error. 288 | 289 | ErrorParameter4 - Additional information for the error. 290 | 291 | Returns: 292 | 293 | None. 294 | 295 | --*/ 296 | 297 | { 298 | 299 | // 300 | // The implementation details of this function need to be resolved. In the 301 | // shorterm, break into the debugger with the error parameters. 302 | // 303 | 304 | if (BlBdDebuggerEnabled() != FALSE) { 305 | BlStatusPrint(L"\n*** Fatal Error 0x%08x :\n" 306 | L" (0x%p, 0x%p, 0x%p, 0x%p)\n\n", 307 | ErrorCode, 308 | ErrorParameter1, 309 | ErrorParameter2, 310 | ErrorParameter3, 311 | ErrorParameter4); 312 | 313 | DbgBreakPoint(); 314 | } 315 | 316 | return; 317 | } 318 | 319 | -------------------------------------------------------------------------------- /boot/environ/lib/misc/time_cmn.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | time_cmn.c 8 | 9 | Abstract: 10 | 11 | Implementation of firmware independent boot library time-related APIs. 12 | 13 | Environment: 14 | 15 | Boot. 16 | 17 | --*/ 18 | 19 | // 20 | // ------------------------------------------------------------------- Includes 21 | // 22 | 23 | #include "bootlibp.h" 24 | 25 | // 26 | // -------------------------------------------------------------------- Globals 27 | // 28 | 29 | LARGE_INTEGER BlpTimePerformanceFrequency = { 0, 0 }; 30 | 31 | // 32 | // ------------------------------------------------------------------ Functions 33 | // 34 | 35 | LARGE_INTEGER 36 | BlTimeQueryPerformanceCounter ( 37 | __out_opt PLARGE_INTEGER Frequency 38 | ) 39 | 40 | /*++ 41 | 42 | Routine Description: 43 | 44 | This routine implements a 64-bit increasing fixed-frequency performance 45 | counter. 46 | 47 | Arguments: 48 | 49 | Frequency - Supplies an optional buffer to receive the performance 50 | frequency. 51 | 52 | Return Value: 53 | 54 | Returns a 64-bit performance counter value. 55 | 56 | --*/ 57 | 58 | { 59 | 60 | LARGE_INTEGER ReturnValue; 61 | 62 | if (ARGUMENT_PRESENT(Frequency) != FALSE) { 63 | Frequency->QuadPart = BlpTimePerformanceFrequency.QuadPart; 64 | } 65 | 66 | ReturnValue.QuadPart = ReadTimeStampCounter(); 67 | return ReturnValue; 68 | } 69 | 70 | VOID 71 | BlTimeStallExecution ( 72 | ULONG Duration 73 | ) 74 | 75 | /*++ 76 | 77 | Routine Description: 78 | 79 | This routine will stall the processsor for specified number of 80 | microseconds. 81 | 82 | Arguments: 83 | 84 | Duration - Supplies the number of microseconds to stall. 85 | 86 | Return Value: 87 | 88 | None 89 | 90 | --*/ 91 | 92 | { 93 | 94 | LARGE_INTEGER TickTarget; 95 | 96 | TickTarget.QuadPart = BlTimeQueryPerformanceCounter(NULL).QuadPart + 97 | ((BlpTimePerformanceFrequency.QuadPart / (1000 * 1000)) * Duration); 98 | 99 | do { 100 | NOTHING; 101 | } while (BlTimeQueryPerformanceCounter(NULL).QuadPart < 102 | TickTarget.QuadPart); 103 | 104 | return; 105 | } 106 | 107 | // 108 | // ---------------------------------------------------------- Private Functions 109 | // 110 | 111 | NTSTATUS 112 | BlpTimeDestroy ( 113 | VOID 114 | ) 115 | 116 | /*++ 117 | 118 | Routine Description: 119 | 120 | This routine frees any resources used by the boot library time-related 121 | APIs. 122 | 123 | Arguments: 124 | 125 | None. 126 | 127 | Return Value: 128 | 129 | NT status code. 130 | 131 | --*/ 132 | 133 | { 134 | 135 | return STATUS_SUCCESS; 136 | } 137 | 138 | NTSTATUS 139 | BlpTimeInitialize ( 140 | VOID 141 | ) 142 | 143 | /*++ 144 | 145 | Routine Description: 146 | 147 | This routine handles initialization of the boot library time-related 148 | services. 149 | 150 | Arguments: 151 | 152 | None. 153 | 154 | Return Value: 155 | 156 | NT status code. 157 | 158 | --*/ 159 | 160 | { 161 | 162 | ULONGLONG Frequency; 163 | NTSTATUS Status; 164 | 165 | Frequency = 0; 166 | Status = BlGetApplicationOptionInteger( 167 | BCDE_LIBRARY_TYPE_PERFORMANCE_FREQUENCY, 168 | &Frequency); 169 | 170 | // 171 | // Fallback to normal performance counter calibration 172 | // when pre-calculated frequency is not provided. 173 | // 174 | 175 | if (!NT_SUCCESS(Status) || (Frequency == 0)) { 176 | Status = BlpTimeCalibratePerformanceCounter(); 177 | 178 | } else { 179 | BlpTimePerformanceFrequency.QuadPart = Frequency; 180 | } 181 | 182 | return Status; 183 | } 184 | 185 | -------------------------------------------------------------------------------- /boot/environ/lib/platform/platinit.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (C) Microsoft. All rights reserved. 4 | 5 | Module Name: 6 | 7 | platinit.c 8 | 9 | Abstract: 10 | 11 | This module implements initialization of the platform library. 12 | 13 | Environment: 14 | 15 | Boot Environment. 16 | 17 | --*/ 18 | 19 | // ------------------------------------------------------------------- Includes 20 | 21 | #include "platform.h" 22 | 23 | // ------------------------------------------------------------------ Functions 24 | 25 | VOID 26 | BlpPltDestroy ( 27 | VOID 28 | ) 29 | 30 | /*++ 31 | 32 | Routine Description: 33 | 34 | This routine destroys the platform library. 35 | 36 | Arguments: 37 | 38 | None. 39 | 40 | Return Value: 41 | 42 | None. 43 | 44 | --*/ 45 | 46 | { 47 | 48 | // 49 | // Destroy PCI configuration space. 50 | // 51 | 52 | PltDestroyPciConfiguration(); 53 | return; 54 | } 55 | 56 | NTSTATUS 57 | BlpPltInitialize ( 58 | VOID 59 | ) 60 | 61 | /*++ 62 | 63 | Routine Description: 64 | 65 | This routine initializes the platform library. 66 | 67 | Arguments: 68 | 69 | None. 70 | 71 | Return Value: 72 | 73 | NT Status code. 74 | 75 | --*/ 76 | 77 | { 78 | 79 | // 80 | // Initialize PCI configuration space access. 81 | // 82 | 83 | return PltInitializePciConfiguration(); 84 | } 85 | 86 | --------------------------------------------------------------------------------