Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Dec 2002 14:28:14 -0800 (PST)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 22048 for review
Message-ID:  <200212072228.gB7MSEAC064926@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22048

Change 22048 by marcel@marcel_nfs on 2002/12/07 14:27:23

	Combined changes:
	When an OS loader exits and returns to the boot manager or
	EFI shell, it is responsible to free any memory allocated.
	We have our own heap, but we do allocate memory for it.
	This we never freed upon exit.
	
	To avoid nasty holes and other corner cases caused by trying
	to fix this in a quick 'n dirty way, we change the EFI
	startup code. Instead of having efi_main() be the user
	provided function that serves as the entry point and from
	which we further initialize the process, we have efi_main()
	be the entry point that resides in libefi and which will
	eventually call the user-level entry point. This we simply
	call main(). We allocate the heap in efi_main().
	
	The exit() function has been moved to libefi.c so that when
	the process calls exit() or returns from main(), we free
	the heap before turning off the lights.
	
	As a side-effect we now also have a better basis to pass
	command line arguments to main (AKA load options). At this
	time we simply pass the string length as argc and a pointer
	to the ASCII or Unicode-16 string in argv, but this will
	be changed to match the standard C prototype (with the
	exception that argv will probably contain pointers to
	Unicode-16 strings instead of ASCII strings).
	
	This change also includes the introduction of efi_get_table().
	This function will return a pointer to the configuration table
	identified by the UUID (or GUID). We already had a couple of
	places where we duplicated the logic and it could only get
	worse. This function could have its own file, but I doubt it
	will be useful...
	
	Can you believe that this is the result of wanting to put a
	pointer to the HCDP table in bootinfo? Talk about side-
	tracking... It's terry-fying :-)

Affected files ...

.. //depot/projects/ia64/sys/boot/efi/include/efilib.h#2 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/Makefile#6 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/libefi.c#2 edit
.. //depot/projects/ia64/sys/boot/efi/loader/main.c#10 edit

Differences ...

==== //depot/projects/ia64/sys/boot/efi/include/efilib.h#2 (text+ko) ====

@@ -31,4 +31,5 @@
 extern EFI_BOOT_SERVICES	*BS;
 extern EFI_RUNTIME_SERVICES	*RS;
 
+void *efi_get_table(EFI_GUID *tbl);
 void efi_init(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);

==== //depot/projects/ia64/sys/boot/efi/libefi/Makefile#6 (text+ko) ====

@@ -5,7 +5,7 @@
 LIB=		efi
 INTERNALLIB=	true
 
-SRCS=	libefi.c efi_console.c time.c copy.c devicename.c module.c exit.c
+SRCS=	libefi.c efi_console.c time.c copy.c devicename.c module.c
 SRCS+=	delay.c efifs.c efinet.c elf_freebsd.c bootinfo.c pal.s
 
 .if ${MACHINE_ARCH} == "ia64"

==== //depot/projects/ia64/sys/boot/efi/libefi/libefi.c#2 (text+ko) ====

@@ -37,11 +37,56 @@
 EFI_BOOT_SERVICES	*BS;
 EFI_RUNTIME_SERVICES	*RS;
 
+static EFI_PHYSICAL_ADDRESS heap;
+static UINTN heapsize;
+
+void *
+efi_get_table(EFI_GUID *tbl)
+{
+	EFI_GUID *id;
+	int i;
+
+	for (i = 0; i < ST->NumberOfTableEntries; i++) {
+		id = &ST->ConfigurationTable[i].VendorGuid;
+		if (!memcmp(id, tbl, sizeof(EFI_GUID)))
+			return (ST->ConfigurationTable[i].VendorTable);
+        }
+        return (NULL);
+}
+
+void exit(EFI_STATUS exit_code)
+{
+
+	BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize));
+	BS->Exit(IH, exit_code, 0, NULL);
+}
+
 void
-efi_init(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
+efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
 {
+	static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL;
+	EFI_LOADED_IMAGE *image;
+	EFI_STATUS status;
+
 	IH = image_handle;
 	ST = system_table;
 	BS = ST->BootServices;
 	RS = ST->RuntimeServices;
+
+	heapsize = 512*1024;
+	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
+	    EFI_SIZE_TO_PAGES(heapsize), &heap);
+	if (status != EFI_SUCCESS)
+		BS->Exit(IH, status, 0, NULL);
+
+	setheap((void *)heap, (void *)(heap + heapsize));
+
+	/* Use exit() from here on... */
+
+	status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&image);
+	if (status != EFI_SUCCESS)
+		exit(status);
+
+	status = main(image->LoadOptionsSize, image->LoadOptions);
+	exit(status);
 }

==== //depot/projects/ia64/sys/boot/efi/loader/main.c#10 (text+ko) ====

@@ -53,6 +53,15 @@
 
 extern u_int64_t	ia64_pal_entry;
 
+EFI_GUID acpi = ACPI_TABLE_GUID;
+EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
+EFI_GUID hcdp = HCDP_TABLE_GUID;
+EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
+EFI_GUID mps = MPS_TABLE_GUID;
+EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
+EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
+EFI_GUID smbios = SMBIOS_TABLE_GUID;
+
 static void
 find_pal_proc(void)
 {
@@ -63,14 +72,8 @@
 	};
 	u_int8_t *p;
 
-	for (i = 0; i < ST->NumberOfTableEntries; i++) {
-		static EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
-		if (!memcmp(&ST->ConfigurationTable[i].VendorGuid,
-				 &sal, sizeof(EFI_GUID)))
-			saltab = ST->ConfigurationTable[i].VendorTable;
-	}
-
-	if (!saltab) {
+	saltab = efi_get_table(&sal);
+	if (saltab == NULL) {
 		printf("Can't find SAL System Table\n");
 		return;
 	}
@@ -96,30 +99,14 @@
 }
 
 EFI_STATUS
-efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
+main(int argc, char *argv)
 {
-	static EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
-	static EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
-	EFI_PHYSICAL_ADDRESS mem;
 	EFI_LOADED_IMAGE *img;
 	EFI_SIMPLE_NETWORK *net;
 	EFI_STATUS status;
-	struct ia64_pal_result res;
-	char buf[32];
 	int i;
 
-	efi_init(image_handle, system_table);
-
 	/* 
-	 * Initialise the heap as early as possible.  Once this is done,
-	 * alloc() is usable. The stack is buried inside us, so this is
-	 * safe.
-	 */
-	BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
-			  512*1024/4096, &mem);
-	setheap((void *)mem, (void *)(mem + 512*1024));
-
-	/* 
 	 * XXX Chicken-and-egg problem; we want to have console output
 	 * early, but some console attributes may depend on reading from
 	 * eg. the boot device, which we can't do yet.  We can use
@@ -156,7 +143,7 @@
 	 * other cases we set the default device to 'disk'. We presume
 	 * fixed positions in devsw for both net and disk.
 	 */
-	BS->HandleProtocol(image_handle, &imgid, (VOID**)&img);
+	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
 
 	status = BS->HandleProtocol(img->DeviceHandle, &netid, (VOID**)&net);
 	if (status == EFI_SUCCESS && net != NULL) {
@@ -308,12 +295,6 @@
 
 	printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
 	for (i = 0; i < ST->NumberOfTableEntries; i++) {
-		static EFI_GUID mps = MPS_TABLE_GUID;
-		static EFI_GUID acpi = ACPI_TABLE_GUID;
-		static EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
-		static EFI_GUID smbios = SMBIOS_TABLE_GUID;
-		static EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
-		static EFI_GUID hcdp = HCDP_TABLE_GUID;
 		EFI_GUID *guid;
 
 		printf("  ");
@@ -350,14 +331,8 @@
 	};
 	u_int8_t *p;
 
-	for (i = 0; i < ST->NumberOfTableEntries; i++) {
-		static EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
-		if (!memcmp(&ST->ConfigurationTable[i].VendorGuid,
-				 &sal, sizeof(EFI_GUID)))
-			saltab = ST->ConfigurationTable[i].VendorTable;
-	}
-
-	if (!saltab) {
+	saltab = efi_get_table(&sal);
+	if (saltab == NULL) {
 		printf("Can't find SAL System Table\n");
 		return CMD_ERROR;
 	}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212072228.gB7MSEAC064926>