2 HII Config Access protocol implementation of RamDiskDxe driver.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016-2018 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "RamDiskImpl.h"
18 CHAR16 mRamDiskStorageName
[] = L
"RAM_DISK_CONFIGURATION";
20 RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate
= {
21 RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE
,
24 RAM_DISK_BOOT_SERVICE_DATA_MEMORY
33 HII_VENDOR_DEVICE_PATH mRamDiskHiiVendorDevicePath
= {
39 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
40 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
43 RAM_DISK_FORM_SET_GUID
47 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 (UINT8
) (END_DEVICE_PATH_LENGTH
),
50 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
57 This function publish the RAM disk configuration Form.
59 @param[in, out] ConfigPrivateData
60 Points to RAM disk configuration private data.
62 @retval EFI_SUCCESS HII Form is installed successfully.
63 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
64 @retval Others Other errors as indicated.
68 InstallRamDiskConfigForm (
69 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA
*ConfigPrivateData
73 EFI_HII_HANDLE HiiHandle
;
74 EFI_HANDLE DriverHandle
;
75 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
78 ConfigAccess
= &ConfigPrivateData
->ConfigAccess
;
79 Status
= gBS
->InstallMultipleProtocolInterfaces (
81 &gEfiDevicePathProtocolGuid
,
82 &mRamDiskHiiVendorDevicePath
,
83 &gEfiHiiConfigAccessProtocolGuid
,
87 if (EFI_ERROR (Status
)) {
91 ConfigPrivateData
->DriverHandle
= DriverHandle
;
94 // Publish the HII package list
96 HiiHandle
= HiiAddPackages (
103 if (HiiHandle
== NULL
) {
104 gBS
->UninstallMultipleProtocolInterfaces (
106 &gEfiDevicePathProtocolGuid
,
107 &mRamDiskHiiVendorDevicePath
,
108 &gEfiHiiConfigAccessProtocolGuid
,
112 return EFI_OUT_OF_RESOURCES
;
115 ConfigPrivateData
->HiiHandle
= HiiHandle
;
122 This function removes RAM disk configuration Form.
124 @param[in, out] ConfigPrivateData
125 Points to RAM disk configuration private data.
129 UninstallRamDiskConfigForm (
130 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA
*ConfigPrivateData
134 // Uninstall HII package list
136 if (ConfigPrivateData
->HiiHandle
!= NULL
) {
137 HiiRemovePackages (ConfigPrivateData
->HiiHandle
);
138 ConfigPrivateData
->HiiHandle
= NULL
;
142 // Uninstall HII Config Access Protocol
144 if (ConfigPrivateData
->DriverHandle
!= NULL
) {
145 gBS
->UninstallMultipleProtocolInterfaces (
146 ConfigPrivateData
->DriverHandle
,
147 &gEfiDevicePathProtocolGuid
,
148 &mRamDiskHiiVendorDevicePath
,
149 &gEfiHiiConfigAccessProtocolGuid
,
150 &ConfigPrivateData
->ConfigAccess
,
153 ConfigPrivateData
->DriverHandle
= NULL
;
156 FreePool (ConfigPrivateData
);
161 Unregister all registered RAM disks.
165 UnregisterAllRamDisks (
170 LIST_ENTRY
*NextEntry
;
171 RAM_DISK_PRIVATE_DATA
*PrivateData
;
173 if (!IsListEmpty(&RegisteredRamDisks
)) {
174 EFI_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &RegisteredRamDisks
) {
175 PrivateData
= RAM_DISK_PRIVATE_FROM_THIS (Entry
);
177 gBS
->UninstallMultipleProtocolInterfaces (
179 &gEfiBlockIoProtocolGuid
,
180 &PrivateData
->BlockIo
,
181 &gEfiBlockIo2ProtocolGuid
,
182 &PrivateData
->BlockIo2
,
183 &gEfiDevicePathProtocolGuid
,
184 (EFI_DEVICE_PATH_PROTOCOL
*) PrivateData
->DevicePath
,
188 RemoveEntryList (&PrivateData
->ThisInstance
);
190 if (RamDiskCreateHii
== PrivateData
->CreateMethod
) {
192 // If a RAM disk is created within HII, then the RamDiskDxe driver
193 // driver is responsible for freeing the allocated memory for the
196 FreePool ((VOID
*)(UINTN
) PrivateData
->StartingAddr
);
199 FreePool (PrivateData
->DevicePath
);
200 FreePool (PrivateData
);
207 This function allows a caller to extract the current configuration for one
208 or more named elements from the target driver.
210 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
211 @param[in] Request A null-terminated Unicode string in
212 <ConfigRequest> format.
213 @param[out] Progress On return, points to a character in the Request
214 string. Points to the string's null terminator if
215 request was successful. Points to the most recent
216 '&' before the first failing name/value pair (or
217 the beginning of the string if the failure is in
218 the first name/value pair) if the request was not
220 @param[out] Results A null-terminated Unicode string in
221 <ConfigAltResp> format which has all values filled
222 in for the names in the Request string. String to
223 be allocated by the called function.
225 @retval EFI_SUCCESS The Results is filled with the requested
227 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
228 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
229 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
235 RamDiskExtractConfig (
236 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
237 IN CONST EFI_STRING Request
,
238 OUT EFI_STRING
*Progress
,
239 OUT EFI_STRING
*Results
242 if (Progress
== NULL
|| Results
== NULL
) {
243 return EFI_INVALID_PARAMETER
;
246 return EFI_NOT_FOUND
;
251 This function processes the results of changes in configuration.
253 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
254 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
256 @param[out] Progress A pointer to a string filled in with the offset of
257 the most recent '&' before the first failing
258 name/value pair (or the beginning of the string if
259 the failure is in the first name/value pair) or
260 the terminating NULL if all was successful.
262 @retval EFI_SUCCESS The Results is processed successfully.
263 @retval EFI_INVALID_PARAMETER Configuration is NULL.
264 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
271 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
272 IN CONST EFI_STRING Configuration
,
273 OUT EFI_STRING
*Progress
276 if (Configuration
== NULL
|| Progress
== NULL
) {
277 return EFI_INVALID_PARAMETER
;
280 *Progress
= Configuration
;
282 return EFI_NOT_FOUND
;
287 Allocate memory and register the RAM disk created within RamDiskDxe
290 @param[in] Size If creating raw, size of the RAM disk to create.
291 If creating from file, zero.
292 @param[in] FileHandle If creating raw, NULL. If creating from file, the
294 @param[in] MemoryType Type of memory to be used to create RAM Disk.
296 @retval EFI_SUCCESS RAM disk is created and registered.
297 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the
304 IN EFI_FILE_HANDLE FileHandle
,
310 UINT64
*StartingAddr
;
312 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
313 RAM_DISK_PRIVATE_DATA
*PrivateData
;
314 EFI_FILE_INFO
*FileInformation
;
316 FileInformation
= NULL
;
319 if (FileHandle
!= NULL
) {
323 FileInformation
= FileInfo (FileHandle
);
324 if (NULL
== FileInformation
) {
327 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
330 L
"Not enough memory to get the file information!",
331 L
"Press ENTER to continue ...",
335 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
337 return EFI_OUT_OF_RESOURCES
;
341 // Update the size of RAM disk according to the file size.
343 Size
= FileInformation
->FileSize
;
346 if (Size
> (UINTN
) -1) {
349 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
352 L
"The given RAM disk size is too large!",
353 L
"Press ENTER to continue ...",
357 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
359 return EFI_OUT_OF_RESOURCES
;
362 if (MemoryType
== RAM_DISK_BOOT_SERVICE_DATA_MEMORY
) {
363 Status
= gBS
->AllocatePool (
366 (VOID
**)&StartingAddr
368 } else if (MemoryType
== RAM_DISK_RESERVED_MEMORY
) {
369 Status
= gBS
->AllocatePool (
370 EfiReservedMemoryType
,
372 (VOID
**)&StartingAddr
375 Status
= EFI_INVALID_PARAMETER
;
378 if ((StartingAddr
== NULL
) || EFI_ERROR(Status
)) {
381 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
384 L
"Not enough memory to create the RAM disk!",
385 L
"Press ENTER to continue ...",
389 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
391 return EFI_OUT_OF_RESOURCES
;
394 if (FileHandle
!= NULL
) {
396 // Copy the file content to the RAM disk.
398 BufferSize
= (UINTN
) Size
;
402 (VOID
*)(UINTN
) StartingAddr
404 if (BufferSize
!= FileInformation
->FileSize
) {
407 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
410 L
"File content read error!",
411 L
"Press ENTER to continue ...",
415 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
417 return EFI_DEVICE_ERROR
;
422 // Register the newly created RAM disk.
424 Status
= RamDiskRegister (
425 ((UINT64
)(UINTN
) StartingAddr
),
427 &gEfiVirtualDiskGuid
,
431 if (EFI_ERROR (Status
)) {
434 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
437 L
"Fail to register the newly created RAM disk!",
438 L
"Press ENTER to continue ...",
442 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
448 // If RAM disk is created within HII, memory should be freed when the
449 // RAM disk is unregisterd.
451 PrivateData
= RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks
.BackLink
);
452 PrivateData
->CreateMethod
= RamDiskCreateHii
;
459 This function updates the registered RAM disks list on the main form.
461 @param[in, out] ConfigPrivate
462 Private data for configurating hii data for RAM
468 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA
*ConfigPrivate
471 VOID
*StartOpCodeHandle
;
472 VOID
*EndOpCodeHandle
;
473 EFI_IFR_GUID_LABEL
*StartLabel
;
474 EFI_IFR_GUID_LABEL
*EndLabel
;
477 RAM_DISK_PRIVATE_DATA
*PrivateData
;
479 CHAR16 RamDiskStr
[128];
480 EFI_STRING_ID StringId
;
483 // Init OpCode Handle
485 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
486 ASSERT (StartOpCodeHandle
!= NULL
);
488 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
489 ASSERT (EndOpCodeHandle
!= NULL
);
492 // Create Hii Extend Label OpCode as the start opcode
494 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
498 sizeof (EFI_IFR_GUID_LABEL
)
500 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
501 StartLabel
->Number
= MAIN_LABEL_LIST_START
;
504 // Create Hii Extend Label OpCode as the end opcode
506 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
510 sizeof (EFI_IFR_GUID_LABEL
)
512 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
513 EndLabel
->Number
= MAIN_LABEL_LIST_END
;
516 EFI_LIST_FOR_EACH (Entry
, &RegisteredRamDisks
) {
517 PrivateData
= RAM_DISK_PRIVATE_FROM_THIS (Entry
);
518 PrivateData
->CheckBoxId
= (EFI_QUESTION_ID
)
519 (MAIN_CHECKBOX_QUESTION_ID_START
+ Index
);
521 // CheckBox is unchecked by default.
523 PrivateData
->CheckBoxChecked
= FALSE
;
529 L
" RAM Disk %d: [0x%lx, 0x%lx]\n",
531 PrivateData
->StartingAddr
,
532 PrivateData
->StartingAddr
+ PrivateData
->Size
- 1
535 StringId
= HiiSetString (ConfigPrivate
->HiiHandle
, 0, RamDiskStr
, NULL
);
536 ASSERT (StringId
!= 0);
538 HiiCreateCheckBoxOpCode (
540 PrivateData
->CheckBoxId
,
544 STRING_TOKEN (STR_RAM_DISK_LIST_HELP
),
545 EFI_IFR_FLAG_CALLBACK
,
554 ConfigPrivate
->HiiHandle
,
555 &gRamDiskFormSetGuid
,
561 HiiFreeOpCodeHandle (StartOpCodeHandle
);
562 HiiFreeOpCodeHandle (EndOpCodeHandle
);
567 This function processes the results of changes in configuration.
569 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
570 @param[in] Action Specifies the type of action taken by the browser.
571 @param[in] QuestionId A unique value which is sent to the original
572 exporting driver so that it can identify the type
574 @param[in] Type The type of value for the question.
575 @param[in] Value A pointer to the data being sent to the original
577 @param[out] ActionRequest On return, points to the action requested by the
580 @retval EFI_SUCCESS The callback successfully handled the action.
581 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
582 variable and its data.
583 @retval EFI_DEVICE_ERROR The variable could not be saved.
584 @retval EFI_UNSUPPORTED The specified Action is not supported by the
591 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
592 IN EFI_BROWSER_ACTION Action
,
593 IN EFI_QUESTION_ID QuestionId
,
595 IN EFI_IFR_TYPE_VALUE
*Value
,
596 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
600 RAM_DISK_PRIVATE_DATA
*PrivateData
;
601 RAM_DISK_CONFIG_PRIVATE_DATA
*ConfigPrivate
;
602 EFI_DEVICE_PATH_PROTOCOL
*FileDevPath
;
603 EFI_FILE_HANDLE FileHandle
;
605 LIST_ENTRY
*NextEntry
;
607 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
608 return EFI_INVALID_PARAMETER
;
611 ConfigPrivate
= RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This
);
613 if (Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
614 Status
= EFI_UNSUPPORTED
;
615 if (QuestionId
== CREATE_RAW_SIZE_QUESTION_ID
) {
616 Value
->u64
= EFI_PAGE_SIZE
;
617 ConfigPrivate
->ConfigStore
.Size
= EFI_PAGE_SIZE
;
618 Status
= EFI_SUCCESS
;
619 } else if (QuestionId
== CREATE_RAW_MEMORY_TYPE_QUESTION_ID
) {
620 Value
->u8
= RAM_DISK_BOOT_SERVICE_DATA_MEMORY
;
621 ConfigPrivate
->ConfigStore
.MemType
= RAM_DISK_BOOT_SERVICE_DATA_MEMORY
;
622 Status
= EFI_SUCCESS
;
627 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) &&
628 (Action
!= EFI_BROWSER_ACTION_CHANGING
) &&
629 (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
)) {
630 return EFI_UNSUPPORTED
;
634 // Update the RAM disk list show at the main form first.
636 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
637 Status
= EFI_UNSUPPORTED
;
638 if (QuestionId
== MAIN_GOTO_FILE_EXPLORER_ID
) {
639 UpdateMainForm (ConfigPrivate
);
640 Status
= EFI_SUCCESS
;
645 Status
= EFI_SUCCESS
;
647 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
648 switch (QuestionId
) {
649 case MAIN_GOTO_FILE_EXPLORER_ID
:
650 Status
= ChooseFile (NULL
, NULL
, NULL
, &FileDevPath
);
651 if (EFI_ERROR (Status
)) {
655 if (FileDevPath
!= NULL
) {
659 Status
= OpenFileByDevicePath (
665 if (EFI_ERROR (Status
)) {
670 // Create from file, RAM disk size is zero. It will be updated
671 // according to the file size.
673 Status
= HiiCreateRamDisk (
676 ConfigPrivate
->ConfigStore
.MemType
678 if (EFI_ERROR (Status
)) {
683 // Refresh the registered RAM disks list.
685 UpdateMainForm (ConfigPrivate
);
692 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
693 switch (QuestionId
) {
694 case MAIN_REMOVE_RD_QUESTION_ID
:
696 // Remove the selected RAM disks
698 EFI_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &RegisteredRamDisks
) {
699 PrivateData
= RAM_DISK_PRIVATE_FROM_THIS (Entry
);
700 if (PrivateData
->CheckBoxChecked
) {
702 (EFI_DEVICE_PATH_PROTOCOL
*) PrivateData
->DevicePath
707 UpdateMainForm (ConfigPrivate
);
709 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
712 case CREATE_RAW_SIZE_QUESTION_ID
:
713 ConfigPrivate
->ConfigStore
.Size
= Value
->u64
;
716 case CREATE_RAW_MEMORY_TYPE_QUESTION_ID
:
717 ConfigPrivate
->ConfigStore
.MemType
= Value
->u8
;
720 case CREATE_RAW_SUBMIT_QUESTION_ID
:
722 // Create raw, FileHandle is NULL.
724 Status
= HiiCreateRamDisk (
725 ConfigPrivate
->ConfigStore
.Size
,
727 ConfigPrivate
->ConfigStore
.MemType
729 if (EFI_ERROR (Status
)) {
734 // Refresh the registered RAM disks list.
736 UpdateMainForm (ConfigPrivate
);
738 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
741 case CREATE_RAW_DISCARD_QUESTION_ID
:
742 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
747 // QuestionIds for checkboxes
749 if ((QuestionId
>= MAIN_CHECKBOX_QUESTION_ID_START
) &&
750 (QuestionId
< CREATE_RAW_RAM_DISK_FORM_ID
)) {
751 EFI_LIST_FOR_EACH (Entry
, &RegisteredRamDisks
) {
752 PrivateData
= RAM_DISK_PRIVATE_FROM_THIS (Entry
);
753 if (PrivateData
->CheckBoxId
== QuestionId
) {
754 PrivateData
->CheckBoxChecked
= (BOOLEAN
) (Value
->u8
!= 0);