Hi,

Here are a few headers for the DXE service table, firmware volume protocol
and legacy bios protocol (this one currently misses the
grub_efi_ia32_register_set structure).

I'm posting them here, so that if someone wants to play with these parts of
EFI, he/she does not have to duplicate the effort.

I'll repost them as a patch once I get a use of them, as I'm not sure if
100% EFI support is exactly one of grub's goals.

If someone wants to review them, the specs are available at
http://www.intel.com/technology/framework/download.htm

Also, enabling legacy bios protocol in Apple EFI depends on a few drivers
that need to be scheduled and dispatched using dxe table functions. On my
machine (mac pro 1.1), the GUIDs of these drivers are:
  {0x6229630c, 0x32c3, 0x4638, {0x80, 0x91, 0x83, 0x8d, 0x98, 0x5d, 0xfa,
0x82}},
  {0x5479662b, 0x6ae4, 0x49e8, {0xa6, 0xbd, 0x6d, 0xe4, 0xb6, 0x25, 0x81,
0x1f}},
  {0xf122a15c, 0xc10b, 0x4d54, {0x8f, 0x48, 0x60, 0xf4, 0xf0, 0x6d, 0xd1,
0xad}},
  {0xbc6d08dc, 0x865d, 0x4ffe, {0x8b, 0x7a, 0xfb, 0x5f, 0xb0, 0x4f, 0x12,
0xf1}},
  {0xd3709bb4, 0xb194, 0x4b71, {0xb9, 0xc0, 0xdb, 0xd8, 0xd2, 0xda, 0x97,
0xad}},
  {0x208117f2, 0x25f8, 0x479d, {0xb7, 0x26, 0x10, 0xc1, 0xb, 0xed, 0x6d,
0xc1}},
  {0xef33c296, 0xf64c, 0x4146, {0xad, 0x4, 0x34, 0x78, 0x99, 0x70, 0x2c,
0x84}},
  {0x1f36527e, 0xa97c, 0x45f8, {0xb2, 0x4a, 0x9d, 0x95, 0xb0, 0xa9, 0x40,
0xfe}},
  {0x9f2a114a, 0x834b, 0x4916, {0x94, 0x5c, 0x1c, 0x9, 0xf4, 0x94, 0x48,
0x19}},
  {0x29cf55f8, 0xb675, 0x4f5d, {0x8f, 0x2f, 0xb8, 0x7a, 0x3e, 0xcf, 0xd0,
0x63}}

Then, chainloading to a legacy bios bootloader should be as easy as calling
the legacy_boot function form the legacy bios protocol. This is what I'll
try now ...

Regards,
Alex
/* dxe.h - definitions of the driver execution environment core interface */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

/* The driver execution environment core interface is not a part of the EFI
   spec, but defined in Intel's DXE CIS.  */

#ifndef GRUB_EFI_DXE_HEADER
#define GRUB_EFI_DXE_HEADER	1

#define GRUB_EFI_DXE_SERVICES_SIGNATURE	0x565245535f455844

enum grub_efi_gcd_memory_type
  {
    GRUB_EFI_GCD_MEMORY_TYPE_NON_EXISTENT,
    GRUB_EFI_GCD_MEMORY_TYPE_RESERVED,
    GRUB_EFI_GCD_MEMORY_TYPE_SYSTEM_MEMORY,
    GRUB_EFI_GCD_MEMORY_TYPE_MEMORY_MAPPED_IO,
    GRUB_EFI_GCD_MEMORY_TYPE_MAXIMUM
  };
typedef grub_efi_gcd_memory_type grub_efi_gcd_memory_type_t;

enum grub_efi_gcd_allocate_type
  {
    GRUB_EFI_GCD_ALLOCATE_ANY_SEARCH_BOTTOM_UP,
    GRUB_EFI_GCD_ALLOCATE_MAX_ADDRESS_SEARCH_BOTTOM_UP,
    GRUB_EFI_GCD_ALLOCATE_ADDRESS,
    GRUB_EFI_GCD_ALLOCATE_ANY_SEARCH_TOP_DOWN,
    GRUB_EFI_GCD_ALLOCATE_MAX_ADDRESS_SEARCH_TOP_DOWN,
    GRUB_EFI_GCD_MAX_ALLOCATE_TYPE
  };
typedef grub_efi_gcd_allocate_type grub_efi_gcd_allocate_type_t;

struct grub_efi_gcd_memory_space_descriptor
{
  grub_efi_physical_address_t base_address;
  grub_efi_uint64_t length;
  grub_efi_uint64_t capabilities;
  grub_efi_gcd_memory_type_t gcd_memory_type;
  grub_efi_handle_t image_handle;
  grub_efi_handle_t device_hande;
}
typedef grub_efi_gcd_memory_space_descriptor grub_efi_gcd_memory_space_descriptor_t;

enum grub_efi_gcd_io_type
  {
    GRUB_EFI_GCD_IO_TYPE_NON_EXISTENT,
    GRUB_EFI_GCD_IO_TYPE_RESERVED,
    GRUB_EFI_GCD_IO_TYPE_IO,
    GRUB_EFI_GCD_IO_TYPE_MAXIMUM
  };
typedef grub_efi_gcd_io_type grub_efi_gcd_io_type_t;

struct grub_efi_gcd_io_space_descriptor
{
  grub_efi_physical_address_t base_address;
  grub_efi_uint64_t length;
  grub_efi_gcd_io_type_t gcd_io_type;
  grub_efi_handle_t image_handle;
  grub_efi_handle_t device_hande;
}
typedef grub_efi_gcd_io_space_descriptor grub_efi_gcd_io_space_descriptor_t;


struct grub_efi_dxe_services
{
  grub_efi_table_header_t hdr;

  grub_efi_status_t
  (*add_memory_space) (grub_efi_gcd_memory_type_t gcd_memory_type,
		       grub_efi_physical_address_t base_address,
		       grub_efi_uint64_t length,
		       grub_efi_uint64_t capabilities);

  grub_efi_status_t
  (*allocate_memory_space) (grub_efi_gcd_allocate_type_t gcd_allocate_type,
			    grub_efi_gcd_memory_type_t gcd_memory_type,
			    grub_efi_uintn_t alignment,
			    grub_efi_uint64_t length,
			    grub_efi_physical_address_t *base_address,
			    grub_efi_handle_t image_handle,
			    grub_efi_handle_t device_handle);

  grub_efi_status_t
  (*free_memory_space) (grub_efi_physical_address_t base_address,
			grub_efi_uint64_t length);

  grub_efi_status_t
  (*remove_memory_space) (grub_efi_physical_address_t base_address,
			  grub_efi_uint64_t length);

  grub_efi_status_t
  (*get_memory_space_descriptor) (grub_efi_physical_address_t base_address,
				  grub_efi_gcd_memory_space_descriptor_t *descriptor);

  grub_efi_status_t
  (*set_memory_space_attributes) (grub_efi_physical_address_t base_address,
				  grub_efi_uint64_t length,
				  grub_efi_uint64_t attributes);

  grub_efi_status_t
  (*get_memory_space_map) (grub_efi_uintn_t *number_of_descriptors,
			   grub_efi_gcd_memory_space_descriptor_t **memory_space_map);

  grub_efi_status_t
  (*add_io_space) (grub_efi_gcd_io_type_t gcd_io_type,
		   grub_efi_physical_address_t base_address,
		   grub_efi_uint64_t length);

  grub_efi_status_t
  (*allocate_io_space) (grub_efi_gcd_allocate_type_t gcd_allocate_type,
			grub_efi_gcd_io_type_t gcd_io_type,
			grub_efi_uintn_t alignment,
			grub_efi_uint64_t length,
			grub_efi_physical_address_t *base_address,
			grub_efi_handle_t image_handle,
			grub_efi_handle_t device_handle);

  grub_efi_status_t
  (*free_io_space) (grub_efi_physical_address_t base_address,
		    grub_efi_uint64_t length);

  grub_efi_status_t
  (*remove io_space) (grub_efi_physical_address_t base_address,
		      grub_efi_uint64_t length);

  grub_efi_status_t
  (*get_io_space_descriptor) (grub_efi_physical_address_t base_address,
			      grub_efi_gcd_io_space_descriptor_t *descriptor);

  grub_efi_status_t
  (*get_io_space_map) (grub_efi_uintn_t *number_of_descriptors,
		       grub_efi_gcd_io_space_descriptor_t **io_space_map);

  grub_efi_status_t
  (*dispatch) ();

  grub_efi_status_t
  (*schedule) (grub_efi_handle_t firmware_volume_handle,
	       grub_efi_guid_t *filename);

  grub_efi_status_t
  (*trust) (grub_efi_handle_t firmware_volume_handle,
	    grub_efi_guid_t *filename);

  grub_efi_status_t
  (*process_firmware_volume) (void *firmware_volume_header,
			      grub_efi_uintn_t size,
			      grub_efi_handle_t *firmware_volume_handle);
};
typedef struct grub_efi_dxe_services grub_efi_dxe_services_t;

#endif /* ! GRUB_EFI_DXE_HEADER */
/* firmware_volume.h - definitions of the firmware volume protocol */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

/* The firmware volume bios protocol is not a part of the EFI spec,
   but defined in Intel's Firmware Volume Specification. */

#ifndef GRUB_EFI_FIRMWARE_VOLUME_HEADER
#define GRUB_EFI_FIRMWARE_VOLUME_HEADER	1

#define GRUB_EFI_FIRMWARE_VOLUME_GUID	\
  { 0x389f751f, 0x1838, 0x4388, \
    { 0x83, 0x90, 0xcd, 0x81, 0x54, 0xbd, 0x27, 0xf8 } \
  }

#define GRUB_EFI_FV_FILETYPE_ALL 0
#define GRUB_EFI_FV_FILETYPE_RAW 1
#define GRUB_EFI_FV_FILETYPE_FREEFORM 2
#define GRUB_EFI_FV_FILETYPE_SECURITY_CORE 3
#define GRUB_EFI_FV_FILETYPE_PEI_CORE 4
#define GRUB_EFI_FV_FILETYPE_DXE_CORE 5
#define GRUB_EFI_FV_FILETYPE_PEIM 6
#define GRUB_EFI_FV_FILETYPE_DRIVER 7
#define GRUB_EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 8
#define GRUB_EFI_FV_FILETYPE_APPLICATION 9
#define GRUB_EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 11

typedef grub_uint64_t grub_efi_fv_attributes_t;
typedef grub_uint8_t grub_efi_fv_filetype_t;
typedef grub_uint32_t grub_efi_fv_file_attributes_t;
typedef grub_uint8_t grub_efi_section_type_t;
typedef grub_uint32_t grub_efi_fv_write_policy_t;

struct grub_efi_fv_write_file_data
{
  grub_efi_guid_t *name_guid;
  grub_efi_fv_filetype_t type;
  grub_efi_fv_file_attributes_t file_attributes;
  void *buffer;
  grub_efi_uint32_t buffer_size;
};
typedef struct grub_efi_fv_write_file_data grub_efi_fv_write_file_data_t;

struct grub_efi_firmware_volume_protocol
{
  grub_efi_status_t
  (*get_volume_attributes) (struct grub_efi_firmware_volume_protocol *this,
			    grub_efi_fv_attributes_t *fvattributes);

  grub_efi_status_t
  (*set_volume_attributes) (struct grub_efi_firmware_volume_protocol *this,
			    grub_efi_fv_attributes_t *fvattributes);

  grub_efi_status_t
  (*read_file) (struct grub_efi_firmware_volume_protocol *this,
		grub_efi_guid_t *name_guid,
		void **buffer,
		grub_efi_uintn_t *buffer_size,
		grub_efi_fv_filetype_t *found_type,
		grub_efi_fv_file_attributes_t *file_attributes,
		grub_efi_uint32_t *authentication_status);

  grub_efi_status_t
  (*read_section) (struct grub_efi_firmware_volume_protocol *this,
		   grub_efi_guid_t *name_guid,
		   grub_efi_section_type_t section_type,
		   grub_efi_uintn_t section_instance,
		   void **buffer,
		   grub_efi_uintn_t *buffer_size,
		   grub_efi_uint32_t *authentication_status);

  grub_efi_status_t
  (*write_file) (struct grub_efi_firmware_volume_protocol *this,
      		 grub_efi_uint32_t number_of_files,
		 grub_efi_fv_write_policy_t write_policy,
		 grub_efi_fv_write_file_data_t *file_data);

  grub_efi_status_t
  (*get_next_file) (struct grub_efi_firmware_volume_protocol *this,
		    void *key,
		    grub_efi_fv_filetype_t *file_type,
		    grub_efi_guid_t *name_guid,
		    grub_efi_fv_file_attributes_t *file_attributes,
		    grub_efi_uintn_t *size);

  grub_efi_uint32_t key_size;
  grub_efi_handle_t parent_handle;
};
typedef struct grub_efi_firmware_volume_protocol grub_efi_firmware_volume_protocol_t;

#endif /* ! GRUB_EFI_FIRMWARE_VOLUME_HEADER */
/* legacy_bios.h - definitions of the legacy bios protocol */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

/* The legacy bios protocol is not a part of the EFI spec,
   but defined in Intel's Compatibility Support Module Specification. */

#ifndef GRUB_EFI_LEGACY_BIOS_HEADER
#define GRUB_EFI_LEGACY_BIOS_HEADER	1

#define GRUB_EFI_LEGACY_BIOS_GUID	\
  { 0xdb9a1e3d, 0x45cb, 0x4abb, \
    { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \
  }

#define GRUB_EFI_BBS_FLOPPY 0x1
#define GRUB_EFI_BBS_HARDDISK 0x2
#define GRUB_EFI_BBS_CDROM 0x3
#define GRUB_EFI_BBS_PCMCIA 0x4
#define GRUB_EFI_BBS_USB 0x5
#define GRUB_EFI_BBS_EMBED_NETWORK 0x6
#define GRUB_EFI_BBS_BEV_DEVICE 0x80

struct grub_efi_ia32_register_set
{
  void *regs; /* FIXME: must define this structure following specification */
};
typedef struct grub_efi_ia32_register_set grub_efi_ia32_register_set_t;

struct grub_efi_atapi_identify
{
  grub_uint16_t raw[256];
};
typedef struct grub_efi_atapi_identify grub_efi_atapi_identify_t;

struct grub_efi_hdd_info
{
  grub_uint16_t status;
  grub_uint32_t bus;
  grub_uint32_t device;
  grub_uint32_t function;
  grub_uint16_t command_base_address;
  grub_uint16_t control_base_address;
  grub_uint16_t bus_master_address;
  grub_uint8_t  hdd_irq;
  grub_efi_atapi_identify_t identify_drive[2];
};
typedef struct grub_efi_hdd_info grub_efi_hdd_info_t;

struct grub_efi_bbs_status_flags
{
  grub_uint16_t old_position:4;
  grub_uint16_t reserved1:4;
  grub_uint16_t enabled:1;
  grub_uint16_t failed:1;
  grub_uint16_t media_present:2;
  grub_uint16_t reserved2:4;
};
typedef struct grub_efi_bbs_status_flags grub_efi_bbs_status_flags_t;

struct grub_efi_bbs_table
{
  grub_uint16_t boot_priority;
  grub_uint32_t bus;
  grub_uint32_t device;
  grub_uint32_t function;
  grub_uint8_t class;
  grub_uint8_t sub_class;
  grub_uint16_t mfg_string_offset;
  grub_uint16_t mfg_string_segment;
  grub_uint16_t device_type;
  grub_efi_bbs_status_flags_t status_flags;
  grub_uint16_t boot_handler_offset;
  grub_uint16_t boot_handler_segment;
  grub_uint16_t desc_string_offset;
  grub_uint16_t desc_string_segment;
  grub_uint32_t init_per_reserved;
  grub_uint32_t additional_irq13_handler;
  grub_uint32_t additional_irq18_handler;
  grub_uint32_t additional_irq19_handler;
  grub_uint32_t additional_irq40_handler;
  grub_uint8_t assigned_drive_number;
  grub_uint32_t additional_irq41_handler;
  grub_uint32_t additional_irq46_handler;
  grub_uint32_t ibv1;
  grub_uint32_t ibv2;
};
typedef struct grub_efi_bbs_table grub_efi_bbs_table_t;

struct grub_efi_udc_attributes
{
  grub_efi_uint8_t directory_service_validity:1;
  grub_efi_uint8_t rabca_used_flag:1;
  grub_efi_uint8_t execute_hdd_diagnostics_flag:1;
  grub_efi_uint8_t reserved:5;
};
typedef struct grub_efi_udc_attributes grub_efi_udc_attributes_t;

struct grub_efi_legacy_bios_protocol
{
  grub_efi_boolean_t
  (*int86) (struct grub_efi_legacy_bios_protocol *this,
	    grub_efi_uint8_t bios_int,
	    grub_efi_ia32_register_set_t *regs);

  grub_efi_boolean_t
  (*far_call86) (struct grub_efi_legacy_bios_protocol *this,
      		 grub_uint16_t segment,
		 grub_uint16_t offset,
		 grub_efi_ia32_register_set_t *regs,
		 void *stack,
		 grub_efi_uintn_t stack_size);

  grub_efi_status_t
  (*check_pci_rom) (struct grub_efi_legacy_bios_protocol *this,
		    grub_efi_handle_t pci_handle,
		    void **rom_image,
		    grub_efi_uintn_t *rom_size,
		    grub_efi_uintn_t *flags);

  grub_efi_status_t
  (*install_pci_rom) (struct grub_efi_legacy_bios_protocol *this,
		      grub_efi_handle_t pci_handle,
		      void **rom_image,
		      grub_efi_uintn_t *flags,
		      grub_efi_uint8_t *disk_start,
		      grub_efi_uint8_t *disk_end,
		      void **rom_shadow_address,
		      grub_efi_uint32_t *shadowed_rom_size);

  grub_efi_status_t
  (*legacy_boot) (struct grub_efi_legacy_bios_protocol *this,
		  grub_efi_bios_device_path_t *boot_option,
		  grub_efi_uint32_t load_options_size,
		  void *load_options);

  grub_efi_status_t
  (*update_keyboard_led_status) (struct grub_efi_legacy_bios_protocol *this,
				 grub_efi_uint8_t leds);

  grub_efi_status_t
  (*get_bbs_info) (struct grub_efi_legacy_bios_protocol *this,
		   grub_efi_uint16_t *hdd_count,
		   grub_efi_hdd_info_t **hdd_info,
		   grub_efi_uint16_t *bbs_count,
		   grub_efi_bbs_table_t **bbs_table);

  grub_efi_status_t
  (*shadow_all_legacy_oproms) (struct grub_efi_legacy_bios_protocol *this);

  grub_efi_status_t
  (*prepare_to_boot_efi) (struct grub_efi_legacy_bios_protocol *this,
			  grub_efi_uint16_t *bbs_count,
			  grub_efi_bbs_table_t **bbs_table);

  grub_efi_status_t
  (*get_legacy_region) (struct grub_efi_legacy_bios_protocol *this,
			grub_efi_uintn_t legacy_memory_size,
			grub_efi_uintn_t region,
			grub_efi_uintn_t alignment,
			void **legacy_memory_address);

  grub_efi_status_t
  (*copy_legacy_region) (struct grub_efi_legacy_bios_protocol *this,
			 grub_efi_uintn_t legacy_memory_size,
			 void *legacy_memory_address,
			 void *legacy_memory_source_address);

  grub_efi_status_t
  (*boot_unconventional_device) (struct grub_efi_legacy_bios_protocol *this,
				 grub_efi_udc_attributes_t attributes,
				 grub_efi_uintn_t bbs_entry,
				 void *beer_data,
				 void *service_area_data);
};
typedef struct grub_efi_legacy_bios_protocol grub_efi_legacy_bios_protocol_t;

#endif /* ! GRUB_EFI_LEGACY_BIOS_HEADER */
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to