mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-26 16:47:40 +01:00
620401dca6
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
387 lines
11 KiB
C
387 lines
11 KiB
C
/** @file
|
|
Apple RAM Disk protocol.
|
|
|
|
Copyright (C) 2019, vit9696. All rights reserved.<BR>
|
|
This program and the accompanying materials are licensed and made available
|
|
under the terms and conditions of the BSD License which accompanies this
|
|
distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#ifndef APPLE_RAM_DISK_PROTOCOL_H
|
|
#define APPLE_RAM_DISK_PROTOCOL_H
|
|
|
|
#include <Library/DebugLib.h>
|
|
#include <Protocol/BlockIo.h>
|
|
#include <Protocol/DevicePath.h>
|
|
|
|
/**
|
|
Apple RAM Disk protocol GUID.
|
|
957932CC-7E8E-433B-8F41-D391EA3C10F8
|
|
**/
|
|
#define APPLE_RAM_DISK_PROTOCOL_GUID \
|
|
{ 0x957932CC, 0x7E8E, 0x433B, \
|
|
{ 0x8F, 0x41, 0xD3, 0x91, 0xEA, 0x3C, 0x10, 0xF8 } }
|
|
|
|
/**
|
|
Apple RAM Disk protocol revision.
|
|
**/
|
|
#define APPLE_DMG_BOOT_PROTOCOL_REVISION 3
|
|
|
|
/**
|
|
RAM Disk extent signature, "RAMDXTNT".
|
|
**/
|
|
#define APPLE_RAM_DISK_EXTENT_SIGNATURE 0x544E5458444D4152ULL
|
|
|
|
/**
|
|
RAM Disk extent version.
|
|
**/
|
|
#define APPLE_RAM_DISK_EXTENT_VERSION 0x10000U
|
|
|
|
/**
|
|
RAM Disk maximum extent count.
|
|
**/
|
|
#define APPLE_RAM_DISK_MAX_EXTENTS 0xFE
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
/**
|
|
RAM Disk extent.
|
|
When automatically allocating at RAM disk creation, extents are created
|
|
on demand as long as contiguous memory is found in the firmware.
|
|
|
|
Please note, that this must match IOAddressRange type in XNU,
|
|
which can be found in iokit/IOKit/IOTypes.h.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Extentent address pointing to a sequence of allocated pages from
|
|
/// EfiACPIMemoryNVS or EfiBootServicesData depending on RamDisk init.
|
|
///
|
|
UINT64 Start;
|
|
///
|
|
/// Actual size of the extent. Allocated area size may be >= Length.
|
|
///
|
|
UINT64 Length;
|
|
} APPLE_RAM_DISK_EXTENT;
|
|
|
|
/**
|
|
RAM Disk externally accessible header containing references to extents.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Set to APPLE_RAM_DISK_EXTENT_SIGNATURE.
|
|
///
|
|
UINT64 Signature;
|
|
///
|
|
/// Set to APPLE_RAM_DISK_EXTENT_VERSION.
|
|
///
|
|
UINT32 Version;
|
|
///
|
|
/// Externally visible amount of extents.
|
|
///
|
|
UINT32 ExtentCount;
|
|
///
|
|
/// Externally visible extent array.
|
|
///
|
|
APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS];
|
|
///
|
|
/// Currently reserved or rather unknown.
|
|
///
|
|
UINT64 Reserved;
|
|
///
|
|
/// Set to APPLE_RAM_DISK_EXTENT_SIGNATURE.
|
|
///
|
|
UINT64 Signature2;
|
|
} APPLE_RAM_DISK_EXTENT_TABLE;
|
|
|
|
/**
|
|
RAM Disk protocol context. This might be called scatter pool.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Internally visible amount of extents.
|
|
///
|
|
UINT64 ExtentCount;
|
|
///
|
|
/// Currently reserved or rather unknown. Padding?
|
|
///
|
|
UINT64 Reserved1;
|
|
///
|
|
/// Total addressible disk size specified at creation.
|
|
///
|
|
UINT64 DiskSize;
|
|
///
|
|
/// Internally visible extent array.
|
|
///
|
|
APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS];
|
|
///
|
|
/// Currently reserved or rather unknown. Padding?
|
|
///
|
|
UINT64 Reserved2;
|
|
///
|
|
/// Normal extent table.
|
|
///
|
|
APPLE_RAM_DISK_EXTENT_TABLE ExtentTable;
|
|
///
|
|
/// More data may follow, for Apple implementation it will be 0x9FD000 bytes.
|
|
/// (This struct and 1 page for internal header.)
|
|
///
|
|
} APPLE_RAM_DISK_CONTEXT;
|
|
|
|
/**
|
|
RAM Disk vendor device path, 24 bytes in total.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Vendor device path.
|
|
/// Type = HARDWARE_DEVICE_PATH.
|
|
/// Subtype = HW_VENDOR_DP.
|
|
/// Length = sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32).
|
|
/// Guid = APPLE_RAM_DISK_PROTOCOL_GUID.
|
|
///
|
|
VENDOR_DEVICE_PATH Vendor;
|
|
///
|
|
/// Globally incremented counter to make every path unique.
|
|
///
|
|
UINT32 Counter;
|
|
} APPLE_RAM_DISK_DP_VENDOR;
|
|
|
|
/**
|
|
RAM Disk device path header for endpoint devices.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Vendor device path.
|
|
///
|
|
APPLE_RAM_DISK_DP_VENDOR Vendor;
|
|
///
|
|
/// Memmap device path.
|
|
///
|
|
MEMMAP_DEVICE_PATH MemMap;
|
|
} APPLE_RAM_DISK_DP_HEADER;
|
|
|
|
/**
|
|
RAM Disk device path, 52 bytes in total.
|
|
**/
|
|
typedef PACKED struct {
|
|
///
|
|
/// Vendor device path with APPLE_RAM_DISK_PROTOCOL_GUID.
|
|
/// Type = HARDWARE_DEVICE_PATH.
|
|
/// Subtype = HW_MEMMAP_DP.
|
|
/// Length = sizeof (APPLE_RAM_DISK_ENTRY_DP).
|
|
/// StartingAddresss = APPLE_RAM_DISK_EXTENT_TABLE pointer.
|
|
/// EndingAddress = StartingAddresss + sizeof (APPLE_RAM_DISK_EXTENT_TABLE).
|
|
/// MemoryType = EfiACPIMemoryNVS or EfiBootServicesData as allocated.
|
|
///
|
|
/// Note: EndingAddress, per UEFI specification and edk2 implementation, is supposed
|
|
/// to be the top usable address, not the top of the buffer. Perhaps there is a mistake here.
|
|
///
|
|
APPLE_RAM_DISK_DP_VENDOR Vendor;
|
|
///
|
|
/// Memmap device path.
|
|
///
|
|
MEMMAP_DEVICE_PATH MemMap;
|
|
///
|
|
/// Device path end.
|
|
///
|
|
EFI_DEVICE_PATH_PROTOCOL End;
|
|
} APPLE_RAM_DISK_DP;
|
|
|
|
#pragma pack(pop)
|
|
|
|
/**
|
|
Create new RAM disk providing relevant protocols:
|
|
- gEfiDevicePathProtocolGuid
|
|
- gEfiBlockIoProtocolGuid
|
|
- gAppleRamDiskProtocolGuid (as NULL)
|
|
|
|
When AllocateMemory is TRUE, a writeable RAM disk is created.
|
|
Its contents are initially zeroed, and then may be modified through normal writing
|
|
and via RAM Disk context, which is accessible through GetRamDiskContext.
|
|
|
|
When AllocateMemory is FALSE, a read only RAM disk is created.
|
|
Its contents are not allocated but reported to be all zero.
|
|
MemMap StartingAddresss will be 0 and EndingAddress will be sizeof (APPLE_RAM_DISK_EXTENT_TABLE).
|
|
Vit: Since no context is allocated, there is no way to initialise this disk image except in an
|
|
implementatation specific way. AllocateMemory = FALSE is never used, so it may be a bug.
|
|
|
|
@param[in] BlockCount Block amount, ignored if AllocateMemory is FALSE.
|
|
@param[in] BlockSize Block size, ignored if AllocateMemory is FALSE.
|
|
@param[in] AllocateMemory Allocate disk memory.
|
|
@param[in] ReserveMemory Mark memory as EfiACPIMemoryNVS, otherwise EfiBootServicesData.
|
|
@param[in] Handle Resulting handle.
|
|
|
|
@retval EFI_SUCCESS RAM disk was successfully created.
|
|
@retval EFI_OUT_OF_RESOURCES Requested RAM disk of more than SIZE_16TB.
|
|
@retval EFI_OUT_OF_RESOURCES Memory allocation error happened.
|
|
@retval EFI_INVALID_PARAMETER Too many extents are needed for the allocation.
|
|
@retval EFI_BUFFER_TOO_SMALL Not enough extents to allocate context extent.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *APPLE_RAM_DISK_CREATE) (
|
|
IN UINT64 BlockCount OPTIONAL,
|
|
IN UINT32 BlockSize OPTIONAL,
|
|
IN BOOLEAN AllocateMemory,
|
|
IN BOOLEAN ReserveMemory,
|
|
OUT EFI_HANDLE *Handle
|
|
);
|
|
|
|
/**
|
|
Destroy RAM disk freeing resources and uninstalling relevant protocols:
|
|
- gEfiDevicePathProtocolGuid
|
|
- gEfiBlockIoProtocolGuid
|
|
- gAppleRamDiskProtocolGuid
|
|
- gTDMApprovedGuid
|
|
|
|
@param[in] Handle RAM disk handle.
|
|
|
|
@retval EFI_INVALID_PARAMETER Not a RAM disk handle.
|
|
@retval EFI_NOT_FOUND Missing Block I/O protocol.
|
|
@retval EFI_SUCCESS Destroyed successfully.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *APPLE_RAM_DISK_DESTROY) (
|
|
IN EFI_HANDLE Handle
|
|
);
|
|
|
|
/**
|
|
Obtain RAM disk context. Context exists only for "allocated" RAM disks,
|
|
i.e. disks created with AllocateMemory = TRUE. When an unallocated
|
|
RAM disk is created, NULL Context will be returned.
|
|
|
|
@param[in] Handle RAM disk handle.
|
|
@param[out] Context RAM disk context.
|
|
|
|
@retval EFI_INVALID_PARAMETER Not a RAM disk handle.
|
|
@retval EFI_NOT_FOUND Missing Block I/O protocol.
|
|
@retval EFI_SUCCESS Obtained NULL or non-NULL context successfully.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *APPLE_RAM_DISK_GET_CONTEXT) (
|
|
IN EFI_HANDLE Handle,
|
|
OUT APPLE_RAM_DISK_CONTEXT *Context
|
|
);
|
|
|
|
/**
|
|
Apple RAM Disk protocol.
|
|
**/
|
|
typedef struct {
|
|
UINT64 Revision;
|
|
APPLE_RAM_DISK_CREATE CreateRamDisk;
|
|
APPLE_RAM_DISK_DESTROY DestroyRamDisk;
|
|
APPLE_RAM_DISK_GET_CONTEXT GetRamDiskContext;
|
|
} APPLE_RAM_DISK_PROTOCOL;
|
|
/*
|
|
STATIC_ASSERT (sizeof (APPLE_RAM_DISK_DP_VENDOR) == 24, "Invalid APPLE_RAM_DISK_DP_VENDOR size");
|
|
STATIC_ASSERT (sizeof (APPLE_RAM_DISK_DP) == 52, "Invalid APPLE_RAM_DISK_DP size");
|
|
STATIC_ASSERT (sizeof (APPLE_RAM_DISK_EXTENT) == 16, "Invalid APPLE_RAM_DISK_EXTENT size");
|
|
STATIC_ASSERT (sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == 4096, "Invalid APPLE_RAM_DISK_EXTENT_TABLE size");
|
|
STATIC_ASSERT (sizeof (APPLE_RAM_DISK_CONTEXT) == 8192, "Invalid APPLE_RAM_DISK_CONTEXT size");
|
|
*/
|
|
extern EFI_GUID gAppleRamDiskProtocolGuid;
|
|
|
|
/**
|
|
Vit: Below come the implementation specific details, which probably do not belong here.
|
|
Since this is the only way to initialize RAM disk when it was not allocated at creation time,
|
|
I put it here for now.
|
|
**/
|
|
|
|
/**
|
|
RAM Disk instance signature, "RAMD".
|
|
**/
|
|
#define APPLE_RAM_DISK_INSTANCE_SIGNATURE 0x444D4152U
|
|
|
|
/**
|
|
RAM Disk default size.
|
|
This value is used when allocating APPLE_RAM_DISK structure.
|
|
**/
|
|
#define APPLE_RAM_DISK_DEFAULT_SIZE 0xA00000U
|
|
|
|
/**
|
|
RAM Disk outermost structure. Allocated in pages with matching MemoryType.
|
|
**/
|
|
typedef struct {
|
|
///
|
|
/// Amount of allocated extents in the RAM disk.
|
|
///
|
|
UINT64 AllocatedExtents;
|
|
///
|
|
/// Amount of allocated pages in APPLE_RAM_DISK structure.
|
|
/// Normally EFI_SIZE_TO_PAGES (APPLE_RAM_DISK_DEFAULT_SIZE).
|
|
///
|
|
UINT64 PageCount;
|
|
///
|
|
/// Total disk size allocated from memory map.
|
|
/// It is bigger by sizeof(APPLE_RAM_DISK_CONTEXT) than actual requested size,
|
|
/// when AllocateMemory = TRUE is specified.
|
|
///
|
|
UINT64 TotalSize;
|
|
///
|
|
/// All allocated and owned extents.
|
|
/// First extent is special, as it points to OwnExtentData, and thus
|
|
/// has APPLE_RAM_DISK_DEFAULT_SIZE - sizeof (APPLE_RAM_DISK) bytes.
|
|
///
|
|
APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS];
|
|
///
|
|
/// Currently reserved or rather unknown. Padding?
|
|
///
|
|
UINT64 Reserved;
|
|
///
|
|
/// Own extent data lasting till PageCount end.
|
|
///
|
|
UINT8 OwnExtentData[];
|
|
} APPLE_RAM_DISK;
|
|
|
|
/**
|
|
Apple RAM Disk instance structure.
|
|
**/
|
|
typedef struct {
|
|
///
|
|
/// Set to APPLE_RAM_DISK_INSTANCE_SIGNATURE.
|
|
///
|
|
UINT32 Magic;
|
|
///
|
|
/// Set to RAM disk handle, formerly returned with CreateRamDisk.
|
|
///
|
|
EFI_HANDLE Handle;
|
|
///
|
|
/// RAM disk device path.
|
|
///
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
///
|
|
/// RAM disk Block I/O protocol.
|
|
///
|
|
EFI_BLOCK_IO_PROTOCOL BlockIo;
|
|
///
|
|
/// Outer RAM disk structure, which owns all allocated extents.
|
|
/// This field is NULL when AllocateMemory = FALSE.
|
|
///
|
|
APPLE_RAM_DISK *RamDisk;
|
|
///
|
|
/// RAM disk context allocated within RAM disk structure memory.
|
|
/// Apple implementation puts it to the end of RamDisk structure.
|
|
/// This field is NULL when AllocateMemory = FALSE.
|
|
///
|
|
APPLE_RAM_DISK_CONTEXT *Context;
|
|
///
|
|
/// Extra pointer to Context->Extents.
|
|
/// This field is NULL when AllocateMemory = FALSE.
|
|
///
|
|
APPLE_RAM_DISK_EXTENT_TABLE *Extents;
|
|
///
|
|
/// Total addressible disk size specified at creation.
|
|
/// This field is -1 when AllocateMemory = FALSE.
|
|
///
|
|
INT64 DiskSize;
|
|
} APPLE_RAM_DISK_INSTANCE;
|
|
|
|
#endif // APPLE_RAM_DISK_PROTOCOL_H
|