diff options
Diffstat (limited to 'sys/boot/efi')
44 files changed, 8711 insertions, 0 deletions
diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile new file mode 100644 index 0000000..f7f72f7 --- /dev/null +++ b/sys/boot/efi/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= libefi loader + +.include <bsd.subdir.mk> diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc new file mode 100644 index 0000000..81f7724 --- /dev/null +++ b/sys/boot/efi/Makefile.inc @@ -0,0 +1,4 @@ +# $FreeBSD$ + +# Options used when building app-specific efi components +CFLAGS+= -ffreestanding -fshort-wchar -Wformat diff --git a/sys/boot/efi/include/README b/sys/boot/efi/include/README new file mode 100644 index 0000000..151bac9 --- /dev/null +++ b/sys/boot/efi/include/README @@ -0,0 +1,33 @@ +/* $FreeBSD$ */ + +Files in this directory and subdirectories are subject to the following +copyright unless superceded or supplemented by additional specific license +terms found in the file headers of individual files. + +Copyright (c) 1998-2000 Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL INTEL BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. THE EFI SPECIFICATION AND ALL +OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO +WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE. diff --git a/sys/boot/efi/include/efi.h b/sys/boot/efi/include/efi.h new file mode 100644 index 0000000..f476a25 --- /dev/null +++ b/sys/boot/efi/include/efi.h @@ -0,0 +1,49 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efi.h + +Abstract: + + Public EFI header files + + + +Revision History + +--*/ + +/* + * Build flags on input + * EFI32 + * EFI_DEBUG - Enable debugging code + * EFI_NT_EMULATOR - Building for running under NT + */ + +#ifndef _EFI_INCLUDE_ +#define _EFI_INCLUDE_ + +#define EFI_FIRMWARE_VENDOR L"INTEL" +#define EFI_FIRMWARE_MAJOR_REVISION 12 +#define EFI_FIRMWARE_MINOR_REVISION 33 +#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) + +#include "efibind.h" +#include "efidef.h" +#include "efidevp.h" +#include "efiprot.h" +#include "eficon.h" +#include "efiser.h" +#include "efi_nii.h" +#include "efipxebc.h" +#include "efinet.h" +#include "efiapi.h" +#include "efifs.h" +#include "efifpswa.h" +#include "efierr.h" + +#endif diff --git a/sys/boot/efi/include/efi_nii.h b/sys/boot/efi/include/efi_nii.h new file mode 100644 index 0000000..6a9c05d --- /dev/null +++ b/sys/boot/efi/include/efi_nii.h @@ -0,0 +1,82 @@ +/* $FreeBSD$ */ +#ifndef _EFI_NII_H +#define _EFI_NII_H + +/*++ +Copyright (c) 2000 Intel Corporation + +Module name: + efi_nii.h + +Abstract: + +Revision history: + 2000-Feb-18 M(f)J GUID updated. + Structure order changed for machine word alignment. + Added StringId[4] to structure. + + 2000-Feb-14 M(f)J Genesis. +--*/ + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL \ + { 0xE18541CD, 0xF755, 0x4f73, 0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29 } + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION 0x00010000 + +typedef enum { + EfiNetworkInterfaceUndi = 1 +} EFI_NETWORK_INTERFACE_TYPE; + +typedef struct { + + /* Revision of the network interface identifier protocol interface. */ + UINT64 Revision; + + /* + * Address of the first byte of the identifying structure for this + * network interface. This is set to zero if there is no structure. + * For PXE/UNDI this is the first byte of the !PXE structure. + */ + UINT64 ID; + + /* + * Address of the UNrelocated driver/ROM image. This is set + * to zero if there is no driver/ROM image. + * For 16-bit UNDI, this is the first byte of the option ROM in + * upper memory. + * For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM + * image. + * For H/W UNDI, this is set to zero. + */ + UINT64 ImageAddr; + + /* + * Size of the UNrelocated driver/ROM image of this network interface. + * This is set to zero if there is no driver/ROM image. + */ + UINT32 ImageSize; + + /* + * 4 char ASCII string to go in class identifier (option 60) in DHCP + * and Boot Server discover packets. + * For EfiNetworkInterfaceUndi this field is "UNDI". + * For EfiNetworkInterfaceSnp this field is "SNPN". + */ + CHAR8 StringId[4]; + + /* + * Information to be placed into the PXE DHCP and Discover packets. + * This is the network interface type and version number that will + * be placed into DHCP option 94 (client network interface identifier). + */ + UINT8 Type; + UINT8 MajorVer; + UINT8 MinorVer; + + BOOLEAN Ipv6Supported; + UINT8 IfNum; /* interface number to be used with pxeid structure */ +} EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE; + +extern EFI_GUID NetworkInterfaceIdentifierProtocol; + +#endif /* _EFI_NII_H */ diff --git a/sys/boot/efi/include/efiapi.h b/sys/boot/efi/include/efiapi.h new file mode 100644 index 0000000..673d63f --- /dev/null +++ b/sys/boot/efi/include/efiapi.h @@ -0,0 +1,704 @@ +/* $FreeBSD$ */ +#ifndef _EFI_API_H +#define _EFI_API_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiapi.h + +Abstract: + + Global EFI runtime & boot service interfaces + + + + +Revision History + +--*/ + +/* + * EFI Specification Revision + */ + +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 02 + +/* + * Declare forward referenced data structures + */ + +INTERFACE_DECL(_EFI_SYSTEM_TABLE); + +/* + * EFI Memory + */ + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_PAGES) ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NoPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_PAGES) ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_MAP) ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) + + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_POOL) ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_POOL) ( + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + + +#define EFI_OPTIONAL_PTR 0x00000001 +#define EFI_INTERNAL_FNC 0x00000002 /* Pointer to internal runtime fnc */ +#define EFI_INTERNAL_PTR 0x00000004 /* Pointer to internal runtime data */ + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + + +/* + * EFI Events + */ + + + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_RUNTIME_CONTEXT 0x20000000 + +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 + +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define EVT_EFI_SIGNAL_MASK 0x000000FF +#define EVT_EFI_SIGNAL_MAX 2 + +typedef +VOID +(EFIAPI *EFI_EVENT_NOTIFY) ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event + ); + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} EFI_TIMER_DELAY; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIMER) ( + IN EFI_EVENT Event, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIGNAL_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_WAIT_FOR_EVENT) ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *Event, + OUT UINTN *Index + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CHECK_EVENT) ( + IN EFI_EVENT Event + ); + +/* + * Task priority level + */ + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +typedef +EFI_TPL +(EFIAPI *EFI_RAISE_TPL) ( + IN EFI_TPL NewTpl + ); + +typedef +VOID +(EFIAPI *EFI_RESTORE_TPL) ( + IN EFI_TPL OldTpl + ); + + +/* + * EFI platform varibles + */ + +#define EFI_GLOBAL_VARIABLE \ + { 0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } + +/* Variable attributes */ +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 + +/* Variable size limitation */ +#define EFI_MAXIMUM_VARIABLE_SIZE 1024 + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +/* + * EFI Time + */ + +typedef struct { + UINT32 Resolution; /* 1e-6 parts per million */ + UINT32 Accuracy; /* hertz */ + BOOLEAN SetsToZero; /* Set clears sub-second time */ +} EFI_TIME_CAPABILITIES; + + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + + +/* + * Image functions + */ + + +/* PE32+ Subsystem type for EFI images */ + +#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION) +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#endif + +/* PE32+ Machine type for EFI images */ + +#if !defined(EFI_IMAGE_MACHINE_IA32) +#define EFI_IMAGE_MACHINE_IA32 0x014c +#endif + +#if !defined(EFI_IMAGE_MACHINE_IA64) +#define EFI_IMAGE_MACHINE_IA64 0x0200 +#endif + +/* Image Entry prototype */ + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_ENTRY_POINT) ( + IN EFI_HANDLE ImageHandle, + IN struct _EFI_SYSTEM_TABLE *SystemTable + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_LOAD) ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_START) ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT) ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_UNLOAD) ( + IN EFI_HANDLE ImageHandle + ); + + +/* Image handle */ +#define LOADED_IMAGE_PROTOCOL \ + { 0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } + +#define EFI_IMAGE_INFORMATION_REVISION 0x1000 +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + /* Source location of image */ + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + /* Images load options */ + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + /* Location of where image was loaded */ + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + /* If the driver image supports a dynamic unload request */ + EFI_IMAGE_UNLOAD Unload; + +} EFI_LOADED_IMAGE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT_BOOT_SERVICES) ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/* + * Misc + */ + + +typedef +EFI_STATUS +(EFIAPI *EFI_STALL) ( + IN UINTN Microseconds + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WATCHDOG_TIMER) ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + + +typedef enum { + EfiResetCold, + EfiResetWarm +} EFI_RESET_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) ( + OUT UINT64 *Count + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT UINT32 *HighCount + ); + +/* + * Protocol handler functions + */ + +typedef enum { + EFI_NATIVE_INTERFACE, + EFI_PCODE_INTERFACE +} EFI_INTERFACE_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) ( + IN OUT EFI_HANDLE *Handle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HANDLE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} EFI_LOCATE_SEARCH_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_DEVICE_PATH) ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT EFI_HANDLE *Device + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RESERVED_SERVICE) ( + VOID + ); + +/* + * Standard EFI table header + */ + +typedef struct _EFI_TABLE_HEARDER { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + + +/* + * EFI Runtime Serivces Table + */ + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct { + EFI_TABLE_HEADER Hdr; + + /* Time services */ + + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + /* Virtual memory services */ + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + /* Variable serviers */ + + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + /* Misc */ + + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + +} EFI_RUNTIME_SERVICES; + + +/* + * EFI Boot Services Table + */ + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct _EFI_BOOT_SERVICES { + + EFI_TABLE_HEADER Hdr; + + /* Task priority functions */ + + EFI_RAISE_TPL RaiseTPL; + EFI_RESTORE_TPL RestoreTPL; + + /* Memory functions */ + + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + EFI_ALLOCATE_POOL AllocatePool; + EFI_FREE_POOL FreePool; + + /* Event & timer functions */ + + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + + /* Protocol handler functions */ + + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; + EFI_HANDLE_PROTOCOL HandleProtocol; + EFI_HANDLE_PROTOCOL PCHandleProtocol; + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; + EFI_LOCATE_HANDLE LocateHandle; + EFI_LOCATE_DEVICE_PATH LocateDevicePath; + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; + + /* Image functions */ + + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; + EFI_EXIT_BOOT_SERVICES ExitBootServices; + + /* Misc functions */ + + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + +} EFI_BOOT_SERVICES; + + +/* + * EFI Configuration Table and GUID definitions + */ + +#define MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define SAL_SYSTEM_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +/* DIG64 Headless Console & Debug Port Table. */ +#define HCDP_TABLE_GUID \ + {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}} + +typedef struct _EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + + +/* + * EFI System Table + */ + + + + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_SYSTEM_TABLE_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct _EFI_SYSTEM_TABLE { + EFI_TABLE_HEADER Hdr; + + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + SIMPLE_INPUT_INTERFACE *ConIn; + + EFI_HANDLE ConsoleOutHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut; + + EFI_HANDLE StandardErrorHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + +} EFI_SYSTEM_TABLE; + +#endif diff --git a/sys/boot/efi/include/eficon.h b/sys/boot/efi/include/eficon.h new file mode 100644 index 0000000..a288571 --- /dev/null +++ b/sys/boot/efi/include/eficon.h @@ -0,0 +1,299 @@ +/* $FreeBSD$ */ +#ifndef _EFI_CON_H +#define _EFI_CON_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + eficon.h + +Abstract: + + EFI console protocols + + + +Revision History + +--*/ + +/* + * Text output protocol + */ + +#define SIMPLE_TEXT_OUTPUT_PROTOCOL \ + { 0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_RESET) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_OUTPUT_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_TEST_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_QUERY_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Attribute + ); + +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN (EFI_BLUE | EFI_GREEN) +#define EFI_RED 0x04 +#define EFI_MAGENTA (EFI_BLUE | EFI_RED) +#define EFI_BROWN (EFI_GREEN | EFI_RED) +#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY (EFI_BRIGHT) +#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) +#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) +#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) +#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) +#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) +#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) +#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) + +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) + + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_CLEAR_SCREEN) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Column, + IN UINTN Row + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_ENABLE_CURSOR) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN Enable + ); + +typedef struct { + INT32 MaxMode; + /* current settings */ + INT32 Mode; + INT32 Attribute; + INT32 CursorColumn; + INT32 CursorRow; + BOOLEAN CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE { + EFI_TEXT_RESET Reset; + + EFI_TEXT_OUTPUT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + + /* Current mode */ + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} SIMPLE_TEXT_OUTPUT_INTERFACE; + +/* + * Define's for required EFI Unicode Box Draw character + */ + +#define BOXDRAW_HORIZONTAL 0x2500 +#define BOXDRAW_VERTICAL 0x2502 +#define BOXDRAW_DOWN_RIGHT 0x250c +#define BOXDRAW_DOWN_LEFT 0x2510 +#define BOXDRAW_UP_RIGHT 0x2514 +#define BOXDRAW_UP_LEFT 0x2518 +#define BOXDRAW_VERTICAL_RIGHT 0x251c +#define BOXDRAW_VERTICAL_LEFT 0x2524 +#define BOXDRAW_DOWN_HORIZONTAL 0x252c +#define BOXDRAW_UP_HORIZONTAL 0x2534 +#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c + +#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 +#define BOXDRAW_DOUBLE_VERTICAL 0x2551 +#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 +#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 +#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 + +#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 +#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 +#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 + +#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 +#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 +#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a + +#define BOXDRAW_UP_LEFT_DOUBLE 0x255b +#define BOXDRAW_UP_DOUBLE_LEFT 0x255c +#define BOXDRAW_DOUBLE_UP_LEFT 0x255d + +#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e +#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f +#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 + +#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 +#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 +#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 + +#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 +#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 +#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 + +#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 +#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 +#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 + +#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a +#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b +#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c + +/* + * EFI Required Block Elements Code Chart + */ +#define BLOCKELEMENT_FULL_BLOCK 0x2588 +#define BLOCKELEMENT_LIGHT_SHADE 0x2591 + +/* + * EFI Required Geometric Shapes Code Chart + */ +#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 +#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba +#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc +#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 + +/* + * EFI Required Arrow shapes + */ +#define ARROW_UP 0x2191 +#define ARROW_DOWN 0x2193 + +/* + * Text input protocol + */ + +#define SIMPLE_TEXT_INPUT_PROTOCOL \ + { 0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE); + +typedef struct { + UINT16 ScanCode; + CHAR16 UnicodeChar; +} EFI_INPUT_KEY; + +/* + * Baseline unicode control chars + */ + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +/* + * Scan codes for base line keys + */ +#define SCAN_NULL 0x0000 +#define SCAN_UP 0x0001 +#define SCAN_DOWN 0x0002 +#define SCAN_RIGHT 0x0003 +#define SCAN_LEFT 0x0004 +#define SCAN_HOME 0x0005 +#define SCAN_END 0x0006 +#define SCAN_INSERT 0x0007 +#define SCAN_DELETE 0x0008 +#define SCAN_PAGE_UP 0x0009 +#define SCAN_PAGE_DOWN 0x000A +#define SCAN_F1 0x000B +#define SCAN_F2 0x000C +#define SCAN_F3 0x000D +#define SCAN_F4 0x000E +#define SCAN_F5 0x000F +#define SCAN_F6 0x0010 +#define SCAN_F7 0x0011 +#define SCAN_F8 0x0012 +#define SCAN_F9 0x0013 +#define SCAN_F10 0x0014 +#define SCAN_ESC 0x0017 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + OUT EFI_INPUT_KEY *Key + ); + +typedef struct _SIMPLE_INPUT_INTERFACE { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} SIMPLE_INPUT_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efidebug.h b/sys/boot/efi/include/efidebug.h new file mode 100644 index 0000000..5214737 --- /dev/null +++ b/sys/boot/efi/include/efidebug.h @@ -0,0 +1,105 @@ +/* $FreeBSD$ */ +#ifndef _EFI_DEBUG_H +#define _EFI_DEBUG_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidebug.h + +Abstract: + + EFI library debug functions + + + +Revision History + +--*/ + +extern UINTN EFIDebug; + +#if EFI_DEBUG + + #define DBGASSERT(a) DbgAssert(__FILE__, __LINE__, #a) + #define DEBUG(a) DbgPrint a + +#else + + #define DBGASSERT(a) + #define DEBUG(a) + +#endif + +#if EFI_DEBUG_CLEAR_MEMORY + + #define DBGSETMEM(a,l) SetMem(a,l,(CHAR8)BAD_POINTER) + +#else + + #define DBGSETMEM(a,l) + +#endif + +#define D_INIT 0x00000001 /* Initialization style messages */ +#define D_WARN 0x00000002 /* Warnings */ +#define D_LOAD 0x00000004 /* Load events */ +#define D_FS 0x00000008 /* EFI File system */ +#define D_POOL 0x00000010 /* Alloc & Free's */ +#define D_PAGE 0x00000020 /* Alloc & Free's */ +#define D_INFO 0x00000040 /* Verbose */ +#define D_VAR 0x00000100 /* Variable */ +#define D_PARSE 0x00000200 /* Command parsing */ +#define D_BM 0x00000400 /* Boot manager */ +#define D_BLKIO 0x00001000 /* BlkIo Driver */ +#define D_BLKIO_ULTRA 0x00002000 /* BlkIo Driver */ +#define D_NET 0x00004000 /* SNI Driver */ +#define D_NET_ULTRA 0x00008000 /* SNI Driver */ +#define D_TXTIN 0x00010000 /* Simple Input Driver */ +#define D_TXTOUT 0x00020000 /* Simple Text Output Driver */ +#define D_ERROR_ATA 0x00040000 /* ATA error messages */ +#define D_ERROR 0x80000000 /* Error */ + +#define D_RESERVED 0x7fffC880 /* Bits not reserved above */ + +/* + * Current Debug level of the system, value of EFIDebug + */ +#define EFI_DBUG_MASK (D_ERROR) + +#if EFI_DEBUG + + #define ASSERT(a) if(!(a)) DBGASSERT(a) + #define ASSERT_LOCKED(l) if(!(l)->Lock) DBGASSERT(l not locked) + #define ASSERT_STRUCT(p,t) DBGASSERT(t not structure), p + +#else + + #define ASSERT(a) + #define ASSERT_LOCKED(l) + #define ASSERT_STRUCT(p,t) + +#endif + +/* + * Prototypes + */ + +INTN +DbgAssert ( + CHAR8 *file, + INTN lineno, + CHAR8 *string + ); + +INTN +DbgPrint ( + INTN mask, + CHAR8 *format, + ... + ); + +#endif diff --git a/sys/boot/efi/include/efidef.h b/sys/boot/efi/include/efidef.h new file mode 100644 index 0000000..2bd7f9b --- /dev/null +++ b/sys/boot/efi/include/efidef.h @@ -0,0 +1,193 @@ +/* $FreeBSD$ */ +#ifndef _EFI_DEF_H +#define _EFI_DEF_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidef.h + +Abstract: + + EFI definitions + + + + +Revision History + +--*/ + +typedef UINT16 CHAR16; +typedef UINT8 CHAR8; +typedef UINT8 BOOLEAN; + +#ifndef TRUE + #define TRUE ((BOOLEAN) 1) + #define FALSE ((BOOLEAN) 0) +#endif + +#ifndef NULL + #define NULL ((VOID *) 0) +#endif + +typedef UINTN EFI_STATUS; +typedef UINT64 EFI_LBA; +typedef UINTN EFI_TPL; +typedef VOID *EFI_HANDLE; +typedef VOID *EFI_EVENT; + + +/* + * Prototype argument decoration for EFI parameters to indicate + * their direction + * + * IN - argument is passed into the function + * OUT - argument (pointer) is returned from the function + * OPTIONAL - argument is optional + */ + +#ifndef IN + #define IN + #define OUT + #define OPTIONAL +#endif + + +/* + * A GUID + */ + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + + +/* + * Time + */ + +typedef struct { + UINT16 Year; /* 1998 - 20XX */ + UINT8 Month; /* 1 - 12 */ + UINT8 Day; /* 1 - 31 */ + UINT8 Hour; /* 0 - 23 */ + UINT8 Minute; /* 0 - 59 */ + UINT8 Second; /* 0 - 59 */ + UINT8 Pad1; + UINT32 Nanosecond; /* 0 - 999,999,999 */ + INT16 TimeZone; /* -1440 to 1440 or 2047 */ + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +/* Bit definitions for EFI_TIME.Daylight */ +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +/* Value definition for EFI_TIME.TimeZone */ +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + + + +/* + * Networking + */ + +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +/* + * Memory + */ + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +/* + * Preseve the attr on any range supplied. + * ConventialMemory must have WB,SR,SW when supplied. + * When allocating from ConventialMemory always make it WB,SR,SW + * When returning to ConventialMemory always make it WB,SR,SW + * When getting the memory map, or on RT for runtime types + */ + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +/* possible caching types for the memory range */ +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +/* physical memory protection on range */ +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 + +/* range requires a runtime mapping */ +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; /* 32 bit padding */ + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + UINT64 NumberOfPages; + UINT64 Attribute; +} EFI_MEMORY_DESCRIPTOR; + +/* + * International Language + */ + +typedef UINT8 ISO_639_2; +#define ISO_639_2_ENTRY_SIZE 3 + +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) \ + ( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) ) + +#endif diff --git a/sys/boot/efi/include/efidevp.h b/sys/boot/efi/include/efidevp.h new file mode 100644 index 0000000..ebd6b3b --- /dev/null +++ b/sys/boot/efi/include/efidevp.h @@ -0,0 +1,391 @@ +/* $FreeBSD$ */ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +/* + * Device Path structures - Section C + */ + +typedef struct _EFI_DEVICE_PATH { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 + +#define END_DEVICE_PATH_TYPE 0x7f + +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH)) + + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) +#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE ) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \ + (a)->Length[1] = 0; \ + } + + + +/* + * + */ +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 +typedef struct _PCI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Function; + UINT8 Device; +} PCI_DEVICE_PATH; + +#define HW_PCCARD_DP 0x02 +typedef struct _PCCARD_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 SocketNumber; +} PCCARD_DEVICE_PATH; + +#define HW_MEMMAP_DP 0x03 +typedef struct _MEMMAP_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 MemoryType; + EFI_PHYSICAL_ADDRESS StartingAddress; + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +#define HW_VENDOR_DP 0x04 +typedef struct _VENDOR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Guid; +} VENDOR_DEVICE_PATH; + +#define UNKNOWN_DEVICE_GUID \ + { 0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } + +typedef struct _UKNOWN_DEVICE_VENDOR_DP { + VENDOR_DEVICE_PATH DevicePath; + UINT8 LegacyDriveLetter; +} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH; + +#define HW_CONTROLLER_DP 0x05 +typedef struct _CONTROLLER_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Controller; +} CONTROLLER_DEVICE_PATH; + +/* + * + */ +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 +typedef struct _ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +/* + * EISA ID Macro + * EISA ID Definition 32-bits + * bits[15:0] - three character compressed ASCII EISA ID. + * bits[31:16] - binary number + * Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' + */ +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) +/* + * + */ +#define MESSAGING_DEVICE_PATH 0x03 + +#define MSG_ATAPI_DP 0x01 +typedef struct _ATAPI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +#define MSG_SCSI_DP 0x02 +typedef struct _SCSI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 Pun; + UINT16 Lun; +} SCSI_DEVICE_PATH; + +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct _FIBRECHANNEL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 WWN; + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +#define MSG_1394_DP 0x04 +typedef struct _F1394_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 Guid; +} F1394_DEVICE_PATH; + +#define MSG_USB_DP 0x05 +typedef struct _USB_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Port; + UINT8 Endpoint; +} USB_DEVICE_PATH; + +#define MSG_USB_CLASS_DP 0x0F +typedef struct _USB_CLASS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 VendorId; + UINT16 ProductId; + UINT8 DeviceClass; + UINT8 DeviceSubclass; + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +#define MSG_I2O_DP 0x06 +typedef struct _I2O_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Tid; +} I2O_DEVICE_PATH; + +#define MSG_MAC_ADDR_DP 0x0b +typedef struct _MAC_ADDR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_MAC_ADDRESS MacAddress; + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +#define MSG_IPv4_DP 0x0c +typedef struct _IPv4_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv4_ADDRESS LocalIpAddress; + EFI_IPv4_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv4_DEVICE_PATH; + +#define MSG_IPv6_DP 0x0d +typedef struct _IPv6_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv6_ADDRESS LocalIpAddress; + EFI_IPv6_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv6_DEVICE_PATH; + +#define MSG_INFINIBAND_DP 0x09 +typedef struct _INFINIBAND_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 NodeGuid; + UINT64 IocGuid; + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define MSG_UART_DP 0x0e +typedef struct _UART_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 BaudRate; + UINT8 DataBits; + UINT8 Parity; + UINT8 StopBits; +} UART_DEVICE_PATH; + +#define MSG_VENDOR_DP 0x0A +/* Use VENDOR_DEVICE_PATH struct */ + +#define DEVICE_PATH_MESSAGING_PC_ANSI \ + { 0xe0c14753, 0xf9be, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +#define DEVICE_PATH_MESSAGING_VT_100 \ + { 0xdfa66065, 0xb419, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + + + +#define MEDIA_DEVICE_PATH 0x04 + +#define MEDIA_HARDDRIVE_DP 0x01 +typedef struct _HARDDRIVE_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 PartitionNumber; + UINT64 PartitionStart; + UINT64 PartitionSize; + UINT8 Signature[16]; + UINT8 MBRType; + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +#define MEDIA_CDROM_DP 0x02 +typedef struct _CDROM_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 BootEntry; + UINT64 PartitionStart; + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +#define MEDIA_VENDOR_DP 0x03 +/* Use VENDOR_DEVICE_PATH struct */ + +#define MEDIA_FILEPATH_DP 0x04 +typedef struct _FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH Header; + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName) + +#define MEDIA_PROTOCOL_DP 0x05 +typedef struct _MEDIA_PROTOCOL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + + +#define BBS_DEVICE_PATH 0x05 +#define BBS_BBS_DP 0x01 +typedef struct _BBS_BBS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 DeviceType; + UINT16 StatusFlag; + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +/* DeviceType definitions - from BBS specification */ +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_DEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + +typedef union { + EFI_DEVICE_PATH DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + CONTROLLER_DEVICE_PATH Controller; + ACPI_HID_DEVICE_PATH Acpi; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + USB_CLASS_DEVICE_PATH UsbClass; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + BBS_BBS_DEVICE_PATH Bbs; + +} EFI_DEV_PATH; + +typedef union { + EFI_DEVICE_PATH *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + CONTROLLER_DEVICE_PATH *Controller; + ACPI_HID_DEVICE_PATH *Acpi; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + USB_CLASS_DEVICE_PATH *UsbClass; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + + HARDDRIVE_DEVICE_PATH *HardDrive; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + CDROM_DEVICE_PATH *CD; + BBS_BBS_DEVICE_PATH *Bbs; + +} EFI_DEV_PATH_PTR; + + +#endif diff --git a/sys/boot/efi/include/efierr.h b/sys/boot/efi/include/efierr.h new file mode 100644 index 0000000..a6db90c --- /dev/null +++ b/sys/boot/efi/include/efierr.h @@ -0,0 +1,60 @@ +/* $FreeBSD$ */ +#ifndef _EFI_ERR_H +#define _EFI_ERR_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efierr.h + +Abstract: + + EFI error codes + + + + +Revision History + +--*/ + + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) a) < 0) + + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_INVALID_PARAMETER EFIERR(2) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BAD_BUFFER_SIZE EFIERR(4) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_NOT_READY EFIERR(6) +#define EFI_DEVICE_ERROR EFIERR(7) +#define EFI_WRITE_PROTECTED EFIERR(8) +#define EFI_OUT_OF_RESOURCES EFIERR(9) +#define EFI_VOLUME_CORRUPTED EFIERR(10) +#define EFI_VOLUME_FULL EFIERR(11) +#define EFI_NO_MEDIA EFIERR(12) +#define EFI_MEDIA_CHANGED EFIERR(13) +#define EFI_NOT_FOUND EFIERR(14) +#define EFI_ACCESS_DENIED EFIERR(15) +#define EFI_NO_RESPONSE EFIERR(16) +#define EFI_NO_MAPPING EFIERR(17) +#define EFI_TIMEOUT EFIERR(18) +#define EFI_NOT_STARTED EFIERR(19) +#define EFI_ALREADY_STARTED EFIERR(20) +#define EFI_ABORTED EFIERR(21) +#define EFI_ICMP_ERROR EFIERR(22) +#define EFI_TFTP_ERROR EFIERR(23) +#define EFI_PROTOCOL_ERROR EFIERR(24) + +#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) +#define EFI_WARN_DELETE_FAILURE EFIWARN(2) +#define EFI_WARN_WRITE_FAILURE EFIWARN(3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) + +#endif diff --git a/sys/boot/efi/include/efifpswa.h b/sys/boot/efi/include/efifpswa.h new file mode 100644 index 0000000..3e039ef --- /dev/null +++ b/sys/boot/efi/include/efifpswa.h @@ -0,0 +1,40 @@ +/* $FreeBSD$ */ +#ifndef _EFI_FPSWA_H +#define _EFI_FPSWA_H + +/* + * EFI FP SWA Driver (Floating Point Software Assist) + */ + +#define EFI_INTEL_FPSWA \ + { 0xc41b6531, 0x97b9, 0x11d3, 0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +INTERFACE_DECL(_FPSWA_INTERFACE); + +typedef struct _FPSWA_RET { + UINT64 status; + UINT64 err1; + UINT64 err2; + UINT64 err3; +} FPSWA_RET; + +typedef +FPSWA_RET +(EFIAPI *EFI_FPSWA) ( + IN UINTN TrapType, + IN OUT VOID *Bundle, + IN OUT UINT64 *pipsr, + IN OUT UINT64 *pfsr, + IN OUT UINT64 *pisr, + IN OUT UINT64 *ppreds, + IN OUT UINT64 *pifs, + IN OUT VOID *fp_state + ); + +typedef struct _FPSWA_INTERFACE { + UINT32 Revision; + UINT32 Reserved; + EFI_FPSWA Fpswa; +} FPSWA_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efifs.h b/sys/boot/efi/include/efifs.h new file mode 100644 index 0000000..8ef3615 --- /dev/null +++ b/sys/boot/efi/include/efifs.h @@ -0,0 +1,116 @@ +/* $FreeBSD$ */ +#ifndef _EFI_FS_H +#define _EFI_FS_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efifs.h + +Abstract: + + EFI File System structures + + + +Revision History + +--*/ + + +/* + * EFI Partition header (normaly starts in LBA 1) + */ + +#define EFI_PARTITION_SIGNATURE 0x5053595320494249 +#define EFI_PARTITION_REVISION 0x00010001 +#define MIN_EFI_PARTITION_BLOCK_SIZE 512 +#define EFI_PARTITION_LBA 1 + +typedef struct _EFI_PARTITION_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 DirectoryAllocationNumber; + UINT32 BlockSize; + EFI_LBA FirstUsableLba; + EFI_LBA LastUsableLba; + EFI_LBA UnusableSpace; + EFI_LBA FreeSpace; + EFI_LBA RootFile; + EFI_LBA SecutiryFile; +} EFI_PARTITION_HEADER; + + +/* + * File header + */ + +#define EFI_FILE_HEADER_SIGNATURE 0x454c494620494249 +#define EFI_FILE_HEADER_REVISION 0x00010000 +#define EFI_FILE_STRING_SIZE 260 + +typedef struct _EFI_FILE_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + UINT32 LBALOffset; + EFI_LBA Parent; + UINT64 FileSize; + UINT64 FileAttributes; + EFI_TIME FileCreateTime; + EFI_TIME FileModificationTime; + EFI_GUID VendorGuid; + CHAR16 FileString[EFI_FILE_STRING_SIZE]; +} EFI_FILE_HEADER; + + +/* + * Return the file's first LBAL which is in the same + * logical block as the file header + */ + +#define EFI_FILE_LBAL(a) ((EFI_LBAL *) (((CHAR8 *) (a)) + (a)->LBALOffset)) + +#define EFI_FILE_CLASS_FREE_SPACE 1 +#define EFI_FILE_CLASS_EMPTY 2 +#define EFI_FILE_CLASS_NORMAL 3 + + +/* + * Logical Block Address List - the fundemental block + * description structure + */ + +#define EFI_LBAL_SIGNATURE 0x4c41424c20494249 +#define EFI_LBAL_REVISION 0x00010000 + +typedef struct _EFI_LBAL { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + EFI_LBA Parent; + EFI_LBA Next; + UINT32 ArraySize; + UINT32 ArrayCount; +} EFI_LBAL; + +/* Array size */ +#define EFI_LBAL_ARRAY_SIZE(lbal,offs,blks) \ + (((blks) - (offs) - (lbal)->Hdr.HeaderSize) / sizeof(EFI_RL)) + +/* + * Logical Block run-length + */ + +typedef struct { + EFI_LBA Start; + UINT64 Length; +} EFI_RL; + +/* + * Return the run-length structure from an LBAL header + */ + +#define EFI_LBAL_RL(a) ((EFI_RL*) (((CHAR8 *) (a)) + (a)->Hdr.HeaderSize)) + +#endif diff --git a/sys/boot/efi/include/efilib.h b/sys/boot/efi/include/efilib.h new file mode 100644 index 0000000..1e7b269 --- /dev/null +++ b/sys/boot/efi/include/efilib.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +extern EFI_HANDLE IH; +extern EFI_SYSTEM_TABLE *ST; +extern EFI_BOOT_SERVICES *BS; +extern EFI_RUNTIME_SERVICES *RS; + +void *efi_get_table(EFI_GUID *tbl); +void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table); + +EFI_STATUS main(int argc, CHAR16 *argv[]); +void exit(EFI_STATUS status); diff --git a/sys/boot/efi/include/efinet.h b/sys/boot/efi/include/efinet.h new file mode 100644 index 0000000..c137ef8 --- /dev/null +++ b/sys/boot/efi/include/efinet.h @@ -0,0 +1,261 @@ +/* $FreeBSD$ */ +#ifndef _EFINET_H +#define _EFINET_H + + +/*++ +Copyright (c) 1999 Intel Corporation + +Module Name: + efinet.h + +Abstract: + EFI Simple Network protocol + +Revision History +--*/ + + +#define EFI_SIMPLE_NETWORK_PROTOCOL \ + { 0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + +INTERFACE_DECL(_EFI_SIMPLE_NETWORK); + +typedef struct { + /* + * Total number of frames received. Includes frames with errors and + * dropped frames. + */ + UINT64 RxTotalFrames; + + /* Number of valid frames received and copied into receive buffers. */ + UINT64 RxGoodFrames; + + /* + * Number of frames below the minimum length for the media. + * This would be <64 for ethernet. + */ + UINT64 RxUndersizeFrames; + + /* + * Number of frames longer than the maxminum length for the + * media. This would be >1500 for ethernet. + */ + UINT64 RxOversizeFrames; + + /* Valid frames that were dropped because receive buffers were full. */ + UINT64 RxDroppedFrames; + + /* Number of valid unicast frames received and not dropped. */ + UINT64 RxUnicastFrames; + + /* Number of valid broadcast frames received and not dropped. */ + UINT64 RxBroadcastFrames; + + /* Number of valid mutlicast frames received and not dropped. */ + UINT64 RxMulticastFrames; + + /* Number of frames w/ CRC or alignment errors. */ + UINT64 RxCrcErrorFrames; + + /* + * Total number of bytes received. Includes frames with errors + * and dropped frames. + */ + UINT64 RxTotalBytes; + + /* Transmit statistics. */ + UINT64 TxTotalFrames; + UINT64 TxGoodFrames; + UINT64 TxUndersizeFrames; + UINT64 TxOversizeFrames; + UINT64 TxDroppedFrames; + UINT64 TxUnicastFrames; + UINT64 TxBroadcastFrames; + UINT64 TxMulticastFrames; + UINT64 TxCrcErrorFrames; + UINT64 TxTotalBytes; + + /* Number of collisions detection on this subnet. */ + UINT64 Collisions; + + /* Number of frames destined for unsupported protocol. */ + UINT64 UnsupportedProtocol; + +} EFI_NETWORK_STATISTICS; + +typedef enum { + EfiSimpleNetworkStopped, + EfiSimpleNetworkStarted, + EfiSimpleNetworkInitialized, + EfiSimpleNetworkMaxState +} EFI_SIMPLE_NETWORK_STATE; + +#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 +#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 +#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 + +#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 +#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 +#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 +#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 + +#define MAX_MCAST_FILTER_CNT 16 +typedef struct { + UINT32 State; + UINT32 HwAddressSize; + UINT32 MediaHeaderSize; + UINT32 MaxPacketSize; + UINT32 NvRamSize; + UINT32 NvRamAccessSize; + UINT32 ReceiveFilterMask; + UINT32 ReceiveFilterSetting; + UINT32 MaxMCastFilterCount; + UINT32 MCastFilterCount; + EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]; + EFI_MAC_ADDRESS CurrentAddress; + EFI_MAC_ADDRESS BroadcastAddress; + EFI_MAC_ADDRESS PermanentAddress; + UINT8 IfType; + BOOLEAN MacAddressChangeable; + BOOLEAN MultipleTxSupported; + BOOLEAN MediaPresentSupported; + BOOLEAN MediaPresent; +} EFI_SIMPLE_NETWORK_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_START) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STOP) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RESET) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN ExtendedVerification +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINTN HeaderSize, + IN UINTN BufferSize, + IN VOID *Buffer, + IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, + IN UINT16 *Protocol OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) ( + IN struct _EFI_SIMPLE_NETWORK *This, + OUT UINTN *HeaderSize OPTIONAL, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer, + OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, + OUT UINT16 *Protocol OPTIONAL +); + +#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_SIMPLE_NETWORK { + UINT64 Revision; + EFI_SIMPLE_NETWORK_START Start; + EFI_SIMPLE_NETWORK_STOP Stop; + EFI_SIMPLE_NETWORK_INITIALIZE Initialize; + EFI_SIMPLE_NETWORK_RESET Reset; + EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; + EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters; + EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress; + EFI_SIMPLE_NETWORK_STATISTICS Statistics; + EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac; + EFI_SIMPLE_NETWORK_NVDATA NvData; + EFI_SIMPLE_NETWORK_GET_STATUS GetStatus; + EFI_SIMPLE_NETWORK_TRANSMIT Transmit; + EFI_SIMPLE_NETWORK_RECEIVE Receive; + EFI_EVENT WaitForPacket; + EFI_SIMPLE_NETWORK_MODE *Mode; +} EFI_SIMPLE_NETWORK; + +#endif /* _EFINET_H */ diff --git a/sys/boot/efi/include/efipart.h b/sys/boot/efi/include/efipart.h new file mode 100644 index 0000000..b504bd9 --- /dev/null +++ b/sys/boot/efi/include/efipart.h @@ -0,0 +1,58 @@ +/* $FreeBSD$ */ +#ifndef _EFI_PART_H +#define _EFI_PART_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipart.h + +Abstract: + Info about disk partitions and Master Boot Records + + + + +Revision History + +--*/ + +#define EFI_PARTITION 0xef +#define MBR_SIZE 512 + +#pragma pack(1) + +typedef struct { + UINT8 BootIndicator; + UINT8 StartHead; + UINT8 StartSector; + UINT8 StartTrack; + UINT8 OSIndicator; + UINT8 EndHead; + UINT8 EndSector; + UINT8 EndTrack; + UINT8 StartingLBA[4]; + UINT8 SizeInLBA[4]; +} MBR_PARTITION_RECORD; + +#define EXTRACT_UINT32(D) (UINT32)(D[0] | (D[1] << 8) | (D[2] << 16) | (D[3] << 24)) + +#define MBR_SIGNATURE 0xaa55 +#define MIN_MBR_DEVICE_SIZE 0x80000 +#define MBR_ERRATA_PAD 0x40000 /* 128 MB */ + +#define MAX_MBR_PARTITIONS 4 +typedef struct { + UINT8 BootStrapCode[440]; + UINT8 UniqueMbrSignature[4]; + UINT8 Unknown[2]; + MBR_PARTITION_RECORD Partition[MAX_MBR_PARTITIONS]; + UINT16 Signature; +} MASTER_BOOT_RECORD; +#pragma pack() + + +#endif diff --git a/sys/boot/efi/include/efiprot.h b/sys/boot/efi/include/efiprot.h new file mode 100644 index 0000000..d81d605 --- /dev/null +++ b/sys/boot/efi/include/efiprot.h @@ -0,0 +1,551 @@ +/* $FreeBSD$ */ +#ifndef _EFI_PROT_H +#define _EFI_PROT_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiprot.h + +Abstract: + + EFI Protocols + + + +Revision History + +--*/ + +/* + * Device Path protocol + */ + +#define DEVICE_PATH_PROTOCOL \ + { 0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + + +/* + * Block IO protocol + */ + +#define BLOCK_IO_PROTOCOL \ + { 0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } +#define EFI_BLOCK_IO_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_BLOCK_IO); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_RESET) ( + IN struct _EFI_BLOCK_IO *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_READ) ( + IN struct _EFI_BLOCK_IO *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_WRITE) ( + IN struct _EFI_BLOCK_IO *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_FLUSH) ( + IN struct _EFI_BLOCK_IO *This + ); + + + +typedef struct { + UINT32 MediaId; + BOOLEAN RemovableMedia; + BOOLEAN MediaPresent; + + BOOLEAN LogicalPartition; + BOOLEAN ReadOnly; + BOOLEAN WriteCaching; + + UINT32 BlockSize; + UINT32 IoAlign; + + EFI_LBA LastBlock; +} EFI_BLOCK_IO_MEDIA; + +typedef struct _EFI_BLOCK_IO { + UINT64 Revision; + + EFI_BLOCK_IO_MEDIA *Media; + + EFI_BLOCK_RESET Reset; + EFI_BLOCK_READ ReadBlocks; + EFI_BLOCK_WRITE WriteBlocks; + EFI_BLOCK_FLUSH FlushBlocks; + +} EFI_BLOCK_IO; + + + +/* + * Disk Block IO protocol + */ + +#define DISK_IO_PROTOCOL \ + { 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } +#define EFI_DISK_IO_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_DISK_IO); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_READ) ( + IN struct _EFI_DISK_IO *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_WRITE) ( + IN struct _EFI_DISK_IO *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef struct _EFI_DISK_IO { + UINT64 Revision; + EFI_DISK_READ ReadDisk; + EFI_DISK_WRITE WriteDisk; +} EFI_DISK_IO; + + +/* + * Simple filesystem protocol + */ + +#define SIMPLE_FILE_SYSTEM_PROTOCOL \ + { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_EFI_FILE_IO_INTERFACE); +INTERFACE_DECL(_EFI_FILE_HANDLE); + +typedef +EFI_STATUS +(EFIAPI *EFI_VOLUME_OPEN) ( + IN struct _EFI_FILE_IO_INTERFACE *This, + OUT struct _EFI_FILE_HANDLE **Root + ); + +#define EFI_FILE_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_FILE_IO_INTERFACE { + UINT64 Revision; + EFI_VOLUME_OPEN OpenVolume; +} EFI_FILE_IO_INTERFACE; + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN) ( + IN struct _EFI_FILE_HANDLE *File, + OUT struct _EFI_FILE_HANDLE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/* Open modes */ +#define EFI_FILE_MODE_READ 0x0000000000000001 +#define EFI_FILE_MODE_WRITE 0x0000000000000002 +#define EFI_FILE_MODE_CREATE 0x8000000000000000 + +/* File attributes */ +#define EFI_FILE_READ_ONLY 0x0000000000000001 +#define EFI_FILE_HIDDEN 0x0000000000000002 +#define EFI_FILE_SYSTEM 0x0000000000000004 +#define EFI_FILE_RESERVIED 0x0000000000000008 +#define EFI_FILE_DIRECTORY 0x0000000000000010 +#define EFI_FILE_ARCHIVE 0x0000000000000020 +#define EFI_FILE_VALID_ATTR 0x0000000000000037 + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_CLOSE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_DELETE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + IN UINT64 Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + OUT UINT64 *Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH) ( + IN struct _EFI_FILE_HANDLE *File + ); + + + +#define EFI_FILE_HANDLE_REVISION 0x00010000 +typedef struct _EFI_FILE_HANDLE { + UINT64 Revision; + EFI_FILE_OPEN Open; + EFI_FILE_CLOSE Close; + EFI_FILE_DELETE Delete; + EFI_FILE_READ Read; + EFI_FILE_WRITE Write; + EFI_FILE_GET_POSITION GetPosition; + EFI_FILE_SET_POSITION SetPosition; + EFI_FILE_GET_INFO GetInfo; + EFI_FILE_SET_INFO SetInfo; + EFI_FILE_FLUSH Flush; +} EFI_FILE, *EFI_FILE_HANDLE; + + +/* + * File information types + */ + +#define EFI_FILE_INFO_ID \ + { 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +typedef struct { + UINT64 Size; + UINT64 FileSize; + UINT64 PhysicalSize; + EFI_TIME CreateTime; + EFI_TIME LastAccessTime; + EFI_TIME ModificationTime; + UINT64 Attribute; + CHAR16 FileName[1]; +} EFI_FILE_INFO; + +/* + * The FileName field of the EFI_FILE_INFO data structure is variable length. + * Whenever code needs to know the size of the EFI_FILE_INFO data structure, + * it needs to be the size of the data structure without the FileName field. + * The following macro computes this size correctly no matter how big the + * FileName array is declared. This is required to make the EFI_FILE_INFO + * data structure ANSI compliant. + */ + +#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName) + +#define EFI_FILE_SYSTEM_INFO_ID \ + { 0x9576e93, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +typedef struct { + UINT64 Size; + BOOLEAN ReadOnly; + UINT64 VolumeSize; + UINT64 FreeSpace; + UINT32 BlockSize; + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_INFO; + +/* + * The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is + * variable length. Whenever code needs to know the size of the + * EFI_FILE_SYSTEM_INFO data structure, it needs to be the size of the data + * structure without the VolumeLable field. The following macro computes + * this size correctly no matter how big the VolumeLable array is declared. + * This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI + * compilant. + */ + +#define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel) + +#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID \ + { 0xDB47D7D3,0xFE81, 0x11d3, 0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + +typedef struct { + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_VOLUME_LABEL_INFO; + +#define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_VOLUME_LABEL_INFO,VolumeLabel) + +/* + * Load file protocol + */ + +#define LOAD_FILE_PROTOCOL \ + { 0x56EC3091, 0x954C, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } + +INTERFACE_DECL(_EFI_LOAD_FILE_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOAD_FILE) ( + IN struct _EFI_LOAD_FILE_INTERFACE *This, + IN EFI_DEVICE_PATH *FilePath, + IN BOOLEAN BootPolicy, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL + ); + +typedef struct _EFI_LOAD_FILE_INTERFACE { + EFI_LOAD_FILE LoadFile; +} EFI_LOAD_FILE_INTERFACE; + + +/* + * Device IO protocol + */ + +#define DEVICE_IO_PROTOCOL \ + { 0xaf6ac311, 0x84c3, 0x11d2, 0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_EFI_DEVICE_IO_INTERFACE); + +typedef enum { + IO_UINT8, + IO_UINT16, + IO_UINT32, + IO_UINT64, +/* + * Specification Change: Copy from MMIO to MMIO vs. MMIO to buffer, buffer to + * MMIO + */ + MMIO_COPY_UINT8, + MMIO_COPY_UINT16, + MMIO_COPY_UINT32, + MMIO_COPY_UINT64 +} EFI_IO_WIDTH; + +#define EFI_PCI_ADDRESS(_bus,_dev,_func) \ + ( (UINT64) ( (((UINTN)_bus) << 24) + (((UINTN)_dev) << 16) + (((UINTN)_func) << 8) ) ) + + +typedef +EFI_STATUS +(EFIAPI *EFI_DEVICE_IO) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + EFI_DEVICE_IO Read; + EFI_DEVICE_IO Write; +} EFI_IO_ACCESS; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_DEVICE_PATH) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN UINT64 Address, + IN OUT EFI_DEVICE_PATH **PciDevicePath + ); + +typedef enum { + EfiBusMasterRead, + EfiBusMasterWrite, + EfiBusMasterCommonBuffer +} EFI_IO_OPERATION_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_MAP) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_IO_OPERATION_TYPE Operation, + IN EFI_PHYSICAL_ADDRESS *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_UNMAP) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN VOID *Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_ALLOCATE_BUFFER) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *HostAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FLUSH) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FREE_BUFFER) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN UINTN Pages, + IN EFI_PHYSICAL_ADDRESS HostAddress + ); + +typedef struct _EFI_DEVICE_IO_INTERFACE { + EFI_IO_ACCESS Mem; + EFI_IO_ACCESS Io; + EFI_IO_ACCESS Pci; + EFI_IO_MAP Map; + EFI_PCI_DEVICE_PATH PciDevicePath; + EFI_IO_UNMAP Unmap; + EFI_IO_ALLOCATE_BUFFER AllocateBuffer; + EFI_IO_FLUSH Flush; + EFI_IO_FREE_BUFFER FreeBuffer; +} EFI_DEVICE_IO_INTERFACE; + + +/* + * Unicode Collation protocol + */ + +#define UNICODE_COLLATION_PROTOCOL \ + { 0x1d85cd7f, 0xf43d, 0x11d2, 0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +#define UNICODE_BYTE_ORDER_MARK (CHAR16)(0xfeff) + +INTERFACE_DECL(_EFI_UNICODE_COLLATION_INTERFACE); + +typedef +INTN +(EFIAPI *EFI_UNICODE_STRICOLL) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_METAIMATCH) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRLWR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRUPR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_FATTOSTR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_STRTOFAT) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); + + +typedef struct _EFI_UNICODE_COLLATION_INTERFACE { + + /* general */ + EFI_UNICODE_STRICOLL StriColl; + EFI_UNICODE_METAIMATCH MetaiMatch; + EFI_UNICODE_STRLWR StrLwr; + EFI_UNICODE_STRUPR StrUpr; + + /* for supporting fat volumes */ + EFI_UNICODE_FATTOSTR FatToStr; + EFI_UNICODE_STRTOFAT StrToFat; + + CHAR8 *SupportedLanguages; +} EFI_UNICODE_COLLATION_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efipxebc.h b/sys/boot/efi/include/efipxebc.h new file mode 100644 index 0000000..7a6df76 --- /dev/null +++ b/sys/boot/efi/include/efipxebc.h @@ -0,0 +1,459 @@ +/* $FreeBSD$ */ +#ifndef _EFIPXEBC_H +#define _EFIPXEBC_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipxebc.h + +Abstract: + + EFI PXE Base Code Protocol + + + +Revision History + +--*/ + +/* + * PXE Base Code protocol + */ + +#define EFI_PXE_BASE_CODE_PROTOCOL \ + { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +INTERFACE_DECL(_EFI_PXE_BASE_CODE); + +#define DEFAULT_TTL 4 +#define DEFAULT_ToS 0 + +/* + * Address definitions + */ + +typedef union { + UINT32 Addr[4]; + EFI_IPv4_ADDRESS v4; + EFI_IPv6_ADDRESS v6; +} EFI_IP_ADDRESS; + +typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; + +/* + * Packet definitions + */ + +typedef struct { + UINT8 BootpOpcode; + UINT8 BootpHwType; + UINT8 BootpHwAddrLen; + UINT8 BootpGateHops; + UINT32 BootpIdent; + UINT16 BootpSeconds; + UINT16 BootpFlags; + UINT8 BootpCiAddr[4]; + UINT8 BootpYiAddr[4]; + UINT8 BootpSiAddr[4]; + UINT8 BootpGiAddr[4]; + UINT8 BootpHwAddr[16]; + UINT8 BootpSrvName[64]; + UINT8 BootpBootFile[128]; + UINT32 DhcpMagik; + UINT8 DhcpOptions[56]; +} EFI_PXE_BASE_CODE_DHCPV4_PACKET; + +typedef union { + UINT8 Raw[1472]; + EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; +} EFI_PXE_BASE_CODE_PACKET; + +typedef struct { + UINT8 Type; + UINT8 Code; + UINT16 Checksum; + union { + UINT32 reserved; + UINT32 Mtu; + UINT32 Pointer; + struct { + UINT16 Identifier; + UINT16 Sequence; + } Echo; + } u; + UINT8 Data[494]; +} EFI_PXE_BASE_CODE_ICMP_ERROR; + +typedef struct { + UINT8 ErrorCode; + CHAR8 ErrorString[127]; +} EFI_PXE_BASE_CODE_TFTP_ERROR; + +/* + * IP Receive Filter definitions + */ +#define EFI_PXE_BASE_CODE_MAX_IPCNT 8 +typedef struct { + UINT8 Filters; + UINT8 IpCnt; + UINT16 reserved; + EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT]; +} EFI_PXE_BASE_CODE_IP_FILTER; + +#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001 +#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008 + +/* + * ARP Cache definitions + */ + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_MAC_ADDRESS MacAddr; +} EFI_PXE_BASE_CODE_ARP_ENTRY; + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_IP_ADDRESS SubnetMask; + EFI_IP_ADDRESS GwAddr; +} EFI_PXE_BASE_CODE_ROUTE_ENTRY; + +/* + * UDP definitions + */ + +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020 + +/* + * Discover() definitions + */ + +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16 +/* + * 17 through 32767 are reserved + * 32768 through 65279 are for vendor use + * 65280 through 65534 are reserved + */ +#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535 + +#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF +#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000 + + +typedef struct { + UINT16 Type; + BOOLEAN AcceptAnyResponse; + UINT8 Reserved; + EFI_IP_ADDRESS IpAddr; +} EFI_PXE_BASE_CODE_SRVLIST; + +typedef struct { + BOOLEAN UseMCast; + BOOLEAN UseBCast; + BOOLEAN UseUCast; + BOOLEAN MustUseList; + EFI_IP_ADDRESS ServerMCastIp; + UINT16 IpCnt; + EFI_PXE_BASE_CODE_SRVLIST SrvList[1]; +} EFI_PXE_BASE_CODE_DISCOVER_INFO; + +/* + * Mtftp() definitions + */ + +typedef enum { + EFI_PXE_BASE_CODE_TFTP_FIRST, + EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, + EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_MTFTP_READ_FILE, + EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_LAST +} EFI_PXE_BASE_CODE_TFTP_OPCODE; + +typedef struct { + EFI_IP_ADDRESS MCastIp; + EFI_PXE_BASE_CODE_UDP_PORT CPort; + EFI_PXE_BASE_CODE_UDP_PORT SPort; + UINT16 ListenTimeout; + UINT16 TransmitTimeout; +} EFI_PXE_BASE_CODE_MTFTP_INFO; + +/* + * PXE Base Code Mode structure + */ + +#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 +#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 + +typedef struct { + BOOLEAN Started; + BOOLEAN Ipv6Available; + BOOLEAN Ipv6Supported; + BOOLEAN UsingIpv6; + BOOLEAN BisSupported; + BOOLEAN BisDetected; + BOOLEAN AutoArp; + BOOLEAN SendGUID; + BOOLEAN DhcpDiscoverValid; + BOOLEAN DhcpAckReceived; + BOOLEAN ProxyOfferReceived; + BOOLEAN PxeDiscoverValid; + BOOLEAN PxeReplyReceived; + BOOLEAN PxeBisReplyReceived; + BOOLEAN IcmpErrorReceived; + BOOLEAN TftpErrorReceived; + BOOLEAN MakeCallbacks; + UINT8 TTL; + UINT8 ToS; + EFI_IP_ADDRESS StationIp; + EFI_IP_ADDRESS SubnetMask; + EFI_PXE_BASE_CODE_PACKET DhcpDiscover; + EFI_PXE_BASE_CODE_PACKET DhcpAck; + EFI_PXE_BASE_CODE_PACKET ProxyOffer; + EFI_PXE_BASE_CODE_PACKET PxeDiscover; + EFI_PXE_BASE_CODE_PACKET PxeReply; + EFI_PXE_BASE_CODE_PACKET PxeBisReply; + EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + UINT32 ArpCacheEntries; + EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; + UINT32 RouteTableEntries; + EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; + EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; + EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; +} EFI_PXE_BASE_CODE_MODE; + +/* + * PXE Base Code Interface Function definitions + */ + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_START) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN UseIpv6 + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_STOP) ( + IN struct _EFI_PXE_BASE_CODE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DHCP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN SortOffers + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 Type, + IN UINT16 *Layer, + IN BOOLEAN UseBis, + IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_MTFTP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, + IN OUT VOID *BufferPtr OPTIONAL, + IN BOOLEAN Overwrite, + IN OUT UINTN *BufferSize, + IN UINTN *BlockSize OPTIONAL, + IN EFI_IP_ADDRESS *ServerIp, + IN UINT8 *Filename, + IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, + IN BOOLEAN DontUseBuffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 OpFlags, + IN EFI_IP_ADDRESS *DestIp, + IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, + IN EFI_IP_ADDRESS *GatewayIp, OPTIONAL + IN EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 OpFlags, + IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL + IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN OUT UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_ARP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_IP_ADDRESS *IpAddr, + IN EFI_MAC_ADDRESS *MacAddr OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN *NewAutoArp, OPTIONAL + IN BOOLEAN *NewSendGUID, OPTIONAL + IN UINT8 *NewTTL, OPTIONAL + IN UINT8 *NewToS, OPTIONAL + IN BOOLEAN *NewMakeCallback OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL + IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS) ( + IN struct _EFI_PXE_BASE_CODE *This, + BOOLEAN *NewDhcpDiscoverValid, OPTIONAL + BOOLEAN *NewDhcpAckReceived, OPTIONAL + BOOLEAN *NewProxyOfferReceived, OPTIONAL + BOOLEAN *NewPxeDiscoverValid, OPTIONAL + BOOLEAN *NewPxeReplyReceived, OPTIONAL + BOOLEAN *NewPxeBisReplyReceived,OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL + ); + +/* + * PXE Base Code Protocol structure + */ + +#define EFI_PXE_BASE_CODE_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_PXE_BASE_CODE { + UINT64 Revision; + EFI_PXE_BASE_CODE_START Start; + EFI_PXE_BASE_CODE_STOP Stop; + EFI_PXE_BASE_CODE_DHCP Dhcp; + EFI_PXE_BASE_CODE_DISCOVER Discover; + EFI_PXE_BASE_CODE_MTFTP Mtftp; + EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite; + EFI_PXE_BASE_CODE_UDP_READ UdpRead; + EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter; + EFI_PXE_BASE_CODE_ARP Arp; + EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters; + EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp; + EFI_PXE_BASE_CODE_SET_PACKETS SetPackets; + EFI_PXE_BASE_CODE_MODE *Mode; +} EFI_PXE_BASE_CODE; + +/* + * Call Back Definitions + */ + +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL \ + { 0x245dca21, 0xfb7b, 0x11d3, 0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +/* + * Revision Number + */ + +#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_PXE_BASE_CODE_CALLBACK); + +typedef enum { + EFI_PXE_BASE_CODE_FUNCTION_FIRST, + EFI_PXE_BASE_CODE_FUNCTION_DHCP, + EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, + EFI_PXE_BASE_CODE_FUNCTION_MTFTP, + EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, + EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, + EFI_PXE_BASE_CODE_FUNCTION_ARP, + EFI_PXE_BASE_CODE_FUNCTION_IGMP, + EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST +} EFI_PXE_BASE_CODE_FUNCTION; + +typedef enum { + EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST +} EFI_PXE_BASE_CODE_CALLBACK_STATUS; + +typedef +EFI_PXE_BASE_CODE_CALLBACK_STATUS +(EFIAPI *EFI_PXE_CALLBACK) ( + IN struct _EFI_PXE_BASE_CODE_CALLBACK *This, + IN EFI_PXE_BASE_CODE_FUNCTION Function, + IN BOOLEAN Received, + IN UINT32 PacketLen, + IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL + ); + +typedef struct _EFI_PXE_BASE_CODE_CALLBACK { + UINT64 Revision; + EFI_PXE_CALLBACK Callback; +} EFI_PXE_BASE_CODE_CALLBACK; + +#endif /* _EFIPXEBC_H */ diff --git a/sys/boot/efi/include/efiser.h b/sys/boot/efi/include/efiser.h new file mode 100644 index 0000000..e2d63bd --- /dev/null +++ b/sys/boot/efi/include/efiser.h @@ -0,0 +1,132 @@ +/* $FreeBSD$ */ +#ifndef _EFI_SER_H +#define _EFI_SER_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiser.h + +Abstract: + + EFI serial protocol + +Revision History + +--*/ + +/* + * Serial protocol + */ + +#define SERIAL_IO_PROTOCOL \ + { 0xBB25CF6F, 0xF1D4, 0x11D2, 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } + +INTERFACE_DECL(_SERIAL_IO_INTERFACE); + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} EFI_PARITY_TYPE; + +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} EFI_STOP_BITS_TYPE; + +#define EFI_SERIAL_CLEAR_TO_SEND 0x0010 +#define EFI_SERIAL_DATA_SET_READY 0x0020 +#define EFI_SERIAL_RING_INDICATE 0x0040 +#define EFI_SERIAL_CARRIER_DETECT 0x0080 +#define EFI_SERIAL_REQUEST_TO_SEND 0x0002 +#define EFI_SERIAL_DATA_TERMINAL_READY 0x0001 +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x0100 +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x0200 +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x1000 +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x2000 +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x4000 + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_RESET) ( + IN struct _SERIAL_IO_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN UINT32 Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS) ( + IN struct _SERIAL_IO_INTERFACE *This, + OUT UINT32 *Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_WRITE) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_READ) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef struct { + UINT32 ControlMask; + + /* current Attributes. */ + UINT32 Timeout; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + UINT32 DataBits; + UINT32 Parity; + UINT32 StopBits; +} SERIAL_IO_MODE; + +#define SERIAL_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _SERIAL_IO_INTERFACE { + UINT32 Revision; + EFI_SERIAL_RESET Reset; + EFI_SERIAL_SET_ATTRIBUTES SetAttributes; + EFI_SERIAL_SET_CONTROL_BITS SetControl; + EFI_SERIAL_GET_CONTROL_BITS GetControl; + EFI_SERIAL_WRITE Write; + EFI_SERIAL_READ Read; + + SERIAL_IO_MODE *Mode; +} SERIAL_IO_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efistdarg.h b/sys/boot/efi/include/efistdarg.h new file mode 100644 index 0000000..68c2221 --- /dev/null +++ b/sys/boot/efi/include/efistdarg.h @@ -0,0 +1,32 @@ +/* $FreeBSD$ */ +#ifndef _EFISTDARG_H_ +#define _EFISTDARG_H_ + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(UINTN) - 1) & ~(sizeof(UINTN) - 1) ) + +typedef CHAR8 * va_list; + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + + +#endif /* _INC_STDARG */ diff --git a/sys/boot/efi/include/i386/efibind.h b/sys/boot/efi/include/i386/efibind.h new file mode 100644 index 0000000..5c19495 --- /dev/null +++ b/sys/boot/efi/include/i386/efibind.h @@ -0,0 +1,249 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + + +/* + * Basic int types of various widths + */ + +#if (__STDC_VERSION__ < 199901L ) + +/* No ANSI C 1999/2000 stdint.h integer width declarations */ + + #if _MSC_EXTENSIONS + +/* Use Microsoft C compiler integer width declarations */ + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + #ifdef UNIX_LP64 + +/* Use LP64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + +/* Assume P64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + #endif +#endif + +/* + * Basic EFI types of various widths + */ + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + + +#undef VOID +#define VOID void + + +typedef int32_t INTN; +typedef uint32_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x80000000 | a) +#define EFI_ERROR_MASK 0x80000000 +#define EFIERR_OEM(a) (0xc0000000 | a) + + +#define BAD_POINTER 0xFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFF + +#ifdef EFI_NT_EMULATOR + #define BREAKPOINT() __asm { int 3 } +#else + #define BREAKPOINT() while (TRUE); +#endif + +/* + * Pointers must be aligned to these address to function + */ + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +/* + * Define macros to build data structure signatures from characters. + */ + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +/* + * To export & import functions in the EFI emulator environment + */ + +#if EFI_NT_EMULATOR + #define EXPORTAPI __declspec( dllexport ) +#else + #define EXPORTAPI +#endif + + +/* + * EFIAPI - prototype calling convention for EFI function pointers + * BOOTSERVICE - prototype for implementation of a boot service interface + * RUNTIMESERVICE - prototype for implementation of a runtime service interface + * RUNTIMEFUNCTION - prototype for implementation of a runtime function that + * is not a service + * RUNTIME_CODE - pragma macro for declaring runtime code + */ + +/* Forces EFI calling conventions reguardless of compiler options */ +#ifndef EFIAPI + #if _MSC_EXTENSIONS + #define EFIAPI __cdecl + #else + #define EFIAPI + #endif +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NT_EMULATOR + +/* + * To help ensure proper coding of integrated drivers, they are + * compiled as DLLs. In NT they require a dll init entry pointer. + * The macro puts a stub entry point into the DLL so it will load. + */ + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + EXPORTAPI \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else /* EFI_NT_EMULATOR */ + +/* + * When build similiar to FW, then link everything together as + * one big module. + */ + + #define EFI_DRIVER_ENTRY_POINT(InitFunction) + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif /* EFI_FW_NT */ + +/* + * Some compilers don't support the forward reference construct: + * typedef struct XXXXX + * + * The following macro provide a workaround for such cases. + */ +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#define INTERFACE_DECL(x) typedef struct x +#endif + +#if _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) +#endif + diff --git a/sys/boot/efi/include/i386/pe.h b/sys/boot/efi/include/i386/pe.h new file mode 100644 index 0000000..1120464 --- /dev/null +++ b/sys/boot/efi/include/i386/pe.h @@ -0,0 +1,592 @@ +/* $FreeBSD$ */ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + + // + // NT additional fields. + // + + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Reserved1; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!<arch>\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 *AddressOfFunctions; + UINT32 *AddressOfNames; + UINT32 *AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/sys/boot/efi/include/ia64/efibind.h b/sys/boot/efi/include/ia64/efibind.h new file mode 100644 index 0000000..73f3469 --- /dev/null +++ b/sys/boot/efi/include/ia64/efibind.h @@ -0,0 +1,150 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + +#include <sys/stdint.h> + +/* Basic EFI types of various widths. */ + +typedef uint64_t UINT64; +typedef int64_t INT64; +typedef uint32_t UINT32; +typedef int32_t INT32; +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + + +#undef VOID +#define VOID void + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +/* + *XXX BugBug: Code to debug + */ +#define BIT63 0x8000000000000000 + +#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) +#define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) ) + +/* Macro's with casts make this much easier to use and read. */ +#define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port))) +#define POST_CODE(_Data) (PORT_TO_MEM8D(0x80) = (_Data)) + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE) + +/* + * Pointers must be aligned to these address to function + * you will get an alignment fault if this value is less than 8 + */ +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value , Adjustment) \ + (UINTN) Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + +/* + * Define macros to create data structure signatures. + */ + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +/* + * To export & import functions in the EFI emulator environment + */ + +#define EXPORTAPI + +/* + * EFIAPI - prototype calling convention for EFI function pointers + * BOOTSERVICE - prototype for implementation of a boot service interface + * RUNTIMESERVICE - prototype for implementation of a runtime service interface + * RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service + * RUNTIME_CODE - pragma macro for declaring runtime code + */ + +#ifndef EFIAPI /* Forces EFI calling conventions reguardless of compiler options */ +#if _MSC_EXTENSIONS +#define EFIAPI __cdecl +#else +#define EFIAPI +#endif +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +/* + * XXX Need to find out if this is portable accross compliers. + */ +void __mf (void); +#ifndef __GNUC__ +#pragma intrinsic (__mf) +#endif +#define MEMORY_FENCE() __mf() + +/* + * When build similiar to FW, then link everything together as + * one big module. + */ + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +/* + * Some compilers don't support the forward reference construct: + * typedef struct XXXXX + * + * The following macro provide a workaround for such cases. + */ +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#ifdef __GNUC__ +#define INTERFACE_DECL(x) struct x +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif diff --git a/sys/boot/efi/include/ia64/pe.h b/sys/boot/efi/include/ia64/pe.h new file mode 100644 index 0000000..59839d2 --- /dev/null +++ b/sys/boot/efi/include/ia64/pe.h @@ -0,0 +1,598 @@ +/* $FreeBSD$ */ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + +/***************************************************************************** + * The following stuff comes from winnt.h from the ia64sdk, plus the Plabel for + * loading EM executables. + *****************************************************************************/ +// +// Intel IA64 specific +// + +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_IA64_DIR64 10 + +struct Plabel { + UINT64 EntryPoint; + UINT64 NewGP; +}; + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +typedef struct _IMAGE_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + // UINT32 BaseOfData; + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 244 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!<arch>\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile new file mode 100644 index 0000000..bd8e034 --- /dev/null +++ b/sys/boot/efi/libefi/Makefile @@ -0,0 +1,39 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../${MACHINE_ARCH}/${MACHINE_ARCH} + +LIB= efi +INTERNALLIB= true + +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" +SRCS+= efifpswa.c +.endif + +CFLAGS+= -ffreestanding -fpic +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ + +# Pick up the bootstrap header for some interface items +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. + +.if ${MACHINE_ARCH} == "powerpc" +CFLAGS+= -msoft-float +.endif + +.ifdef(BOOT_DISK_DEBUG) +# Make the disk code more talkative +CFLAGS+= -DDISK_DEBUG +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +CLEANFILES+= machine + +.include <bsd.lib.mk> + +beforedepend ${OBJS}: machine diff --git a/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 b/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 new file mode 100644 index 0000000..002c263 --- /dev/null +++ b/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 @@ -0,0 +1,73 @@ +/* $FreeBSD$ */ +OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start_plabel) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + ImageBase = .; + . = SIZEOF_HEADERS; + . = ALIGN(4096); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) + *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.IA_64.pltoff) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : { + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.plt) + *(.rela.IA_64.pltoff) + *(.relaset_*) + *(.rela.dyn .rela.dyn.*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } +} diff --git a/sys/boot/efi/libefi/arch/ia64/start.S b/sys/boot/efi/libefi/arch/ia64/start.S new file mode 100644 index 0000000..643f1c9 --- /dev/null +++ b/sys/boot/efi/libefi/arch/ia64/start.S @@ -0,0 +1,305 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + + .text + +#include <machine/asm.h> + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR 1 +#define EFI_BUFFER_TOO_SMALL 5 + +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ + +#define DT_COUNT 24 /* Number of defined d_tag values. */ + +#define R_IA64_NONE 0 /* None */ +#define R_IA64_DIR64MSB 0x26 /* word64 MSB S + A */ +#define R_IA64_DIR64LSB 0x27 /* word64 LSB S + A */ +#define R_IA64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ +#define R_IA64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ +#define R_IA64_REL64MSB 0x6e /* word64 MSB BD + A */ +#define R_IA64_REL64LSB 0x6f /* word64 LSB BD + A */ +#define R_IA64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ + +ENTRY(_start, 2) + alloc loc0=ar.pfs,2,3,3,0 + mov loc1=rp + movl loc2=@gprel(ImageBase) + ;; + add loc2=gp,loc2 + ;; + mov out0=loc2 + mov out1=in1 + ;; + br.call.sptk.few rp=_reloc // relocate image + + cmp.ne p6,p0=EFI_SUCCESS,r8 // did it work? +(p6) br.cond.dpnt.few 9f + + mov out0=in0 // image_handle + mov out1=in1 // system_table + br.call.sptk.few rp=efi_main +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_start) + + // PLABEL for PE32+ + .global _start_plabel + .section .plabel, "a" + .align 16 +_start_plabel: + .quad _start + .quad __gp + .previous + + // A PE32+ relocation entry for the plabel + + .section .reloc, "a" + .long _start_plabel + .long 12 + .short (10 << 12) + 0 + .short (10 << 12) + 8 + .previous + +// in0: image base +// in1: system table +// +// XXX Assumes PLT relocations are of type Elf_Rela +// +// r2 = address of fptr_storage +// r3 = address of fptr_storage_end +// r4 = address of first free fptr +// +// r15 = r_offset +// r16 = r_info -OR- d_tag +// r17 = r_addend -OR- d_val (=d_ptr) +// r18 = address of .rela dynamic section +// r19 = size of .rela section +// r20 = size of .rela element (Elf_Rela) +// r21 = address of first PLT relocation +// r22 = size of PLT relocations +// r23 = relocation type +// r24 = address of symbol +// r28 = R_IA64_IPLTLSB +// f8 = address of symbol table +// f9 = size of symtab element + +STATIC_ENTRY(_reloc, 2) + alloc loc0=ar.pfs,2,2,0,0 + ;; + mov loc1=rp + movl r29=@gprel(_DYNAMIC) // find _DYNAMIC etc. + ;; + add r15=r29,gp + movl r29=@gprel(fptr_storage) + ;; + add r2=r29,gp + movl r29=@gprel(fptr_storage_end) + ;; + add r3=r29,gp + mov r4=r2 + mov r19=0 + mov r22=0 + mov r20=24 + mov r28=R_IA64_IPLTLSB + ;; +1: + ld8 r16=[r15],8 // read r15->d_tag + ;; + ld8 r17=[r15],8 // and r15->d_val + ;; + cmp.eq p6,p0=DT_NULL,r16 // done? +(p6) br.cond.dpnt.few 2f + ;; + cmp.eq p6,p0=DT_RELA,r16 // rela section? + ;; +(p6) add r18=r17,in0 + cmp.eq p6,p0=DT_RELASZ,r16 // rela section size? + ;; +(p6) mov r19=r17 + cmp.eq p6,p0=DT_RELAENT,r16 // rela entry size? + ;; +(p6) mov r20=r17 + cmp.eq p6,p0=DT_JMPREL,r16 // PLT relocs? + ;; +(p6) add r21=r17,in0 + cmp.eq p6,p0=DT_PLTRELSZ,r16 // PLT relocs size? + ;; +(p6) mov r22=r17 + cmp.eq p6,p0=DT_SYMTAB,r16 // symbol table? + ;; +(p6) add r29=r17,in0 + ;; +(p6) setf.sig f8=r29 + cmp.eq p6,p0=DT_SYMENT,r16 // symbol entry size? + ;; +(p6) setf.sig f9=r17 + br.dptk 1b + +2: + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r19=r22 + mov r18=r21 + mov r21=0 + mov r22=0 + ;; + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r8=EFI_SUCCESS + br.dptk 9f +3: + ld8 r29=[r18],8 // read r_offset + ;; + ld8 r16=[r18],8 // read r_info + add r15=r29,in0 // relocate r_offset + ;; + ld8 r17=[r18],8 // read r_addend + sub r19=r19,r20 // update relasz + extr.u r23=r16,0,32 // ELF64_R_TYPE(r16) + ;; + cmp.eq p6,p0=R_IA64_NONE,r23 +(p6) br.cond.dpnt.few 2b + ;; + cmp.eq p6,p0=R_IA64_REL64LSB,r23 +(p6) br.cond.dptk.few 4f + ;; + extr.u r29=r16,32,32 // ELF64_R_SYM(r16) + ;; + setf.sig f10=r29 // so we can multiply + ;; + xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment + ;; + getf.sig r29=f10 + ;; + add r29=8,r29 // address of st_value + ;; + ld8 r29=[r29] // read symbol value + ;; + add r24=r29,in0 // relocate symbol value + ;; + cmp.eq p6,p0=R_IA64_DIR64LSB,r23 +(p6) br.cond.dptk.few 5f + ;; + cmp.eq p6,p0=R_IA64_FPTR64LSB,r23 +(p6) br.cond.dptk.few 6f + ;; + cmp.ne p6,p0=r28,r23 // IPLTLSB +(p6) br.cond.dptk.few 2b + + // IPLTLSB + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29,8 // fdesc:FP + ;; + st8 [r15]=gp // fdesc:GP + br.cond.sptk.few 2b + + // REL64LSB +4: + add r29=in0,r17 // BD + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + + // DIR64LSB +5: + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + +6: + mov r29=r2 // FPTR64LSB + ;; +7: + cmp.geu p6,p0=r29,r4 // end of fptrs? +(p6) br.cond.dpnt.few 8f // can't find existing fptr + ld8 r17=[r29] // read function from fptr + ;; + cmp.eq p6,p0=r24,r17 // same function? + ;; +(p6) st8 [r15]=r29 // reuse fptr +(p6) br.cond.sptk.few 2b // done + add r29=16,r29 // next fptr + br.sptk.few 7b +8: + mov r8=EFI_BUFFER_TOO_SMALL // failure return value + cmp.geu p6,p0=r4,r3 // space left? +(p6) br.cond.dpnt.few 9f // bail out + st8 [r15]=r4 // install fptr + ;; + st8 [r4]=r24,8 // write fptr address + ;; + st8 [r4]=gp,8 // write fptr gp + br.cond.sptk.few 2b + +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_reloc) + + .data + .align 16 +fptr_storage: + .space 1024*16 // XXX +fptr_storage_end: diff --git a/sys/boot/efi/libefi/bootinfo.c b/sys/boot/efi/libefi/bootinfo.c new file mode 100644 index 0000000..076aed1 --- /dev/null +++ b/sys/boot/efi/libefi/bootinfo.c @@ -0,0 +1,348 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include <string.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +static EFI_GUID hcdp = HCDP_TABLE_GUID; + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_userconfig", RB_CONFIG}, + {"boot_ddb", RB_KDB}, + {"boot_gdb", RB_GDB}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, + {NULL, 0} +}; + +extern char *efi_fmtdev(void *vdev); + +int +bi_getboothowto(char *kargs) +{ + char *cp; + int howto; + int active; + int i; + + /* Parse kargs */ + howto = 0; + if (kargs != NULL) { + cp = kargs; + active = 0; + while (*cp != 0) { + if (!active && (*cp == '-')) { + active = 1; + } else if (active) + switch (*cp) { + case 'a': + howto |= RB_ASKNAME; + break; + case 'c': + howto |= RB_CONFIG; + break; + case 'C': + howto |= RB_CDROM; + break; + case 'd': + howto |= RB_KDB; + break; + case 'D': + howto |= RB_MULTIPLE; + break; + case 'm': + howto |= RB_MUTE; + break; + case 'g': + howto |= RB_GDB; + break; + case 'h': + howto |= RB_SERIAL; + break; + case 'r': + howto |= RB_DFLTROOT; + break; + case 's': + howto |= RB_SINGLE; + break; + case 'v': + howto |= RB_VERBOSE; + break; + default: + active = 0; + break; + } + cp++; + } + } + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + if (!strcmp(getenv("console"), "comconsole")) + howto |= RB_SERIAL; + if (!strcmp(getenv("console"), "nullconsole")) + howto |= RB_MUTE; + return(howto); +} + +/* + * Copy the environment into the load area starting at (addr). + * Each variable is formatted as <name>=<value>, with a single nul + * separating each variable, and a double nul terminating the environment. + */ +vm_offset_t +bi_copyenv(vm_offset_t addr) +{ + struct env_var *ep; + + /* traverse the environment */ + for (ep = environ; ep != NULL; ep = ep->ev_next) { + efi_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + addr += strlen(ep->ev_name); + efi_copyin("=", addr, 1); + addr++; + if (ep->ev_value != NULL) { + efi_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + addr += strlen(ep->ev_value); + } + efi_copyin("", addr, 1); + addr++; + } + efi_copyin("", addr, 1); + addr++; + return(addr); +} + +/* + * Copy module-related data into the load area, where it can be + * used as a directory for loaded modules. + * + * Module data is presented in a self-describing format. Each datum + * is preceded by a 32-bit identifier and a 32-bit size field. + * + * Currently, the following data are saved: + * + * MOD_NAME (variable) module name (string) + * MOD_TYPE (variable) module type (string) + * MOD_ARGS (variable) module parameters (string) + * MOD_ADDR sizeof(vm_offset_t) module load address + * MOD_SIZE sizeof(size_t) module size + * MOD_METADATA (variable) type-specific metadata + */ +#define COPY32(v, a) { \ + u_int32_t x = (v); \ + efi_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s) { \ + COPY32(t, a); \ + COPY32(strlen(s) + 1, a); \ + efi_copyin(s, a, strlen(s) + 1); \ + a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ +} + +#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) +#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) +#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) + +#define MOD_VAR(t, a, s) { \ + COPY32(t, a); \ + COPY32(sizeof(s), a); \ + efi_copyin(&s, a, sizeof(s)); \ + a += roundup(sizeof(s), sizeof(u_int64_t)); \ +} + +#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) +#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) + +#define MOD_METADATA(a, mm) { \ + COPY32(MODINFO_METADATA | mm->md_type, a); \ + COPY32(mm->md_size, a); \ + efi_copyin(mm->md_data, a, mm->md_size); \ + a += roundup(mm->md_size, sizeof(u_int64_t));\ +} + +#define MOD_END(a) { \ + COPY32(MODINFO_END, a); \ + COPY32(0, a); \ +} + +vm_offset_t +bi_copymodules(vm_offset_t addr) +{ + struct preloaded_file *fp; + struct file_metadata *md; + + /* start with the first module on the list, should be the kernel */ + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { + + MOD_NAME(addr, fp->f_name); /* this field must come first */ + MOD_TYPE(addr, fp->f_type); + if (fp->f_args) + MOD_ARGS(addr, fp->f_args); + MOD_ADDR(addr, fp->f_addr); + MOD_SIZE(addr, fp->f_size); + for (md = fp->f_metadata; md != NULL; md = md->md_next) + if (!(md->md_type & MODINFOMD_NOCOPY)) + MOD_METADATA(addr, md); + } + MOD_END(addr); + return(addr); +} + +/* + * Load the information expected by an alpha kernel. + * + * - The kernel environment is copied into kernel space. + * - Module metadata are formatted and placed in kernel space. + */ +int +bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey, + UINTN pages) +{ + char *rootdevname; + struct efi_devdesc *rootdev; + struct preloaded_file *xp; + vm_offset_t addr, bootinfo_addr; + vm_offset_t ssym, esym; + struct file_metadata *md; + EFI_STATUS status; + UINTN bisz, key; + + /* + * Version 1 bootinfo. + */ + bi->bi_magic = BOOTINFO_MAGIC; + bi->bi_version = 1; + + /* + * Calculate boothowto. + */ + bi->bi_boothowto = bi_getboothowto(fp->f_args); + + /* + * Stash EFI System Table. + */ + bi->bi_systab = (u_int64_t) ST; + + /* + * Allow the environment variable 'rootdev' to override the supplied + * device. This should perhaps go to MI code and/or have $rootdev + * tested/set by MI code before launching the kernel. + */ + rootdevname = getenv("rootdev"); + efi_getdev((void **)(&rootdev), rootdevname, NULL); + if (rootdev == NULL) { /* bad $rootdev/$currdev */ + printf("can't determine root device\n"); + return(EINVAL); + } + + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(efi_fmtdev((void *)rootdev)); + free(rootdev); + + ssym = esym = 0; + if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) + ssym = *((vm_offset_t *)&(md->md_data)); + if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) + esym = *((vm_offset_t *)&(md->md_data)); + if (ssym == 0 || esym == 0) + ssym = esym = 0; /* sanity */ + + bi->bi_symtab = ssym; + bi->bi_esymtab = esym; + + bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp); /* DIG64 HCDP table addr. */ + fpswa_init(&bi->bi_fpswa); /* find FPSWA interface */ + + /* find the last module in the chain */ + addr = 0; + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; + } + + /* pad to a page boundary */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy our environment */ + bi->bi_envp = addr; + addr = bi_copyenv(addr); + + /* pad to a page boundary */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy module list and metadata */ + bi->bi_modulep = addr; + addr = bi_copymodules(addr); + + /* all done copying stuff in, save end of loaded object space */ + bi->bi_kernend = addr; + + /* + * Read the memory map and stash it after bootinfo. Align the memory map + * on a 16-byte boundary (the bootinfo block is page aligned). + */ + bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f; + bi->bi_memmap = ((u_int64_t)bi) + bisz; + bi->bi_memmap_size = EFI_PAGE_SIZE * pages - bisz; + status = BS->GetMemoryMap(&bi->bi_memmap_size, + (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap, &key, + &bi->bi_memdesc_size, &bi->bi_memdesc_version); + if (EFI_ERROR(status)) { + printf("bi_load: Can't read memory map\n"); + return EINVAL; + } + *mapkey = key; + + return(0); +} diff --git a/sys/boot/efi/libefi/copy.c b/sys/boot/efi/libefi/copy.c new file mode 100644 index 0000000..7bc4edf --- /dev/null +++ b/sys/boot/efi/libefi/copy.c @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * MD primitives supporting placement of module data + */ +#include <stand.h> + +#include <efi.h> +#include <efilib.h> +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +int +efi_copyin(void *src, vm_offset_t dest, size_t len) +{ + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + bcopy(src, (void*) p, len); + return (len); +} + +int +efi_copyout(vm_offset_t src, void *dest, size_t len) +{ + bcopy((void*) IA64_RR_MASK(src), dest, len); + return (len); +} + +int +efi_readin(int fd, vm_offset_t dest, size_t len) +{ + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + return (read(fd, (void*) p, len)); +} diff --git a/sys/boot/efi/libefi/delay.c b/sys/boot/efi/libefi/delay.c new file mode 100644 index 0000000..723f681 --- /dev/null +++ b/sys/boot/efi/libefi/delay.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> + +void +delay(int usecs) +{ + static EFI_EVENT ev = 0; + UINTN junk; + + if (!ev) { + if (BS->CreateEvent(EVT_TIMER, TPL_APPLICATION, 0, 0, &ev) + != EFI_SUCCESS) + return; + } + + BS->SetTimer(ev, TimerRelative, usecs * 10); + BS->WaitForEvent(1, &ev, &junk); +} diff --git a/sys/boot/efi/libefi/devicename.c b/sys/boot/efi/libefi/devicename.c new file mode 100644 index 0000000..dda2fb0 --- /dev/null +++ b/sys/boot/efi/libefi/devicename.c @@ -0,0 +1,240 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include <string.h> +#include <sys/disklabel.h> +#include "bootstrap.h" + +#include <efi.h> +#include <efilib.h> +#include "efiboot.h" + +static int efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +efi_getdev(void **vdev, const char *devspec, const char **path) +{ + struct efi_devdesc **dev = (struct efi_devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no + * device, go with the current device. + */ + if ((devspec == NULL) || + (devspec[0] == '/') || + (strchr(devspec, ':') == NULL)) { + + if (((rv = efi_parsedev(dev, getenv("currdev"), NULL)) == 0) && + (path != NULL)) + *path = devspec; + return(rv); + } + + /* + * Try to parse the device name off the beginning of the devspec + */ + return(efi_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + * + * In all cases, the beginning of (devspec) is compared to the names + * of known devices in the device switch, and then any following text + * is parsed according to the rules applied to the device type. + * + * For disk-type devices, the syntax is: + * + * disk<unit>[s<slice>][<partition>]: + * + */ +static int +efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path) +{ + struct efi_devdesc *idev; + struct devsw *dv; + int i, unit, slice, partition, err; + char *cp; + const char *np; + + /* minimum length check */ + if (strlen(devspec) < 2) + return(EINVAL); + + /* look for a device that matches */ + for (i = 0, dv = NULL; devsw[i] != NULL; i++) { + if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) { + dv = devsw[i]; + break; + } + } + + if (dv == NULL) + return(ENOENT); + idev = malloc(sizeof(struct efi_devdesc)); + err = 0; + np = (devspec + strlen(dv->dv_name)); + + switch(dv->dv_type) { + case DEVT_NONE: /* XXX what to do here? Do we care? */ + break; + + case DEVT_DISK: + unit = -1; + slice = -1; + partition = -1; + if (*np && (*np != ':')) { + unit = strtol(np, &cp, 10); /* next comes the unit number */ + if (cp == np) { + err = EUNIT; + goto fail; + } + if (*cp == 's') { /* got a slice number */ + np = cp + 1; + slice = strtol(np, &cp, 10); + if (cp == np) { + err = ESLICE; + goto fail; + } + } + if (*cp && (*cp != ':')) { + partition = *cp - 'a'; /* get a partition number */ + if ((partition < 0) || (partition >= MAXPARTITIONS)) { + err = EPART; + goto fail; + } + cp++; + } + } + if (*cp && (*cp != ':')) { + err = EINVAL; + goto fail; + } + + idev->d_kind.efidisk.unit = unit; + idev->d_kind.efidisk.slice = slice; + idev->d_kind.efidisk.partition = partition; + + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + break; + + case DEVT_NET: + unit = 0; + + if (*np && (*np != ':')) { + unit = strtol(np, &cp, 0); /* get unit number if present */ + if (cp == np) { + err = EUNIT; + goto fail; + } + } + if (*cp && (*cp != ':')) { + err = EINVAL; + goto fail; + } + + idev->d_kind.netif.unit = unit; + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + break; + + default: + err = EINVAL; + goto fail; + } + idev->d_dev = dv; + idev->d_type = dv->dv_type; + if (dev == NULL) { + free(idev); + } else { + *dev = idev; + } + return(0); + + fail: + free(idev); + return(err); +} + + +char * +efi_fmtdev(void *vdev) +{ + struct efi_devdesc *dev = (struct efi_devdesc *)vdev; + static char buf[128]; /* XXX device length constant? */ + char *cp; + + switch(dev->d_type) { + case DEVT_NONE: + strcpy(buf, "(no device)"); + break; + + case DEVT_DISK: + cp = buf; + cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_kind.efidisk.unit); + if (dev->d_kind.efidisk.slice > 0) + cp += sprintf(cp, "s%d", dev->d_kind.efidisk.slice); + if (dev->d_kind.efidisk.partition >= 0) + cp += sprintf(cp, "%c", dev->d_kind.efidisk.partition + 'a'); + strcat(cp, ":"); + break; + + case DEVT_NET: + sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_kind.netif.unit); + break; + } + return(buf); +} + + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +efi_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct efi_devdesc *ncurr; + int rv; + + if ((rv = efi_parsedev(&ncurr, value, NULL)) != 0) + return(rv); + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return(0); +} + diff --git a/sys/boot/efi/libefi/efi_console.c b/sys/boot/efi/libefi/efi_console.c new file mode 100644 index 0000000..c88462e --- /dev/null +++ b/sys/boot/efi/libefi/efi_console.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +static SIMPLE_TEXT_OUTPUT_INTERFACE *conout; +static SIMPLE_INPUT_INTERFACE *conin; + +static void +efi_cons_probe(struct console *cp) +{ + conout = ST->ConOut; + conin = ST->ConIn; + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +efi_cons_init(int arg) +{ + return 0; +} + +void +efi_cons_putchar(int c) +{ + CHAR16 buf[2]; + + if (c == '\n') + efi_cons_putchar('\r'); + + buf[0] = c; + buf[1] = 0; + + conout->OutputString(conout, buf); +} + +int +efi_cons_getchar() +{ + EFI_INPUT_KEY key; + EFI_STATUS status; + UINTN junk; + + /* Try to read a key stroke. We wait for one if none is pending. */ + status = conin->ReadKeyStroke(conin, &key); + if (status == EFI_NOT_READY) { + BS->WaitForEvent(1, &conin->WaitForKey, &junk); + status = conin->ReadKeyStroke(conin, &key); + } + return (key.UnicodeChar); +} + +int +efi_cons_poll() +{ + /* This can clear the signaled state. */ + return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS); +} + +struct console efi_console = { + "efi", + "EFI console", + 0, + efi_cons_probe, + efi_cons_init, + efi_cons_putchar, + efi_cons_getchar, + efi_cons_poll +}; diff --git a/sys/boot/efi/libefi/efiboot.h b/sys/boot/efi/libefi/efiboot.h new file mode 100644 index 0000000..18af3f4 --- /dev/null +++ b/sys/boot/efi/libefi/efiboot.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1996 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Matthias Drochner. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * EFI fully-qualified device descriptor + */ +struct efi_devdesc { + struct devsw *d_dev; + int d_type; +#define DEVT_NONE 0 +#define DEVT_DISK 1 +#define DEVT_NET 2 + EFI_HANDLE d_handle; + union { + struct { + int unit; + int slice; + int partition; + } efidisk; + struct { + int unit; /* XXX net layer lives over these? */ + } netif; + } d_kind; +}; + +extern int efi_getdev(void **vdev, const char *devspec, const char **path); +extern char *efi_fmtdev(void *vdev); +extern int efi_setcurrdev(struct env_var *ev, int flags, void *value); + +#define MAXDEV 31 /* maximum number of distinct devices */ + +typedef unsigned long physaddr_t; + +/* exported devices XXX rename? */ +extern struct devsw efifs_dev; +extern struct devsw efi_disk; +extern struct netif_driver efi_net; + +/* Find EFI network resources */ +extern void efinet_init_driver(void); + +/* Map handles to units */ +int efifs_get_unit(EFI_HANDLE); + +/* Wrapper over EFI filesystems. */ +extern struct fs_ops efi_fsops; + +/* this is in startup code */ +extern void delay(int); +extern void reboot(void); + +extern ssize_t efi_copyin(const void *src, vm_offset_t dest, size_t len); +extern ssize_t efi_copyout(const vm_offset_t src, void *dest, size_t len); +extern ssize_t efi_readin(int fd, vm_offset_t dest, size_t len); + +extern int efi_boot(void); +extern int efi_autoload(void); + +extern int fpswa_init(u_int64_t *fpswa_interface); + +struct bootinfo; +struct preloaded_file; +extern int bi_load(struct bootinfo *, struct preloaded_file *, + UINTN *mapkey, UINTN pages); diff --git a/sys/boot/efi/libefi/efifpswa.c b/sys/boot/efi/libefi/efifpswa.c new file mode 100644 index 0000000..b3bff92 --- /dev/null +++ b/sys/boot/efi/libefi/efifpswa.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2001 Peter Wemm <peter@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include <efi.h> +#include <efilib.h> +#include "efiboot.h" + +int +fpswa_init(u_int64_t *fpswa_interface) +{ + EFI_STATUS status; + static EFI_GUID fpswaid = EFI_INTEL_FPSWA; + UINTN sz; + EFI_HANDLE fpswa_handle; + FPSWA_INTERFACE *fpswa; + + *fpswa_interface = 0; + sz = sizeof(EFI_HANDLE); + status = BS->LocateHandle(ByProtocol, &fpswaid, 0, &sz, &fpswa_handle); + if (EFI_ERROR(status)) + return ENOENT; + + status = BS->HandleProtocol(fpswa_handle, &fpswaid, (VOID **)&fpswa); + if (EFI_ERROR(status)) + return ENOENT; + *fpswa_interface = (u_int64_t)fpswa; + return 0; +} diff --git a/sys/boot/efi/libefi/efifs.c b/sys/boot/efi/libefi/efifs.c new file mode 100644 index 0000000..cf89a9d --- /dev/null +++ b/sys/boot/efi/libefi/efifs.c @@ -0,0 +1,401 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include <efi.h> +#include <efilib.h> +#include "efiboot.h" + +/* Perform I/O in blocks of size EFI_BLOCK_SIZE. */ +#define EFI_BLOCK_SIZE (1024 * 1024) + +static int +efifs_open(const char *upath, struct open_file *f) +{ + struct efi_devdesc *dev = f->f_devdata; + static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL; + EFI_FILE_IO_INTERFACE *sfs; + EFI_FILE *root; + EFI_FILE *file; + EFI_STATUS status; + CHAR16 *cp; + CHAR16 *path; + + /* + * We cannot blindly assume that f->f_devdata points to a + * efi_devdesc structure. Before we dereference 'dev', make + * sure that the underlying device is ours. + */ + if (f->f_dev != &efifs_dev || dev->d_handle == NULL) + return ENOENT; + + status = BS->HandleProtocol(dev->d_handle, &sfsid, (VOID **)&sfs); + if (EFI_ERROR(status)) + return ENOENT; + + /* + * Find the root directory. + */ + status = sfs->OpenVolume(sfs, &root); + + /* + * Convert path to CHAR16, skipping leading separators. + */ + while (*upath == '/') + upath++; + if (!*upath) { + /* Opening the root directory, */ + f->f_fsdata = root; + return 0; + } + cp = path = malloc((strlen(upath) + 1) * sizeof(CHAR16)); + if (path == NULL) + return ENOMEM; + while (*upath) { + if (*upath == '/') + *cp = '\\'; + else + *cp = *upath; + upath++; + cp++; + } + *cp++ = 0; + + /* + * Try to open it. + */ + status = root->Open(root, &file, path, EFI_FILE_MODE_READ, 0); + free(path); + if (EFI_ERROR(status)) { + root->Close(root); + return ENOENT; + } + + root->Close(root); + f->f_fsdata = file; + return 0; +} + +static int +efifs_close(struct open_file *f) +{ + EFI_FILE *file = f->f_fsdata; + + file->Close(file); + return 0; +} + +static int +efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINTN sz = size; + char *bufp; + + bufp = buf; + while (size > 0) { + sz = size; + if (sz > EFI_BLOCK_SIZE) + sz = EFI_BLOCK_SIZE; + status = file->Read(file, &sz, bufp); + twiddle(); + if (EFI_ERROR(status)) + return EIO; + if (sz == 0) + break; + size -= sz; + bufp += sz; + } + if (resid) + *resid = size; + return 0; +} + +static int +efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINTN sz = size; + char *bufp; + + bufp = buf; + while (size > 0) { + sz = size; + if (sz > EFI_BLOCK_SIZE) + sz = EFI_BLOCK_SIZE; + status = file->Write(file, &sz, bufp); + twiddle(); + if (EFI_ERROR(status)) + return EIO; + if (sz == 0) + break; + size -= sz; + bufp += sz; + } + if (resid) + *resid = size; + return 0; +} + +static off_t +efifs_seek(struct open_file *f, off_t offset, int where) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINT64 base; + UINTN sz; + static EFI_GUID infoid = EFI_FILE_INFO_ID; + EFI_FILE_INFO info; + + switch (where) { + case SEEK_SET: + base = 0; + break; + + case SEEK_CUR: + status = file->GetPosition(file, &base); + if (EFI_ERROR(status)) + return -1; + break; + + case SEEK_END: + sz = sizeof(info); + status = file->GetInfo(file, &infoid, &sz, &info); + if (EFI_ERROR(status)) + return -1; + base = info.FileSize; + break; + } + + status = file->SetPosition(file, base + offset); + if (EFI_ERROR(status)) + return -1; + file->GetPosition(file, &base); + + return base; +} + +static int +efifs_stat(struct open_file *f, struct stat *sb) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + char *buf; + UINTN sz; + static EFI_GUID infoid = EFI_FILE_INFO_ID; + EFI_FILE_INFO *info; + + bzero(sb, sizeof(*sb)); + + buf = malloc(1024); + sz = 1024; + + status = file->GetInfo(file, &infoid, &sz, buf); + if (EFI_ERROR(status)) { + free(buf); + return -1; + } + + info = (EFI_FILE_INFO *) buf; + + if (info->Attribute & EFI_FILE_READ_ONLY) + sb->st_mode = S_IRUSR; + else + sb->st_mode = S_IRUSR | S_IWUSR; + if (info->Attribute & EFI_FILE_DIRECTORY) + sb->st_mode |= S_IFDIR; + else + sb->st_mode |= S_IFREG; + sb->st_size = info->FileSize; + + free(buf); + return 0; +} + +static int +efifs_readdir(struct open_file *f, struct dirent *d) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + char *buf; + UINTN sz; + EFI_FILE_INFO *info; + int i; + + buf = malloc(1024); + sz = 1024; + + status = file->Read(file, &sz, buf); + if (EFI_ERROR(status) || sz < offsetof(EFI_FILE_INFO, FileName)) + return ENOENT; + + info = (EFI_FILE_INFO *) buf; + + d->d_fileno = 0; + d->d_reclen = sizeof(*d); + if (info->Attribute & EFI_FILE_DIRECTORY) + d->d_type = DT_DIR; + else + d->d_type = DT_REG; + d->d_namlen = ((info->Size - offsetof(EFI_FILE_INFO, FileName)) + / sizeof(CHAR16)); + for (i = 0; i < d->d_namlen; i++) + d->d_name[i] = info->FileName[i]; + d->d_name[i] = 0; + + free(buf); + return 0; +} + +struct fs_ops efi_fsops = { + "fs", + efifs_open, + efifs_close, + efifs_read, + efifs_write, + efifs_seek, + efifs_stat, + efifs_readdir +}; + +static EFI_HANDLE *fs_handles; +UINTN fs_handle_count; + +int +efifs_get_unit(EFI_HANDLE h) +{ + UINTN u; + + u = 0; + while (u < fs_handle_count && fs_handles[u] != h) + u++; + return ((u < fs_handle_count) ? u : -1); +} + +static int +efifs_dev_init(void) +{ + EFI_STATUS status; + UINTN sz; + static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL; + + sz = 0; + status = BS->LocateHandle(ByProtocol, &sfsid, 0, &sz, 0); + if (status != EFI_BUFFER_TOO_SMALL) + return ENOENT; + fs_handles = (EFI_HANDLE *) malloc(sz); + status = BS->LocateHandle(ByProtocol, &sfsid, 0, + &sz, fs_handles); + if (EFI_ERROR(status)) { + free(fs_handles); + return ENOENT; + } + fs_handle_count = sz / sizeof(EFI_HANDLE); + + return 0; +} + +/* + * Print information about disks + */ +static void +efifs_dev_print(int verbose) +{ + int i; + char line[80]; + + for (i = 0; i < fs_handle_count; i++) { + sprintf(line, " fs%d: EFI filesystem", i); + pager_output(line); + /* XXX more detail? */ + pager_output("\n"); + } +} + +/* + * Attempt to open the disk described by (dev) for use by (f). + * + * Note that the philosophy here is "give them exactly what + * they ask for". This is necessary because being too "smart" + * about what the user might want leads to complications. + * (eg. given no slice or partition value, with a disk that is + * sliced - are they after the first BSD slice, or the DOS + * slice before it?) + */ +static int +efifs_dev_open(struct open_file *f, ...) +{ + va_list args; + struct efi_devdesc *dev; + int unit; + + va_start(args, f); + dev = va_arg(args, struct efi_devdesc*); + va_end(args); + + unit = dev->d_kind.efidisk.unit; + if (unit < 0 || unit >= fs_handle_count) { + printf("attempt to open nonexistent EFI filesystem\n"); + return(ENXIO); + } + + dev->d_handle = fs_handles[unit]; + + return 0; +} + +static int +efifs_dev_close(struct open_file *f) +{ + + return 0; +} + +static int +efifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) +{ + return 0; +} + +struct devsw efifs_dev = { + "fs", + DEVT_DISK, + efifs_dev_init, + efifs_dev_strategy, + efifs_dev_open, + efifs_dev_close, + noioctl, + efifs_dev_print +}; diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c new file mode 100644 index 0000000..85814f9 --- /dev/null +++ b/sys/boot/efi/libefi/efinet.c @@ -0,0 +1,267 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> + +#include <stand.h> +#include <net.h> +#include <netif.h> + +#include <efi.h> +#include <efilib.h> + +extern struct netif_driver efi_net; + +#ifdef EFINET_DEBUG +static void +dump_mode(EFI_SIMPLE_NETWORK_MODE *mode) +{ + int i; + + printf("State = %x\n", mode->State); + printf("HwAddressSize = %u\n", mode->HwAddressSize); + printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize); + printf("MaxPacketSize = %u\n", mode->MaxPacketSize); + printf("NvRamSize = %u\n", mode->NvRamSize); + printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize); + printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask); + printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting); + printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount); + printf("MCastFilterCount = %u\n", mode->MCastFilterCount); + printf("MCastFilter = {"); + for (i = 0; i < mode->MCastFilterCount; i++) + printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr)); + printf(" }\n"); + printf("CurrentAddress = %s\n", + ether_sprintf(mode->CurrentAddress.Addr)); + printf("BroadcastAddress = %s\n", + ether_sprintf(mode->BroadcastAddress.Addr)); + printf("PermanentAddress = %s\n", + ether_sprintf(mode->PermanentAddress.Addr)); + printf("IfType = %u\n", mode->IfType); + printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable); + printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported); + printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported); + printf("MediaPresent = %d\n", mode->MediaPresent); +} +#endif + +int +efinet_match(struct netif *nif, void *machdep_hint) +{ + + return (1); +} + +int +efinet_probe(struct netif *nif, void *machdep_hint) +{ + + return (0); +} + +int +efinet_put(struct iodesc *desc, void *pkt, size_t len) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + void *buf; + + net = nif->nif_devdata; + + status = net->Transmit(net, 0, len, pkt, 0, 0, 0); + if (status != EFI_SUCCESS) + return -1; + + /* Wait for the buffer to be transmitted */ + do { + buf = 0; /* XXX Is this needed? */ + status = net->GetStatus(net, 0, &buf); + /* + * XXX EFI1.1 and the E1000 card returns a different + * address than we gave. Sigh. + */ + } while (status == EFI_SUCCESS && buf == 0); + + /* XXX How do we deal with status != EFI_SUCCESS now? */ + return (status == EFI_SUCCESS) ? len : -1; +} + + +int +efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + UINTN bufsz; + time_t t; + char buf[2048]; + + net = nif->nif_devdata; + + t = time(0); + while ((time(0) - t) < timeout) { + bufsz = sizeof(buf); + status = net->Receive(net, 0, &bufsz, buf, 0, 0, 0); + if (status == EFI_SUCCESS) { + /* + * XXX EFI1.1 and the E1000 card trash our + * workspace if we do not do this silly copy. + * Either they are not respecting the len + * value or do not like the alignment. + */ + if (bufsz > len) + bufsz = len; + bcopy(buf, pkt, bufsz); + return bufsz; + } + if (status != EFI_NOT_READY) + return 0; + } + + return 0; +} + +void +efinet_init(struct iodesc *desc, void *machdep_hint) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + + net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; + nif->nif_devdata = net; + + if (net->Mode->State == EfiSimpleNetworkStopped) { + status = net->Start(net); + if (status != EFI_SUCCESS) { + printf("net%d: cannot start interface (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->State != EfiSimpleNetworkInitialized) { + status = net->Initialize(net, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot init. interface (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->ReceiveFilterSetting == 0) { + UINT32 mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | + EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; + + status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot set rx. filters (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + +#ifdef EFINET_DEBUG + dump_mode(net->Mode); +#endif + + bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6); + desc->xid = 1; + + return; +} + +void +efinet_init_driver() +{ + EFI_STATUS status; + UINTN sz; + static EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; + EFI_HANDLE *handles; + int nifs, i; +#define MAX_INTERFACES 4 + static struct netif_dif difs[MAX_INTERFACES]; + static struct netif_stats stats[MAX_INTERFACES]; + + sz = 0; + status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, 0); + if (status != EFI_BUFFER_TOO_SMALL) + return; + handles = (EFI_HANDLE *) malloc(sz); + status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, handles); + if (EFI_ERROR(status)) { + free(handles); + return; + } + + nifs = sz / sizeof(EFI_HANDLE); + if (nifs > MAX_INTERFACES) + nifs = MAX_INTERFACES; + + efi_net.netif_nifs = nifs; + efi_net.netif_ifs = difs; + + bzero(stats, sizeof(stats)); + for (i = 0; i < nifs; i++) { + struct netif_dif *dif = &efi_net.netif_ifs[i]; + dif->dif_unit = i; + dif->dif_nsel = 1; + dif->dif_stats = &stats[i]; + + BS->HandleProtocol(handles[i], &netid, + (VOID**) &dif->dif_private); + } + + return; +} + +void +efinet_end(struct netif *nif) +{ + EFI_SIMPLE_NETWORK *net = nif->nif_devdata; + + net->Shutdown(net); +} + +struct netif_driver efi_net = { + "net", /* netif_bname */ + efinet_match, /* netif_match */ + efinet_probe, /* netif_probe */ + efinet_init, /* netif_init */ + efinet_get, /* netif_get */ + efinet_put, /* netif_put */ + efinet_end, /* netif_end */ + 0, /* netif_ifs */ + 0 /* netif_nifs */ +}; + diff --git a/sys/boot/efi/libefi/elf_freebsd.c b/sys/boot/efi/libefi/elf_freebsd.c new file mode 100644 index 0000000..27d2b6e --- /dev/null +++ b/sys/boot/efi/libefi/elf_freebsd.c @@ -0,0 +1,223 @@ +/* $FreeBSD$ */ +/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include <stand.h> +#include <string.h> + +#include <sys/param.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> +#include <machine/ia64_cpu.h> +#include <machine/pte.h> +#include <machine/vmparam.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +#define _KERNEL + +static int elf64_exec(struct preloaded_file *amp); + +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; + +static __inline u_int64_t +disable_ic() +{ + u_int64_t psr; + __asm __volatile("mov %0=psr;;" : "=r" (psr)); + __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;"); + return psr; +} + +static __inline void +restore_ic(u_int64_t psr) +{ + __asm __volatile("mov psr.l=%0;; srlz.i" :: "r" (psr)); +} + +/* + * Entered with psr.ic and psr.i both zero. + */ +void +enter_kernel(u_int64_t start, struct bootinfo *bi) +{ + u_int64_t psr; + + __asm __volatile("srlz.i;;"); + __asm __volatile("mov cr.ipsr=%0" + :: "r"(IA64_PSR_IC + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_IT + | IA64_PSR_BN)); + __asm __volatile("mov cr.iip=%0" :: "r"(start)); + __asm __volatile("mov cr.ifs=r0;;"); + __asm __volatile("mov ar.rsc=0;; flushrs;;"); + __asm __volatile("mov r8=%0" :: "r" (bi)); + __asm __volatile("rfi;;"); +} + +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *hdr; + struct ia64_pte pte; + struct bootinfo *bi; + u_int64_t psr; + UINTN mapkey, pages, size; + UINTN descsz; + UINT32 descver; + EFI_STATUS status; + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); /* XXX actually EFUCKUP */ + hdr = (Elf_Ehdr *)&(md->md_data); + + /* + * Allocate enough pages to hold the bootinfo block and the memory + * map EFI will return to us. The memory map has an unknown size, + * so we have to determine that first. Note that the AllocatePages + * call can itself modify the memory map, so we have to take that + * into account as well. The changes to the memory map are caused + * by splitting a range of free memory into two (AFAICT), so that + * one is marked as being loader data. + */ + size = 0; + descsz = sizeof(EFI_MEMORY_DESCRIPTOR); + BS->GetMemoryMap(&size, NULL, &mapkey, &descsz, &descver); + size += descsz + ((sizeof(struct bootinfo) + 0x0f) & ~0x0f); + pages = EFI_SIZE_TO_PAGES(size); + status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, + (void*)&bi); + if (EFI_ERROR(status)) { + printf("unable to create bootinfo block (status=0x%lx)\n", + (long)status); + return (ENOMEM); + } + + bzero(bi, sizeof(struct bootinfo)); + bi_load(bi, fp, &mapkey, pages); + + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); + + status = BS->ExitBootServices(IH, mapkey); + if (EFI_ERROR(status)) { + printf("ExitBootServices returned 0x%lx\n", status); + return (EINVAL); + } + + psr = disable_ic(); + + /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + + bzero(&pte, sizeof(pte)); + pte.pte_p = 1; + pte.pte_ma = PTE_MA_WB; + pte.pte_a = 1; + pte.pte_d = 1; + pte.pte_pl = PTE_PL_KERN; + pte.pte_ar = PTE_AR_RWX; + pte.pte_ppn = 0; + + __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); + __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); + __asm __volatile("ptr.i %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("ptr.d %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.i itr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.d dtr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + + enter_kernel(hdr->e_entry, bi); + + restore_ic(psr); +} diff --git a/sys/boot/efi/libefi/libefi.c b/sys/boot/efi/libefi/libefi.c new file mode 100644 index 0000000..563b533 --- /dev/null +++ b/sys/boot/efi/libefi/libefi.c @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> +#include <stand.h> + +EFI_HANDLE IH; +EFI_SYSTEM_TABLE *ST; +EFI_BOOT_SERVICES *BS; +EFI_RUNTIME_SERVICES *RS; + +static EFI_PHYSICAL_ADDRESS heap; +static UINTN heapsize; + +static CHAR16 * +arg_skipsep(CHAR16 *argp) +{ + + while (*argp == ' ' || *argp == '\t') + argp++; + return (argp); +} + +static CHAR16 * +arg_skipword(CHAR16 *argp) +{ + + while (*argp && *argp != ' ' && *argp != '\t') + argp++; + return (argp); +} + +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_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) +{ + static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL; + EFI_LOADED_IMAGE *img; + CHAR16 *argp, *args, **argv; + EFI_STATUS status; + int argc, addprog; + + 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**)&img); + if (status != EFI_SUCCESS) + exit(status); + + /* + * Pre-process the (optional) load options. If the option string + * is given as an ASCII string, we use a poor man's ASCII to + * Unicode-16 translation. The size of the option string as given + * to us includes the terminating null character. We assume the + * string is an ASCII string if strlen() plus the terminating + * '\0' is less than LoadOptionsSize. Even if all Unicode-16 + * characters have the upper 8 bits non-zero, the terminating + * null character will cause a one-off. + * If the string is already in Unicode-16, we make a copy so that + * we know we can always modify the string. + */ + if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { + if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { + args = malloc(img->LoadOptionsSize << 1); + for (argc = 0; argc < img->LoadOptionsSize; argc++) + args[argc] = ((char*)img->LoadOptions)[argc]; + } else { + args = malloc(img->LoadOptionsSize); + memcpy(args, img->LoadOptions, img->LoadOptionsSize); + } + } else + args = NULL; + + /* + * Use a quick and dirty algorithm to build the argv vector. We + * first count the number of words. Then, after allocating the + * vector, we split the string up. We don't deal with quotes or + * other more advanced shell features. + * The EFI shell will pas the name of the image as the first + * word in the argument list. This does not happen if we're + * loaded by the boot manager. This is not so easy to figure + * out though. The ParentHandle is not always NULL, because + * there can be a function (=image) that will perform the task + * for the boot manager. + */ + /* Part 1: Figure out if we need to add our program name. */ + addprog = (args == NULL || img->ParentHandle == NULL || + img->FilePath == NULL) ? 1 : 0; + if (!addprog) { + addprog = + (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || + DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || + DevicePathNodeLength(img->FilePath) <= + sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0; + if (!addprog) { + /* XXX todo. */ + } + } + /* Part 2: count words. */ + argc = (addprog) ? 1 : 0; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argc++; + argp = arg_skipword(argp); + } + /* Part 3: build vector. */ + argv = malloc((argc + 1) * sizeof(CHAR16*)); + argc = 0; + if (addprog) + argv[argc++] = L"loader.efi"; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argv[argc++] = argp; + argp = arg_skipword(argp); + /* Terminate the words. */ + if (*argp != 0) + *argp++ = 0; + } + argv[argc] = NULL; + + status = main(argc, argv); + exit(status); +} diff --git a/sys/boot/efi/libefi/module.c b/sys/boot/efi/libefi/module.c new file mode 100644 index 0000000..7a3f4b2 --- /dev/null +++ b/sys/boot/efi/libefi/module.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +/* + * Use voodoo to load modules required by current hardware. + */ +int +efi_autoload(void) +{ + /* XXX use PnP to locate stuff here */ + return (0); +} diff --git a/sys/boot/efi/libefi/time.c b/sys/boot/efi/libefi/time.c new file mode 100644 index 0000000..3ca456e --- /dev/null +++ b/sys/boot/efi/libefi/time.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> + +#include <time.h> +#include <sys/time.h> + +/* +// Accurate only for the past couple of centuries; +// that will probably do. +// +// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR ( 60*60 ) +#define SECSPERDAY (24 * SECSPERHOUR) + +time_t +EfiTimeToUnixTime(EFI_TIME *ETime) +{ + /* + // These arrays give the cumulative number of days up to the first of the + // month number used as the index (1 -> 12) for regular and leap years. + // The value at index 13 is for the whole year. + */ + static time_t CumulativeDays[2][14] = { + {0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, + {0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; + + time_t UTime; + int Year; + + /* + // Do a santity check + */ + if ( ETime->Year < 1998 || ETime->Year > 2099 || + ETime->Month == 0 || ETime->Month > 12 || + ETime->Day == 0 || ETime->Month > 31 || + ETime->Hour > 23 || + ETime->Minute > 59 || + ETime->Second > 59 || + ETime->TimeZone < -1440 || + (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) { + return (0); + } + + /* + // Years + */ + UTime = 0; + for (Year = 1970; Year != ETime->Year; ++Year) { + UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); + } + + /* + // UTime should now be set to 00:00:00 on Jan 1 of the file's year. + // + // Months + */ + UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); + + /* + // UTime should now be set to 00:00:00 on the first of the file's month and year + // + // Days -- Don't count the file's day + */ + UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); + + /* + // Hours + */ + UTime += (ETime->Hour * SECSPERHOUR); + + /* + // Minutes + */ + UTime += (ETime->Minute * 60); + + /* + // Seconds + */ + UTime += ETime->Second; + + /* + // EFI time is repored in local time. Adjust for any time zone offset to + // get true UT + */ + if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) { + /* + // TimeZone is kept in minues... + */ + UTime += (ETime->TimeZone * 60); + } + + return UTime; +} + +int +EFI_GetTimeOfDay( + OUT struct timeval *tp, + OUT struct timezone *tzp + ) +{ + EFI_TIME EfiTime; + EFI_TIME_CAPABILITIES Capabilities; + EFI_STATUS Status; + + /* + // Get time from EFI + */ + + Status = RS->GetTime( &EfiTime, &Capabilities ); + if (EFI_ERROR(Status)) + return (-1); + + /* + // Convert to UNIX time (ie seconds since the epoch + */ + + tp->tv_sec = EfiTimeToUnixTime( &EfiTime ); + tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ + + /* + // Do something with the timezone if needed + */ + + if (tzp) { + tzp->tz_minuteswest = + EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone; + /* + // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT + */ + tzp->tz_dsttime = + EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; + } + + return (0); +} + +time_t +time(time_t *tloc) +{ + struct timeval tv; + EFI_GetTimeOfDay(&tv, 0); + + if (tloc) + *tloc = tv.tv_sec; + return tv.tv_sec; +} + +time_t +getsecs() +{ + return time(0); +} diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile new file mode 100644 index 0000000..e2f9a84 --- /dev/null +++ b/sys/boot/efi/loader/Makefile @@ -0,0 +1,123 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../common + +BASE= loader +PROG= ${BASE}.efi +NOMAN= +NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH} +BINDIR?= /boot +STRIP= # We must not strip loader.efi at install time. + +SRCS+= main.c conf.c dev_net.c + +CFLAGS+= -ffreestanding + +.if !defined(NOFORTH) +# Enable BootForth +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH} +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.endif + +# where to get libstand from +.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a) +LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a +.else +LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a +.endif + +.if exists(${.OBJDIR}/../libefi/libefi.a) +LIBEFI= ${.OBJDIR}/../libefi/libefi.a +.else +LIBEFI= ${.CURDIR}/../libefi/libefi.a +.endif + +# Always add MI sources +.PATH: ${.CURDIR}/../../common +.include <${.CURDIR}/../../common/Makefile.inc> + +CFLAGS+= -I- +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR} +CFLAGS+= -I${.CURDIR}/../../.. -I. +CFLAGS+= -I${.CURDIR}/../libefi +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand +CFLAGS+= -DLOADER + +LDSCRIPT= ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/ldscript.${MACHINE_ARCH} +LDFLAGS= -nostdlib -T ${LDSCRIPT} -shared -Bsymbolic +OBJCOPY?= objcopy + +CLEANFILES+= setdef0.c setdef0.o setdef1.c setdef1.o setdefs.h start.o \ + vers.c vers.o ${BASE}.efi ${BASE}.sym ${BASE}.list +CLEANFILES+= loader.help +CLEANFILES+= machine + +CRT= start.o + +all: ${BASE} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${BASE}: ${BASE}.efi ${BASE}.help + +${BASE}.efi: ${BASE}.sym + ${OBJCOPY} -j .text \ + -j .hash \ + -j .data \ + -j .sdata \ + -j .dynamic \ + -j .rela \ + -j .reloc \ + -j .dynsym \ + -j .dynstr \ + --target=efi-app-${MACHINE_ARCH} \ + ${BASE}.sym ${BASE}.efi + +${BASE}.help: help.common + cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \ + > ${.TARGET} + +beforeinstall: +.if exists(${.OBJDIR}/loader.help) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot +.else + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/${BASE}.help ${DESTDIR}/boot +.endif +.if !exists(${DESTDIR}/boot/loader.rc) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.rc ${DESTDIR}/boot +.endif + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.4th ${DESTDIR}/boot + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/support.4th ${DESTDIR}/boot + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.conf ${DESTDIR}/boot/defaults + + +# Other fragments still to be brought in from ../Makfile.booters? +start.o: ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/start.S + ${CC} -c ${CFLAGS} ${.IMPSRC} + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +.include <bsd.prog.mk> + +${BASE}.sym: ${OBJS} ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${CRT} vers.o + ${LD} ${LDFLAGS} -o ${BASE}.sym -M ${CRT} ${OBJS} vers.o \ + ${LIBFICL} ${LIBEFI} ${LIBSTAND} > ${.OBJDIR}/${BASE}.list + +beforedepend ${OBJS}: machine diff --git a/sys/boot/efi/loader/conf.c b/sys/boot/efi/loader/conf.c new file mode 100644 index 0000000..145b16b --- /dev/null +++ b/sys/boot/efi/loader/conf.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1997 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Matthias Drochner. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <efi.h> +#include <efilib.h> + +#include "efiboot.h" + +/* + * We could use linker sets for some or all of these, but + * then we would have to control what ended up linked into + * the bootstrap. So it's easier to conditionalise things + * here. + * + * XXX rename these arrays to be consistent and less namespace-hostile + */ + +/* Exported for libstand */ +struct devsw *devsw[] = { + &efifs_dev, + &netdev, + NULL +}; + +struct fs_ops *file_system[] = { + &efi_fsops, +/* &ufs_fsops, */ + &nfs_fsops, + &gzipfs_fsops, + NULL +}; + +struct netif_driver *netif_drivers[] = { + &efi_net, + NULL, +}; + +/* Exported for ia64 only */ +/* + * Sort formats so that those that can detect based on arguments + * rather than reading the file go first. + */ +extern struct file_format ia64_elf; + +struct file_format *file_formats[] = { + &ia64_elf, + NULL +}; + +/* + * Consoles + * + * We don't prototype these in efiboot.h because they require + * data structures from bootstrap.h as well. + */ +extern struct console efi_console; + +struct console *consoles[] = { + &efi_console, + NULL +}; diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c new file mode 100644 index 0000000..752c243 --- /dev/null +++ b/sys/boot/efi/loader/main.c @@ -0,0 +1,562 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <setjmp.h> +#include <machine/sal.h> +#include <machine/pal.h> +#include <machine/pte.h> +#include <machine/dig64.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" +#include "efiboot.h" + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct efi_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +extern u_int64_t ia64_pal_entry; + +EFI_GUID acpi = ACPI_TABLE_GUID; +EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; +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) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return; + } + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + ia64_pal_entry = dp->sale_pal_proc; + return; + } + p += sizes[*p]; + } + + printf("Can't find PAL proc\n"); + return; +} + +EFI_STATUS +main(int argc, CHAR16 *argv[]) +{ + EFI_LOADED_IMAGE *img; + int i; + + /* + * 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 + * printf() etc. once this is done. + */ + cons_probe(); + + /* + * Initialise the block cache + */ + bcache_init(32, 512); /* 16k XXX tune this */ + + find_pal_proc(); + + /* + * March through the device switch probing for things. + */ + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + + efinet_init_driver(); + + /* Get our loaded image protocol interface structure. */ + BS->HandleProtocol(IH, &imgid, (VOID**)&img); + + printf("Image base: 0x%016lx\n", (u_long)img->ImageBase); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + + i = efifs_get_unit(img->DeviceHandle); + if (i >= 0) { + currdev.d_dev = devsw[0]; /* XXX disk */ + currdev.d_kind.efidisk.unit = i; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.efidisk.slice = -1; + currdev.d_kind.efidisk.partition = 0; + } else { + currdev.d_dev = devsw[1]; /* XXX net */ + currdev.d_kind.netif.unit = 0; /* XXX */ + } + currdev.d_type = currdev.d_dev->dv_type; + + /* + * Disable the watchdog timer. By default the boot manager sets + * the timer to 5 minutes before invoking a boot option. If we + * want to return to the boot manager, we have to disable the + * watchdog timer and since we're an interactive program, we don't + * want to wait until the user types "quit". The timer may have + * fired by then. We don't care if this fails. It does not prevent + * normal functioning in any way... + */ + BS->SetWatchdogTimer(0, 0, 0, NULL); + + env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), + efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, + env_nounset); + + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = efi_autoload; + archsw.arch_getdev = efi_getdev; + archsw.arch_copyin = efi_copyin; + archsw.arch_copyout = efi_copyout; + archsw.arch_readin = efi_readin; + + interact(); /* doesn't return */ + + return (EFI_SUCCESS); /* keep compiler happy */ +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return (CMD_OK); +} + +COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); + +static int +command_memmap(int argc, char *argv[]) +{ + UINTN sz; + EFI_MEMORY_DESCRIPTOR *map, *p; + UINTN key, dsz; + UINT32 dver; + EFI_STATUS status; + int i, ndesc; + static char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode" + }; + + sz = 0; + status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); + if (status != EFI_BUFFER_TOO_SMALL) { + printf("Can't determine memory map size\n"); + return CMD_ERROR; + } + map = malloc(sz); + status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); + if (EFI_ERROR(status)) { + printf("Can't read memory map\n"); + return CMD_ERROR; + } + + ndesc = sz / dsz; + printf("%23s %12s %12s %8s %4s\n", + "Type", "Physical", "Virtual", "#Pages", "Attr"); + + for (i = 0, p = map; i < ndesc; + i++, p = NextMemoryDescriptor(p, dsz)) { + printf("%23s %012lx %012lx %08lx ", + types[p->Type], + p->PhysicalStart, + p->VirtualStart, + p->NumberOfPages); + if (p->Attribute & EFI_MEMORY_UC) + printf("UC "); + if (p->Attribute & EFI_MEMORY_WC) + printf("WC "); + if (p->Attribute & EFI_MEMORY_WT) + printf("WT "); + if (p->Attribute & EFI_MEMORY_WB) + printf("WB "); + if (p->Attribute & EFI_MEMORY_UCE) + printf("UCE "); + if (p->Attribute & EFI_MEMORY_WP) + printf("WP "); + if (p->Attribute & EFI_MEMORY_RP) + printf("RP "); + if (p->Attribute & EFI_MEMORY_XP) + printf("XP "); + if (p->Attribute & EFI_MEMORY_RUNTIME) + printf("RUNTIME"); + printf("\n"); + } + + return CMD_OK; +} + +COMMAND_SET(configuration, "configuration", + "print configuration tables", command_configuration); + +static const char * +guid_to_string(EFI_GUID *guid) +{ + static char buf[40]; + + sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], + guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], + guid->Data4[5], guid->Data4[6], guid->Data4[7]); + return (buf); +} + +static int +command_configuration(int argc, char *argv[]) +{ + int i; + + printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); + for (i = 0; i < ST->NumberOfTableEntries; i++) { + EFI_GUID *guid; + + printf(" "); + guid = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(guid, &mps, sizeof(EFI_GUID))) + printf("MPS Table"); + else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) + printf("ACPI Table"); + else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) + printf("ACPI 2.0 Table"); + else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) + printf("SMBIOS Table"); + else if (!memcmp(guid, &sal, sizeof(EFI_GUID))) + printf("SAL System Table"); + else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID))) + printf("DIG64 HCDP Table"); + else + printf("Unknown Table (%s)", guid_to_string(guid)); + printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); + } + + return CMD_OK; +} + +COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); + +static int +command_sal(int argc, char *argv[]) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return CMD_ERROR; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return CMD_ERROR; + } + + printf("SAL Revision %x.%02x\n", + saltab->sal_rev[1], + saltab->sal_rev[0]); + printf("SAL A Version %x.%02x\n", + saltab->sal_a_version[1], + saltab->sal_a_version[0]); + printf("SAL B Version %x.%02x\n", + saltab->sal_b_version[1], + saltab->sal_b_version[0]); + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + printf(" Desc %d", *p); + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + printf("\n"); + printf(" PAL Proc at 0x%lx\n", + dp->sale_pal_proc); + printf(" SAL Proc at 0x%lx\n", + dp->sale_sal_proc); + printf(" SAL GP at 0x%lx\n", + dp->sale_sal_gp); + } else if (*p == 1) { + struct sal_memory_descriptor *dp; + dp = (struct sal_memory_descriptor *) p; + printf(" Type %d.%d, ", + dp->sale_memory_type[0], + dp->sale_memory_type[1]); + printf("Address 0x%lx, ", + dp->sale_physical_address); + printf("Length 0x%x\n", + dp->sale_length); + } else if (*p == 5) { + struct sal_ap_wakeup_descriptor *dp; + dp = (struct sal_ap_wakeup_descriptor *) p; + printf("\n"); + printf(" Mechanism %d\n", dp->sale_mechanism); + printf(" Vector 0x%lx\n", dp->sale_vector); + } else + printf("\n"); + + p += sizes[*p]; + } + + return CMD_OK; +} + +int +print_trs(int type) +{ + struct ia64_pal_result res; + int i, maxtr; + struct { + struct ia64_pte pte; + struct ia64_itir itir; + struct ia64_ifa ifa; + struct ia64_rr rr; + } buf; + static const char* psnames[] = { + "1B", "2B", "4B", "8B", + "16B", "32B", "64B", "128B", + "256B", "512B", "1K", "2K", + "4K", "8K", "16K", "32K", + "64K", "128K", "256K", "512K", + "1M", "2M", "4M", "8M", + "16M", "32M", "64M", "128M", + "256M", "512M", "1G", "2G" + }; + static const char* manames[] = { + "WB", "bad", "bad", "bad", + "UC", "UCE", "WC", "NaT", + + }; + + res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0); + if (res.pal_status != 0) { + printf("Can't get VM summary\n"); + return CMD_ERROR; + } + + if (type == 0) + maxtr = (res.pal_result[0] >> 40) & 0xff; + else + maxtr = (res.pal_result[0] >> 32) & 0xff; + + printf("%d translation registers\n", maxtr); + + pager_open(); + pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n"); + for (i = 0; i <= maxtr; i++) { + char lbuf[128]; + + bzero(&buf, sizeof(buf)); + res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type, + (u_int64_t) &buf); + if (res.pal_status != 0) + break; + + /* Only display valid translations */ + if ((buf.ifa.ifa_ig & 1) == 0) + continue; + + if (!(res.pal_result[0] & 1)) + buf.pte.pte_ar = 0; + if (!(res.pal_result[0] & 2)) + buf.pte.pte_pl = 0; + if (!(res.pal_result[0] & 4)) + buf.pte.pte_d = 0; + if (!(res.pal_result[0] & 8)) + buf.pte.pte_ma = 0; + sprintf(lbuf, + "%03d %06x %013lx %013lx %4s %d %d %d %d %d %-3s %d %06x\n", + i, + buf.rr.rr_rid, + buf.ifa.ifa_vpn, + buf.pte.pte_ppn, + psnames[buf.itir.itir_ps], + buf.pte.pte_ed, + buf.pte.pte_ar, + buf.pte.pte_pl, + buf.pte.pte_d, + buf.pte.pte_a, + manames[buf.pte.pte_ma], + buf.pte.pte_p, + buf.itir.itir_key); + pager_output(lbuf); + } + pager_close(); + + if (res.pal_status != 0) { + printf("Error while getting TR contents\n"); + return CMD_ERROR; + } + return CMD_OK; +} + +COMMAND_SET(itr, "itr", "print instruction TRs", command_itr); + +static int +command_itr(int argc, char *argv[]) +{ + return print_trs(0); +} + +COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr); + +static int +command_dtr(int argc, char *argv[]) +{ + return print_trs(1); +} + +COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp); + +static char * +hcdp_string(char *s, u_int len) +{ + static char buffer[256]; + + memcpy(buffer, s, len); + buffer[len] = 0; + return (buffer); +} + +static int +command_hcdp(int argc, char *argv[]) +{ + struct dig64_hcdp_table *tbl; + struct dig64_hcdp_entry *ent; + struct dig64_gas *gas; + int i; + + tbl = efi_get_table(&hcdp); + if (tbl == NULL) { + printf("No HCDP table present\n"); + return (CMD_OK); + } + if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) { + printf("HCDP table has invalid signature\n"); + return (CMD_OK); + } + if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) { + printf("HCDP table too short\n"); + return (CMD_OK); + } + printf("HCDP table at 0x%016lx\n", (u_long)tbl); + printf("Signature = %s\n", hcdp_string(tbl->signature, 4)); + printf("Length = %u\n", tbl->length); + printf("Revision = %u\n", tbl->revision); + printf("Checksum = %u\n", tbl->checksum); + printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6)); + printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8)); + printf("OEM rev = %u\n", tbl->oem_rev); + printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4)); + printf("Creator rev= %u\n", tbl->creator_rev); + printf("Entries = %u\n", tbl->entries); + for (i = 0; i < tbl->entries; i++) { + ent = tbl->entry + i; + printf("Entry #%d:\n", i + 1); + printf(" Type = %u\n", ent->type); + printf(" Databits = %u\n", ent->databits); + printf(" Parity = %u\n", ent->parity); + printf(" Stopbits = %u\n", ent->stopbits); + printf(" PCI seg = %u\n", ent->pci_segment); + printf(" PCI bus = %u\n", ent->pci_bus); + printf(" PCI dev = %u\n", ent->pci_device); + printf(" PCI func = %u\n", ent->pci_function); + printf(" Interrupt = %u\n", ent->interrupt); + printf(" PCI flag = %u\n", ent->pci_flag); + printf(" Baudrate = %lu\n", + ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low); + gas = &ent->address; + printf(" Addr space= %u\n", gas->addr_space); + printf(" Bit width = %u\n", gas->bit_width); + printf(" Bit offset= %u\n", gas->bit_offset); + printf(" Address = 0x%016lx\n", + ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low); + printf(" PCI type = %u\n", ent->pci_devid); + printf(" PCI vndr = %u\n", ent->pci_vendor); + printf(" IRQ = %u\n", ent->irq); + printf(" PClock = %u\n", ent->pclock); + printf(" PCI iface = %u\n", ent->pci_interface); + } + printf("<EOT>\n"); + return (CMD_OK); +} diff --git a/sys/boot/efi/loader/version b/sys/boot/efi/loader/version new file mode 100644 index 0000000..71f9400 --- /dev/null +++ b/sys/boot/efi/loader/version @@ -0,0 +1,16 @@ +$FreeBSD$ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important. Make sure the current version number is on line 6. + +1.1: Pass the HCDP table address to the kernel via bootinfo if one + is present in the EFI system table. +1.0: Don't map the I/O port range. We expect the kernel to do it. It + was done in the loader as a debugging aid and not intended as a + service/feature. +0.3: Pass the physical address of the bootinfo block in register r8 + to the kernel. Continue to put it at the fixed address for now. +0.2: Much improved version. Significant is the support for passing + the FPSWA interface pointer to the kernel. +0.1: Initial EFI version, germinated from the NetBSD i386 + standalone, but enormously modified. |