1 /******************************************************************************
2 *
3 * Module Name: osefixf - EFI OSL interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acapps.h"
47
48 #define _COMPONENT ACPI_OS_SERVICES
49 ACPI_MODULE_NAME ("osefixf")
50
51
52 /* Local definitions */
53
54 #define ACPI_EFI_PRINT_LENGTH 256
55
56
57 /* Local prototypes */
58
59 static ACPI_STATUS
60 AcpiEfiArgify (
61 char *String,
62 int *ArgcPtr,
63 char ***ArgvPtr);
64
65 static BOOLEAN
66 AcpiEfiCompareGuid (
67 EFI_GUID *Guid1,
68 EFI_GUID *Guid2);
69
70 static ACPI_STATUS
71 AcpiEfiConvertArgcv (
72 CHAR16 *LoadOpt,
73 UINT32 LoadOptSize,
74 int *ArgcPtr,
75 char ***ArgvPtr,
76 char **BufferPtr);
77
78 static ACPI_PHYSICAL_ADDRESS
79 AcpiEfiGetRsdpViaGuid (
80 EFI_GUID *Guid);
81
82 static CHAR16 *
83 AcpiEfiFlushFile (
84 ACPI_FILE File,
85 CHAR16 *Begin,
86 CHAR16 *End,
87 CHAR16 *Pos,
88 BOOLEAN FlushAll);
89
90
91 /* Local variables */
92
93 static EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL;
94 EFI_GUID AcpiGbl_LoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
95 EFI_GUID AcpiGbl_TextInProtocol = SIMPLE_TEXT_INPUT_PROTOCOL;
96 EFI_GUID AcpiGbl_TextOutProtocol = SIMPLE_TEXT_OUTPUT_PROTOCOL;
97 EFI_GUID AcpiGbl_FileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
98
99
100 /******************************************************************************
101 *
102 * FUNCTION: AcpiEfiGetRsdpViaGuid
103 *
104 * PARAMETERS: Guid1 - GUID to compare
105 * Guid2 - GUID to compare
106 *
107 * RETURN: TRUE if Guid1 == Guid2
108 *
109 * DESCRIPTION: Compares two GUIDs
110 *
111 *****************************************************************************/
112
113 static BOOLEAN
AcpiEfiCompareGuid(EFI_GUID * Guid1,EFI_GUID * Guid2)114 AcpiEfiCompareGuid (
115 EFI_GUID *Guid1,
116 EFI_GUID *Guid2)
117 {
118 INT32 *g1;
119 INT32 *g2;
120 INT32 r;
121
122
123 g1 = (INT32 *) Guid1;
124 g2 = (INT32 *) Guid2;
125
126 r = g1[0] - g2[0];
127 r |= g1[1] - g2[1];
128 r |= g1[2] - g2[2];
129 r |= g1[3] - g2[3];
130
131 return (r ? FALSE : TRUE);
132 }
133
134
135 /******************************************************************************
136 *
137 * FUNCTION: AcpiEfiGetRsdpViaGuid
138 *
139 * PARAMETERS: None
140 *
141 * RETURN: RSDP address if found
142 *
143 * DESCRIPTION: Find RSDP address via EFI using specified GUID.
144 *
145 *****************************************************************************/
146
147 static ACPI_PHYSICAL_ADDRESS
AcpiEfiGetRsdpViaGuid(EFI_GUID * Guid)148 AcpiEfiGetRsdpViaGuid (
149 EFI_GUID *Guid)
150 {
151 ACPI_PHYSICAL_ADDRESS Address = 0;
152 int i;
153
154
155 for (i = 0; i < ST->NumberOfTableEntries; i++)
156 {
157 if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid))
158 {
159 Address = ACPI_PTR_TO_PHYSADDR (
160 ST->ConfigurationTable[i].VendorTable);
161 break;
162 }
163 }
164
165 return (Address);
166 }
167
168
169 /******************************************************************************
170 *
171 * FUNCTION: AcpiOsGetRootPointer
172 *
173 * PARAMETERS: None
174 *
175 * RETURN: RSDP physical address
176 *
177 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
178 *
179 *****************************************************************************/
180
181 ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer(void)182 AcpiOsGetRootPointer (
183 void)
184 {
185 ACPI_PHYSICAL_ADDRESS Address;
186 EFI_GUID Guid10 = ACPI_TABLE_GUID;
187 EFI_GUID Guid20 = ACPI_20_TABLE_GUID;
188
189
190 Address = AcpiEfiGetRsdpViaGuid (&Guid20);
191 if (!Address)
192 {
193 Address = AcpiEfiGetRsdpViaGuid (&Guid10);
194 }
195
196 return (Address);
197 }
198
199
200 /******************************************************************************
201 *
202 * FUNCTION: AcpiOsMapMemory
203 *
204 * PARAMETERS: where - Physical address of memory to be mapped
205 * length - How much memory to map
206 *
207 * RETURN: Pointer to mapped memory. Null on error.
208 *
209 * DESCRIPTION: Map physical memory into caller's address space
210 *
211 *****************************************************************************/
212
213 void *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS where,ACPI_SIZE length)214 AcpiOsMapMemory (
215 ACPI_PHYSICAL_ADDRESS where,
216 ACPI_SIZE length)
217 {
218
219 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
220 }
221
222
223 /******************************************************************************
224 *
225 * FUNCTION: AcpiOsUnmapMemory
226 *
227 * PARAMETERS: where - Logical address of memory to be unmapped
228 * length - How much memory to unmap
229 *
230 * RETURN: None
231 *
232 * DESCRIPTION: Delete a previously created mapping. Where and Length must
233 * correspond to a previous mapping exactly.
234 *
235 *****************************************************************************/
236
237 void
AcpiOsUnmapMemory(void * where,ACPI_SIZE length)238 AcpiOsUnmapMemory (
239 void *where,
240 ACPI_SIZE length)
241 {
242
243 return;
244 }
245
246
247 /******************************************************************************
248 *
249 * FUNCTION: Spinlock interfaces
250 *
251 * DESCRIPTION: No-op on single threaded BIOS
252 *
253 *****************************************************************************/
254
255 ACPI_STATUS
AcpiOsCreateLock(ACPI_SPINLOCK * OutHandle)256 AcpiOsCreateLock (
257 ACPI_SPINLOCK *OutHandle)
258 {
259 return (AE_OK);
260 }
261
262 void
AcpiOsDeleteLock(ACPI_SPINLOCK Handle)263 AcpiOsDeleteLock (
264 ACPI_SPINLOCK Handle)
265 {
266 }
267
268 ACPI_CPU_FLAGS
AcpiOsAcquireLock(ACPI_SPINLOCK Handle)269 AcpiOsAcquireLock (
270 ACPI_SPINLOCK Handle)
271 {
272 return (0);
273 }
274
275 void
AcpiOsReleaseLock(ACPI_SPINLOCK Handle,ACPI_CPU_FLAGS Flags)276 AcpiOsReleaseLock (
277 ACPI_SPINLOCK Handle,
278 ACPI_CPU_FLAGS Flags)
279 {
280 }
281
282
283 /******************************************************************************
284 *
285 * FUNCTION: AcpiOsAllocate
286 *
287 * PARAMETERS: Size - Amount to allocate, in bytes
288 *
289 * RETURN: Pointer to the new allocation. Null on error.
290 *
291 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
292 *
293 *****************************************************************************/
294
295 void *
AcpiOsAllocate(ACPI_SIZE Size)296 AcpiOsAllocate (
297 ACPI_SIZE Size)
298 {
299 EFI_STATUS EfiStatus;
300 void *Mem;
301
302
303 EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3,
304 EfiLoaderData, Size, &Mem);
305 if (EFI_ERROR (EfiStatus))
306 {
307 AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n");
308 return (NULL);
309 }
310
311 return (Mem);
312 }
313
314
315 #ifdef USE_NATIVE_ALLOCATE_ZEROED
316 /******************************************************************************
317 *
318 * FUNCTION: AcpiOsAllocateZeroed
319 *
320 * PARAMETERS: Size - Amount to allocate, in bytes
321 *
322 * RETURN: Pointer to the new allocation. Null on error.
323 *
324 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
325 *
326 *****************************************************************************/
327
328 void *
AcpiOsAllocateZeroed(ACPI_SIZE Size)329 AcpiOsAllocateZeroed (
330 ACPI_SIZE Size)
331 {
332 void *Mem;
333
334
335 Mem = AcpiOsAllocate (Size);
336 if (Mem)
337 {
338 memset (Mem, 0, Size);
339 }
340
341 return (Mem);
342 }
343 #endif
344
345
346 /******************************************************************************
347 *
348 * FUNCTION: AcpiOsFree
349 *
350 * PARAMETERS: Mem - Pointer to previously allocated memory
351 *
352 * RETURN: None
353 *
354 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
355 *
356 *****************************************************************************/
357
358 void
AcpiOsFree(void * Mem)359 AcpiOsFree (
360 void *Mem)
361 {
362
363 uefi_call_wrapper (BS->FreePool, 1, Mem);
364 }
365
366
367 /*******************************************************************************
368 *
369 * FUNCTION: AcpiOsOpenFile
370 *
371 * PARAMETERS: Path - File path
372 * Modes - File operation type
373 *
374 * RETURN: File descriptor
375 *
376 * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
377 * (ACPI_FILE_WRITING).
378 *
379 ******************************************************************************/
380
381 ACPI_FILE
AcpiOsOpenFile(const char * Path,UINT8 Modes)382 AcpiOsOpenFile (
383 const char *Path,
384 UINT8 Modes)
385 {
386 EFI_STATUS EfiStatus = EFI_SUCCESS;
387 UINT64 OpenModes;
388 EFI_FILE_HANDLE EfiFile = NULL;
389 CHAR16 *Path16 = NULL;
390 CHAR16 *Pos16;
391 const char *Pos;
392 INTN Count, i;
393
394
395 if (!Path)
396 {
397 return (NULL);
398 }
399
400 /* Convert modes */
401
402 OpenModes = EFI_FILE_MODE_READ;
403 if (Modes & ACPI_FILE_WRITING)
404 {
405 OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
406 }
407
408 /* Allocate path buffer */
409
410 Count = strlen (Path);
411 Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16));
412 if (!Path16)
413 {
414 EfiStatus = EFI_BAD_BUFFER_SIZE;
415 goto ErrorExit;
416 }
417 Pos = Path;
418 Pos16 = Path16;
419 while (*Pos == '/' || *Pos == '\\')
420 {
421 Pos++;
422 Count--;
423 }
424 for (i = 0; i < Count; i++)
425 {
426 if (*Pos == '/')
427 {
428 *Pos16++ = '\\';
429 Pos++;
430 }
431 else
432 {
433 *Pos16++ = *Pos++;
434 }
435 }
436 *Pos16 = '\0';
437
438 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5,
439 AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0);
440 if (EFI_ERROR (EfiStatus))
441 {
442 AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n");
443 goto ErrorExit;
444 }
445
446 ErrorExit:
447
448 if (Path16)
449 {
450 ACPI_FREE (Path16);
451 }
452
453 return ((ACPI_FILE) EfiFile);
454 }
455
456
457 /*******************************************************************************
458 *
459 * FUNCTION: AcpiOsCloseFile
460 *
461 * PARAMETERS: File - File descriptor
462 *
463 * RETURN: None.
464 *
465 * DESCRIPTION: Close a file.
466 *
467 ******************************************************************************/
468
469 void
AcpiOsCloseFile(ACPI_FILE File)470 AcpiOsCloseFile (
471 ACPI_FILE File)
472 {
473 EFI_FILE_HANDLE EfiFile;
474
475
476 if (File == ACPI_FILE_OUT ||
477 File == ACPI_FILE_ERR)
478 {
479 return;
480 }
481 EfiFile = (EFI_FILE_HANDLE) File;
482 (void) uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Close, 1, EfiFile);
483
484 return;
485 }
486
487
488 /*******************************************************************************
489 *
490 * FUNCTION: AcpiOsReadFile
491 *
492 * PARAMETERS: File - File descriptor
493 * Buffer - Data buffer
494 * Size - Data block size
495 * Count - Number of data blocks
496 *
497 * RETURN: Size of successfully read buffer
498 *
499 * DESCRIPTION: Read from a file.
500 *
501 ******************************************************************************/
502
503 int
AcpiOsReadFile(ACPI_FILE File,void * Buffer,ACPI_SIZE Size,ACPI_SIZE Count)504 AcpiOsReadFile (
505 ACPI_FILE File,
506 void *Buffer,
507 ACPI_SIZE Size,
508 ACPI_SIZE Count)
509 {
510 int Length = -1;
511 EFI_FILE_HANDLE EfiFile;
512 UINTN ReadSize;
513 EFI_STATUS EfiStatus;
514
515
516 if (File == ACPI_FILE_OUT ||
517 File == ACPI_FILE_ERR)
518 {
519 }
520 else
521 {
522 EfiFile = (EFI_FILE_HANDLE) File;
523 if (!EfiFile)
524 {
525 goto ErrorExit;
526 }
527 ReadSize = Size * Count;
528
529 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3,
530 EfiFile, &ReadSize, Buffer);
531 if (EFI_ERROR (EfiStatus))
532 {
533 AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n");
534 goto ErrorExit;
535 }
536 Length = ReadSize;
537 }
538
539 ErrorExit:
540
541 return (Length);
542 }
543
544
545 /*******************************************************************************
546 *
547 * FUNCTION: AcpiEfiFlushFile
548 *
549 * PARAMETERS: File - File descriptor
550 * Begin - String with boundary
551 * End - Boundary of the string
552 * Pos - Current position
553 * FlushAll - Whether checking boundary before flushing
554 *
555 * RETURN: Updated position
556 *
557 * DESCRIPTION: Flush cached buffer to the file.
558 *
559 ******************************************************************************/
560
561 static CHAR16 *
AcpiEfiFlushFile(ACPI_FILE File,CHAR16 * Begin,CHAR16 * End,CHAR16 * Pos,BOOLEAN FlushAll)562 AcpiEfiFlushFile (
563 ACPI_FILE File,
564 CHAR16 *Begin,
565 CHAR16 *End,
566 CHAR16 *Pos,
567 BOOLEAN FlushAll)
568 {
569
570 if (FlushAll || Pos >= (End - 1))
571 {
572 *Pos = 0;
573 uefi_call_wrapper (File->OutputString, 2, File, Begin);
574 Pos = Begin;
575 }
576
577 return (Pos);
578 }
579
580
581 /*******************************************************************************
582 *
583 * FUNCTION: AcpiOsWriteFile
584 *
585 * PARAMETERS: File - File descriptor
586 * Buffer - Data buffer
587 * Size - Data block size
588 * Count - Number of data blocks
589 *
590 * RETURN: Size of successfully written buffer
591 *
592 * DESCRIPTION: Write to a file.
593 *
594 ******************************************************************************/
595
596 int
AcpiOsWriteFile(ACPI_FILE File,void * Buffer,ACPI_SIZE Size,ACPI_SIZE Count)597 AcpiOsWriteFile (
598 ACPI_FILE File,
599 void *Buffer,
600 ACPI_SIZE Size,
601 ACPI_SIZE Count)
602 {
603 int Length = -1;
604 CHAR16 String[ACPI_EFI_PRINT_LENGTH];
605 const char *Ascii;
606 CHAR16 *End;
607 CHAR16 *Pos;
608 int i, j;
609 EFI_FILE_HANDLE EfiFile;
610 UINTN WriteSize;
611 EFI_STATUS EfiStatus;
612
613
614 if (File == ACPI_FILE_OUT ||
615 File == ACPI_FILE_ERR)
616 {
617 Pos = String;
618 End = String + ACPI_EFI_PRINT_LENGTH - 1;
619 Ascii = ACPI_CAST_PTR (const char, Buffer);
620 Length = 0;
621
622 for (j = 0; j < Count; j++)
623 {
624 for (i = 0; i < Size; i++)
625 {
626 if (*Ascii == '\n')
627 {
628 *Pos++ = '\r';
629 Pos = AcpiEfiFlushFile (File, String,
630 End, Pos, FALSE);
631 }
632 *Pos++ = *Ascii++;
633 Length++;
634 Pos = AcpiEfiFlushFile (File, String,
635 End, Pos, FALSE);
636 }
637 }
638 Pos = AcpiEfiFlushFile (File, String, End, Pos, TRUE);
639 }
640 else
641 {
642 EfiFile = (EFI_FILE_HANDLE) File;
643 if (!EfiFile)
644 {
645 goto ErrorExit;
646 }
647 WriteSize = Size * Count;
648
649 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Write, 3,
650 EfiFile, &WriteSize, Buffer);
651 if (EFI_ERROR (EfiStatus))
652 {
653 AcpiLogError ("EFI_FILE_HANDLE->Write() failure.\n");
654 goto ErrorExit;
655 }
656 Length = WriteSize;
657 }
658
659 ErrorExit:
660
661 return (Length);
662 }
663
664
665 /*******************************************************************************
666 *
667 * FUNCTION: AcpiOsGetFileOffset
668 *
669 * PARAMETERS: File - File descriptor
670 *
671 * RETURN: Size of current position
672 *
673 * DESCRIPTION: Get current file offset.
674 *
675 ******************************************************************************/
676
677 long
AcpiOsGetFileOffset(ACPI_FILE File)678 AcpiOsGetFileOffset (
679 ACPI_FILE File)
680 {
681 long Offset = -1;
682
683
684 return (Offset);
685 }
686
687
688 /*******************************************************************************
689 *
690 * FUNCTION: AcpiOsSetFileOffset
691 *
692 * PARAMETERS: File - File descriptor
693 * Offset - File offset
694 * From - From begin/end of file
695 *
696 * RETURN: Status
697 *
698 * DESCRIPTION: Set current file offset.
699 *
700 ******************************************************************************/
701
702 ACPI_STATUS
AcpiOsSetFileOffset(ACPI_FILE File,long Offset,UINT8 From)703 AcpiOsSetFileOffset (
704 ACPI_FILE File,
705 long Offset,
706 UINT8 From)
707 {
708
709 return (AE_SUPPORT);
710 }
711
712
713 /******************************************************************************
714 *
715 * FUNCTION: AcpiOsPrintf
716 *
717 * PARAMETERS: Format, ... - Standard printf format
718 *
719 * RETURN: None
720 *
721 * DESCRIPTION: Formatted output.
722 *
723 *****************************************************************************/
724
725 void ACPI_INTERNAL_VAR_XFACE
AcpiOsPrintf(const char * Format,...)726 AcpiOsPrintf (
727 const char *Format,
728 ...)
729 {
730 va_list Args;
731
732
733 va_start (Args, Format);
734 AcpiOsVprintf (Format, Args);
735 va_end (Args);
736 }
737
738
739 /******************************************************************************
740 *
741 * FUNCTION: AcpiOsVprintf
742 *
743 * PARAMETERS: Format - Standard printf format
744 * Args - Argument list
745 *
746 * RETURN: None
747 *
748 * DESCRIPTION: Formatted output with arguments list pointer.
749 *
750 *****************************************************************************/
751
752 void
AcpiOsVprintf(const char * Format,va_list Args)753 AcpiOsVprintf (
754 const char *Format,
755 va_list Args)
756 {
757
758 (void) AcpiUtFileVprintf (ACPI_FILE_OUT, Format, Args);
759 }
760
761
762 /******************************************************************************
763 *
764 * FUNCTION: AcpiOsInitialize
765 *
766 * PARAMETERS: None
767 *
768 * RETURN: Status
769 *
770 * DESCRIPTION: Initialize this module.
771 *
772 *****************************************************************************/
773
774 ACPI_STATUS
AcpiOsInitialize(void)775 AcpiOsInitialize (
776 void)
777 {
778
779 return (AE_OK);
780 }
781
782
783 /******************************************************************************
784 *
785 * FUNCTION: AcpiEfiArgify
786 *
787 * PARAMETERS: String - Pointer to command line argument strings
788 * which are seperated with spaces
789 * ArgcPtr - Return number of the arguments
790 * ArgvPtr - Return vector of the arguments
791 *
792 * RETURN: Status
793 *
794 * DESCRIPTION: Convert EFI arguments into C arguments.
795 *
796 *****************************************************************************/
797
798 static ACPI_STATUS
AcpiEfiArgify(char * String,int * ArgcPtr,char *** ArgvPtr)799 AcpiEfiArgify (
800 char *String,
801 int *ArgcPtr,
802 char ***ArgvPtr)
803 {
804 char *CopyBuffer;
805 int MaxArgc = *ArgcPtr;
806 int Argc = 0;
807 char **Argv = *ArgvPtr;
808 char *Arg;
809 BOOLEAN IsSingleQuote = FALSE;
810 BOOLEAN IsDoubleQuote = FALSE;
811 BOOLEAN IsEscape = FALSE;
812
813
814 if (String == NULL)
815 {
816 return (AE_BAD_PARAMETER);
817 }
818
819 CopyBuffer = String;
820
821 while (*String != '\0')
822 {
823 while (isspace (*String))
824 {
825 *String++ = '\0';
826 }
827 Arg = CopyBuffer;
828 while (*String != '\0')
829 {
830 if (isspace (*String) &&
831 !IsSingleQuote && !IsDoubleQuote && !IsEscape)
832 {
833 *Arg++ = '\0';
834 String++;
835 break;
836 }
837 if (IsEscape)
838 {
839 IsEscape = FALSE;
840 *Arg++ = *String;
841 }
842 else if (*String == '\\')
843 {
844 IsEscape = TRUE;
845 }
846 else if (IsSingleQuote)
847 {
848 if (*String == '\'')
849 {
850 IsSingleQuote = FALSE;
851 *Arg++ = '\0';
852 }
853 else
854 {
855 *Arg++ = *String;
856 }
857 }
858 else if (IsDoubleQuote)
859 {
860 if (*String == '"')
861 {
862 IsDoubleQuote = FALSE;
863 *Arg = '\0';
864 }
865 else
866 {
867 *Arg++ = *String;
868 }
869 }
870 else
871 {
872 if (*String == '\'')
873 {
874 IsSingleQuote = TRUE;
875 }
876 else if (*String == '"')
877 {
878 IsDoubleQuote = TRUE;
879 }
880 else
881 {
882 *Arg++ = *String;
883 }
884 }
885 String++;
886 }
887 if (Argv && Argc < MaxArgc)
888 {
889 Argv[Argc] = CopyBuffer;
890 }
891 Argc++;
892 CopyBuffer = Arg;
893 }
894 if (Argv && Argc < MaxArgc)
895 {
896 Argv[Argc] = NULL;
897 }
898
899 *ArgcPtr = Argc;
900 *ArgvPtr = Argv;
901
902 return ((MaxArgc < Argc) ? AE_NO_MEMORY : AE_OK);
903 }
904
905
906 /******************************************************************************
907 *
908 * FUNCTION: AcpiEfiConvertArgcv
909 *
910 * PARAMETERS: LoadOptions - Pointer to the EFI options buffer, which
911 * is NULL terminated
912 * LoadOptionsSize - Size of the EFI options buffer
913 * ArgcPtr - Return number of the arguments
914 * ArgvPtr - Return vector of the arguments
915 * BufferPtr - Buffer to contain the argument strings
916 *
917 * RETURN: Status
918 *
919 * DESCRIPTION: Convert EFI arguments into C arguments.
920 *
921 *****************************************************************************/
922
923 static ACPI_STATUS
AcpiEfiConvertArgcv(CHAR16 * LoadOptions,UINT32 LoadOptionsSize,int * ArgcPtr,char *** ArgvPtr,char ** BufferPtr)924 AcpiEfiConvertArgcv (
925 CHAR16 *LoadOptions,
926 UINT32 LoadOptionsSize,
927 int *ArgcPtr,
928 char ***ArgvPtr,
929 char **BufferPtr)
930 {
931 ACPI_STATUS Status = AE_OK;
932 UINT32 Count = LoadOptionsSize / sizeof (CHAR16);
933 UINT32 i;
934 CHAR16 *From;
935 char *To;
936 int Argc = 0;
937 char **Argv = NULL;
938 char *Buffer;
939
940
941 /* Prepare a buffer to contain the argument strings */
942
943 Buffer = ACPI_ALLOCATE_ZEROED (Count);
944 if (!Buffer)
945 {
946 Status = AE_NO_MEMORY;
947 goto ErrorExit;
948 }
949
950 TryAgain:
951
952 /* Extend the argument vector */
953
954 if (Argv)
955 {
956 ACPI_FREE (Argv);
957 Argv = NULL;
958 }
959 if (Argc > 0)
960 {
961 Argv = ACPI_ALLOCATE_ZEROED (sizeof (char *) * (Argc + 1));
962 if (!Argv)
963 {
964 Status = AE_NO_MEMORY;
965 goto ErrorExit;
966 }
967 }
968
969 /*
970 * Note: As AcpiEfiArgify() will modify the content of the buffer, so
971 * we need to restore it each time before invoking
972 * AcpiEfiArgify().
973 */
974 From = LoadOptions;
975 To = ACPI_CAST_PTR (char, Buffer);
976 for (i = 0; i < Count; i++)
977 {
978 *To++ = (char) *From++;
979 }
980
981 /*
982 * The "Buffer" will contain NULL terminated strings after invoking
983 * AcpiEfiArgify(). The number of the strings are saved in Argc and the
984 * pointers of the strings are saved in Argv.
985 */
986 Status = AcpiEfiArgify (Buffer, &Argc, &Argv);
987 if (ACPI_FAILURE (Status))
988 {
989 if (Status == AE_NO_MEMORY)
990 {
991 goto TryAgain;
992 }
993 }
994
995 ErrorExit:
996
997 if (ACPI_FAILURE (Status))
998 {
999 ACPI_FREE (Buffer);
1000 ACPI_FREE (Argv);
1001 }
1002 else
1003 {
1004 *ArgcPtr = Argc;
1005 *ArgvPtr = Argv;
1006 *BufferPtr = Buffer;
1007 }
1008 return (Status);
1009 }
1010
1011
1012 /******************************************************************************
1013 *
1014 * FUNCTION: efi_main
1015 *
1016 * PARAMETERS: Image - EFI image handle
1017 * SystemTab - EFI system table
1018 *
1019 * RETURN: EFI Status
1020 *
1021 * DESCRIPTION: Entry point of EFI executable
1022 *
1023 *****************************************************************************/
1024
1025 EFI_STATUS
efi_main(EFI_HANDLE Image,EFI_SYSTEM_TABLE * SystemTab)1026 efi_main (
1027 EFI_HANDLE Image,
1028 EFI_SYSTEM_TABLE *SystemTab)
1029 {
1030 EFI_LOADED_IMAGE *Info;
1031 EFI_STATUS EfiStatus = EFI_SUCCESS;
1032 ACPI_STATUS Status;
1033 int argc;
1034 char **argv = NULL;
1035 char *OptBuffer = NULL;
1036 EFI_FILE_IO_INTERFACE *Volume = NULL;
1037
1038
1039 /* Initialize global variables */
1040
1041 ST = SystemTab;
1042 BS = SystemTab->BootServices;
1043
1044 /* Retrieve image information */
1045
1046 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1047 Image, &AcpiGbl_LoadedImageProtocol, ACPI_CAST_PTR (VOID, &Info));
1048 if (EFI_ERROR (EfiStatus))
1049 {
1050 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(LoadedImageProtocol) failure.\n");
1051 return (EfiStatus);
1052 }
1053
1054 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1055 Info->DeviceHandle, &AcpiGbl_FileSystemProtocol, (void **) &Volume);
1056 if (EFI_ERROR (EfiStatus))
1057 {
1058 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(FileSystemProtocol) failure.\n");
1059 return (EfiStatus);
1060 }
1061 EfiStatus = uefi_call_wrapper (Volume->OpenVolume, 2,
1062 Volume, &AcpiGbl_EfiCurrentVolume);
1063 if (EFI_ERROR (EfiStatus))
1064 {
1065 AcpiLogError ("EFI_FILE_IO_INTERFACE->OpenVolume() failure.\n");
1066 return (EfiStatus);
1067 }
1068
1069 Status = AcpiEfiConvertArgcv (Info->LoadOptions,
1070 Info->LoadOptionsSize, &argc, &argv, &OptBuffer);
1071 if (ACPI_FAILURE (Status))
1072 {
1073 EfiStatus = EFI_DEVICE_ERROR;
1074 goto ErrorAlloc;
1075 }
1076
1077 acpi_main (argc, argv);
1078
1079 ErrorAlloc:
1080
1081 if (argv)
1082 {
1083 ACPI_FREE (argv);
1084 }
1085 if (OptBuffer)
1086 {
1087 ACPI_FREE (OptBuffer);
1088 }
1089
1090 return (EfiStatus);
1091 }
1092