public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Krish Sadhukhan <krish.sadhukhan@oracle.com>
To: Varad Gautam <varadgautam@gmail.com>,
	Zixuan Wang <zixuanwang@google.com>,
	Nadav Amit <nadav.amit@gmail.com>, Marc Orr <marcorr@google.com>,
	Joerg Roedel <jroedel@suse.de>, kvm list <kvm@vger.kernel.org>,
	Linux Virtualization <virtualization@lists.linux-foundation.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Andrew Jones <drjones@redhat.com>,
	bp@suse.de, Thomas.Lendacky@amd.com, brijesh.singh@amd.com,
	Hyunwook Baek <baekhw@google.com>,
	Erdem Aktas <erdemaktas@google.com>,
	Tom Roeder <tmroeder@google.com>
Cc: Varad Gautam <varad.gautam@suse.com>
Subject: Re: [kvm-unit-tests PATCH v2 2/6] x86: Call efi_main from _efi_pe_entry
Date: Tue, 24 Aug 2021 15:08:49 -0700	[thread overview]
Message-ID: <61ee15ee-c415-c24b-c886-b7f6ba2be149@oracle.com> (raw)
In-Reply-To: <20210819113400.26516-3-varad.gautam@suse.com>


On 8/19/21 4:33 AM, Varad Gautam wrote:
> EFI calls _efi_pe_entry in long mode with the location of EFI
> handle/system table. Add an efi_main() C handler to make it easier
> to communicate with EFI for initial setup. efi_main will later,
> 1. Acquire the efi memmap
> 2. Call ExitBootServices
> 3. Perform remaining bootstrapping before calling the testcase main()
>
> Signed-off-by: Varad Gautam<varad.gautam@suse.com>
> ---
>   lib/linux/uefi.h    | 518 ++++++++++++++++++++++++++++++++++++++++++++
>   x86/Makefile.common |   2 +-
>   x86/cstart64.S      |  10 +-
>   x86/efi_main.c      |  11 +
>   4 files changed, 539 insertions(+), 2 deletions(-)
>   create mode 100644 lib/linux/uefi.h
>   create mode 100644 x86/efi_main.c
>
> diff --git a/lib/linux/uefi.h b/lib/linux/uefi.h
> new file mode 100644
> index 0000000..15692eb
> --- /dev/null
> +++ b/lib/linux/uefi.h
> @@ -0,0 +1,518 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Relevant definitions from linux/efi.h. */
> +
> +#ifndef __LINUX_UEFI_H
> +#define __LINUX_UEFI_H
> +
> +#define BITS_PER_LONG 64
> +
> +#define EFI_SUCCESS		0
> +#define EFI_LOAD_ERROR		( 1 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_INVALID_PARAMETER	( 2 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_UNSUPPORTED		( 3 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_BAD_BUFFER_SIZE	( 4 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_BUFFER_TOO_SMALL	( 5 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_NOT_READY		( 6 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_DEVICE_ERROR	( 7 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_WRITE_PROTECTED	( 8 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_OUT_OF_RESOURCES	( 9 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_NOT_FOUND		(14 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_TIMEOUT		(18 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_ABORTED		(21 | (1UL << (BITS_PER_LONG-1)))
> +#define EFI_SECURITY_VIOLATION	(26 | (1UL << (BITS_PER_LONG-1)))
> +
> +typedef unsigned long efi_status_t;
> +typedef u8 efi_bool_t;
> +typedef u16 efi_char16_t;		/* UNICODE character */
> +typedef u64 efi_physical_addr_t;
> +typedef void *efi_handle_t;
> +
> +#define __efiapi __attribute__((ms_abi))
> +
> +/*
> + * The UEFI spec and EDK2 reference implementation both define EFI_GUID as
> + * struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment
> + * is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM),
> + * this means that firmware services invoked by the kernel may assume that
> + * efi_guid_t* arguments are 32-bit aligned, and use memory accessors that
> + * do not tolerate misalignment. So let's set the minimum alignment to 32 bits.
> + *
> + * Note that the UEFI spec as well as some comments in the EDK2 code base
> + * suggest that EFI_GUID should be 64-bit aligned, but this appears to be
> + * a mistake, given that no code seems to exist that actually enforces that
> + * or relies on it.
> + */
> +typedef struct {
> +	u8 b[16];
> +} guid_t;
> +typedef guid_t efi_guid_t;
> +
> +#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {					\
> +	(a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff,	\
> +	(b) & 0xff, ((b) >> 8) & 0xff,						\
> +	(c) & 0xff, ((c) >> 8) & 0xff, d } }
> +
> +/*
> + * Generic EFI table header
> + */
> +typedef	struct {
> +	u64 signature;
> +	u32 revision;
> +	u32 headersize;
> +	u32 crc32;
> +	u32 reserved;
> +} efi_table_hdr_t;
> +
> +/*
> + * Memory map descriptor:
> + */
> +
> +/* Memory types: */
> +#define EFI_RESERVED_TYPE		 0
> +#define EFI_LOADER_CODE			 1
> +#define EFI_LOADER_DATA			 2
> +#define EFI_BOOT_SERVICES_CODE		 3
> +#define EFI_BOOT_SERVICES_DATA		 4
> +#define EFI_RUNTIME_SERVICES_CODE	 5
> +#define EFI_RUNTIME_SERVICES_DATA	 6
> +#define EFI_CONVENTIONAL_MEMORY		 7
> +#define EFI_UNUSABLE_MEMORY		 8
> +#define EFI_ACPI_RECLAIM_MEMORY		 9
> +#define EFI_ACPI_MEMORY_NVS		10
> +#define EFI_MEMORY_MAPPED_IO		11
> +#define EFI_MEMORY_MAPPED_IO_PORT_SPACE	12
> +#define EFI_PAL_CODE			13
> +#define EFI_PERSISTENT_MEMORY		14
> +#define EFI_MAX_MEMORY_TYPE		15
> +
> +/* Attribute values: */
> +#define EFI_MEMORY_UC		((u64)0x0000000000000001ULL)	/* uncached */
> +#define EFI_MEMORY_WC		((u64)0x0000000000000002ULL)	/* write-coalescing */
> +#define EFI_MEMORY_WT		((u64)0x0000000000000004ULL)	/* write-through */
> +#define EFI_MEMORY_WB		((u64)0x0000000000000008ULL)	/* write-back */
> +#define EFI_MEMORY_UCE		((u64)0x0000000000000010ULL)	/* uncached, exported */
> +#define EFI_MEMORY_WP		((u64)0x0000000000001000ULL)	/* write-protect */
> +#define EFI_MEMORY_RP		((u64)0x0000000000002000ULL)	/* read-protect */
> +#define EFI_MEMORY_XP		((u64)0x0000000000004000ULL)	/* execute-protect */
> +#define EFI_MEMORY_NV		((u64)0x0000000000008000ULL)	/* non-volatile */
> +#define EFI_MEMORY_MORE_RELIABLE \
> +				((u64)0x0000000000010000ULL)	/* higher reliability */
> +#define EFI_MEMORY_RO		((u64)0x0000000000020000ULL)	/* read-only */
> +#define EFI_MEMORY_SP		((u64)0x0000000000040000ULL)	/* soft reserved */
> +#define EFI_MEMORY_CPU_CRYPTO	((u64)0x0000000000080000ULL)	/* supports encryption */
> +#define EFI_MEMORY_RUNTIME	((u64)0x8000000000000000ULL)	/* range requires runtime mapping */
> +#define EFI_MEMORY_DESCRIPTOR_VERSION	1
> +
> +#define EFI_PAGE_SHIFT		12
> +#define EFI_PAGE_SIZE		(1UL << EFI_PAGE_SHIFT)
> +#define EFI_PAGES_MAX		(U64_MAX >> EFI_PAGE_SHIFT)
> +
> +typedef struct {
> +	u32 type;
> +	u32 pad;
> +	u64 phys_addr;
> +	u64 virt_addr;
> +	u64 num_pages;
> +	u64 attribute;
> +} efi_memory_desc_t;
> +
> +typedef struct {
> +	efi_guid_t guid;
> +	u32 headersize;
> +	u32 flags;
> +	u32 imagesize;
> +} efi_capsule_header_t;
> +
> +/*
> + * EFI capsule flags
> + */
> +#define EFI_CAPSULE_PERSIST_ACROSS_RESET	0x00010000
> +#define EFI_CAPSULE_POPULATE_SYSTEM_TABLE	0x00020000
> +#define EFI_CAPSULE_INITIATE_RESET		0x00040000
> +
> +struct capsule_info {
> +	efi_capsule_header_t	header;
> +	efi_capsule_header_t	*capsule;
> +	int			reset_type;
> +	long			index;
> +	size_t			count;
> +	size_t			total_size;
> +	struct page		**pages;
> +	phys_addr_t		*phys;
> +	size_t			page_bytes_remain;
> +};
> +
> +int __efi_capsule_setup_info(struct capsule_info *cap_info);
> +
> +/*
> + * Types and defines for Time Services
> + */
> +#define EFI_TIME_ADJUST_DAYLIGHT 0x1
> +#define EFI_TIME_IN_DAYLIGHT     0x2
> +#define EFI_UNSPECIFIED_TIMEZONE 0x07ff
> +
> +typedef struct {
> +	u16 year;
> +	u8 month;
> +	u8 day;
> +	u8 hour;
> +	u8 minute;
> +	u8 second;
> +	u8 pad1;
> +	u32 nanosecond;
> +	s16 timezone;
> +	u8 daylight;
> +	u8 pad2;
> +} efi_time_t;
> +
> +typedef struct {
> +	u32 resolution;
> +	u32 accuracy;
> +	u8 sets_to_zero;
> +} efi_time_cap_t;
> +
> +typedef void *efi_event_t;
> +/* Note that notifications won't work in mixed mode */
> +typedef void (__efiapi *efi_event_notify_t)(efi_event_t, void *);
> +
> +typedef enum {
> +	EfiTimerCancel,
> +	EfiTimerPeriodic,
> +	EfiTimerRelative
> +} EFI_TIMER_DELAY;
> +
> +/*
> + * EFI Device Path information
> + */
> +#define EFI_DEV_HW			0x01
> +#define  EFI_DEV_PCI				 1
> +#define  EFI_DEV_PCCARD				 2
> +#define  EFI_DEV_MEM_MAPPED			 3
> +#define  EFI_DEV_VENDOR				 4
> +#define  EFI_DEV_CONTROLLER			 5
> +#define EFI_DEV_ACPI			0x02
> +#define   EFI_DEV_BASIC_ACPI			 1
> +#define   EFI_DEV_EXPANDED_ACPI			 2
> +#define EFI_DEV_MSG			0x03
> +#define   EFI_DEV_MSG_ATAPI			 1
> +#define   EFI_DEV_MSG_SCSI			 2
> +#define   EFI_DEV_MSG_FC			 3
> +#define   EFI_DEV_MSG_1394			 4
> +#define   EFI_DEV_MSG_USB			 5
> +#define   EFI_DEV_MSG_USB_CLASS			15
> +#define   EFI_DEV_MSG_I20			 6
> +#define   EFI_DEV_MSG_MAC			11
> +#define   EFI_DEV_MSG_IPV4			12
> +#define   EFI_DEV_MSG_IPV6			13
> +#define   EFI_DEV_MSG_INFINIBAND		 9
> +#define   EFI_DEV_MSG_UART			14
> +#define   EFI_DEV_MSG_VENDOR			10
> +#define EFI_DEV_MEDIA			0x04
> +#define   EFI_DEV_MEDIA_HARD_DRIVE		 1
> +#define   EFI_DEV_MEDIA_CDROM			 2
> +#define   EFI_DEV_MEDIA_VENDOR			 3
> +#define   EFI_DEV_MEDIA_FILE			 4
> +#define   EFI_DEV_MEDIA_PROTOCOL		 5
> +#define EFI_DEV_BIOS_BOOT		0x05
> +#define EFI_DEV_END_PATH		0x7F
> +#define EFI_DEV_END_PATH2		0xFF
> +#define   EFI_DEV_END_INSTANCE			0x01
> +#define   EFI_DEV_END_ENTIRE			0xFF
> +
> +struct efi_generic_dev_path {
> +	u8				type;
> +	u8				sub_type;
> +	u16				length;
> +} __packed;
> +
> +typedef struct efi_generic_dev_path efi_device_path_protocol_t;


BTW, the following syntax is also allowed by gcc and you can use it here:

+typedef struct efi_generic_dev_path {
+	u8				type;
+	u8				sub_type;
+	u16				length;
+} __packed, efi_device_path_protocol_t;

> +
> +/*
> + * EFI Boot Services table
> + */
> +union efi_boot_services {
> +	struct {
> +		efi_table_hdr_t hdr;
> +		void *raise_tpl;
> +		void *restore_tpl;
> +		efi_status_t (__efiapi *allocate_pages)(int, int, unsigned long,
> +							efi_physical_addr_t *);
> +		efi_status_t (__efiapi *free_pages)(efi_physical_addr_t,
> +						    unsigned long);
> +		efi_status_t (__efiapi *get_memory_map)(unsigned long *, void *,
> +							unsigned long *,
> +							unsigned long *, u32 *);
> +		efi_status_t (__efiapi *allocate_pool)(int, unsigned long,
> +						       void **);
> +		efi_status_t (__efiapi *free_pool)(void *);
> +		efi_status_t (__efiapi *create_event)(u32, unsigned long,
> +						      efi_event_notify_t, void *,
> +						      efi_event_t *);
> +		efi_status_t (__efiapi *set_timer)(efi_event_t,
> +						  EFI_TIMER_DELAY, u64);
> +		efi_status_t (__efiapi *wait_for_event)(unsigned long,
> +							efi_event_t *,
> +							unsigned long *);
> +		void *signal_event;
> +		efi_status_t (__efiapi *close_event)(efi_event_t);
> +		void *check_event;
> +		void *install_protocol_interface;
> +		void *reinstall_protocol_interface;
> +		void *uninstall_protocol_interface;
> +		efi_status_t (__efiapi *handle_protocol)(efi_handle_t,
> +							 efi_guid_t *, void **);
> +		void *__reserved;
> +		void *register_protocol_notify;
> +		efi_status_t (__efiapi *locate_handle)(int, efi_guid_t *,
> +						       void *, unsigned long *,
> +						       efi_handle_t *);
> +		efi_status_t (__efiapi *locate_device_path)(efi_guid_t *,
> +							    efi_device_path_protocol_t **,
> +							    efi_handle_t *);
> +		efi_status_t (__efiapi *install_configuration_table)(efi_guid_t *,
> +								     void *);
> +		void *load_image;
> +		void *start_image;
> +		efi_status_t (__efiapi *exit)(efi_handle_t,
> +							 efi_status_t,
> +							 unsigned long,
> +							 efi_char16_t *);
> +		void *unload_image;
> +		efi_status_t (__efiapi *exit_boot_services)(efi_handle_t,
> +							    unsigned long);
> +		void *get_next_monotonic_count;
> +		efi_status_t (__efiapi *stall)(unsigned long);
> +		void *set_watchdog_timer;
> +		void *connect_controller;
> +		efi_status_t (__efiapi *disconnect_controller)(efi_handle_t,
> +							       efi_handle_t,
> +							       efi_handle_t);
> +		void *open_protocol;
> +		void *close_protocol;
> +		void *open_protocol_information;
> +		void *protocols_per_handle;
> +		void *locate_handle_buffer;
> +		efi_status_t (__efiapi *locate_protocol)(efi_guid_t *, void *,
> +							 void **);
> +		void *install_multiple_protocol_interfaces;
> +		void *uninstall_multiple_protocol_interfaces;
> +		void *calculate_crc32;
> +		void *copy_mem;
> +		void *set_mem;
> +		void *create_event_ex;


It's probably better to group the function pointers together for 
readability purposes.

> +	};
> +	struct {
> +		efi_table_hdr_t hdr;
> +		u32 raise_tpl;
> +		u32 restore_tpl;
> +		u32 allocate_pages;
> +		u32 free_pages;
> +		u32 get_memory_map;
> +		u32 allocate_pool;
> +		u32 free_pool;
> +		u32 create_event;
> +		u32 set_timer;
> +		u32 wait_for_event;
> +		u32 signal_event;
> +		u32 close_event;
> +		u32 check_event;
> +		u32 install_protocol_interface;
> +		u32 reinstall_protocol_interface;
> +		u32 uninstall_protocol_interface;
> +		u32 handle_protocol;
> +		u32 __reserved;
> +		u32 register_protocol_notify;
> +		u32 locate_handle;
> +		u32 locate_device_path;
> +		u32 install_configuration_table;
> +		u32 load_image;
> +		u32 start_image;
> +		u32 exit;
> +		u32 unload_image;
> +		u32 exit_boot_services;
> +		u32 get_next_monotonic_count;
> +		u32 stall;
> +		u32 set_watchdog_timer;
> +		u32 connect_controller;
> +		u32 disconnect_controller;
> +		u32 open_protocol;
> +		u32 close_protocol;
> +		u32 open_protocol_information;
> +		u32 protocols_per_handle;
> +		u32 locate_handle_buffer;
> +		u32 locate_protocol;
> +		u32 install_multiple_protocol_interfaces;
> +		u32 uninstall_multiple_protocol_interfaces;
> +		u32 calculate_crc32;
> +		u32 copy_mem;
> +		u32 set_mem;
> +		u32 create_event_ex;
> +	} mixed_mode;


Just curious why we need mixed mode because we are building the tests as 
64-bit UEFI executable.

> +};
> +
> +typedef union efi_boot_services efi_boot_services_t;
> +
> +/*
> + * Types and defines for EFI ResetSystem
> + */
> +#define EFI_RESET_COLD 0
> +#define EFI_RESET_WARM 1
> +#define EFI_RESET_SHUTDOWN 2
> +
> +/*
> + * EFI Runtime Services table
> + */
> +#define EFI_RUNTIME_SERVICES_SIGNATURE ((u64)0x5652453544e5552ULL)
> +#define EFI_RUNTIME_SERVICES_REVISION  0x00010000
> +
> +typedef struct {
> +	efi_table_hdr_t hdr;
> +	u32 get_time;
> +	u32 set_time;
> +	u32 get_wakeup_time;
> +	u32 set_wakeup_time;
> +	u32 set_virtual_address_map;
> +	u32 convert_pointer;
> +	u32 get_variable;
> +	u32 get_next_variable;
> +	u32 set_variable;
> +	u32 get_next_high_mono_count;
> +	u32 reset_system;
> +	u32 update_capsule;
> +	u32 query_capsule_caps;
> +	u32 query_variable_info;
> +} efi_runtime_services_32_t;
> +
> +typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
> +typedef efi_status_t efi_set_time_t (efi_time_t *tm);
> +typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
> +					    efi_time_t *tm);
> +typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm);
> +typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
> +					 unsigned long *data_size, void *data);
> +typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name,
> +					      efi_guid_t *vendor);
> +typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor,
> +					 u32 attr, unsigned long data_size,
> +					 void *data);
> +typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
> +typedef void efi_reset_system_t (int reset_type, efi_status_t status,
> +				 unsigned long data_size, efi_char16_t *data);
> +typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_size,
> +						unsigned long descriptor_size,
> +						u32 descriptor_version,
> +						efi_memory_desc_t *virtual_map);
> +typedef efi_status_t efi_query_variable_info_t(u32 attr,
> +					       u64 *storage_space,
> +					       u64 *remaining_space,
> +					       u64 *max_variable_size);
> +typedef efi_status_t efi_update_capsule_t(efi_capsule_header_t **capsules,
> +					  unsigned long count,
> +					  unsigned long sg_list);
> +typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
> +					      unsigned long count,
> +					      u64 *max_size,
> +					      int *reset_type);
> +typedef efi_status_t efi_query_variable_store_t(u32 attributes,
> +						unsigned long size,
> +						bool nonblocking);
> +
> +typedef union {
> +	struct {
> +		efi_table_hdr_t				hdr;
> +		efi_get_time_t __efiapi			*get_time;
> +		efi_set_time_t __efiapi			*set_time;
> +		efi_get_wakeup_time_t __efiapi		*get_wakeup_time;
> +		efi_set_wakeup_time_t __efiapi		*set_wakeup_time;
> +		efi_set_virtual_address_map_t __efiapi	*set_virtual_address_map;
> +		void					*convert_pointer;
> +		efi_get_variable_t __efiapi		*get_variable;
> +		efi_get_next_variable_t __efiapi	*get_next_variable;
> +		efi_set_variable_t __efiapi		*set_variable;
> +		efi_get_next_high_mono_count_t __efiapi	*get_next_high_mono_count;
> +		efi_reset_system_t __efiapi		*reset_system;
> +		efi_update_capsule_t __efiapi		*update_capsule;
> +		efi_query_capsule_caps_t __efiapi	*query_capsule_caps;
> +		efi_query_variable_info_t __efiapi	*query_variable_info;
> +	};
> +	efi_runtime_services_32_t mixed_mode;
> +} efi_runtime_services_t;
> +
> +#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
> +
> +#define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
> +#define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
> +#define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
> +#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
> +#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
> +#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
> +
> +typedef struct {
> +	efi_table_hdr_t hdr;
> +	u64 fw_vendor;	/* physical addr of CHAR16 vendor string */
> +	u32 fw_revision;
> +	u32 __pad1;
> +	u64 con_in_handle;
> +	u64 con_in;
> +	u64 con_out_handle;
> +	u64 con_out;
> +	u64 stderr_handle;
> +	u64 stderr;
> +	u64 runtime;
> +	u64 boottime;
> +	u32 nr_tables;
> +	u32 __pad2;
> +	u64 tables;
> +} efi_system_table_64_t;
> +
> +typedef struct {
> +	efi_table_hdr_t hdr;
> +	u32 fw_vendor;	/* physical addr of CHAR16 vendor string */
> +	u32 fw_revision;
> +	u32 con_in_handle;
> +	u32 con_in;
> +	u32 con_out_handle;
> +	u32 con_out;
> +	u32 stderr_handle;
> +	u32 stderr;
> +	u32 runtime;
> +	u32 boottime;
> +	u32 nr_tables;
> +	u32 tables;
> +} efi_system_table_32_t;
> +
> +typedef union efi_simple_text_input_protocol efi_simple_text_input_protocol_t;
> +typedef union efi_simple_text_output_protocol efi_simple_text_output_protocol_t;
> +
> +typedef union {
> +	struct {
> +		efi_table_hdr_t hdr;
> +		unsigned long fw_vendor;	/* physical addr of CHAR16 vendor string */
> +		u32 fw_revision;
> +		unsigned long con_in_handle;
> +		efi_simple_text_input_protocol_t *con_in;
> +		unsigned long con_out_handle;
> +		efi_simple_text_output_protocol_t *con_out;
> +		unsigned long stderr_handle;
> +		unsigned long stderr;
> +		efi_runtime_services_t *runtime;
> +		efi_boot_services_t *boottime;
> +		unsigned long nr_tables;
> +		unsigned long tables;
> +	};
> +	efi_system_table_32_t mixed_mode;
> +} efi_system_table_t;
> +
> +struct efi_boot_memmap {
> +	efi_memory_desc_t       **map;
> +	unsigned long           *map_size;
> +	unsigned long           *desc_size;
> +	u32                     *desc_ver;
> +	unsigned long           *key_ptr;
> +	unsigned long           *buff_size;
> +};
> +
> +#define efi_bs_call(func, ...)						\
> +	efi_system_table->boottime->func(__VA_ARGS__)
> +
> +#endif /* __LINUX_UEFI_H */
> diff --git a/x86/Makefile.common b/x86/Makefile.common
> index fc9a693..ca33e8e 100644
> --- a/x86/Makefile.common
> +++ b/x86/Makefile.common
> @@ -50,7 +50,7 @@ FLATLIBS = lib/libcflat.a
>   	$(OBJCOPY) -O elf32-i386 $^ $@
>   	@chmod a-x $@
>   
> -%.so: %.o $(FLATLIBS) $(cstart.o)
> +%.so: %.o $(FLATLIBS) $(TEST_DIR)/efi_main.o $(cstart.o)
>   	$(LD) -shared -nostdlib -znocombreloc -Bsymbolic -T $(SRCDIR)/x86/efi.lds $^ \
>   		-o $@ $(FLATLIBS)
>   	@chmod a-x $@
> diff --git a/x86/cstart64.S b/x86/cstart64.S
> index 404fcac..98e7848 100644
> --- a/x86/cstart64.S
> +++ b/x86/cstart64.S
> @@ -267,7 +267,15 @@ ap_start64:
>   #ifdef CONFIG_EFI
>   .globl _efi_pe_entry
>   _efi_pe_entry:
> -	ret
> +	# EFI image loader calls this with rcx=efi_handle,
> +	# rdx=efi_system_table. Pass these to efi_main.
> +	mov     %rcx, %rdi
> +	mov     %rdx, %rsi
> +
> +	pushq   %rdi
> +	pushq   %rsi
> +
> +	call efi_main
>   #endif
>   
>   start64:
> diff --git a/x86/efi_main.c b/x86/efi_main.c
> new file mode 100644
> index 0000000..00e7086
> --- /dev/null
> +++ b/x86/efi_main.c
> @@ -0,0 +1,11 @@
> +#include <linux/uefi.h>
> +
> +unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab);
> +efi_system_table_t *efi_system_table = NULL;
> +
> +unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
> +{
> +	efi_system_table = sys_tab;
> +
> +	return 0;
> +}

  reply	other threads:[~2021-08-24 22:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-19 11:33 [kvm-unit-tests PATCH v2 0/6] Initial x86_64 UEFI support Varad Gautam
2021-08-19 11:33 ` [kvm-unit-tests PATCH v2 1/6] x86: Build tests as PE objects for the EFI loader Varad Gautam
2021-08-19 11:33 ` [kvm-unit-tests PATCH v2 2/6] x86: Call efi_main from _efi_pe_entry Varad Gautam
2021-08-24 22:08   ` Krish Sadhukhan [this message]
2021-08-19 11:33 ` [kvm-unit-tests PATCH v2 3/6] x86: efi_main: Get EFI memory map and exit boot services Varad Gautam
2021-08-24 22:10   ` Krish Sadhukhan
2021-08-19 11:33 ` [kvm-unit-tests PATCH v2 4/6] x86: efi_main: Self-relocate ELF .dynamic addresses Varad Gautam
2021-08-24 22:10   ` Krish Sadhukhan
2021-08-19 11:33 ` [kvm-unit-tests PATCH v2 5/6] cstart64.S: x86_64 bootstrapping after exiting EFI Varad Gautam
2021-08-24 22:11   ` Krish Sadhukhan
2021-08-19 11:34 ` [kvm-unit-tests PATCH v2 6/6] x86 UEFI: Convert x86 test cases to PIC Varad Gautam
2021-08-24 22:12   ` Krish Sadhukhan
2021-08-21  0:01 ` [kvm-unit-tests PATCH v2 0/6] Initial x86_64 UEFI support Sean Christopherson
2021-08-21  0:42   ` Zixuan Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=61ee15ee-c415-c24b-c886-b7f6ba2be149@oracle.com \
    --to=krish.sadhukhan@oracle.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=baekhw@google.com \
    --cc=bp@suse.de \
    --cc=brijesh.singh@amd.com \
    --cc=drjones@redhat.com \
    --cc=erdemaktas@google.com \
    --cc=jroedel@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=marcorr@google.com \
    --cc=nadav.amit@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=tmroeder@google.com \
    --cc=varad.gautam@suse.com \
    --cc=varadgautam@gmail.com \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=zixuanwang@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox