From 485b5cf8bc00ab5aaee5db81a91d135dc61d9cc3 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Fri, 13 Dec 2019 14:59:07 -0600 Subject: [PATCH] efi: Refactor our EFI code to use fuchsia's cleaner EFI headers. * Drop gnu-efi Change-Id: Ib601fc8ced49b18281b6b98cf861a5aef1b9c065 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2026 Reviewed-by: Alex von Gluck IV Reviewed-by: Adrien Destugues --- .../kernel/platform/efi/boot-services.h | 205 ++++++++++++++++++ .../kernel/platform/efi/protocol/block-io.h | 56 +++++ .../efi/protocol/device-path-to-text.h | 21 ++ .../platform/efi/protocol/device-path.h | 52 +++++ .../kernel/platform/efi/protocol/disk-io.h | 28 +++ .../platform/efi/protocol/driver-binding.h | 30 +++ .../kernel/platform/efi/protocol/file.h | 97 +++++++++ .../platform/efi/protocol/graphics-output.h | 76 +++++++ .../platform/efi/protocol/loaded-image.h | 32 +++ .../platform/efi/protocol/managed-network.h | 92 ++++++++ .../efi/protocol/pci-root-bridge-io.h | 115 ++++++++++ .../kernel/platform/efi/protocol/serial-io.h | 67 ++++++ .../efi/protocol/simple-file-system.h | 21 ++ .../platform/efi/protocol/simple-network.h | 132 +++++++++++ .../platform/efi/protocol/simple-text-input.h | 26 +++ .../efi/protocol/simple-text-output.h | 143 ++++++++++++ .../kernel/platform/efi/protocol/usb-io.h | 147 +++++++++++++ .../kernel/platform/efi/runtime-services.h | 151 +++++++++++++ .../kernel/platform/efi/system-table.h | 48 ++++ headers/private/kernel/platform/efi/types.h | 150 +++++++++++++ src/system/boot/platform/efi/Jamfile | 24 +- src/system/boot/platform/efi/acpi.cpp | 16 +- src/system/boot/platform/efi/arch/arm/Jamfile | 14 +- .../boot/platform/efi/arch/arm/crt0-efi-arm.S | 145 +++++++++++++ .../platform/efi/arch/arm/relocation_func.cpp | 8 +- .../platform/efi/arch/arm64/crt0-efi-arm64.S | 130 +++++++++++ .../efi/arch/arm64/relocation_func.cpp | 6 +- .../boot/platform/efi/arch/x86/crt0-efi-x86.S | 76 +++++++ .../boot/platform/efi/arch/x86_64/Jamfile | 15 +- .../efi/arch/x86_64/crt0-efi-x86_64.S | 76 +++++++ .../efi/arch/x86_64/relocation_func.cpp | 9 +- src/system/boot/platform/efi/console.cpp | 22 +- src/system/boot/platform/efi/devices.cpp | 191 ++++++++++------ src/system/boot/platform/efi/efi_platform.h | 58 +++-- src/system/boot/platform/efi/heap.cpp | 2 +- src/system/boot/platform/efi/mmu.cpp | 26 +-- src/system/boot/platform/efi/mmu.h | 41 ++-- src/system/boot/platform/efi/serial.cpp | 10 +- src/system/boot/platform/efi/start.cpp | 66 +++--- src/system/boot/platform/efi/video.cpp | 27 +-- 40 files changed, 2413 insertions(+), 238 deletions(-) create mode 100644 headers/private/kernel/platform/efi/boot-services.h create mode 100644 headers/private/kernel/platform/efi/protocol/block-io.h create mode 100644 headers/private/kernel/platform/efi/protocol/device-path-to-text.h create mode 100644 headers/private/kernel/platform/efi/protocol/device-path.h create mode 100644 headers/private/kernel/platform/efi/protocol/disk-io.h create mode 100644 headers/private/kernel/platform/efi/protocol/driver-binding.h create mode 100644 headers/private/kernel/platform/efi/protocol/file.h create mode 100644 headers/private/kernel/platform/efi/protocol/graphics-output.h create mode 100644 headers/private/kernel/platform/efi/protocol/loaded-image.h create mode 100644 headers/private/kernel/platform/efi/protocol/managed-network.h create mode 100644 headers/private/kernel/platform/efi/protocol/pci-root-bridge-io.h create mode 100644 headers/private/kernel/platform/efi/protocol/serial-io.h create mode 100644 headers/private/kernel/platform/efi/protocol/simple-file-system.h create mode 100644 headers/private/kernel/platform/efi/protocol/simple-network.h create mode 100644 headers/private/kernel/platform/efi/protocol/simple-text-input.h create mode 100644 headers/private/kernel/platform/efi/protocol/simple-text-output.h create mode 100644 headers/private/kernel/platform/efi/protocol/usb-io.h create mode 100644 headers/private/kernel/platform/efi/runtime-services.h create mode 100644 headers/private/kernel/platform/efi/system-table.h create mode 100644 headers/private/kernel/platform/efi/types.h create mode 100644 src/system/boot/platform/efi/arch/arm/crt0-efi-arm.S create mode 100644 src/system/boot/platform/efi/arch/arm64/crt0-efi-arm64.S create mode 100644 src/system/boot/platform/efi/arch/x86/crt0-efi-x86.S create mode 100644 src/system/boot/platform/efi/arch/x86_64/crt0-efi-x86_64.S diff --git a/headers/private/kernel/platform/efi/boot-services.h b/headers/private/kernel/platform/efi/boot-services.h new file mode 100644 index 0000000000..8cc5f44cef --- /dev/null +++ b/headers/private/kernel/platform/efi/boot-services.h @@ -0,0 +1,205 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +typedef size_t efi_tpl; + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} efi_allocate_type; + +typedef struct { + uint32_t Type; + efi_physical_addr PhysicalStart; + efi_virtual_addr VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +} efi_memory_descriptor; + +#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 +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_RO 0x0000000000020000 +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 + +typedef enum { + EFI_NATIVE_INTERFACE +} efi_interface_type; + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} efi_locate_search_type; + +#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 + +typedef struct { + efi_handle agent_handle; + efi_handle controller_handle; + uint32_t attributes; + uint32_t open_count; +} efi_open_protocol_information_entry; + +#define EFI_HII_PACKAGE_LIST_PROTOCOL_GUID \ + {0x6a1ee763, 0xd47a, 0x43b4, {0xaa, 0xbe, 0xef, 0x1d, 0xe2, 0xab, 0x56, 0xfc}} + +typedef struct efi_hii_package_list_header efi_hii_package_list_header; +typedef efi_hii_package_list_header* efi_hii_package_list_protocol; + +// fwd declare efi_system_table to break circular dependencies +typedef struct efi_system_table efi_system_table; +typedef efi_status (*efi_image_entry_point) (efi_handle img, efi_system_table* sys) EFIAPI; + +typedef struct { + efi_table_header Hdr; + + efi_tpl (*RaiseTPL) (efi_tpl new_tpl) EFIAPI; + + void (*RestoreTPL) (efi_tpl old_tpl) EFIAPI; + + efi_status (*AllocatePages) (efi_allocate_type type, efi_memory_type memory_type, + size_t pages, efi_physical_addr* memory) EFIAPI; + + efi_status (*FreePages) (efi_physical_addr memory, size_t pages) EFIAPI; + + efi_status (*GetMemoryMap) (size_t* memory_map_size, efi_memory_descriptor* memory_map, + size_t* map_key, size_t* desc_size, uint32_t* desc_version) EFIAPI; + + efi_status (*AllocatePool) (efi_memory_type pool_type, size_t size, void** buf) EFIAPI; + + efi_status (*FreePool) (void* buf) EFIAPI; + + efi_status (*CreateEvent) (uint32_t type, efi_tpl notify_tpl, + efi_event_notify notify_fn, void* notify_ctx, + efi_event* event) EFIAPI; + + efi_status (*SetTimer) (efi_event event, efi_timer_delay type, uint64_t trigger_time) EFIAPI; + + efi_status (*WaitForEvent) (size_t num_events, efi_event* event, size_t* index) EFIAPI; + + efi_status (*SignalEvent) (efi_event event) EFIAPI; + + efi_status (*CloseEvent) (efi_event event) EFIAPI; + + efi_status (*CheckEvent) (efi_event event) EFIAPI; + + efi_status (*InstallProtocolInterface) (efi_handle* handle, efi_guid* protocol, + efi_interface_type intf_type, void* intf) EFIAPI; + + efi_status (*ReinstallProtocolInterface) (efi_handle hadle, efi_guid* protocol, + void* old_intf, void* new_intf) EFIAPI; + + efi_status (*UninstallProtocolInterface) (efi_handle handle, efi_guid* protocol, + void* intf) EFIAPI; + + efi_status (*HandleProtocol) (efi_handle handle, efi_guid* protocol, void** intf) EFIAPI; + + void* Reserved; + + efi_status (*RegisterProtocolNotify) (efi_guid* protocol, efi_event event, + void** registration) EFIAPI; + + efi_status (*LocateHandle) (efi_locate_search_type search_type, efi_guid* protocol, + void* search_key, size_t* buf_size, efi_handle* buf) EFIAPI; + + efi_status (*LocateDevicePath) (efi_guid* protocol, efi_device_path_protocol** path, + efi_handle* device) EFIAPI; + + efi_status (*InstallConfigurationTable) (efi_guid* guid, void* table) EFIAPI; + + efi_status (*LoadImage) (bool boot_policy, efi_handle parent_image_handle, + efi_device_path_protocol* path, void* src, size_t src_size, + efi_handle* image_handle) EFIAPI; + + efi_status (*StartImage) (efi_handle image_handle, size_t* exit_data_size, + char16_t** exit_data) EFIAPI; + + efi_status (*Exit) (efi_handle image_handle, efi_status exit_status, + size_t exit_data_size, char16_t* exit_data) EFIAPI; + + efi_status (*UnloadImage) (efi_handle image_handle) EFIAPI; + + efi_status (*ExitBootServices) (efi_handle image_handle, size_t map_key) EFIAPI; + + efi_status (*GetNextMonotonicCount) (uint64_t* count) EFIAPI; + + efi_status (*Stall) (size_t microseconds) EFIAPI; + + efi_status (*SetWatchdogTimer) (size_t timeout, uint64_t watchdog_code, + size_t data_size, char16_t* watchdog_data) EFIAPI; + + efi_status (*ConnectController) (efi_handle controller_handle, + efi_handle* driver_image_handle, + efi_device_path_protocol* remaining_path, + bool recursive) EFIAPI; + + efi_status (*DisconnectController) (efi_handle controller_handle, + efi_handle driver_image_handle, + efi_handle child_handle) EFIAPI; + + efi_status (*OpenProtocol) (efi_handle handle, efi_guid* protocol, void** intf, + efi_handle agent_handle, efi_handle controller_handle, + uint32_t attributes) EFIAPI; + + efi_status (*CloseProtocol) (efi_handle handle, efi_guid* protocol, + efi_handle agent_handle, efi_handle controller_handle) EFIAPI; + + efi_status (*OpenProtocolInformation) (efi_handle handle, efi_guid* protocol, + efi_open_protocol_information_entry** entry_buf, + size_t* entry_count) EFIAPI; + + efi_status (*ProtocolsPerHandle) (efi_handle handle, efi_guid*** protocol_buf, + size_t* protocol_buf_count) EFIAPI; + + efi_status (*LocateHandleBuffer) (efi_locate_search_type search_type, + efi_guid* protocol, void* search_key, + size_t* num_handles, efi_handle** buf) EFIAPI; + + efi_status (*LocateProtocol) (efi_guid* protocol, void* registration, void** intf) EFIAPI; + + efi_status (*InstallMultipleProtocolInterfaces) (efi_handle* handle, ...) EFIAPI; + + efi_status (*UninstallMultipleProtocolInterfaces) (efi_handle handle, ...) EFIAPI; + + efi_status (*CalculateCrc32) (void* data, size_t len, uint32_t* crc32) EFIAPI; + + void (*CopyMem) (void* dest, const void* src, size_t len) EFIAPI; + + void (*SetMem) (void* buf, size_t len, uint8_t val) EFIAPI; + + efi_status (*CreateEventEx) (uint32_t type, efi_tpl notify_tpl, + efi_event_notify notify_fn, const void* notify_ctx, + const efi_guid* event_group, efi_event* event) EFIAPI; +} efi_boot_services; diff --git a/headers/private/kernel/platform/efi/protocol/block-io.h b/headers/private/kernel/platform/efi/protocol/block-io.h new file mode 100644 index 0000000000..cf53e6b49b --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/block-io.h @@ -0,0 +1,56 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_BLOCK_IO_PROTOCOL_GUID \ + {0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} + +extern efi_guid BlockIoProtocol; + +#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 +#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x00020031 + +typedef struct efi_block_io_media efi_block_io_media; +typedef struct efi_block_io_protocol efi_block_io_protocol; + +struct efi_block_io_protocol { + uint64_t Revision; + efi_block_io_media* Media; + efi_status (*Reset)(efi_block_io_protocol* self, + bool ExtendedVerification) EFIAPI; + efi_status (*ReadBlocks)(efi_block_io_protocol* self, + uint32_t MediaId, uint64_t LBA, + uint64_t BufferSize, void* Buffer) EFIAPI; + efi_status (*WriteBlocks)(efi_block_io_protocol* self, + uint32_t MediaId, uint64_t LBA, + uint64_t BufferSize, const void* Buffer) EFIAPI; + efi_status (*FlushBlocks)(efi_block_io_protocol* self); + + +}; + +struct efi_block_io_media { + // present in rev1 + uint32_t MediaId; + bool RemovableMedia; + bool MediaPresent; + bool LogicalPartition; + bool ReadOnly; + bool WriteCaching; + uint32_t BlockSize; + uint32_t IoAlign; + uint64_t LastBlock; + + // present in rev2 + uint64_t LowestAlignedLba; + uint32_t LogicalBlocksPerPhysicalBlock; + + // present in rev3 + uint32_t OptimalTransferLengthGranularity; +}; diff --git a/headers/private/kernel/platform/efi/protocol/device-path-to-text.h b/headers/private/kernel/platform/efi/protocol/device-path-to-text.h new file mode 100644 index 0000000000..119d669142 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/device-path-to-text.h @@ -0,0 +1,21 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + {0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c}} +extern efi_guid DevicePathToTextProtocol; + +typedef struct efi_device_path_to_text_protocol { + char16_t* (*ConvertDeviceNodeToText) (const efi_device_path_protocol* dev_node, + bool display_only, bool allow_shortcuts) EFIAPI; + + char16_t* (*ConvertDevicePathToText) (const efi_device_path_protocol* dev_path, + bool display_only, bool allow_shortcuts) EFIAPI; +} efi_device_path_to_text_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/device-path.h b/headers/private/kernel/platform/efi/protocol/device-path.h new file mode 100644 index 0000000000..4f5511db3c --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/device-path.h @@ -0,0 +1,52 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + {0x09576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid DevicePathProtocol; + +typedef struct efi_device_path_protocol { + uint8_t Type; + uint8_t SubType; + uint8_t Length[2]; +} efi_device_path_protocol; + +#define DEVICE_PATH_HARDWARE 0x01 +#define DEVICE_PATH_ACPI 0x02 +#define DEVICE_PATH_MESSAGING 0x03 +#define DEVICE_PATH_MEDIA 0x04 +#define DEVICE_PATH_BIOS_BOOT_SPEC 0x05 +#define DEVICE_PATH_END 0x7f + +#define DEVICE_PATH_INSTANCE_END 0x01 +#define DEVICE_PATH_ENTIRE_END 0xff + +#define DEVICE_PATH_HW_PCI 0x01 +#define DEVICE_PATH_HW_PCCARD 0x02 +#define DEVICE_PATH_HW_MEMMAP 0x03 +#define DEVICE_PATH_HW_VENDOR 0x04 +#define DEVICE_PATH_HW_CONTROLLER 0x05 +#define DEVICE_PATH_HW_BMC 0x06 + +// TODO: sub-types for other types (ACPI, etc) + +// DEVICE_PATH_MEDIA Types +#define MEDIA_HARDDRIVE_DP 0x01 +#define MEDIA_CDROM_DP 0x02 +#define MEDIA_VENDOR_DP 0x03 +#define MEDIA_FILEPATH_DP 0x04 +#define MEDIA_PROTOCOL_DP 0x05 + +// TODO: move this to another header? would break circular dependencies between +// boot-services.h and this header, for efi_memory_type +typedef struct { + efi_device_path_protocol Header; + efi_memory_type MemoryType; + efi_physical_addr StartAddress; + efi_physical_addr EndAddress; +} efi_device_path_hw_memmap; diff --git a/headers/private/kernel/platform/efi/protocol/disk-io.h b/headers/private/kernel/platform/efi/protocol/disk-io.h new file mode 100644 index 0000000000..979d49b923 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/disk-io.h @@ -0,0 +1,28 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_DISK_IO_PROTOCOL_GUID \ + {0xCE345171, 0xBA0B, 0x11d2, {0x8e, 0x4F, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} + +extern efi_guid DiskIoProtocol; + +#define EFI_DISK_IO_PROTOCOL_REVISION 0x00010000 + +typedef struct efi_disk_io_protocol efi_disk_io_protocol; + +struct efi_disk_io_protocol { + uint64_t Revision; + efi_status (*ReadDisk)(efi_disk_io_protocol* self, + uint32_t MediaId, uint64_t Offset, + uint64_t BufferSize, void* Buffer) EFIAPI; + efi_status (*WriteDisk)(efi_disk_io_protocol* self, + uint32_t MediaId, uint64_t Offset, + uint64_t BufferSize, const void* Buffer) EFIAPI; +}; diff --git a/headers/private/kernel/platform/efi/protocol/driver-binding.h b/headers/private/kernel/platform/efi/protocol/driver-binding.h new file mode 100644 index 0000000000..bd928acec5 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/driver-binding.h @@ -0,0 +1,30 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_DRIVER_BINDING_PROTOCOL_GUID \ + {0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71}} +extern efi_guid DriverBindingProtocol; + +typedef struct efi_driver_binding_protocol { + efi_status (*Supported) (struct efi_driver_binding_protocol* self, + efi_handle controller_handle, + efi_device_path_protocol* remaining_path) EFIAPI; + + efi_status (*Start) (struct efi_driver_binding_protocol* self, + efi_handle controller_handle, + efi_device_path_protocol* remaining_path) EFIAPI; + + efi_status (*Stop) (struct efi_driver_binding_protocol* self, + efi_handle controller_handle, + size_t num_children, efi_handle* child_handle_buf) EFIAPI; + + uint32_t Version; + efi_handle ImageHandle; + efi_handle DriverBindingHandle; +} efi_driver_binding_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/file.h b/headers/private/kernel/platform/efi/protocol/file.h new file mode 100644 index 0000000000..394c13ed52 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/file.h @@ -0,0 +1,97 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_FILE_PROTOCOL_REVISION 0x00010000 +#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 +#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 + +#define EFI_FILE_MODE_READ 0x0000000000000001 +#define EFI_FILE_MODE_WRITE 0x0000000000000002 +#define EFI_FILE_MODE_CREATE 0x8000000000000000 + +#define EFI_FILE_READ_ONLY 0x0000000000000001 +#define EFI_FILE_HIDDEN 0x0000000000000002 +#define EFI_FILE_SYSTEM 0x0000000000000004 +#define EFI_FILE_RESERVED 0x0000000000000008 +#define EFI_FILE_DIRECTORY 0x0000000000000010 +#define EFI_FILE_ARCHIVE 0x0000000000000020 +#define EFI_FILE_VALID_ATTR 0x0000000000000037 + +typedef struct { + efi_event Event; + efi_status Status; + size_t BufferSize; + void* Buffer; +} efi_file_io_token; + +#define EFI_FILE_INFO_GUID \ + {0x09576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid FileInfoGuid; + +typedef struct { + uint64_t Size; + uint64_t FileSize; + uint64_t PhysicalSize; + efi_time CreateTime; + efi_time LastAccessTime; + efi_time ModificationTime; + uint64_t Attribute; + char16_t FileName[]; +} efi_file_info; + +#define EFI_FILE_SYSTEM_INFO_GUID \ + {0x09576e93, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid FileSystemInfoGuid; + +typedef struct { + uint64_t Size; + bool ReadOnly; + uint64_t VolumeSize; + uint64_t FreeSpace; + uint32_t BlockSize; + char16_t* VolumeLabel[]; +} efi_file_system_info; + +typedef struct efi_file_protocol { + uint64_t Revision; + + efi_status (*Open) (struct efi_file_protocol* self, struct efi_file_protocol** new_handle, + const char16_t* filename, uint64_t open_mode, uint64_t attributes) EFIAPI; + + efi_status (*Close) (struct efi_file_protocol* self) EFIAPI; + + efi_status (*Delete) (struct efi_file_protocol* self) EFIAPI; + + efi_status (*Read) (struct efi_file_protocol* self, size_t* len, void* buf) EFIAPI; + + efi_status (*Write) (struct efi_file_protocol* self, size_t* len, void* buf) EFIAPI; + + efi_status (*GetPosition) (struct efi_file_protocol* self, uint64_t* position) EFIAPI; + + efi_status (*SetPosition) (struct efi_file_protocol* self, uint64_t position) EFIAPI; + + efi_status (*GetInfo) (struct efi_file_protocol* self, efi_guid* info_type, + size_t* buf_size, void* buf) EFIAPI; + + efi_status (*SetInfo) (struct efi_file_protocol* self, efi_guid* info_type, + size_t buf_size, void* buf) EFIAPI; + + efi_status (*Flush) (struct efi_file_protocol* self) EFIAPI; + + efi_status (*OpenEx) (struct efi_file_protocol* self, struct efi_file_protocol* new_handle, + char16_t* filename, uint64_t open_mode, uint64_t attributes, + efi_file_io_token* token) EFIAPI; + + efi_status (*ReadEx) (struct efi_file_protocol* self, efi_file_io_token* token) EFIAPI; + + efi_status (*WriteEx) (struct efi_file_protocol* self, efi_file_io_token* token) EFIAPI; + + efi_status (*FlushEx) (struct efi_file_protocol* self, efi_file_io_token* token) EFIAPI; +} efi_file_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/graphics-output.h b/headers/private/kernel/platform/efi/protocol/graphics-output.h new file mode 100644 index 0000000000..772cf06960 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/graphics-output.h @@ -0,0 +1,76 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + {0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a}} +extern efi_guid GraphicsOutputProtocol; + +typedef struct { + uint32_t RedMask; + uint32_t GreenMask; + uint32_t BlueMask; + uint32_t ReservedMask; +} efi_pixel_bitmask; + +typedef enum { + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax +} efi_graphics_pixel_format; + +typedef struct { + uint32_t Version; + uint32_t HorizontalResolution; + uint32_t VerticalResolution; + efi_graphics_pixel_format PixelFormat; + efi_pixel_bitmask PixelInformation; + uint32_t PixelsPerScanLine; +} efi_graphics_output_mode_information; + +typedef struct { + uint32_t MaxMode; + uint32_t Mode; + efi_graphics_output_mode_information* Info; + size_t SizeOfInfo; + efi_physical_addr FrameBufferBase; + size_t FrameBufferSize; +} efi_graphics_output_mode; + +typedef struct { + uint8_t Blue; + uint8_t Green; + uint8_t Red; + uint8_t Reserved; +} efi_graphics_output_blt_pixel; + +typedef enum { + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphicsOutputBltOperationMax +} efi_graphics_output_blt_operation; + +typedef struct efi_graphics_output_protocol { + efi_status (*QueryMode) (struct efi_graphics_output_protocol* self, + uint32_t mode_num, size_t* info_len, + efi_graphics_output_mode_information** info) EFIAPI; + + efi_status (*SetMode) (struct efi_graphics_output_protocol* self, + uint32_t mode_num) EFIAPI; + + efi_status (*Blt) (struct efi_graphics_output_protocol* self, + efi_graphics_output_blt_pixel* blt_buf, + efi_graphics_output_blt_operation blt_operation, + size_t src_x, size_t src_y, size_t dest_x, size_t dest_y, + size_t width, size_t height, size_t delta) EFIAPI; + + efi_graphics_output_mode* Mode; +} efi_graphics_output_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/loaded-image.h b/headers/private/kernel/platform/efi/protocol/loaded-image.h new file mode 100644 index 0000000000..800d269107 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/loaded-image.h @@ -0,0 +1,32 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + {0x5b1b31a1, 0x9562, 0x11d2, {0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid LoadedImageProtocol; + +#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 + +typedef struct { + uint32_t Revision; + efi_handle ParentHandle; + efi_system_table* SystemTable; + efi_handle DeviceHandle; + efi_device_path_protocol* FilePath; + void* Reserved; + uint32_t LoadOptionsSize; + void* LoadOptions; + void* ImageBase; + uint64_t ImageSize; + efi_memory_type ImageCodeType; + efi_memory_type ImageDataType; + + efi_status (*Unload) (efi_handle img) EFIAPI; +} efi_loaded_image_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/managed-network.h b/headers/private/kernel/platform/efi/protocol/managed-network.h new file mode 100644 index 0000000000..b2d65e37b6 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/managed-network.h @@ -0,0 +1,92 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \ + {0x7ab33a91, 0xace5, 0x4326,{0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16}} +extern efi_guid ManagedNetworkProtocol; + +typedef struct { + efi_time Timestamp; + efi_event RecycleEvent; + uint32_t PacketLength; + uint32_t HeaderLength; + uint32_t AddressLength; + uint32_t DataLength; + bool BroadcastFlag; + bool MulticastFlag; + bool PromiscuousFlag; + uint16_t ProtocolType; + void* DestinationAddress; + void* SourceAddress; + void* MediaHeader; + void* PacketData; +} efi_managed_network_receive_data; + +typedef struct { + uint32_t FragmentLength; + void* FragmentBuffer; +} efi_managed_network_fragment_data; + +typedef struct { + efi_mac_addr* DestinationAddress; + efi_mac_addr* SourceAddress; + uint16_t ProtocolType; + uint32_t DataLength; + uint16_t HeaderLength; + uint16_t FragmentCount; + efi_managed_network_fragment_data FragmentTable[1]; +} efi_managed_network_transmit_data; + +typedef struct { + uint32_t ReceivedQueueTimeoutValue; + uint32_t TransmitQueueTimeoutValue; + uint16_t ProtocolTypeFilter; + bool EnableUnicastReceive; + bool EnableMulticastReceive; + bool EnableBroadcastReceive; + bool EnablePromiscuousReceive; + bool FlushQueuesOnReset; + bool EnableReceiveTimestamps; + bool DisableBackgroundPolling; +} efi_managed_network_config_data; + +typedef struct { + efi_event Event; + efi_status Status; + union { + efi_managed_network_receive_data* RxData; + efi_managed_network_transmit_data* TxData; + } Packet; +} efi_managed_network_sync_completion_token; + +typedef struct efi_managed_network_protocol { + efi_status (*GetModeData) (struct efi_managed_network_protocol* self, + efi_managed_network_config_data* mnp_config_data, + efi_simple_network_mode* snp_mode_data) EFIAPI; + + efi_status (*Configure) (struct efi_managed_network_protocol* self, + efi_managed_network_config_data* mnp_config_data) EFIAPI; + + efi_status (*McastIpToMac) (struct efi_managed_network_protocol* self, + bool ipv6_flag, efi_ip_addr* ip_addr, efi_mac_addr* mac_addr) EFIAPI; + + efi_status (*Groups) (struct efi_managed_network_protocol* self, bool join_flag, + efi_mac_addr* mac_addr) EFIAPI; + + efi_status (*Transmit) (struct efi_managed_network_protocol* self, + efi_managed_network_sync_completion_token* token) EFIAPI; + + efi_status (*Receive) (struct efi_managed_network_protocol* self, + efi_managed_network_sync_completion_token* token) EFIAPI; + + efi_status (*Cancel) (struct efi_managed_network_protocol* self, + efi_managed_network_sync_completion_token* token) EFIAPI; + + efi_status (*Poll) (struct efi_managed_network_protocol* self) EFIAPI; +} efi_managed_network_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/pci-root-bridge-io.h b/headers/private/kernel/platform/efi/protocol/pci-root-bridge-io.h new file mode 100644 index 0000000000..1e54f895c0 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/pci-root-bridge-io.h @@ -0,0 +1,115 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \ + {0x2f707ebb, 0x4a1a, 0x11D4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} +extern efi_guid PciRootBridgeIoProtocol; + +typedef enum { + EfiPciWidthUint8, + EfiPciWidthUint16, + EfiPciWidthUint32, + EfiPciWidthUint64, + EfiPciWidthFifoUint8, + EfiPciWidthFifoUint16, + EfiPciWidthFifoUint32, + EfiPciWidthFifoUint64, + EfiPciWidthFillUint8, + EfiPciWidthFillUint16, + EfiPciWidthFillUint32, + EfiPciWidthFillUint64, + EfiPciWidthMaximum, +} efi_pci_root_bridge_io_width; + +struct efi_pci_root_bridge_io_protocol; + +typedef struct { + efi_status (*Read) (struct efi_pci_root_bridge_io_protocol* self, + efi_pci_root_bridge_io_width width, + uint64_t addr, size_t count, void* buffer) EFIAPI; + efi_status (*Write) (struct efi_pci_root_bridge_io_protocol* self, + efi_pci_root_bridge_io_width width, + uint64_t addr, size_t count, void* buffer) EFIAPI; +} efi_pci_root_bridge_io_access; + +#define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 +#define EFI_PCI_ATTRIBUTE_ISA_IO 0x0002 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO 0x0004 +#define EFI_PCI_ATTRIBUTE_VGA_MEMORY 0x0008 +#define EFI_PCI_ATTRIBUTE_VGA_IO 0x0010 +#define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 +#define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 +#define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 +#define EFI_PCI_ATTRIBUTE_MEMORY_CACHED 0x0800 +#define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE 0x1000 +#define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 +#define EFI_PCI_ATTRIBUTE_ISA_IO_16 0x10000 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 +#define EFI_PCI_ATTRIBUTE_VGA_IO_16 0x40000 + +typedef enum { + EfiPciOperationBusMasterRead, + EfiPciOperationBusMasterWrite, + EfiPciOperationBusMasterCommonBuffer, + EfiPciOperationBusMasterRead64, + EfiPciOperationBusMasterWrite64, + EfiPciOperationBusMasterCommonBuffer64, + EfiPciOperationMaximum, +} efi_pci_root_bridge_io_operation; + +typedef struct efi_pci_root_bridge_io_protocol { + efi_handle ParentHandle; + + efi_status (*PollMem) (struct efi_pci_root_bridge_io_protocol *self, + efi_pci_root_bridge_io_width width, + uint64_t addr, uint64_t mask, uint64_t value, uint64_t delay, + uint64_t* result) EFIAPI; + + efi_status (*PollIo) (struct efi_pci_root_bridge_io_protocol *self, + efi_pci_root_bridge_io_width width, + uint64_t addr, uint64_t mask, uint64_t value, uint64_t delay, + uint64_t* result) EFIAPI; + + efi_pci_root_bridge_io_access Mem; + efi_pci_root_bridge_io_access Io; + efi_pci_root_bridge_io_access Pci; + + efi_status (*CopyMem) (struct efi_pci_root_bridge_io_protocol* self, + efi_pci_root_bridge_io_width width, + uint64_t dest_addr, uint64_t src_addr, size_t count) EFIAPI; + + efi_status (*Map) (struct efi_pci_root_bridge_io_protocol* self, + efi_pci_root_bridge_io_operation operation, + void* host_addr, size_t* num_bytes, + efi_physical_addr* device_addr, void** mapping) EFIAPI; + + efi_status (*Unmap) (struct efi_pci_root_bridge_io_protocol* self, + void* mapping) EFIAPI; + + efi_status (*AllocateBuffer) (struct efi_pci_root_bridge_io_protocol* self, + efi_allocate_type type, efi_memory_type memory_type, + size_t pages, void** host_addr, uint64_t attributes) EFIAPI; + + efi_status (*FreeBuffer) (struct efi_pci_root_bridge_io_protocol* self, + size_t pages, void* host_addr) EFIAPI; + + efi_status (*Flush) (struct efi_pci_root_bridge_io_protocol* self) EFIAPI; + + efi_status (*GetAttributes) (struct efi_pci_root_bridge_io_protocol* self, + uint64_t* supports, uint64_t* attributes) EFIAPI; + + efi_status (*SetAttributes) (struct efi_pci_root_bridge_io_protocol* self, + uint64_t attributes, uint64_t* resource_base, + uint64_t* resource_len) EFIAPI; + + efi_status (*Configuration) (struct efi_pci_root_bridge_io_protocol* self, + void** resources) EFIAPI; + + uint32_t SegmentNumber; +} efi_pci_root_bridge_io_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/serial-io.h b/headers/private/kernel/platform/efi/protocol/serial-io.h new file mode 100644 index 0000000000..fa338fd66c --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/serial-io.h @@ -0,0 +1,67 @@ +// Copyright 2016-2019 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include +#include + +#define EFI_SERIAL_IO_PROTOCOL_GUID \ + {0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD}} + +extern efi_guid SerialIoProtocol; + +#define EFI_SERIAL_IO_PROTOCOL_REVISION 0x00010000 + +typedef struct efi_serial_io_protocol efi_serial_io_protocol; + +typedef struct { + uint32_t ControlMask; + + // current Attributes + uint32_t Timeout; + uint64_t BaudRate; + uint32_t ReceiveFifoDepth; + uint32_t DataBits; + uint32_t Parity; + uint32_t StopBits; +} efi_serial_io_mode; + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} efi_parity_type; + +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} efi_stop_bits_type; + + +typedef struct efi_serial_io_protocol { + uint32_t Revision; + + efi_status (*Reset)(efi_serial_io_protocol* self) EFIAPI; + efi_status (*SetAttributes)(efi_serial_io_protocol* self, + uint64_t BaudRate, uint32_t ReceiveFifoDepth, + uint32_t Timeout, efi_parity_type Parity, + uint8_t DataBits, efi_stop_bits_type StopBits) EFIAPI; + efi_status (*SetControl)(efi_serial_io_protocol* self, + uint32_t Control) EFIAPI; + efi_status (*GetControl)(efi_serial_io_protocol* self, + uint32_t* Control) EFIAPI; + efi_status (*Write)(efi_serial_io_protocol* self, + size_t* BufferSize, void* Buffer) EFIAPI; + efi_status (*Read)(efi_serial_io_protocol* self, + size_t* BufferSize, void* Buffer) EFIAPI; + + efi_serial_io_mode* Mode; +} efi_serial_io_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/simple-file-system.h b/headers/private/kernel/platform/efi/protocol/simple-file-system.h new file mode 100644 index 0000000000..ad7c42afa6 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/simple-file-system.h @@ -0,0 +1,21 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + {0x0964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid SimpleFileSystemProtocol; + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 + +typedef struct efi_simple_file_system_protocol { + uint64_t Revision; + + efi_status (*OpenVolume) (struct efi_simple_file_system_protocol* self, + efi_file_protocol** root) EFIAPI; +} efi_simple_file_system_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/simple-network.h b/headers/private/kernel/platform/efi/protocol/simple-network.h new file mode 100644 index 0000000000..745bf41e63 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/simple-network.h @@ -0,0 +1,132 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ + {0xa19832b9, 0xac25, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} +extern efi_guid SimpleNetworkProtocol; + +#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 + +#define MAX_MCAST_FILTER_CNT 16 +typedef struct { + uint32_t State; + uint32_t HwAddressSize; + uint32_t MediaHeaderSize; + uint32_t MaxPacketSize; + uint32_t NvRamSize; + uint32_t NvRamAccessSize; + uint32_t ReceiveFilterMask; + uint32_t ReceiveFilterSetting; + uint32_t MaxMCastFilterCount; + uint32_t MCastFilterCount; + efi_mac_addr MCastFilter[MAX_MCAST_FILTER_CNT]; + efi_mac_addr CurrentAddress; + efi_mac_addr BroadcastAddress; + efi_mac_addr PermanentAddress; + uint8_t IfType; + bool MacAddressChangeable; + bool MultipleTxSupported; + bool MediaPresentSupported; + bool MediaPresent; +} efi_simple_network_mode; + +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 + +typedef struct { + uint64_t RxTotalFrames; + uint64_t RxGoodFrames; + uint64_t RxUndersizeFrames; + uint64_t RxOversizeFrames; + uint64_t RxDroppedFrames; + uint64_t RxUnicastFrames; + uint64_t RxBroadcastFrames; + uint64_t RxMulticastFrames; + uint64_t RxCrcErrorFrames; + uint64_t RxTotalBytes; + uint64_t TxTotalFrames; + uint64_t TxGoodFrames; + uint64_t TxUndersizeFrames; + uint64_t TxOversizeFrames; + uint64_t TxDroppedFrames; + uint64_t TxUnicastFrames; + uint64_t TxBroadcastFrames; + uint64_t TxMulticastFrames; + uint64_t TxCrcErrorFrames; + uint64_t TxTotalBytes; + uint64_t Collisions; + uint64_t UnsupportedProtocol; + uint64_t RxDuplicatedFrames; + uint64_t RxDecryptErrorFrames; + uint64_t TxErrorFrames; + uint64_t TxRetryFrames; +} efi_network_statistics; + +#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 + +typedef struct efi_simple_network_protocol { + uint64_t Revision; + + efi_status (*Start) (struct efi_simple_network_protocol* self) EFIAPI; + + efi_status (*Stop) (struct efi_simple_network_protocol* self) EFIAPI; + + efi_status (*Initialize) (struct efi_simple_network_protocol* self, + size_t extra_rx_buf_size, size_t extra_tx_buf_size) EFIAPI; + + efi_status (*Reset) (struct efi_simple_network_protocol* self, + bool extended_verification) EFIAPI; + + efi_status (*Shutdown) (struct efi_simple_network_protocol* self) EFIAPI; + + efi_status (*ReceiveFilters) (struct efi_simple_network_protocol* self, + uint32_t enable, uint32_t disable, + bool reset_mcast_filter, size_t mcast_filter_count, + efi_mac_addr* mcast_filter) EFIAPI; + + efi_status (*StationAddress) (struct efi_simple_network_protocol* self, + bool reset, efi_mac_addr* new_addr) EFIAPI; + + efi_status (*Statistics) (struct efi_simple_network_protocol* self, + bool reset, size_t* stats_size, + efi_network_statistics* stats_table) EFIAPI; + + efi_status (*MCastIpToMac) (struct efi_simple_network_protocol* self, + bool ipv6, efi_ip_addr* ip, efi_mac_addr* mac) EFIAPI; + + efi_status (*NvData) (struct efi_simple_network_protocol* self, + bool read_write, size_t offset, size_t buf_size, void* buf) EFIAPI; + + efi_status (*GetStatus) (struct efi_simple_network_protocol* self, + uint32_t* interrupt_status, void** tx_buf) EFIAPI; + + efi_status (*Transmit) (struct efi_simple_network_protocol* self, + size_t header_size, size_t buf_size, void* buf, + efi_mac_addr* src, efi_mac_addr* dest, uint16_t* protocol) EFIAPI; + + efi_status (*Receive) (struct efi_simple_network_protocol* self, + size_t* header_size, size_t* buf_size, void* buf, + efi_mac_addr* src, efi_mac_addr* dest, uint16_t* protocol) EFIAPI; + + efi_event WaitForPacket; + efi_simple_network_mode* Mode; +} efi_simple_network_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/simple-text-input.h b/headers/private/kernel/platform/efi/protocol/simple-text-input.h new file mode 100644 index 0000000000..ee6bf687bf --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/simple-text-input.h @@ -0,0 +1,26 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + {0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid SimpleTextInputProtocol; + +typedef struct { + uint16_t ScanCode; + char16_t UnicodeChar; +} efi_input_key; + +typedef struct efi_simple_text_input_protocol { + efi_status (*Reset) (struct efi_simple_text_input_protocol* self, + bool extendend_verification) EFIAPI; + + efi_status (*ReadKeyStroke) (struct efi_simple_text_input_protocol* self, + efi_input_key* key) EFIAPI; + + efi_event WaitForKey; +} efi_simple_text_input_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/simple-text-output.h b/headers/private/kernel/platform/efi/protocol/simple-text-output.h new file mode 100644 index 0000000000..6ff0816d6b --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/simple-text-output.h @@ -0,0 +1,143 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ + {0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +extern efi_guid SimpleTextOutputProtocol; + +typedef struct { + int32_t MaxMode; + int32_t Mode; + int32_t Attribute; + int32_t CursorColumn; + int32_t CursorRow; + bool CursorVisible; +} simple_text_output_mode; + +//******************************************************* +// UNICODE DRAWING CHARACTERS +//******************************************************* +#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 + +//******************************************************* +// Attributes +//******************************************************* +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN 0x03 +#define EFI_RED 0x04 +#define EFI_ZIRCON 0x05 +#define EFI_BROWN 0x06 +#define EFI_LIGHTGRAY 0x07 +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY 0x08 +#define EFI_LIGHTBLUE 0x09 +#define EFI_LIGHTGREEN 0x0A +#define EFI_LIGHTCYAN 0x0B +#define EFI_LIGHTRED 0x0C +#define EFI_LIGHTZIRCON 0x0D +#define EFI_YELLOW 0x0E +#define EFI_WHITE 0x0F +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN 0x30 +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_ZIRCON 0x50 +#define EFI_BACKGROUND_BROWN 0x60 +#define EFI_BACKGROUND_LIGHTGRAY 0x70 + +typedef struct efi_simple_text_output_protocol { + efi_status (*Reset) (struct efi_simple_text_output_protocol* self, + bool extended_verification) EFIAPI; + + efi_status (*OutputString) (struct efi_simple_text_output_protocol* self, + char16_t* string) EFIAPI; + + efi_status (*TestString) (struct efi_simple_text_output_protocol* self, + char16_t* string) EFIAPI; + + efi_status (*QueryMode) (struct efi_simple_text_output_protocol* self, + size_t mode_num, size_t* cols, size_t* rows) EFIAPI; + + efi_status (*SetMode) (struct efi_simple_text_output_protocol* self, + size_t mode_num) EFIAPI; + + efi_status (*SetAttribute) (struct efi_simple_text_output_protocol* self, + size_t attribute) EFIAPI; + + efi_status (*ClearScreen) (struct efi_simple_text_output_protocol* self) EFIAPI; + + efi_status (*SetCursorPosition) (struct efi_simple_text_output_protocol* self, + size_t col, size_t row) EFIAPI; + + efi_status (*EnableCursor) (struct efi_simple_text_output_protocol* self, + bool visible) EFIAPI; + + simple_text_output_mode* Mode; +} efi_simple_text_output_protocol; diff --git a/headers/private/kernel/platform/efi/protocol/usb-io.h b/headers/private/kernel/platform/efi/protocol/usb-io.h new file mode 100644 index 0000000000..721ce92cf1 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/usb-io.h @@ -0,0 +1,147 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#define EFI_USB_IO_PROTOCOL_GUID \ + {0x2b2f68d6, 0x0cd2, 0x44cf, {0x8e, 0x8b, 0xbb, 0xa2, 0x0b, 0x1b, 0x5b, 0x75}} +extern efi_guid UsbIoProtocol; + +typedef enum { + EfiUsbDataIn, + EfiUsbDataOut, + EfiUsbNoData +} efi_usb_data_direction; + +#define EFI_USB_NOERROR 0x0000 +#define EFI_USB_ERR_NOTEXECUTE 0x0001 +#define EFI_USB_ERR_STALL 0x0002 +#define EFI_USB_ERR_BUFFER 0x0004 +#define EFI_USB_ERR_BABBLE 0x0008 +#define EFI_USB_ERR_NAK 0x0010 +#define EFI_USB_ERR_CRC 0x0020 +#define EFI_USB_ERR_TIMEOUT 0x0040 +#define EFI_USB_ERR_BITSTUFF 0x0080 +#define EFI_USB_ERR_SYSTEM 0x0100 + +typedef struct { + uint8_t RequestType; + uint8_t Request; + uint16_t Value; + uint16_t Index; + uint16_t Length; +} efi_usb_device_request; + +typedef efi_status (*efi_async_usb_transfer_callback) ( + void* Data, size_t DataLength, void* Context, uint32_t Status) EFIAPI; + +typedef struct { + uint8_t Length; + uint8_t DescriptorType; + uint16_t BcdUSB; + uint8_t DeviceClass; + uint8_t DeviceSubClass; + uint8_t DeviceProtocol; + uint8_t MaxPacketSize0; + uint16_t IdVendor; + uint16_t IdProduct; + uint16_t BcdDevice; + uint8_t StrManufacturer; + uint8_t StrProduct; + uint8_t StrSerialNumber; + uint8_t NumConfigurations; +} efi_usb_device_descriptor; + +typedef struct { + uint8_t Length; + uint8_t DescriptorType; + uint16_t TotalLength; + uint8_t NumInterfaces; + uint8_t ConfigurationValue; + uint8_t Configuration; + uint8_t Attributes; + uint8_t MaxPower; +} efi_usb_config_descriptor; + +typedef struct { + uint8_t Length; + uint8_t DescriptorType; + uint8_t InterfaceNumber; + uint8_t AlternateSetting; + uint8_t NumEndpoints; + uint8_t InterfaceClass; + uint8_t InterfaceSubClass; + uint8_t InterfaceProtocol; + uint8_t Interface; +} efi_usb_interface_descriptor; + +typedef struct { + uint8_t Length; + uint8_t DescriptorType; + uint8_t EndpointAddress; + uint8_t Attributes; + uint16_t MaxPacketSize; + uint8_t Interval; +} efi_usb_endpoint_descriptor; + +typedef struct efi_usb_io_protocol { + efi_status (*UsbControlTransfer) (struct efi_usb_io_protocol* self, + efi_usb_device_request* request, + efi_usb_data_direction direction, + uint32_t timeout, void* data, + size_t data_len, uint32_t* status) EFIAPI; + + efi_status (*UsbBulkTransfer) (struct efi_usb_io_protocol* self, + uint8_t endpoint, void* data, + size_t data_len, size_t timeout, + uint32_t* status) EFIAPI; + + efi_status (*UsbAsyncInterruptTransfer) (struct efi_usb_io_protocol* self, + uint8_t endpoint, bool is_new_transfer, + size_t polling_interval, + size_t data_len, + efi_async_usb_transfer_callback interrupt_cb, + void* context) EFIAPI; + + efi_status (*UsbSyncInterruptTransfer) (struct efi_usb_io_protocol* self, + uint8_t endpoint, void* data, + size_t* data_len, size_t timeout, + uint32_t* status) EFIAPI; + + efi_status (*UsbIsochronousTransfer) (struct efi_usb_io_protocol* self, + uint8_t endpoint, + void* data, size_t data_len, + uint32_t* status) EFIAPI; + + efi_status (*UsbAsyncIsochronousTransfer) (struct efi_usb_io_protocol* self, + uint8_t endpoint, + void* data, size_t data_len, + efi_async_usb_transfer_callback isoc_cb, + void* context) EFIAPI; + + efi_status (*UsbGetDeviceDescriptor) (struct efi_usb_io_protocol* self, + efi_usb_device_descriptor* descriptor) EFIAPI; + + efi_status (*UsbGetConfigDescriptor) (struct efi_usb_io_protocol* self, + efi_usb_config_descriptor* descriptor) EFIAPI; + + efi_status (*UsbGetInterfaceDescriptor) (struct efi_usb_io_protocol* self, + efi_usb_interface_descriptor* descriptor) EFIAPI; + + efi_status (*UsbGetEndpointDescriptor) (struct efi_usb_io_protocol* self, + uint8_t endpt_index, + efi_usb_endpoint_descriptor* descriptor) EFIAPI; + + efi_status (*UsbGetStringDescriptor) (struct efi_usb_io_protocol* self, + uint16_t langid, uint8_t stringid, + char16_t** str) EFIAPI; + + efi_status (*UsbGetSupportedLanguages) (struct efi_usb_io_protocol* self, + uint16_t** langid_table, + uint16_t* table_size) EFIAPI; + + efi_status (*UsbPortReset) (struct efi_usb_io_protocol* self) EFIAPI; +} efi_usb_io_protocol; diff --git a/headers/private/kernel/platform/efi/runtime-services.h b/headers/private/kernel/platform/efi/runtime-services.h new file mode 100644 index 0000000000..613b34f254 --- /dev/null +++ b/headers/private/kernel/platform/efi/runtime-services.h @@ -0,0 +1,151 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 + +// TODO: implement the win_certificate structs if we need them +//typedef struct { +// uint64_t MonotonicCount; +// win_certificate_uefi_guid AuthInfo; +//} efi_variable_authentication; +// +//typedef struct { +// efi_time TimeStamp; +// win_certificate_uefi_guid AuthInfo; +//} efi_variable_authentication_2; + +#define EFI_HARDWARE_ERROR_VARIABLE \ + {0x414e6bdd, 0xe47b, 0x47cc, {0xb2, 0x44, 0xbb, 0x61, 0x02, 0x0c, 0xf5, 0x16}} + +typedef struct { + uint16_t Year; + uint8_t Month; + uint8_t Day; + uint8_t Hour; + uint8_t Minute; + uint8_t Second; + uint8_t Pad1; + uint32_t Nanosecond; + int16_t TimeZone; + uint8_t Daylight; + uint8_t Pad2; +} efi_time; + +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + +typedef struct { + uint32_t Resolution; + uint32_t Accuracy; + bool SetsToZero; +} efi_time_capabilities; + +#define EFI_OPTIONAL_PTR 0x00000001 + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown, + EfiResetPlatformSpecific +} efi_reset_type; + +typedef struct { + uint64_t Length; + union { + efi_physical_addr DataBlock; + efi_physical_addr ContinuationPointer; + } Union; +} efi_capsule_block_descriptor; + +typedef struct { + efi_guid CapsuleGuid; + uint32_t HeaderSize; + uint32_t Flags; + uint32_t CapsuleImageSize; +} efi_capsule_header; + +#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 +#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 +#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 + +#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001 +#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION 0x0000000000000002 +#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 0x0000000000000004 +#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED 0x0000000000000008 +#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED 0x0000000000000010 +#define EFI_OS_INDICATIONS_START_OS_RECOVERY 0x0000000000000020 +#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY 0x0000000000000040 + +#define EFI_CAPSULE_REPORT_GUID \ + {0x39b68c46, 0xf7fb, 0x441b, {0xb6, 0xec, 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3}} + +typedef struct { + uint32_t VariableTotalSize; + uint32_t Reserved; + efi_guid CapsuleGuid; + efi_time CapsuleProcessed; + efi_status CapsuleStatus; +} efi_capsule_result_variable_header; + +typedef struct { + efi_table_header Hdr; + + efi_status (*GetTime) (efi_time* time, efi_time_capabilities* capabilities) EFIAPI; + + efi_status (*SetTime) (efi_time* time) EFIAPI; + + efi_status (*GetWakeupTime) (bool* enabled, bool* pending, efi_time* time) EFIAPI; + + efi_status (*SetWakeupTime) (bool enable, efi_time* time) EFIAPI; + + efi_status (*SetVirtualAddressMap) (size_t memory_map_size, size_t desc_size, + uint32_t desc_version, + efi_memory_descriptor* virtual_map) EFIAPI; + + efi_status (*ConvertPointer) (size_t debug_disposition, void** addr) EFIAPI; + + efi_status (*GetVariable) (char16_t* var_name, efi_guid* vendor_guid, + uint32_t* attributes, size_t* data_size, void* data) EFIAPI; + + efi_status (*GetNextVariableName) (size_t* var_name_size, char16_t* var_name, + efi_guid* vendor_guid) EFIAPI; + + efi_status (*SetVariable) (char16_t* var_name, efi_guid* vendor_guid, + uint32_t attributes, size_t data_size, void* data) EFIAPI; + + efi_status (*GetNextHighMonotonicCount) (uint32_t* high_count) EFIAPI; + + efi_status (*ResetSystem) (efi_reset_type reset_type, efi_status reset_status, + size_t data_size, void* reset_data) EFIAPI; + + efi_status (*UpdateCapsule) (efi_capsule_header** capsule_header_array, + size_t capsule_count, + efi_physical_addr scatter_gather_list) EFIAPI; + + efi_status (*QueryCapsuleCapabilities) (efi_capsule_header** capsule_header_array, + size_t capsule_count, + uint64_t* max_capsule_size, + efi_reset_type* reset_type) EFIAPI; + + efi_status (*QueryVariableInfo) (uint32_t attributes, + uint64_t* max_var_storage_size, + uint64_t* remaining_var_storage_size, + uint64_t* max_var_size) EFIAPI; +} efi_runtime_services; diff --git a/headers/private/kernel/platform/efi/system-table.h b/headers/private/kernel/platform/efi/system-table.h new file mode 100644 index 0000000000..3f145af63d --- /dev/null +++ b/headers/private/kernel/platform/efi/system-table.h @@ -0,0 +1,48 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#include +#include +#include +#include +#include + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_2_60_SYSTEM_TABLE_REVISION ((2<<16) | (60)) +#define EFI_2_50_SYSTEM_TABLE_REVISION ((2<<16) | (50)) +#define EFI_2_40_SYSTEM_TABLE_REVISION ((2<<16) | (40)) +#define EFI_2_31_SYSTEM_TABLE_REVISION ((2<<16) | (31)) +#define EFI_2_30_SYSTEM_TABLE_REVISION ((2<<16) | (30)) +#define EFI_2_20_SYSTEM_TABLE_REVISION ((2<<16) | (20)) +#define EFI_2_10_SYSTEM_TABLE_REVISION ((2<<16) | (10)) +#define EFI_2_00_SYSTEM_TABLE_REVISION ((2<<16) | (00)) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | (10)) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | (02)) +#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION +#define EFI_SYSTEM_TABLE_REVISION EFI_2_60_SYSTEM_TABLE_REVISION + +typedef struct { + efi_guid VendorGuid; + void* VendorTable; +} efi_configuration_table; + +typedef struct efi_system_table { + efi_table_header Hdr; + char16_t* FirmwareVendor; + uint32_t FirmwareRevision; + efi_handle ConsoleInHandle; + efi_simple_text_input_protocol* ConIn; + efi_handle ConsoleOutHandle; + efi_simple_text_output_protocol* ConOut; + efi_handle StandardErrorHandle; + efi_simple_text_output_protocol* StdErr; + efi_runtime_services *RuntimeServices; + efi_boot_services* BootServices; + size_t NumberOfTableEntries; + efi_configuration_table *ConfigurationTable; +} efi_system_table; diff --git a/headers/private/kernel/platform/efi/types.h b/headers/private/kernel/platform/efi/types.h new file mode 100644 index 0000000000..3ccb671535 --- /dev/null +++ b/headers/private/kernel/platform/efi/types.h @@ -0,0 +1,150 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#define EFIAPI __attribute__((ms_abi)) + +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFI_ERR(x) (EFI_ERROR_MASK | x) +#define EFI_ERROR(x) (((int64_t)x) < 0) + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFI_ERR(1) +#define EFI_INVALID_PARAMETER EFI_ERR(2) +#define EFI_UNSUPPORTED EFI_ERR(3) +#define EFI_BAD_BUFFER_SIZE EFI_ERR(4) +#define EFI_BUFFER_TOO_SMALL EFI_ERR(5) +#define EFI_NOT_READY EFI_ERR(6) +#define EFI_DEVICE_ERROR EFI_ERR(7) +#define EFI_WRITE_PROTECTED EFI_ERR(8) +#define EFI_OUT_OF_RESOURCES EFI_ERR(9) +#define EFI_VOLUME_CORRUPTED EFI_ERR(10) +#define EFI_VOLUME_FULL EFI_ERR(11) +#define EFI_NO_MEDIA EFI_ERR(12) +#define EFI_MEDIA_CHANGED EFI_ERR(13) +#define EFI_NOT_FOUND EFI_ERR(14) +#define EFI_ACCESS_DENIED EFI_ERR(15) +#define EFI_NO_RESPONSE EFI_ERR(16) +#define EFI_NO_MAPPING EFI_ERR(17) +#define EFI_TIMEOUT EFI_ERR(18) +#define EFI_NOT_STARTED EFI_ERR(19) +#define EFI_ALREADY_STARTED EFI_ERR(20) +#define EFI_ABORTED EFI_ERR(21) +#define EFI_ICMP_ERROR EFI_ERR(22) +#define EFI_TFTP_ERROR EFI_ERR(23) +#define EFI_PROTOCOL_ERROR EFI_ERR(24) +#define EFI_INCOMPATIBLE_VERSION EFI_ERR(25) +#define EFI_SECURITY_VIOLATION EFI_ERR(26) +#define EFI_CRC_ERROR EFI_ERR(27) +#define EFI_END_OF_MEDIA EFI_ERR(28) +#define EFI_END_OF_FILE EFI_ERR(31) +#define EFI_INVALID_LANGUAGE EFI_ERR(32) +#define EFI_COMPROMISED_DATA EFI_ERR(33) +#define EFI_IP_ADDRESS_CONFLICT EFI_ERR(34) +#define EFI_HTTP_ERROR EFI_ERR(35) + +// TODO: figure out where to put these. They're just mentioned in passing in the +// spec as some of many industry standard GUIDs but not part of the spec itself. +#define ACPI_TABLE_GUID \ + {0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} +#define ACPI_20_TABLE_GUID \ + {0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}} +#define SMBIOS_TABLE_GUID \ + {0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} +#define SMBIOS3_TABLE_GUID \ + {0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94}} + +typedef struct { + uint64_t Signature; + uint32_t Revision; + uint32_t HeaderSize; + uint32_t CRC32; + uint32_t Reserved; +} efi_table_header; + +typedef struct efi_guid { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +} efi_guid; + +typedef void* efi_handle; + +typedef size_t efi_status; + +typedef struct { + uint8_t addr[32]; +} efi_mac_addr; + +typedef struct { + uint8_t addr[4]; +} efi_ipv4_addr; + +typedef struct { + uint8_t addr[16]; +} efi_ipv6_addr; + +typedef union { + efi_ipv4_addr v4; + efi_ipv6_addr v6; +} efi_ip_addr; + +// This really belongs in boot-services.h, but causes circular dependencies with +// device-path.h. +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiMaxMemoryType +} efi_memory_type; + +typedef uint64_t efi_physical_addr; +typedef uint64_t efi_virtual_addr; + +typedef void* efi_event; + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#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 EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \ + {0x27abf055, 0xb1b8, 0x4c26, {0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf}} +#define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \ + {0x13fa7698, 0xc831, 0x49c7, {0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96}} +#define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \ + {0x78bee926, 0x692f, 0x48fd, {0x9e, 0xdb, 0x01, 0x42, 0x2e, 0xf0, 0xd7, 0xab}} +#define EFI_EVENT_GROUP_READY_TO_BOOT \ + {0x7ce88fb3, 0x4bd7, 0x4679, {0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b}} + +typedef void (*efi_event_notify) (efi_event event, void* ctx) EFIAPI; + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative +} efi_timer_delay; + +#ifndef __cplusplus +typedef unsigned short char16_t; +#endif diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index 08d510d65e..1675833a42 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -1,11 +1,10 @@ SubDir HAIKU_TOP src system boot platform efi ; UsePrivateHeaders [ FDirName kernel boot ] ; +UsePrivateHeaders [ FDirName kernel platform ] ; UsePrivateHeaders [ FDirName kernel boot platform efi ] ; UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; -UseBuildFeatureHeaders gnuefi ; -UseBuildFeatureHeaders gnuefi : headersProtocol ; -UseBuildFeatureHeaders gnuefi : headersArch ; + SubDirHdrs $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ; { @@ -15,10 +14,6 @@ SubDirHdrs $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ; SubDirC++Flags $(defines) -fno-rtti ; } -local efi_glue_src = - crt0-efi-$(TARGET_ARCH).S - ; - local platform_src = start.cpp console.cpp @@ -37,19 +32,11 @@ local platform_src = support.S ; -Includes [ FGristFiles $(efi_glue_src) $(platform_src) ] - : - [ BuildFeatureAttribute gnuefi : headers ] - [ BuildFeatureAttribute gnuefi : headersProtocol ] - [ BuildFeatureAttribute gnuefi : headersArch ] - ; - local platform ; for platform in [ MultiBootSubDirSetup efi ] { on $(platform) { BootMergeObject boot_platform_efi_common.o : - $(efi_glue_src) $(platform_src) : : boot_platform_generic_efi.a @@ -60,13 +47,6 @@ for platform in [ MultiBootSubDirSetup efi ] { boot_platform_efi_$(TARGET_ARCH).o boot_platform_efi_common.o ; - - LOCATE on [ FGristFiles $(efi_glue_src) ] - = [ BuildFeatureAttribute gnuefi : libdir : path ] ; - Depends [ FGristFiles $(efi_glue_src) ] - : [ BuildFeatureAttribute gnuefi : libdir ] ; - Depends [ FGristFiles $(platform_src) ] - : [ BuildFeatureAttribute gnuefi : headers ] ; } } diff --git a/src/system/boot/platform/efi/acpi.cpp b/src/system/boot/platform/efi/acpi.cpp index fe5a23d997..8056149545 100644 --- a/src/system/boot/platform/efi/acpi.cpp +++ b/src/system/boot/platform/efi/acpi.cpp @@ -232,20 +232,20 @@ acpi_find_table(const char* signature) void acpi_init() { - EFI_GUID acpi = ACPI_20_TABLE_GUID; - EFI_CONFIGURATION_TABLE *table = kSystemTable->ConfigurationTable; - UINTN entries = kSystemTable->NumberOfTableEntries; + efi_guid acpi = ACPI_20_TABLE_GUID; + efi_configuration_table *table = kSystemTable->ConfigurationTable; + size_t entries = kSystemTable->NumberOfTableEntries; // Try to find the ACPI RSDP. for (uint32 i = 0; i < entries; i++) { acpi_rsdp *rsdp = NULL; - EFI_GUID vendor = table[i].VendorGuid; + efi_guid vendor = table[i].VendorGuid; - if (vendor.Data1 == acpi.Data1 - && vendor.Data2 == acpi.Data2 - && vendor.Data3 == acpi.Data3 - && strncmp((char *)vendor.Data4, (char *)acpi.Data4, 8) == 0) { + if (vendor.data1 == acpi.data1 + && vendor.data2 == acpi.data2 + && vendor.data3 == acpi.data3 + && strncmp((char *)vendor.data4, (char *)acpi.data4, 8) == 0) { rsdp = (acpi_rsdp *)(table[i].VendorTable); if (strncmp((char *)rsdp, ACPI_RSDP_SIGNATURE, 8) == 0) TRACE(("acpi_init: found ACPI RSDP signature at %p\n", rsdp)); diff --git a/src/system/boot/platform/efi/arch/arm/Jamfile b/src/system/boot/platform/efi/arch/arm/Jamfile index 9b25f3fe40..c4940fa88b 100644 --- a/src/system/boot/platform/efi/arch/arm/Jamfile +++ b/src/system/boot/platform/efi/arch/arm/Jamfile @@ -2,10 +2,8 @@ SubDir HAIKU_TOP src system boot platform efi arch arm ; SubDirHdrs $(HAIKU_TOP) src system boot platform efi ; +UsePrivateHeaders [ FDirName kernel platform ] ; UsePrivateHeaders [ FDirName kernel boot platform efi ] ; -UseBuildFeatureHeaders gnuefi ; -UseBuildFeatureHeaders gnuefi : headersProtocol ; -UseBuildFeatureHeaders gnuefi : headersArch ; local arch_src = #entry.S @@ -18,13 +16,3 @@ local arch_src = BootMergeObject boot_platform_efi_arm.o : $(arch_src) ; - -Includes [ FGristFiles $(arch_src) ] - : - [ BuildFeatureAttribute gnuefi : headers ] - [ BuildFeatureAttribute gnuefi : headersProtocol ] - [ BuildFeatureAttribute gnuefi : headersArch ] - ; - -Depends [ FGristFiles $(arch_src) ] - : [ BuildFeatureAttribute gnuefi : libdir ] ; diff --git a/src/system/boot/platform/efi/arch/arm/crt0-efi-arm.S b/src/system/boot/platform/efi/arch/arm/crt0-efi-arm.S new file mode 100644 index 0000000000..c5bb6d482d --- /dev/null +++ b/src/system/boot/platform/efi/arch/arm/crt0-efi-arm.S @@ -0,0 +1,145 @@ +/* + * crt0-efi-arm.S - PE/COFF header for ARM EFI applications + * + * Copright (C) 2014 Linaro Ltd. + * + * 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 and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + + .section .text.head + + /* + * Magic "MZ" signature for PE/COFF + */ + .globl ImageBase +ImageBase: + .ascii "MZ" + .skip 58 // 'MZ' + pad + offset == 64 + .long pe_header - ImageBase // Offset to the PE header. +pe_header: + .ascii "PE" + .short 0 +coff_header: + .short 0x1c2 // Mixed ARM/Thumb + .short 2 // nr_sections + .long 0 // TimeDateStamp + .long 0 // PointerToSymbolTable + .long 1 // NumberOfSymbols + .short section_table - optional_header // SizeOfOptionalHeader + .short 0x306 // Characteristics. + // IMAGE_FILE_32BIT_MACHINE | + // IMAGE_FILE_DEBUG_STRIPPED | + // IMAGE_FILE_EXECUTABLE_IMAGE | + // IMAGE_FILE_LINE_NUMS_STRIPPED +optional_header: + .short 0x10b // PE32+ format + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion + .long _edata - _start // SizeOfCode + .long 0 // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long _start - ImageBase // AddressOfEntryPoint + .long _start - ImageBase // BaseOfCode + .long 0 // BaseOfData + +extra_header_fields: + .long 0 // ImageBase + .long 0x20 // SectionAlignment + .long 0x8 // FileAlignment + .short 0 // MajorOperatingSystemVersion + .short 0 // MinorOperatingSystemVersion + .short 0 // MajorImageVersion + .short 0 // MinorImageVersion + .short 0 // MajorSubsystemVersion + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + + .long _edata - ImageBase // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long _start - ImageBase // SizeOfHeaders + .long 0 // CheckSum + .short EFI_SUBSYSTEM // Subsystem + .short 0 // DllCharacteristics + .long 0 // SizeOfStackReserve + .long 0 // SizeOfStackCommit + .long 0 // SizeOfHeapReserve + .long 0 // SizeOfHeapCommit + .long 0 // LoaderFlags + .long 0x6 // NumberOfRvaAndSizes + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable + + // Section table +section_table: + + /* + * The EFI application loader requires a relocation section + * because EFI applications must be relocatable. This is a + * dummy section as far as we are concerned. + */ + .ascii ".reloc" + .byte 0 + .byte 0 // end of 0 padding of section name + .long 0 + .long 0 + .long 0 // SizeOfRawData + .long 0 // PointerToRawData + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long 0x42100040 // Characteristics (section flags) + + + .ascii ".text" + .byte 0 + .byte 0 + .byte 0 // end of 0 padding of section name + .long _edata - _start // VirtualSize + .long _start - ImageBase // VirtualAddress + .long _edata - _start // SizeOfRawData + .long _start - ImageBase // PointerToRawData + + .long 0 // PointerToRelocations (0 for executables) + .long 0 // PointerToLineNumbers (0 for executables) + .short 0 // NumberOfRelocations (0 for executables) + .short 0 // NumberOfLineNumbers (0 for executables) + .long 0xe0500020 // Characteristics (section flags) + +_start: + stmfd sp!, {r0-r2, lr} + + mov r2, r0 + mov r3, r1 + adr r1, .L_DYNAMIC + ldr r0, [r1] + add r1, r0, r1 + adr r0, ImageBase + bl _relocate + teq r0, #0 + bne 0f + + ldmfd sp, {r0-r1} + bl efi_main + +0: add sp, sp, #12 + ldr pc, [sp], #4 + +.L_DYNAMIC: + .word _DYNAMIC - . diff --git a/src/system/boot/platform/efi/arch/arm/relocation_func.cpp b/src/system/boot/platform/efi/arch/arm/relocation_func.cpp index 7585066695..c0e4ee7b12 100644 --- a/src/system/boot/platform/efi/arch/arm/relocation_func.cpp +++ b/src/system/boot/platform/efi/arch/arm/relocation_func.cpp @@ -34,14 +34,14 @@ SUCH DAMAGE. */ -#include +#include #include #include -EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn, - EFI_HANDLE image EFI_UNUSED, - EFI_SYSTEM_TABLE *systab EFI_UNUSED) +efi_status _relocate(long ldbase, Elf32_Dyn *dyn, + efi_handle image EFI_UNUSED, + efi_system_table *systab EFI_UNUSED) { long relsz = 0, relent = 0; Elf32_Rel *rel = 0; diff --git a/src/system/boot/platform/efi/arch/arm64/crt0-efi-arm64.S b/src/system/boot/platform/efi/arch/arm64/crt0-efi-arm64.S new file mode 100644 index 0000000000..c300d89bdf --- /dev/null +++ b/src/system/boot/platform/efi/arch/arm64/crt0-efi-arm64.S @@ -0,0 +1,130 @@ +/* + * crt0-efi-aarch64.S - PE/COFF header for AArch64 EFI applications + * + * Copright (C) 2014 Linaro Ltd. + * + * 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 and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + + .section .text.head + + /* + * Magic "MZ" signature for PE/COFF + */ + .globl ImageBase +ImageBase: + .ascii "MZ" + .skip 58 // 'MZ' + pad + offset == 64 + .long pe_header - ImageBase // Offset to the PE header. +pe_header: + .ascii "PE" + .short 0 +coff_header: + .short 0xaa64 // AArch64 + .short 2 // nr_sections + .long 0 // TimeDateStamp + .long 0 // PointerToSymbolTable + .long 1 // NumberOfSymbols + .short section_table - optional_header // SizeOfOptionalHeader + .short 0x206 // Characteristics. + // IMAGE_FILE_DEBUG_STRIPPED | + // IMAGE_FILE_EXECUTABLE_IMAGE | + // IMAGE_FILE_LINE_NUMS_STRIPPED +optional_header: + .short 0x20b // PE32+ format + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion + .long _data - _start // SizeOfCode + .long _data_size // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long _start - ImageBase // AddressOfEntryPoint + .long _start - ImageBase // BaseOfCode + +extra_header_fields: + .quad 0 // ImageBase + .long 0x1000 // SectionAlignment + .long 0x200 // FileAlignment + .short 0 // MajorOperatingSystemVersion + .short 0 // MinorOperatingSystemVersion + .short 0 // MajorImageVersion + .short 0 // MinorImageVersion + .short 0 // MajorSubsystemVersion + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + + .long _edata - ImageBase // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long _start - ImageBase // SizeOfHeaders + .long 0 // CheckSum + .short EFI_SUBSYSTEM // Subsystem + .short 0 // DllCharacteristics + .quad 0 // SizeOfStackReserve + .quad 0 // SizeOfStackCommit + .quad 0 // SizeOfHeapReserve + .quad 0 // SizeOfHeapCommit + .long 0 // LoaderFlags + .long 0x6 // NumberOfRvaAndSizes + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable + + // Section table +section_table: + .ascii ".text\0\0\0" + .long _data - _start // VirtualSize + .long _start - ImageBase // VirtualAddress + .long _data - _start // SizeOfRawData + .long _start - ImageBase // PointerToRawData + + .long 0 // PointerToRelocations (0 for executables) + .long 0 // PointerToLineNumbers (0 for executables) + .short 0 // NumberOfRelocations (0 for executables) + .short 0 // NumberOfLineNumbers (0 for executables) + .long 0x60000020 // Characteristics (section flags) + + .ascii ".data\0\0\0" + .long _data_size // VirtualSize + .long _data - ImageBase // VirtualAddress + .long _data_size // SizeOfRawData + .long _data - ImageBase // PointerToRawData + + .long 0 // PointerToRelocations (0 for executables) + .long 0 // PointerToLineNumbers (0 for executables) + .short 0 // NumberOfRelocations (0 for executables) + .short 0 // NumberOfLineNumbers (0 for executables) + .long 0xc0000040 // Characteristics (section flags) + + .align 12 +_start: + stp x29, x30, [sp, #-32]! + mov x29, sp + + stp x0, x1, [sp, #16] + mov x2, x0 + mov x3, x1 + adr x0, ImageBase + adrp x1, _DYNAMIC + add x1, x1, #:lo12:_DYNAMIC + bl _relocate + cbnz x0, 0f + + ldp x0, x1, [sp, #16] + bl efi_main + +0: ldp x29, x30, [sp], #32 + ret diff --git a/src/system/boot/platform/efi/arch/arm64/relocation_func.cpp b/src/system/boot/platform/efi/arch/arm64/relocation_func.cpp index 086727961c..e430e40f2b 100644 --- a/src/system/boot/platform/efi/arch/arm64/relocation_func.cpp +++ b/src/system/boot/platform/efi/arch/arm64/relocation_func.cpp @@ -39,9 +39,9 @@ #include -EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, - EFI_HANDLE image EFI_UNUSED, - EFI_SYSTEM_TABLE *systab EFI_UNUSED) +efi_status _relocate (long ldbase, Elf64_Dyn *dyn, + efi_handle image EFI_UNUSED, + efi_system_table *systab EFI_UNUSED) { long relsz = 0, relent = 0; Elf64_Rela *rel = 0; diff --git a/src/system/boot/platform/efi/arch/x86/crt0-efi-x86.S b/src/system/boot/platform/efi/arch/x86/crt0-efi-x86.S new file mode 100644 index 0000000000..f9d5191ecb --- /dev/null +++ b/src/system/boot/platform/efi/arch/x86/crt0-efi-x86.S @@ -0,0 +1,76 @@ +/* crt0-efi-ia32.S - x86 EFI startup code. + Copyright (C) 1999 Hewlett-Packard Co. + Contributed by David Mosberger . + + All rights reserved. + + 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. + * Neither the name of Hewlett-Packard Co. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANYDIRECT, 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. +*/ + + .text + .align 4 + + .globl _start +_start: + pushl %ebp + movl %esp,%ebp + + pushl 12(%ebp) # copy "image" argument + pushl 8(%ebp) # copy "systab" argument + + call 0f +0: popl %eax + movl %eax,%ebx + + addl $ImageBase-0b,%eax # %eax = ldbase + addl $_DYNAMIC-0b,%ebx # %ebx = _DYNAMIC + + pushl %ebx # pass _DYNAMIC as second argument + pushl %eax # pass ldbase as first argument + call _relocate + popl %ebx + popl %ebx + testl %eax,%eax + jne .exit + + call efi_main # call app with "image" and "systab" argument + +.exit: leave + ret + + // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: + + .data +dummy: .long 0 + +#define IMAGE_REL_ABSOLUTE 0 + .section .reloc + .long dummy // Page RVA + .long 10 // Block Size (2*4+2) + .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy diff --git a/src/system/boot/platform/efi/arch/x86_64/Jamfile b/src/system/boot/platform/efi/arch/x86_64/Jamfile index e870ca6bfe..13c02e7cc1 100644 --- a/src/system/boot/platform/efi/arch/x86_64/Jamfile +++ b/src/system/boot/platform/efi/arch/x86_64/Jamfile @@ -2,12 +2,11 @@ SubDir HAIKU_TOP src system boot platform efi arch x86_64 ; SubDirHdrs $(HAIKU_TOP) src system boot platform efi ; +UsePrivateHeaders [ FDirName kernel platform ] ; UsePrivateHeaders [ FDirName kernel boot platform efi ] ; -UseBuildFeatureHeaders gnuefi ; -UseBuildFeatureHeaders gnuefi : headersProtocol ; -UseBuildFeatureHeaders gnuefi : headersArch ; local arch_src = + crt0-efi-$(TARGET_ARCH).S entry.S relocation_func.cpp arch_smp.cpp @@ -18,13 +17,3 @@ local arch_src = BootMergeObject boot_platform_efi_x86_64.o : $(arch_src) ; - -Includes [ FGristFiles $(arch_src) ] - : - [ BuildFeatureAttribute gnuefi : headers ] - [ BuildFeatureAttribute gnuefi : headersProtocol ] - [ BuildFeatureAttribute gnuefi : headersArch ] - ; - -Depends [ FGristFiles $(arch_src) ] - : [ BuildFeatureAttribute gnuefi : libdir ] ; diff --git a/src/system/boot/platform/efi/arch/x86_64/crt0-efi-x86_64.S b/src/system/boot/platform/efi/arch/x86_64/crt0-efi-x86_64.S new file mode 100644 index 0000000000..6839150a72 --- /dev/null +++ b/src/system/boot/platform/efi/arch/x86_64/crt0-efi-x86_64.S @@ -0,0 +1,76 @@ +/* crt0-efi-x86_64.S - x86_64 EFI startup code. + Copyright (C) 1999 Hewlett-Packard Co. + Contributed by David Mosberger . + Copyright (C) 2005 Intel Co. + Contributed by Fenghua Yu . + + All rights reserved. + + 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. + * Neither the name of Hewlett-Packard Co. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANYDIRECT, 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. +*/ + .text + .align 4 + + .globl _start +_start: + subq $8, %rsp + pushq %rcx + pushq %rdx + +0: + lea ImageBase(%rip), %rdi + lea _DYNAMIC(%rip), %rsi + + popq %rcx + popq %rdx + pushq %rcx + pushq %rdx + call _relocate + + popq %rdi + popq %rsi + + call efi_main + addq $8, %rsp + +.exit: + ret + + // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: + + .data +dummy: .long 0 + +#define IMAGE_REL_ABSOLUTE 0 + .section .reloc, "a" +label1: + .long dummy-label1 // Page RVA + .long 10 // Block Size (2*4+2) + .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy + diff --git a/src/system/boot/platform/efi/arch/x86_64/relocation_func.cpp b/src/system/boot/platform/efi/arch/x86_64/relocation_func.cpp index 66918e6483..879cde6008 100644 --- a/src/system/boot/platform/efi/arch/x86_64/relocation_func.cpp +++ b/src/system/boot/platform/efi/arch/x86_64/relocation_func.cpp @@ -35,13 +35,14 @@ SUCH DAMAGE. */ -#include +#include +#include #include -extern "C" EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, - EFI_HANDLE image __attribute__((__unused__)), - EFI_SYSTEM_TABLE *systab __attribute__((__unused__))) +extern "C" efi_status _relocate (long ldbase, Elf64_Dyn *dyn, + efi_handle image __attribute__((__unused__)), + efi_system_table *systab __attribute__((__unused__))) { long relsz = 0, relent = 0; Elf64_Rel *rel = 0; diff --git a/src/system/boot/platform/efi/console.cpp b/src/system/boot/platform/efi/console.cpp index 7999692c0f..be04d3b8b7 100644 --- a/src/system/boot/platform/efi/console.cpp +++ b/src/system/boot/platform/efi/console.cpp @@ -58,7 +58,7 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferSize) { const char *string = (const char *)buffer; - CHAR16 ucsBuffer[bufferSize + 3]; + char16_t ucsBuffer[bufferSize + 3]; uint32 j = 0; for (uint32 i = 0; i < bufferSize; i++) { @@ -77,7 +77,7 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, continue; } default: - ucsBuffer[j++] = (CHAR16) string[i]; + ucsBuffer[j++] = (char16_t)string[i]; } } @@ -145,10 +145,10 @@ console_set_color(int32 foreground, int32 background) int console_wait_for_key(void) { - UINTN index; - EFI_STATUS status; - EFI_INPUT_KEY key; - EFI_EVENT event = kSystemTable->ConIn->WaitForKey; + size_t index; + efi_status status; + efi_input_key key; + efi_event event = kSystemTable->ConIn->WaitForKey; do { kBootServices->WaitForEvent(1, &event, &index); @@ -184,9 +184,9 @@ console_wait_for_key(void) static void update_screen_size(void) { - UINTN width, height; - UINTN area = 0; - SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut = kSystemTable->ConOut; + size_t width, height; + size_t area = 0; + efi_simple_text_output_protocol *ConOut = kSystemTable->ConOut; for (int mode = 0; mode < ConOut->Mode->MaxMode; ++mode) { if (ConOut->QueryMode(ConOut, mode, &width, &height) == EFI_SUCCESS) { @@ -220,8 +220,8 @@ console_init(void) uint32 console_check_boot_keys(void) { - EFI_STATUS status; - EFI_INPUT_KEY key; + efi_status status; + efi_input_key key; // give the user a chance to press a key kBootServices->Stall(500000); diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index 13929621c6..f9b3130e66 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -15,31 +15,63 @@ #include "Header.h" #include "efi_platform.h" -#include "efigpt.h" +#include +#include +#include + +#include "gpt.h" #include "gpt_known_guids.h" +#define DevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8)) +#define NextDevicePathNode(a) (efi_device_path_protocol*) \ + (((uint8_t*)(a)) + DevicePathNodeLength(a)) + + struct device_handle { - list_link link; - EFI_DEVICE_PATH* device_path; - EFI_HANDLE handle; + list_link link; + efi_device_path_protocol* device_path; + efi_handle handle; }; static struct list sMessagingDevices; static struct list sMediaDevices; -static EFI_GUID BlockIoGUID = BLOCK_IO_PROTOCOL; -static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; -static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; +static efi_guid BlockIoGUID = EFI_BLOCK_IO_PROTOCOL_GUID; +static efi_guid LoadedImageGUID = EFI_LOADED_IMAGE_PROTOCOL_GUID; +static efi_guid DevicePathGUID = EFI_DEVICE_PATH_PROTOCOL_GUID; -static UINTN -device_path_length(EFI_DEVICE_PATH* path) +static void +device_set_path_end(efi_device_path_protocol* path) { - EFI_DEVICE_PATH *node = path; - UINTN length = 0; - while (!IsDevicePathEnd(node)) { + path->Type = DEVICE_PATH_END; + path->SubType = DEVICE_PATH_ENTIRE_END; + path->Length[0] = sizeof(efi_device_path_protocol); + path->Length[1] = 0; +} + + +static bool +device_path_end(efi_device_path_protocol* path) +{ + if (path == NULL) { + dprintf("ERROR: Unexpected end of device protocol path!\n"); + return false; + } + + return (path->Type == DEVICE_PATH_END + && path->SubType == DEVICE_PATH_ENTIRE_END); +} + + +static size_t +device_path_length(efi_device_path_protocol* path) +{ + efi_device_path_protocol *node = path; + size_t length = 0; + while (!device_path_end(node)) { length += DevicePathNodeLength(node); node = NextDevicePathNode(node); } @@ -52,14 +84,16 @@ device_path_length(EFI_DEVICE_PATH* path) // If matchSubPath is true, then the second device path can be a sub-path // of the first device path static bool -compare_device_paths(EFI_DEVICE_PATH* first, EFI_DEVICE_PATH* second, bool matchSubPath = false) +compare_device_paths(efi_device_path_protocol* first, + efi_device_path_protocol* second, bool matchSubPath = false) { - EFI_DEVICE_PATH *firstNode = first; - EFI_DEVICE_PATH *secondNode = second; - while (!IsDevicePathEnd(firstNode) && !IsDevicePathEnd(secondNode)) { - UINTN firstLength = DevicePathNodeLength(firstNode); - UINTN secondLength = DevicePathNodeLength(secondNode); - if (firstLength != secondLength || memcmp(firstNode, secondNode, firstLength) != 0) { + efi_device_path_protocol *firstNode = first; + efi_device_path_protocol *secondNode = second; + while (!device_path_end(firstNode) && !device_path_end(secondNode)) { + size_t firstLength = DevicePathNodeLength(firstNode); + size_t secondLength = DevicePathNodeLength(secondNode); + if (firstLength != secondLength + || memcmp(firstNode, secondNode, firstLength) != 0) { return false; } firstNode = NextDevicePathNode(firstNode); @@ -67,14 +101,15 @@ compare_device_paths(EFI_DEVICE_PATH* first, EFI_DEVICE_PATH* second, bool match } if (matchSubPath) - return IsDevicePathEnd(secondNode); + return device_path_end(secondNode); - return IsDevicePathEnd(firstNode) && IsDevicePathEnd(secondNode); + return device_path_end(firstNode) && device_path_end(secondNode); } static bool -add_device_path(struct list *list, EFI_DEVICE_PATH* path, EFI_HANDLE handle) +add_device_path(struct list *list, efi_device_path_protocol* path, + efi_handle handle) { device_handle *node = NULL; while ((node = (device_handle*)list_get_next_item(list, node)) != NULL) { @@ -82,9 +117,9 @@ add_device_path(struct list *list, EFI_DEVICE_PATH* path, EFI_HANDLE handle) return false; } - UINTN length = device_path_length(path); + size_t length = device_path_length(path); node = (device_handle*)malloc(sizeof(struct device_handle)); - node->device_path = (EFI_DEVICE_PATH*)malloc(length); + node->device_path = (efi_device_path_protocol*)malloc(length); node->handle = handle; memcpy(node->device_path, path, length); @@ -97,7 +132,8 @@ add_device_path(struct list *list, EFI_DEVICE_PATH* path, EFI_HANDLE handle) class EfiDevice : public Node { public: - EfiDevice(EFI_BLOCK_IO *blockIo, EFI_DEVICE_PATH *devicePath); + EfiDevice(efi_block_io_protocol *blockIo, + efi_device_path_protocol *devicePath); virtual ~EfiDevice(); virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, @@ -110,7 +146,7 @@ class EfiDevice : public Node uint32 BlockSize() const { return fBlockIo->Media->BlockSize; } bool ReadOnly() const { return fBlockIo->Media->ReadOnly; } int32 BootMethod() const { - if (fDevicePath->Type == MEDIA_DEVICE_PATH) { + if (fDevicePath->Type == DEVICE_PATH_MEDIA) { if (fDevicePath->SubType == MEDIA_CDROM_DP) return BOOT_METHOD_CD; if (fDevicePath->SubType == MEDIA_HARDDRIVE_DP) @@ -120,15 +156,16 @@ class EfiDevice : public Node return BOOT_METHOD_DEFAULT; } - EFI_DEVICE_PATH* DevicePath() { return fDevicePath; } + efi_device_path_protocol* DevicePath() { return fDevicePath; } private: - EFI_BLOCK_IO* fBlockIo; - EFI_DEVICE_PATH* fDevicePath; + efi_block_io_protocol* fBlockIo; + efi_device_path_protocol* fDevicePath; }; -EfiDevice::EfiDevice(EFI_BLOCK_IO *blockIo, EFI_DEVICE_PATH *devicePath) +EfiDevice::EfiDevice(efi_block_io_protocol *blockIo, + efi_device_path_protocol *devicePath) : fBlockIo(blockIo), fDevicePath(devicePath) @@ -163,19 +200,19 @@ EfiDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) static status_t build_device_handles() { - EFI_GUID blockIoGuid = BLOCK_IO_PROTOCOL; - EFI_GUID devicePathGuid = DEVICE_PATH_PROTOCOL; + efi_guid blockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; + efi_guid devicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; - EFI_DEVICE_PATH *devicePath, *node; - EFI_HANDLE *handles = NULL; - EFI_STATUS status; - UINTN size = 0; + efi_device_path_protocol *devicePath, *node; + efi_handle *handles = NULL; + efi_status status; + size_t size = 0; status = kBootServices->LocateHandle(ByProtocol, &blockIoGuid, 0, &size, 0); if (status != EFI_BUFFER_TOO_SMALL) return B_ENTRY_NOT_FOUND; - handles = (EFI_HANDLE*)malloc(size); + handles = (efi_handle*)malloc(size); status = kBootServices->LocateHandle(ByProtocol, &blockIoGuid, 0, &size, handles); if (status != EFI_SUCCESS) { @@ -183,19 +220,19 @@ build_device_handles() return B_ENTRY_NOT_FOUND; } - for (UINTN n = 0; n < (size / sizeof(EFI_HANDLE)); n++) { + for (size_t n = 0; n < (size / sizeof(efi_handle)); n++) { status = kBootServices->HandleProtocol(handles[n], &devicePathGuid, (void**)&devicePath); if (status != EFI_SUCCESS) continue; node = devicePath; - while (!IsDevicePathEnd(NextDevicePathNode(node))) + while (!device_path_end(NextDevicePathNode(node))) node = NextDevicePathNode(node); - if (DevicePathType(node) == MEDIA_DEVICE_PATH) + if (node->Type == DEVICE_PATH_MEDIA) add_device_path(&sMediaDevices, devicePath, handles[n]); - else if (DevicePathType(node) == MESSAGING_DEVICE_PATH) + else if (node->Type == DEVICE_PATH_MESSAGING) add_device_path(&sMessagingDevices, devicePath, handles[n]); } @@ -230,8 +267,10 @@ compute_check_sum(Node *device, off_t offset) uint32 *array = (uint32*)buffer; uint32 sum = 0; - for (uint32 i = 0; i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) + for (uint32 i = 0; + i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) { sum += array[i]; + } return sum; } @@ -269,37 +308,38 @@ add_boot_device(NodeList *devicesList) static status_t add_boot_device_for_image(NodeList *devicesList) { - EFI_LOADED_IMAGE *loadedImage; + efi_loaded_image_protocol *loadedImage; if (kBootServices->HandleProtocol(kImage, &LoadedImageGUID, (void**)&loadedImage) != EFI_SUCCESS) return B_ERROR; - EFI_DEVICE_PATH *devicePath, *node; + efi_device_path_protocol *devicePath, *node; if (kBootServices->HandleProtocol(loadedImage->DeviceHandle, &DevicePathGUID, (void**)&devicePath) != EFI_SUCCESS) return B_ERROR; - for (node = devicePath; DevicePathType(node) != MESSAGING_DEVICE_PATH; + for (node = devicePath; node->Type != DEVICE_PATH_MESSAGING; node = NextDevicePathNode(node)) { - if (IsDevicePathEnd(node)) + if (device_path_end(node)) return B_ERROR; } - SetDevicePathEndNode(NextDevicePathNode(node)); + device_set_path_end(NextDevicePathNode(node)); - UINTN length = device_path_length(devicePath); - EFI_DEVICE_PATH *savedDevicePath = (EFI_DEVICE_PATH*)malloc(length); + size_t length = device_path_length(devicePath); + efi_device_path_protocol *savedDevicePath + = (efi_device_path_protocol*)malloc(length); memcpy(savedDevicePath, devicePath, length); - EFI_HANDLE handle; + efi_handle handle; if (kBootServices->LocateDevicePath(&BlockIoGUID, &devicePath, &handle) != EFI_SUCCESS) return B_ERROR; - if (!IsDevicePathEnd(devicePath)) + if (!device_path_end(devicePath)) return B_ERROR; - EFI_BLOCK_IO *blockIo; + efi_block_io_protocol *blockIo; if (kBootServices->HandleProtocol(handle, &BlockIoGUID, (void**)&blockIo) != EFI_SUCCESS) return B_ERROR; @@ -324,14 +364,14 @@ add_cd_devices(NodeList *devicesList) device_handle *handle = NULL; while ((handle = (device_handle*)list_get_next_item(&sMediaDevices, handle)) != NULL) { - EFI_DEVICE_PATH *node = handle->device_path; - while (!IsDevicePathEnd(NextDevicePathNode(node))) + efi_device_path_protocol *node = handle->device_path; + while (!device_path_end(NextDevicePathNode(node))) node = NextDevicePathNode(node); - if (DevicePathType(node) != MEDIA_DEVICE_PATH) + if (node->Type != DEVICE_PATH_MEDIA) continue; - if (DevicePathSubType(node) != MEDIA_CDROM_DP) + if (node->SubType != MEDIA_CDROM_DP) continue; device_handle *messaging_device @@ -339,9 +379,9 @@ add_cd_devices(NodeList *devicesList) if (messaging_device == NULL) continue; - EFI_BLOCK_IO *blockIo; - EFI_GUID blockIoGuid = BLOCK_IO_PROTOCOL; - EFI_STATUS status = kBootServices->HandleProtocol(messaging_device->handle, + efi_block_io_protocol *blockIo; + efi_guid blockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; + efi_status status = kBootServices->HandleProtocol(messaging_device->handle, &blockIoGuid, (void**)&blockIo); if (status != EFI_SUCCESS) continue; @@ -349,7 +389,9 @@ add_cd_devices(NodeList *devicesList) if (!blockIo->Media->MediaPresent) continue; - EfiDevice *device = new(std::nothrow)EfiDevice(blockIo, handle->device_path); + EfiDevice *device = new(std::nothrow)EfiDevice(blockIo, + handle->device_path); + if (device == NULL) continue; @@ -364,22 +406,24 @@ static status_t add_remaining_devices(NodeList *devicesList) { device_handle *node = NULL; - while ((node = (device_handle*)list_get_next_item(&sMessagingDevices, node)) != NULL) { + while ((node = (device_handle*)list_get_next_item(&sMessagingDevices, node)) + != NULL) { NodeIterator it = devicesList->GetIterator(); bool found = false; while (it.HasNext()) { EfiDevice *device = (EfiDevice*)it.Next(); // device->DevicePath() is a Media Device Path instance - if (compare_device_paths(device->DevicePath(), node->device_path, true)) { + if (compare_device_paths(device->DevicePath(), + node->device_path, true)) { found = true; break; } } if (!found) { - EFI_BLOCK_IO *blockIo; - EFI_GUID blockIoGuid = BLOCK_IO_PROTOCOL; - EFI_STATUS status = kBootServices->HandleProtocol(node->handle, + efi_block_io_protocol *blockIo; + efi_guid blockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; + efi_status status = kBootServices->HandleProtocol(node->handle, &blockIoGuid, (void**)&blockIo); if (status != EFI_SUCCESS) continue; @@ -387,7 +431,9 @@ add_remaining_devices(NodeList *devicesList) if (!blockIo->Media->MediaPresent) continue; - EfiDevice *device = new(std::nothrow)EfiDevice(blockIo, node->device_path); + EfiDevice *device = new(std::nothrow)EfiDevice(blockIo, + node->device_path); + if (device == NULL) continue; @@ -406,8 +452,8 @@ device_contains_partition(EfiDevice *device, boot::Partition *partition) if (header != NULL && header->InitCheck() == B_OK) { // check if device is GPT, and contains partition entry uint32 blockSize = device->BlockSize(); - EFI_PARTITION_TABLE_HEADER *deviceHeader = - (EFI_PARTITION_TABLE_HEADER*)malloc(blockSize); + gpt_table_header *deviceHeader = + (gpt_table_header*)malloc(blockSize); ssize_t bytesRead = device->ReadAt(NULL, blockSize, deviceHeader, blockSize); if (bytesRead != blockSize) @@ -419,10 +465,10 @@ device_contains_partition(EfiDevice *device, boot::Partition *partition) // partition->cookie == int partition entry index uint32 index = (uint32)(addr_t)partition->cookie; - uint32 size = sizeof(EFI_PARTITION_ENTRY) * (index + 1); - EFI_PARTITION_ENTRY *entries = (EFI_PARTITION_ENTRY*)malloc(size); + uint32 size = sizeof(gpt_partition_entry) * (index + 1); + gpt_partition_entry *entries = (gpt_partition_entry*)malloc(size); bytesRead = device->ReadAt(NULL, - deviceHeader->PartitionEntryLBA * blockSize, entries, size); + deviceHeader->entries_block * blockSize, entries, size); if (bytesRead != size) return false; @@ -512,7 +558,8 @@ platform_register_boot_device(Node *device) for (uint32 i = 0; i < NUM_DISK_CHECK_SUMS; ++i) { off_t offset = get_next_check_sum_offset(i, device->Size()); identifier.device.unknown.check_sums[i].offset = offset; - identifier.device.unknown.check_sums[i].sum = compute_check_sum(device, offset); + identifier.device.unknown.check_sums[i].sum + = compute_check_sum(device, offset); } gBootVolume.SetInt32(BOOT_METHOD, efiDevice->BootMethod()); diff --git a/src/system/boot/platform/efi/efi_platform.h b/src/system/boot/platform/efi/efi_platform.h index 8067497d5a..86142bec47 100644 --- a/src/system/boot/platform/efi/efi_platform.h +++ b/src/system/boot/platform/efi/efi_platform.h @@ -1,23 +1,55 @@ /* - * Copyright 2013, Fredrik Homlqvist, fredrik.holmqvist@gmail.com. - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2013, Fredrik Homlqvist, fredrik.holmqvist@gmail.com. All rights reserved. + * Copyright 2019-2020, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV */ #ifndef EFI_PLATFORM_H #define EFI_PLATFORM_H -#include "efibind.h" -#include "efidef.h" -#include "efidevp.h" -#include "efiprot.h" -#include "eficon.h" -#include "efierr.h" -#include "efiapi.h" +#include -extern const EFI_SYSTEM_TABLE *kSystemTable; -extern const EFI_BOOT_SERVICES *kBootServices; -extern const EFI_RUNTIME_SERVICES *kRuntimeServices; -extern EFI_HANDLE kImage; +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +#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_F11 0x0015 +#define SCAN_F12 0x0016 +#define SCAN_ESC 0x0017 + + +extern const efi_system_table *kSystemTable; +extern const efi_boot_services *kBootServices; +extern const efi_runtime_services *kRuntimeServices; +extern efi_handle kImage; #endif /* EFI_PLATFORM_H */ diff --git a/src/system/boot/platform/efi/heap.cpp b/src/system/boot/platform/efi/heap.cpp index 725d906849..4f81fc2094 100644 --- a/src/system/boot/platform/efi/heap.cpp +++ b/src/system/boot/platform/efi/heap.cpp @@ -13,7 +13,7 @@ #define STAGE_PAGES 0x2000 /* 32 MB */ -static EFI_PHYSICAL_ADDRESS staging; +static efi_physical_addr staging; extern "C" void diff --git a/src/system/boot/platform/efi/mmu.cpp b/src/system/boot/platform/efi/mmu.cpp index 42bd278f6c..a1e913c0e0 100644 --- a/src/system/boot/platform/efi/mmu.cpp +++ b/src/system/boot/platform/efi/mmu.cpp @@ -33,8 +33,8 @@ static allocated_memory_region *allocated_memory_regions = NULL; static uint64_t mmu_allocate_page() { - EFI_PHYSICAL_ADDRESS addr; - EFI_STATUS s = kBootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, 1, &addr); + efi_physical_addr addr; + efi_status s = kBootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, 1, &addr); if (s != EFI_SUCCESS) panic("Unabled to allocate memory: %li", s); @@ -43,9 +43,9 @@ static uint64_t mmu_allocate_page() uint64_t -mmu_generate_post_efi_page_tables(UINTN memory_map_size, - EFI_MEMORY_DESCRIPTOR *memory_map, UINTN descriptor_size, - UINTN descriptor_version) +mmu_generate_post_efi_page_tables(size_t memory_map_size, + efi_memory_descriptor *memory_map, size_t descriptor_size, + uint32_t descriptor_version) { // Generate page tables, matching bios_ia32/long.cpp. uint64_t *pml4; @@ -72,8 +72,8 @@ mmu_generate_post_efi_page_tables(UINTN memory_map_size, // into the kernel address space, so we want to make sure we map everything // we have available. uint64 maxAddress = 0; - for (UINTN i = 0; i < memory_map_size / descriptor_size; ++i) { - EFI_MEMORY_DESCRIPTOR *entry = (EFI_MEMORY_DESCRIPTOR *)((addr_t)memory_map + i * descriptor_size); + for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { + efi_memory_descriptor *entry = (efi_memory_descriptor *)((addr_t)memory_map + i * descriptor_size); maxAddress = std::max(maxAddress, entry->PhysicalStart + entry->NumberOfPages * 4096); } @@ -146,13 +146,13 @@ mmu_generate_post_efi_page_tables(UINTN memory_map_size, // Currently assumes that the memory map is sane... Sorted and no overlapping // regions. void -mmu_post_efi_setup(UINTN memory_map_size, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN descriptor_size, UINTN descriptor_version) +mmu_post_efi_setup(size_t memory_map_size, efi_memory_descriptor *memory_map, size_t descriptor_size, uint32_t descriptor_version) { // Add physical memory to the kernel args and update virtual addresses for EFI regions.. addr_t addr = (addr_t)memory_map; gKernelArgs.num_physical_memory_ranges = 0; - for (UINTN i = 0; i < memory_map_size / descriptor_size; ++i) { - EFI_MEMORY_DESCRIPTOR *entry = (EFI_MEMORY_DESCRIPTOR *)(addr + i * descriptor_size); + for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { + efi_memory_descriptor *entry = (efi_memory_descriptor *)(addr + i * descriptor_size); switch (entry->Type) { case EfiLoaderCode: case EfiLoaderData: @@ -228,14 +228,14 @@ platform_allocate_region(void **_address, size_t size, uint8 /* protection */, b if (exactAddress) return B_NO_MEMORY; - EFI_PHYSICAL_ADDRESS addr; + efi_physical_addr addr; size_t aligned_size = ROUNDUP(size, B_PAGE_SIZE); allocated_memory_region *region = new(std::nothrow) allocated_memory_region; if (region == NULL) return B_NO_MEMORY; - EFI_STATUS status = kBootServices->AllocatePages(AllocateAnyPages, + efi_status status = kBootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, aligned_size / B_PAGE_SIZE, &addr); if (status != EFI_SUCCESS) { delete region; @@ -402,7 +402,7 @@ platform_free_region(void *address, size_t size) if (!region) panic("Unknown region??"); - kBootServices->FreePages((EFI_PHYSICAL_ADDRESS)address, ROUNDUP(size, B_PAGE_SIZE) / B_PAGE_SIZE); + kBootServices->FreePages((efi_physical_addr)address, ROUNDUP(size, B_PAGE_SIZE) / B_PAGE_SIZE); return B_OK; } diff --git a/src/system/boot/platform/efi/mmu.h b/src/system/boot/platform/efi/mmu.h index e078a3f89d..a553582ff3 100644 --- a/src/system/boot/platform/efi/mmu.h +++ b/src/system/boot/platform/efi/mmu.h @@ -20,27 +20,37 @@ extern segment_descriptor gBootGDT[BOOT_GDT_SEGMENT_COUNT]; -static const uint32 kDefaultPageFlags = 0x3; // present, R/W -static const uint64 kTableMappingFlags = 0x7; // present, R/W, user -static const uint64 kLargePageMappingFlags = 0x183; // present, R/W, user, global, large -static const uint64 kPageMappingFlags = 0x103; // present, R/W, user, global +static const uint32 kDefaultPageFlags = 0x3; + // present, R/W +static const uint64 kTableMappingFlags = 0x7; + // present, R/W, user +static const uint64 kLargePageMappingFlags = 0x183; + // present, R/W, user, global, large +static const uint64 kPageMappingFlags = 0x103; + // present, R/W, user, global #ifdef __cplusplus extern "C" { #endif -extern addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags); +extern addr_t mmu_map_physical_memory(addr_t physicalAddress, + size_t size, uint32 flags); extern void mmu_free(void *virtualAddress, size_t size); -extern void -mmu_post_efi_setup(UINTN memory_map_size, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN descriptor_size, UINTN descriptor_version); -extern uint64_t -mmu_generate_post_efi_page_tables(UINTN memory_map_size, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN descriptor_size, UINTN descriptor_version); -extern status_t -platform_kernel_address_to_bootloader_address(uint64_t address, void **_result); -extern status_t -platform_bootloader_address_to_kernel_address(void *address, uint64_t *_result); +extern void mmu_post_efi_setup(size_t memory_map_size, + efi_memory_descriptor *memory_map, size_t descriptor_size, + uint32_t descriptor_version); + +extern uint64_t mmu_generate_post_efi_page_tables(size_t memory_map_size, + efi_memory_descriptor *memory_map, size_t descriptor_size, + uint32_t descriptor_version); + +extern status_t platform_kernel_address_to_bootloader_address(uint64_t address, + void **_result); + +extern status_t platform_bootloader_address_to_kernel_address(void *address, + uint64_t *_result); #ifdef __cplusplus } @@ -52,9 +62,10 @@ inline uint64 fix_address(uint64 address) { uint64 result; - if (platform_bootloader_address_to_kernel_address((void *)address, &result) != B_OK) + if (platform_bootloader_address_to_kernel_address((void *)address, &result) + != B_OK) { return address; - else + } else return result; } diff --git a/src/system/boot/platform/efi/serial.cpp b/src/system/boot/platform/efi/serial.cpp index 667a787a3a..b8ad4a7ff0 100644 --- a/src/system/boot/platform/efi/serial.cpp +++ b/src/system/boot/platform/efi/serial.cpp @@ -7,7 +7,7 @@ #include "efi_platform.h" -#include "efiser.h" +#include #include "serial.h" #include @@ -18,10 +18,10 @@ #include -static EFI_GUID sSerialIOProtocolGUID = SERIAL_IO_PROTOCOL; +static efi_guid sSerialIOProtocolGUID = EFI_SERIAL_IO_PROTOCOL_GUID; static const uint32 kSerialBaudRate = 115200; -static SERIAL_IO_INTERFACE *sSerial = NULL; +static efi_serial_io_protocol *sSerial = NULL; static bool sSerialEnabled = false; static bool sSerialUsesEFI = true; @@ -48,7 +48,7 @@ serial_putc(char ch) return; if (sSerialUsesEFI) { - UINTN bufSize = 1; + size_t bufSize = 1; sSerial->Write(sSerial, &bufSize, &ch); } else { while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0) @@ -96,7 +96,7 @@ serial_enable(void) extern "C" void serial_init(void) { - EFI_STATUS status = kSystemTable->BootServices->LocateProtocol( + efi_status status = kSystemTable->BootServices->LocateProtocol( &sSerialIOProtocolGUID, NULL, (void**)&sSerial); if (status != EFI_SUCCESS || sSerial == NULL) { diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index 0c1f7ed7c7..4b9d794061 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -33,10 +33,10 @@ extern void (*__ctor_list)(void); extern void (*__ctor_end)(void); -const EFI_SYSTEM_TABLE *kSystemTable; -const EFI_BOOT_SERVICES *kBootServices; -const EFI_RUNTIME_SERVICES *kRuntimeServices; -EFI_HANDLE kImage; +const efi_system_table *kSystemTable; +const efi_boot_services *kBootServices; +const efi_runtime_services *kRuntimeServices; +efi_handle kImage; static uint32 sBootOptions; @@ -139,50 +139,59 @@ platform_start_kernel(void) // map in a kernel stack void *stack_address = NULL; - if (platform_allocate_region(&stack_address, KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) != B_OK) { + if (platform_allocate_region(&stack_address, + KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0, false) + != B_OK) { panic("Unabled to allocate a stack"); } gKernelArgs.cpu_kstack[0].start = fix_address((uint64_t)stack_address); - gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; + gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE + + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start); // Prepare to exit EFI boot services. // Read the memory map. // First call is to determine the buffer size. - UINTN memory_map_size = 0; - EFI_MEMORY_DESCRIPTOR dummy; - EFI_MEMORY_DESCRIPTOR *memory_map; - UINTN map_key; - UINTN descriptor_size; - UINT32 descriptor_version; - if (kBootServices->GetMemoryMap(&memory_map_size, &dummy, &map_key, &descriptor_size, &descriptor_version) != EFI_BUFFER_TOO_SMALL) { + size_t memory_map_size = 0; + efi_memory_descriptor dummy; + efi_memory_descriptor *memory_map; + size_t map_key; + size_t descriptor_size; + uint32_t descriptor_version; + if (kBootServices->GetMemoryMap(&memory_map_size, &dummy, &map_key, + &descriptor_size, &descriptor_version) != EFI_BUFFER_TOO_SMALL) { panic("Unable to determine size of system memory map"); } // Allocate a buffer twice as large as needed just in case it gets bigger between // calls to ExitBootServices. - UINTN actual_memory_map_size = memory_map_size * 2; - memory_map = (EFI_MEMORY_DESCRIPTOR *)kernel_args_malloc(actual_memory_map_size); + size_t actual_memory_map_size = memory_map_size * 2; + memory_map + = (efi_memory_descriptor *)kernel_args_malloc(actual_memory_map_size); + if (memory_map == NULL) panic("Unable to allocate memory map."); // Read (and print) the memory map. memory_map_size = actual_memory_map_size; - if (kBootServices->GetMemoryMap(&memory_map_size, memory_map, &map_key, &descriptor_size, &descriptor_version) != EFI_SUCCESS) { + if (kBootServices->GetMemoryMap(&memory_map_size, memory_map, &map_key, + &descriptor_size, &descriptor_version) != EFI_SUCCESS) { panic("Unable to fetch system memory map."); } addr_t addr = (addr_t)memory_map; dprintf("System provided memory map:\n"); - for (UINTN i = 0; i < memory_map_size / descriptor_size; ++i) { - EFI_MEMORY_DESCRIPTOR *entry = (EFI_MEMORY_DESCRIPTOR *)(addr + i * descriptor_size); - dprintf(" %#lx-%#lx %#lx %#x %#lx\n", - entry->PhysicalStart, entry->PhysicalStart + entry->NumberOfPages * 4096, + for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { + efi_memory_descriptor *entry + = (efi_memory_descriptor *)(addr + i * descriptor_size); + dprintf(" %#lx-%#lx %#lx %#x %#lx\n", entry->PhysicalStart, + entry->PhysicalStart + entry->NumberOfPages * 4096, entry->VirtualStart, entry->Type, entry->Attribute); } // Generate page tables for use after ExitBootServices. - uint64_t final_pml4 = mmu_generate_post_efi_page_tables(memory_map_size, memory_map, descriptor_size, descriptor_version); + uint64_t final_pml4 = mmu_generate_post_efi_page_tables(memory_map_size, + memory_map, descriptor_size, descriptor_version); dprintf("Final PML4 at %#lx\n", final_pml4); // Attempt to fetch the memory map and exit boot services. @@ -208,20 +217,21 @@ platform_start_kernel(void) } memory_map_size = actual_memory_map_size; - if (kBootServices->GetMemoryMap(&memory_map_size, memory_map, &map_key, &descriptor_size, &descriptor_version) != EFI_SUCCESS) { + if (kBootServices->GetMemoryMap(&memory_map_size, memory_map, &map_key, + &descriptor_size, &descriptor_version) != EFI_SUCCESS) { panic("Unable to fetch system memory map."); } } // Update EFI, generate final kernel physical memory map, etc. - mmu_post_efi_setup(memory_map_size, memory_map, descriptor_size, descriptor_version); + mmu_post_efi_setup(memory_map_size, memory_map, + descriptor_size, descriptor_version); smp_boot_other_cpus(final_pml4, gLongKernelEntry); // Enter the kernel! - efi_enter_kernel(final_pml4, - gLongKernelEntry, - gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size); + efi_enter_kernel(final_pml4, gLongKernelEntry, + gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size); panic("Shouldn't get here"); } @@ -239,8 +249,8 @@ platform_exit(void) * @image: firmware-allocated handle that identifies the image * @systemTable: EFI system table */ -extern "C" EFI_STATUS -efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) +extern "C" efi_status +efi_main(efi_handle image, efi_system_table *systemTable) { stage2_args args; diff --git a/src/system/boot/platform/efi/video.cpp b/src/system/boot/platform/efi/video.cpp index bd97ad973a..3c89b570f0 100644 --- a/src/system/boot/platform/efi/video.cpp +++ b/src/system/boot/platform/efi/video.cpp @@ -18,6 +18,7 @@ #include #include "efi_platform.h" +#include //#define TRACE_VIDEO @@ -30,14 +31,14 @@ struct video_mode { list_link link; - UINTN mode; - UINTN width, height, bits_per_pixel, bytes_per_row; + size_t mode; + size_t width, height, bits_per_pixel, bytes_per_row; }; -static EFI_GUID sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; -static EFI_GRAPHICS_OUTPUT_PROTOCOL *sGraphicsOutput; -static UINTN sGraphicsMode; +static efi_guid sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; +static efi_graphics_output_protocol *sGraphicsOutput; +static size_t sGraphicsMode; static struct list sModeList; static uint32 sModeCount; static bool sModeChosen; @@ -157,7 +158,7 @@ platform_init_video(void) // make a guess at the best video mode to use, and save the mode ID // for switching to graphics mode - EFI_STATUS status = kBootServices->LocateProtocol(&sGraphicsOutputGuid, + efi_status status = kBootServices->LocateProtocol(&sGraphicsOutputGuid, NULL, (void **)&sGraphicsOutput); if (sGraphicsOutput == NULL || status != EFI_SUCCESS) { gKernelArgs.frame_buffer.enabled = false; @@ -165,16 +166,16 @@ platform_init_video(void) return B_ERROR; } - UINTN bestArea = 0; - UINTN bestDepth = 0; + size_t bestArea = 0; + size_t bestDepth = 0; TRACE(("looking for best graphics mode...\n")); - for (UINTN mode = 0; mode < sGraphicsOutput->Mode->MaxMode; ++mode) { - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; - UINTN size, depth; + for (size_t mode = 0; mode < sGraphicsOutput->Mode->MaxMode; ++mode) { + efi_graphics_output_mode_information *info; + size_t size, depth; sGraphicsOutput->QueryMode(sGraphicsOutput, mode, &size, &info); - UINTN area = info->HorizontalResolution * info->VerticalResolution; + size_t area = info->HorizontalResolution * info->VerticalResolution; TRACE((" mode: %lu\n", mode)); TRACE((" width: %u\n", info->HorizontalResolution)); TRACE((" height: %u\n", info->VerticalResolution)); @@ -264,7 +265,7 @@ video_mode_hook(Menu *menu, MenuItem *item) Menu* submenu = item->Submenu(); MenuItem* subitem = submenu->FindMarked(); if (subitem != NULL) { - sGraphicsMode = (UINTN)subitem->Data(); + sGraphicsMode = (size_t)subitem->Data(); sModeChosen = true; }