Add function headers

pull/353/head
Tesfa Mael 2023-08-16 19:07:06 -07:00 committed by Daniele Lacamera
parent f791e98b16
commit a29b78d680
14 changed files with 1382 additions and 28 deletions

View File

@ -33,6 +33,9 @@
#define PCI_AHCI_DEV 0x17
#define PCI_AHCI_FUN 0
/*!
* \brief Initializes the SATA controller.
*/
void x86_fsp_tgl_init_sata(void)
{
uint32_t sata_bar;

@ -1 +1 @@
Subproject commit bbbafd68d09c6d453a5ef93214c9296dd7bc93b3
Subproject commit 7c9391ebf3341ac10c8357adedd96ff42d59c845

View File

@ -101,6 +101,16 @@ extern uint8_t _wolfboot_flash_end[];
extern uint8_t wb_end_bss[], wb_start_bss[];
extern int main(void);
/*!
* \brief Get the top address from the EFI HOB (Hand-Off Block) list.
*
* This function retrieves the top address from the EFI Hand-Off Block (HOB) list
* and stores it in the 'top' parameter.
*
* \param top Pointer to a variable where the top address will be stored.
* \param hoblist Pointer to the EFI HOB list.
* \return 0 if the top address is successfully retrieved, -1 otherwise.
*/
static int get_top_address(uint64_t *top, struct efi_hob *hoblist)
{
struct efi_hob_resource_descriptor *fsp_reserved;
@ -115,6 +125,16 @@ static int get_top_address(uint64_t *top, struct efi_hob *hoblist)
return 0;
}
/*!
* \brief Change the stack and invoke a function with the new stack.
*
* This function changes the stack to the specified 'new_stack' value and then
* calls the function pointed to by 'other_func', passing the 'ptr' parameter as an argument.
*
* \param new_stack The new stack address.
* \param other_func Pointer to the function to be invoked with the new stack.
* \param ptr Pointer to the parameter to be passed to the invoked function.
*/
static void change_stack_and_invoke(uint32_t new_stack,
void (*other_func)(void *), void *ptr)
{
@ -127,7 +147,12 @@ static void change_stack_and_invoke(uint32_t new_stack,
: "r"(new_stack), "r"(ptr), "r"(other_func)
: "%eax");
}
/*!
* \brief Load the WolfBoot bootloader into memory.
*
* This static function loads the WolfBoot bootloader into memory at the specified
* address (WOLFBOOT_LOAD_BASE) from the flash memory.
*/
static void load_wolfboot(void)
{
size_t wolfboot_size, bss_size;
@ -153,12 +178,26 @@ static void load_fsp_s_to_ram(void)
extern uint8_t _stage2_params[];
/*!
* \brief Set the stage 2 parameter for the WolfBoot bootloader.
*
* This static function sets the stage 2 parameter for the WolfBoot bootloader,
* which will be used by the bootloader during its execution.
*
* \param p Pointer to the stage 2 parameter structure.
*/
static void set_stage2_parameter(struct stage2_parameter *p)
{
memcpy((uint8_t*)_stage2_params, (uint8_t*)p, sizeof(*p));
}
#ifdef WOLFBOOT_64BIT
/*!
* \brief Jump into the WolfBoot bootloader.
*
* This static function transfers control to the WolfBoot bootloader by calling
* the main() function or switch_to_long_mode() for 64-bit systems.
*/
static void jump_into_wolfboot(void)
{
struct stage2_parameter *params = (struct stage2_parameter*)_stage2_params;
@ -183,7 +222,15 @@ static void jump_into_wolfboot()
main();
}
#endif /* WOLFBOOT_64BIT */
/*!
* \brief Check if the payload is valid.
*
* This static function checks if the given payload is valid by verifying
* its signature.
*
* \param base_addr Pointer to the payload
* \return 0 if the payload is successfully retrieved, -1 otherwise.
*/
static inline int verify_payload(uint8_t *base_addr)
{
int ret = -1;
@ -208,7 +255,14 @@ static inline int verify_payload(uint8_t *base_addr)
}
return ret;
}
/*!
* \brief Entry point after memory initialization.
*
* This static function serves as the entry point for further execution after the
* memory initialization is completed.
*
* \param ptr Pointer to a parameter structure.
*/
static void memory_ready_entry(void *ptr)
{
struct stage2_parameter *stage2_params = (struct stage2_parameter *)ptr;
@ -308,6 +362,15 @@ static void memory_ready_entry(void *ptr)
jump_into_wolfboot();
}
/*!
* \brief Check if the FSP info header is valid.
*
* This static function checks if the given FSP info header is valid by verifying
* its signature.
*
* \param hdr Pointer to the FSP info header structure.
* \return 1 if the FSP info header is valid, 0 otherwise.
*/
static int fsp_info_header_is_ok(struct fsp_info_header *hdr)
{
uint8_t *raw_signature;
@ -320,6 +383,18 @@ static int fsp_info_header_is_ok(struct fsp_info_header *hdr)
return 1;
}
/*!
* \brief Entry point for the FSP-M (Firmware Support Package - Memory) module.
*
* This function serves as the entry point for the FSP-M module, which is executed
* during the boot process. It takes the stack base, stack top, timestamp, and BIST
* (Built-In Self Test) as input arguments.
*
* \param stack_base The base address of the stack.
* \param stack_top The top address of the stack.
* \param timestamp A timestamp value.
* \param bist Built-In Self Test value.
*/
void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp,
uint32_t bist)
{

View File

@ -18,6 +18,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/**
* @file boot_x86_fsp_payload.c
*
* @brief Boot functions for x86 FSP payload
*
* This file contains the boot functions for the x86 FSP payload of wolfBoot.
* These functions include booting into Linux payload or ELF binaries.
*/
#ifndef BOOT_X86_FSP_PAYLOAD_H_
#define BOOT_X86_FSP_PAYLOAD_H_
#include <stdint.h>
#include <string.h>
@ -35,7 +45,13 @@
#include <elf.h>
#include <multiboot.h>
/**
* @brief Maximum size of Multiboot2 boot info data structure.
*/
#define MAX_MB2_BOOT_INFO_SIZE 0x2000
/**
* @brief Multiboot2 boot info data structure.
*/
uint8_t mb2_boot_info[MAX_MB2_BOOT_INFO_SIZE];
#endif
#ifdef WOLFBOOT_64BIT
@ -52,6 +68,13 @@ static char *cmdline = "console=ttyS0,115200 pci=earlydump debug";
static char *cmdline = "auto";
#endif /* TARGET_kontron_vx3060_s2 */
/**
* @brief Jump to the specified entry point.
*
* This function performs an unconditional jump to the provided entry point.
*
* @param entry The entry point address to jump to.
*/
void jump(uintptr_t entry)
{
__asm__(
@ -60,7 +83,15 @@ void jump(uintptr_t entry)
: "g"(entry));
}
/**
* @brief Perform the boot process for the given application.
*
* This function performs the boot process for the specified application.
* It either loads and boots a Linux payload or an ELF binary, depending on the
* configuration.
*
* @param app Pointer to the start of the application.
*/
void do_boot(const uint32_t *app)
{
@ -112,3 +143,4 @@ void do_boot(const uint32_t *app)
#error "No payload compiled in"
#endif /* WOLFBOOT_LINUX_PAYLOAD */
}
#endif /* BOOT_X86_FSP_PAYLOAD_H_ */

View File

@ -18,6 +18,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/**
* @file image.c
* @brief This file contains functions related to image handling and
* verification.
*/
#ifndef IMAGE_H_
#define IMAGE_H_
#include "loader.h"
#include "image.h"
#include "hal.h"
@ -50,6 +57,12 @@ static WOLFTPM2_KEY wolftpm_srk;
static uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE];
/* Forward declarations */
/**
* @brief Find the key slot ID based on the SHA hash of the key.
*
* @param hint The SHA hash to find the key slot ID for.
* @return The key slot ID corresponding to the provided SHA hash.
*/
static int keyslot_id_by_sha(const uint8_t *hint);
#ifdef WOLFBOOT_SIGN_ED25519
@ -116,6 +129,14 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
#define ECC_KEY_TYPE ECC_SECP521R1
#endif
/**
* @brief Verify the ECC signature of the image using the provided key slot
* and signature.
*
* @param key_slot The key slot ID to use for verification.
* @param img The image to verify.
* @param sig The ECC signature to use for verification.
*/
static void wolfBoot_verify_signature(uint8_t key_slot,
struct wolfBoot_image *img, uint8_t *sig)
{
@ -372,10 +393,25 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
#endif /* WOLFBOOT_SIGN_RSA2048 || WOLFBOOT_SIGN_3072 || \
* WOLFBOOT_SIGN_RSA4096 */
/**
* @brief Get the specified header type from the extended flash image.
*
* @param img The image to retrieve the header from.
* @param type The type of header to retrieve.
* @param ptr A pointer to the header data.
* @return The size of the header if found, otherwise 0.
*/
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type,
uint8_t **ptr);
/**
* @brief Get the specified header type from the image.
*
* @param img The image to retrieve the header from.
* @param type The type of header to retrieve.
* @param ptr A pointer to the header data.
* @return The size of the header if found, otherwise 0.
*/
static uint16_t get_header(struct wolfBoot_image *img, uint16_t type,
uint8_t **ptr)
{
@ -388,6 +424,13 @@ static uint16_t get_header(struct wolfBoot_image *img, uint16_t type,
#ifdef EXT_FLASH
static uint8_t ext_hash_block[WOLFBOOT_SHA_BLOCK_SIZE];
#endif
/**
* @brief Get a block of data from the SHA256 hash of the image.
*
* @param img The image to retrieve the data from.
* @param offset The offset to start reading the data from.
* @return A pointer to the data block.
*/
static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset)
{
if (offset > img->fw_size)
@ -406,6 +449,12 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset)
static uint8_t hdr_cpy[IMAGE_HEADER_SIZE];
static int hdr_cpy_done = 0;
/**
* @brief Get a copy of the image header.
*
* @param img The image to retrieve the header from.
* @return A pointer to the copied header data.
*/
static uint8_t *fetch_hdr_cpy(struct wolfBoot_image *img)
{
if (!hdr_cpy_done) {
@ -473,6 +522,13 @@ static int self_sha256(uint8_t *hash)
}
#endif /* WOLFBOOT_MEASURED_BOOT */
/**
* @brief Calculate the SHA256 hash of the image.
*
* @param img The image to calculate the hash for.
* @param hash A pointer to store the resulting SHA256 hash.
* @return 0 on success, -1 on failure.
*/
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
@ -514,6 +570,13 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
}
#ifndef WOLFBOOT_NO_SIGN
/**
* @brief Calculate the SHA256 hash of the RSA key.
*
* @param key_slot The key slot ID to calculate the hash for.
* @param hash A pointer to store the resulting SHA256 hash.
*/
static void key_sha256(uint8_t key_slot, uint8_t *hash)
{
int blksz;
@ -571,6 +634,15 @@ static int self_sha384(uint8_t *hash)
}
#endif /* WOLFBOOT_MEASURED_BOOT */
/**
* @brief Calculate SHA-384 hash of the image.
*
* This function calculates the SHA-384 hash of the given image.
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @param hash The buffer to store the SHA-384 hash (48 bytes).
* @return 0 on success, -1 on error.
*/
static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
@ -612,6 +684,18 @@ static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
}
#ifndef WOLFBOOT_NO_SIGN
/**
* @brief Calculate SHA-384 hash of a public key in the keystore.
*
* This function calculates the SHA-384 hash of the public key stored in
* the keystore at the specified key slot.
*
* @param key_slot The key slot ID where the public key is stored in the
* keystore.
* @param hash The buffer to store the SHA-384 hash (48 bytes).
* @return None.
*/
static void key_sha384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
@ -640,6 +724,15 @@ static void key_sha384(uint8_t key_slot, uint8_t *hash)
#include <wolfssl/wolfcrypt/sha3.h>
/**
* @brief Calculate SHA3-384 hash of the image.
*
* This function calculates the SHA3-384 hash of the given image.
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @param hash The buffer to store the SHA3-384 hash (48 bytes).
* @return 0 on success, -1 on error.
*/
static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
@ -680,6 +773,18 @@ static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
return 0;
}
#ifndef WOLFBOOT_NO_SIGN
/**
* @brief Calculate SHA3-384 hash of a public key in the keystore.
*
* This function calculates the SHA3-384 hash of the public key stored
* in the keystore at the specified key slot.
*
* @param key_slot The key slot ID where the public key is stored in the
* keystore.
* @param hash The buffer to store the SHA3-384 hash (48 bytes).
* @return None.
*/
static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
@ -748,6 +853,21 @@ static void wolfBoot_PrintBin(const byte* buffer, word32 length)
static int TPM2_IoCb(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
word16 size, void* userCtx)
#else
/**
* @brief TPM2 I/O callback function for communication with TPM2 device.
*
* This function is used as the I/O callback function for communication
* with the TPM2 device. It is called during TPM operations to send and
* receive data from the TPM2 device.
*
* @param ctx The pointer to the TPM2 context.
* @param txBuf The buffer containing data to be sent to the TPM2 device.
* @param rxBuf The buffer to store the received data from the TPM2 device.
* @param xferSz The size of the data to be transferred.
* @param userCtx The user context (not used in this implementation).
* @return The return code from the TPM2 device operation.
*/
static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx)
#endif
@ -846,6 +966,17 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
#ifdef WOLFBOOT_MEASURED_BOOT
#define measure_boot(hash) wolfBoot_tpm2_extend((hash), __LINE__)
static int wolfBoot_tpm2_extend(uint8_t* hash, int line)
/**
* @brief Measure the boot state using TPM2 PCR extend operation.
*
* This function measures the boot state by extending the SHA-256 digest of
* the image into the TPM2 Platform Configuration Registers (PCRs).
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @return 0 on success, -1 on error.
*/
static int measure_boot(struct wolfBoot_image *img)
{
int rc;
PCR_Extend_In pcrExtend;
@ -896,6 +1027,13 @@ static int wolfRNG_GetSeedCB(OS_Seed* os, byte* seed, word32 sz)
}
#endif
/**
* @brief Initialize the TPM2 device and retrieve its capabilities.
*
* This function initializes the TPM2 device and retrieves its capabilities.
*
* @return 0 on success, an error code on failure.
*/
int wolfBoot_tpm2_init(void)
{
int rc;
@ -974,6 +1112,13 @@ int wolfBoot_tpm2_init(void)
return rc;
}
/**
* @brief Deinitialize the TPM2 device.
*
* This function deinitializes the TPM2 device and cleans up any resources.
*
* @return None.
*/
void wolfBoot_tpm2_deinit(void)
{
#ifdef WOLFBOOT_TPM_KEYSTORE
@ -996,6 +1141,15 @@ void wolfBoot_tpm2_deinit(void)
#endif /* WOLFBOOT_TPM */
/**
* @brief Convert a 32-bit integer from little-endian to native byte order.
*
* This function converts a 32-bit integer from little-endian byte order to
* the native byte order of the machine.
*
* @param val The 32-bit integer value in little-endian byte order.
* @return The 32-bit integer value in native byte order.
*/
static inline uint32_t im2n(uint32_t val)
{
#ifdef BIG_ENDIAN_ORDER
@ -1007,12 +1161,30 @@ static inline uint32_t im2n(uint32_t val)
return val;
}
/**
* @brief Get the size of the image from the image header.
*
* This function retrieves the size of the image from the image header.
*
* @param image The pointer to the image header.
* @return The size of the image in bytes.
*/
uint32_t wolfBoot_image_size(uint8_t *image)
{
uint32_t *size = (uint32_t *)(image + sizeof (uint32_t));
return im2n(*size);
}
/**
* @brief Open an image using the provided image address.
*
* This function opens an image using the provided image address and initializes
* the wolfBoot_image structure.
*
* @param img The pointer to the wolfBoot_image structure to be initialized.
* @param image The pointer to the image address.
* @return 0 on success, -1 on error.
*/
int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
{
uint32_t *magic = (uint32_t *)(image);
@ -1054,6 +1226,15 @@ static uint32_t wb_reverse_word32(uint32_t x)
return ByteReverseWord32(x);
}
/**
* @brief Get the size of the Device Tree Blob (DTB).
*
* This function retrieves the size of the Device Tree Blob (DTB) from
* the given DTB address.
*
* @param dts_addr The pointer to the Device Tree Blob (DTB) address.
* @return The size of the DTB in bytes, or -1 if the magic number is invalid.
*/
int wolfBoot_get_dts_size(void *dts_addr)
{
uint32_t hdr[2];
@ -1076,6 +1257,17 @@ int wolfBoot_get_dts_size(void *dts_addr)
#endif
#ifdef WOLFBOOT_FIXED_PARTITIONS
/**
* @brief Open an image in a specified partition.
*
* This function opens an image in the specified partition and initializes
* the wolfBoot_image structure.
*
* @param img The pointer to the wolfBoot_image structure to be initialized.
* @param part The partition ID (PART_BOOT, PART_UPDATE, PART_SWAP, etc.).
* @return 0 on success, -1 on error.
*/
int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)
{
#ifdef MMU
@ -1141,6 +1333,15 @@ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)
}
#endif /* WOLFBOOT_FIXED_PARTITIONS */
/**
* @brief Verify the integrity of the image using the stored SHA hash.
*
* This function verifies the integrity of the image by calculating its SHA hash
* and comparing it with the stored hash.
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @return 0 on success, -1 on error.
*/
int wolfBoot_verify_integrity(struct wolfBoot_image *img)
{
uint8_t *stored_sha;
@ -1162,6 +1363,15 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
}
#ifdef WOLFBOOT_NO_SIGN
/**
* @brief Verify the authenticity of the image using a digital signature.
*
* This function verifies the authenticity of the image by verifying its digital
* signature.
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @return 0 on success, -1 on error, -2 if the signature verification fails.
*/
int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
{
wolfBoot_image_confirm_signature_ok(img);
@ -1242,8 +1452,17 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
}
#endif
/* Peek at image offset and return static pointer */
/* sz: optional and returns length of peek */
/**
* @brief Peek at the content of the image at a specific offset.
*
* This function allows peeking at the content of the image at a specific offset
* without modifying the image.
*
* @param img The pointer to the wolfBoot_image structure representing the image.
* @param offset The offset within the image to peek at.
* @param sz Optional pointer to store the size of the peeked data.
* @return The pointer to the peeked data, or NULL if the offset is out of bounds.
*/
uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
uint32_t* sz)
{
@ -1254,6 +1473,16 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
}
#if !defined(WOLFBOOT_NO_SIGN) && !defined(WOLFBOOT_RENESAS_SCEPROTECT)
/**
* @brief Get the key slot ID by SHA hash.
*
* This function retrieves the key slot ID from the keystore that matches the
* provided SHA hash.
*
* @param hint The SHA hash of the public key to search for.
* @return The key slot ID if found, -1 if the key was not found.
*/
static int keyslot_id_by_sha(const uint8_t *hint)
{
#ifdef STAGE1_AUTH
@ -1301,3 +1530,4 @@ static int keyslot_id_by_sha(const uint8_t *hint)
return -1;
}
#endif
#endif /* IMAGE_H_ */

View File

@ -18,7 +18,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/**
* @file libwolfboot.c
*
* @brief wolfBoot library implementation.
*
* This file contains the implementation of the wolfBoot library.
*/
#include <stdint.h>
@ -28,12 +34,30 @@
#include "printf.h"
#ifdef UNIT_TEST
/**
* @def unit_dbg
* @brief Conditional debug macro for unit tests.
*
* Conditional debug macro for unit tests, redirects to wolfBoot_printf.
*/
# define unit_dbg wolfBoot_printf
#else
/**
* @def unit_dbg
* @brief Empty macro for unit_dbg in non-test builds.
*
* Empty macro for unit_dbg in non-test builds.
*/
# define unit_dbg(...) do{}while(0)
#endif
#ifndef TRAILER_SKIP
/**
* @def TRAILER_SKIP
* @brief Trailer skip value for partition encryption.
*
* Trailer skip value for partition encryption, defaults to 0 if not defined.
*/
# define TRAILER_SKIP 0
#endif
@ -265,6 +289,16 @@ finish:
return sel;
}
/**
* @brief Write the trailer in a non-volatile memory.
*
* This function writes the trailer in a non-volatile memory.
*
* @param[in] part Partition number.
* @param[in] addr Address of the trailer.
* @param[in] val New value to write in the trailer.
* @return 0 on success, -1 on failure.
*/
static int RAMFUNCTION trailer_write(uint8_t part, uintptr_t addr, uint8_t val)
{
uintptr_t addr_align = (size_t)(addr & (~(NVM_CACHE_SIZE - 1)));
@ -303,6 +337,15 @@ static int RAMFUNCTION trailer_write(uint8_t part, uintptr_t addr, uint8_t val)
return ret;
}
/**
* @brief Write the partition magic in a non-volatile memory.
*
* This function writes the partition magic in a non-volatile memory.
*
* @param[in] part Partition number.
* @param[in] addr Address of the magic trailer.
* @return 0 on success, -1 on failure.
*/
static int RAMFUNCTION partition_magic_write(uint8_t part, uintptr_t addr)
{
uintptr_t off = addr % NVM_CACHE_SIZE;
@ -328,6 +371,15 @@ static int RAMFUNCTION partition_magic_write(uint8_t part, uintptr_t addr)
#ifdef EXT_FLASH
/**
* @brief Get the trailer at a specific address in a fixed partition.
*
* This function retrieves the trailer at a specific address in a fixed partition.
*
* @param[in] part Partition number.
* @param[in] at Address offset.
* @return Pointer to the trailer at the specified address.
*/
static uint8_t* RAMFUNCTION get_trailer_at(uint8_t part, uint32_t at)
{
uint8_t *ret = NULL;
@ -363,6 +415,15 @@ static uint8_t* RAMFUNCTION get_trailer_at(uint8_t part, uint32_t at)
return ret;
}
/**
* @brief Set the trailer at a specific address in an external flash.
*
* This function sets the trailer at a specific address in an external flash.
*
* @param[in] part Partition number.
* @param[in] at Address offset.
* @param[in] val New value to set in the trailer.
*/
static void RAMFUNCTION set_trailer_at(uint8_t part, uint32_t at, uint8_t val)
{
if (part == PART_BOOT) {
@ -383,6 +444,13 @@ static void RAMFUNCTION set_trailer_at(uint8_t part, uint32_t at, uint8_t val)
}
}
/**
* @brief Set the partition magic trailer in an external flash.
*
* This function sets the partition magic trailer in an external flash.
*
* @param[in] part Partition number.
*/
static void RAMFUNCTION set_partition_magic(uint8_t part)
{
if (part == PART_BOOT) {
@ -465,6 +533,14 @@ static void RAMFUNCTION set_partition_magic(uint8_t part)
#ifdef WOLFBOOT_FIXED_PARTITIONS
/**
* @brief Get the magic trailer of a partition.
*
* This function retrieves the magic trailer of a fixed partition.
*
* @param[in] part Partition number.
* @return Pointer to the magic trailer of the partition.
*/
static uint32_t* RAMFUNCTION get_partition_magic(uint8_t part)
{
return (uint32_t *)get_trailer_at(part, 0);
@ -481,16 +557,42 @@ static void RAMFUNCTION set_partition_state(uint8_t part, uint8_t val)
set_trailer_at(part, 1, val);
}
/**
* @brief Set the flags of an update sector.
*
* This function sets the flags of an update sector in a fixed partition.
*
* @param[in] pos Update sector position.
* @param[in] val New flags value to set.
* @return 0 on success, -1 on failure.
*/
static void RAMFUNCTION set_update_sector_flags(uint32_t pos, uint8_t val)
{
set_trailer_at(PART_UPDATE, 2 + pos, val);
}
/**
* @brief Get the flags of an update sector.
*
* This function retrieves the flags of an update sector in a fixed partition.
*
* @param[in] pos Update sector position.
* @return Pointer to the flags of the update sector.
*/
static uint8_t* RAMFUNCTION get_update_sector_flags(uint32_t pos)
{
return (uint8_t *)get_trailer_at(PART_UPDATE, 2 + pos);
}
/**
* @brief Set the state of a partition.
*
* This function sets the state of a fixed partition.
*
* @param[in] part Partition number.
* @param[in] newst New state value to set.
* @return 0 on success, -1 on failure.
*/
int RAMFUNCTION wolfBoot_set_partition_state(uint8_t part, uint8_t newst)
{
uint32_t *magic;
@ -525,6 +627,15 @@ int RAMFUNCTION wolfBoot_set_update_sector_flag(uint16_t sector, uint8_t newflag
return 0;
}
/**
* @brief Get the state of a partition.
*
* This function retrieves the state of a fixed partition.
*
* @param[in] part Partition number.
* @param[out] st Pointer to store the partition state.
* @return 0 on success, -1 on failure.
*/
int RAMFUNCTION wolfBoot_get_partition_state(uint8_t part, uint8_t *st)
{
uint32_t *magic;
@ -553,7 +664,13 @@ int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag)
return 0;
}
/**
* @brief Erase a partition.
*
* This function erases a partition.
*
* @param[in] part Partition number.
*/
void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
{
uint32_t address = 0;
@ -583,6 +700,15 @@ void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
}
}
/**
* @brief Update trigger function.
*
* This function updates the boot partition state to "IMG_STATE_UPDATING".
* If the FLAGS_HOME macro is defined, it erases the last sector of the boot
* partition before updating the partition state. It also checks FLAGS_UPDATE_EXT
* and calls the appropriate flash unlock and lock functions before
* updating the partition state.
*/
void RAMFUNCTION wolfBoot_update_trigger(void)
{
uint8_t st = IMG_STATE_UPDATING;
@ -636,6 +762,14 @@ void RAMFUNCTION wolfBoot_update_trigger(void)
}
}
/**
* @brief Success function.
*
* This function updates the boot partition state to "IMG_STATE_SUCCESS".
* If the FLAGS_BOOT_EXT macro is defined, it calls the appropriate flash unlock
* and lock functions before updating the partition state. If the EXT_ENCRYPTED
* macro is defined, it calls wolfBoot_erase_encrypt_key function.
*/
void RAMFUNCTION wolfBoot_success(void)
{
uint8_t st = IMG_STATE_SUCCESS;
@ -654,6 +788,19 @@ void RAMFUNCTION wolfBoot_success(void)
}
#endif /* WOLFBOOT_FIXED_PARTITIONS */
/**
* @brief Find header function.
*
* This function searches for a specific header type in the given buffer.
* It returns the length of the header and sets the 'ptr' parameter to the
* position of the header if found.
* @param haystack Pointer to the buffer to search for the header.
* @param type The type of header to search for.
* @param ptr Pointer to store the position of the header.
*
* @return uint16_t The length of the header found, or 0 if not found.
*
*/
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr)
{
uint8_t *p = haystack;
@ -706,6 +853,16 @@ static uint8_t hdr_cpy[IMAGE_HEADER_SIZE];
static uint32_t hdr_cpy_done = 0;
#endif
/**
* @brief Convert little-endian to native-endian (uint32_t).
*
* This function converts a little-endian 32-bit value to the native-endian format.
* It is used to handle endianness differences when reading data from memory.
*
* @param val The value to convert.
*
* @return The converted value.
*/
static inline uint32_t im2n(uint32_t val)
{
#ifdef BIG_ENDIAN_ORDER
@ -717,7 +874,16 @@ static inline uint32_t im2n(uint32_t val)
return val;
}
/**
* @brief Convert little-endian to native-endian (uint16_t).
*
* This function converts a little-endian 16-bit value to the native-endian format.
* It is used to handle endianness differences when reading data from memory.
*
* @param val The value to convert.
* @return uint16_t The converted value.
*/
static inline uint16_t im2ns(uint16_t val)
{
#ifdef BIG_ENDIAN_ORDER
@ -728,6 +894,22 @@ static inline uint16_t im2ns(uint16_t val)
}
#ifdef DELTA_UPDATES
/**
* @brief Get delta update information.
*
* This function retrieves the delta update information for a given partition.
* It checks if the partition is extended, reads the image header, and returns
* the delta image offset and size. The 'inverse' flag indicates whether to get
* the inverse delta information or regular delta information.
*
* @param part The partition to check for delta update information.
* @param inverse Flag to indicate if the delta update is inverse.
* @param img_offset Pointer to store the delta image offset.
* @param img_size Pointer to store the delta image size.
*
* @return int 0 if successful, -1 if not found or an error occurred.
*
*/
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
uint16_t **img_size)
{
@ -805,7 +987,18 @@ static int decrypt_header(uint8_t *src)
}
#endif
/**
* @brief Get blob version.
*
* This function retrieves the version number from the blob.
* It checks the magic number in the blob to ensure it is valid before reading
* the version field.
*
* @param blob Pointer to the buffer containing the blob.
*
* @return The version number of the blob, or 0 if the blob is invalid.
*
*/
uint32_t wolfBoot_get_blob_version(uint8_t *blob)
{
uint32_t *volatile version_field = NULL;
@ -829,6 +1022,17 @@ uint32_t wolfBoot_get_blob_version(uint8_t *blob)
return 0;
}
/**
* @brief Get blob type.
*
* This function retrieves the type of the blob.
* It checks the magic number in the blob to ensure it is valid before reading
* the type field.
*
* @param blob Pointer to the buffer containing the blob.
*
* @return The type of the blob, or 0 if the blob is invalid.
*/
uint32_t wolfBoot_get_blob_type(uint8_t *blob)
{
uint32_t *volatile type_field = NULL;
@ -853,6 +1057,20 @@ uint32_t wolfBoot_get_blob_type(uint8_t *blob)
return 0;
}
/**
* @brief Get blob difference base version.
*
* This function retrieves the difference base version from the blob.
* It checks the magic number in the blob to ensure it is valid before reading
* the difference base field.
*
* @param blob Pointer to the buffer containing the blob.
*
* @return The difference base version of the blob, or 0 if not found
* or the blob is invalid.
*
*/
uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
{
uint32_t *volatile delta_base = NULL;
@ -878,6 +1096,19 @@ uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
#ifdef WOLFBOOT_FIXED_PARTITIONS
/**
* @brief Get image pointer from a partition.
*
* This function retrieves the pointer to the image in the specified partition.
* It handles both regular and extended partitions by reading from memory or
* external flash if needed.
*
* @param part The partition to get the image pointer for.
*
* @return uint8_t* Pointer to the image in the specified partition, or
* NULL if the partition is invalid or empty.
*
*/
static uint8_t* wolfBoot_get_image_from_part(uint8_t part)
{
uint8_t *image = (uint8_t *)0x00000000;
@ -899,6 +1130,19 @@ static uint8_t* wolfBoot_get_image_from_part(uint8_t part)
return image;
}
/**
* @brief Get image version for a partition.
*
* This function retrieves the version number of the image in the specified
* partition. It uses the 'wolfBoot_get_blob_version' function to extract the
* version from the image blob.
*
* @param part The partition to get the image version for.
*
* @return The version number of the image in the partition,
* or 0 if the partition is invalid or empty.
*
*/
uint32_t wolfBoot_get_image_version(uint8_t part)
{
@ -906,13 +1150,39 @@ uint32_t wolfBoot_get_image_version(uint8_t part)
return wolfBoot_get_blob_version(wolfBoot_get_image_from_part(part));
}
/**
* @brief Get difference base version for a partition.
*
* This function retrieves the difference base version from the image in the
* specified partition. It uses the 'wolfBoot_get_blob_diffbase_version'
* function to extract the difference base version from the image blob.
*
* @param part The partition to get the difference base version for.
*
* @return The difference base version of the image in the partition, or
* 0 if not found or the partition is invalid or empty.
*
*/
uint32_t wolfBoot_get_diffbase_version(uint8_t part)
{
/* Don't check image against NULL to allow using address 0x00000000 */
return wolfBoot_get_blob_diffbase_version(
wolfBoot_get_image_from_part(part));
}
/**
* @brief Get image type for a partition.
*
* This function retrieves the image type from the image in the specified
* partition. It uses the 'wolfBoot_get_blob_type' function to extract the image
* type from the image blob.
*
* @param part The partition to get the image type for.
*
* @return uint16_t The image type of the image in the partition, or
* 0 if the partition is invalid or empty.
*
*/
uint16_t wolfBoot_get_image_type(uint8_t part)
{
uint8_t *image = wolfBoot_get_image_from_part(part);
@ -928,7 +1198,21 @@ uint16_t wolfBoot_get_image_type(uint8_t part)
#if defined(WOLFBOOT_DUALBOOT)
#if defined(WOLFBOOT_FIXED_PARTITIONS)
/**
* @brief Find the dual-boot candidate partition.
*
* This function determines the dual-boot candidate partition based on the
* current firmware versions and states. If both primary and update images
* are present, it chooses the one with a higher version.
* If no primary image is present, it selects the update partition.
* It also handles the case where the current partition is in "IMG_STATE_TESTING"
* and switches to the other partition if available.
*
* @return The partition number (PART_BOOT or PART_UPDATE) to be used as
* the dual-boot candidate.
* Returns -1 if no valid candidate is found.
*
*/
int wolfBoot_dualboot_candidate(void)
{
int candidate = PART_BOOT;
@ -1005,7 +1289,15 @@ int wolfBoot_dualboot_candidate_addr(void** addr)
return retval;
}
#endif /* WOLFBOOT_FIXED_PARTITIONS */
/**
* @brief Check if fallback is possible.
*
* This function checks if fallback is possible, i.e., both primary and
* update images are present.
*
* @return 1 if fallback is possible, 0 otherwise.
*
*/
int wolfBoot_fallback_is_possible(void)
{
uint32_t boot_v, update_v;
@ -1068,7 +1360,18 @@ static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
return ret;
#endif
}
/**
* @brief Set the encryption key.
*
* This function sets the encryption key and nonce used for encrypting the
* firmware image. It stores the key and nonce in the designated memory location.
*
* @param key Pointer to the encryption key.
* @param nonce Pointer to the encryption nonce.
*
* @return 0 if successful.
*
*/
int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
const uint8_t *nonce)
{
@ -1077,6 +1380,18 @@ int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
}
#ifndef UNIT_TEST
/**
* @brief Set the encryption key.
*
* This function sets the encryption key and nonce used for encrypting the
* firmware image. It stores the key and nonce in the designated memory location.
*
* @param key Pointer to the encryption key.
* @param nonce Pointer to the encryption nonce.
*
* @return 0 if successful.
*
*/
int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
{
#if defined(MMU)
@ -1096,7 +1411,15 @@ int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
return 0;
}
#endif
/**
* @brief Erase the encryption key.
*
* This function erases the encryption key and nonce, resetting them to all 0xFF
* bytes.It ensures that the key and nonce cannot be accessed after erasure.
*
* @return 0 if successful.
*
*/
int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
{
#if defined(MMU)
@ -1161,7 +1484,15 @@ int RAMFUNCTION chacha_init(void)
#elif defined(ENCRYPT_WITH_AES128) || defined(ENCRYPT_WITH_AES256)
Aes aes_dec, aes_enc;
/**
* @brief Initialize AES encryption.
*
* This function initializes the AES encryption by setting the encryption key
* and encryption nonce, checking for valid keys, and copying the encryption
* nonce from the key buffer.
*
* @return 0 if successful, -1 on failure.
*/
int aes_init(void)
{
#if defined(MMU) || defined(UNIT_TEST)
@ -1202,6 +1533,17 @@ int aes_init(void)
return 0;
}
/**
* @brief Set the AES initialization vector (IV) for CTR mode.
*
* This function sets the AES initialization vector (IV) for the Counter (CTR)
* mode encryption. It takes a 12-byte nonce and a 32-bit IV counter value to
* construct the 16-byte IV used for encryption.
*
* @param nonce Pointer to the 12-byte nonce (IV) buffer.
* @param iv_ctr The IV counter value.
*
*/
void aes_set_iv(uint8_t *nonce, uint32_t iv_ctr)
{
uint32_t iv_buf[ENCRYPT_BLOCK_SIZE / sizeof(uint32_t)];
@ -1232,7 +1574,19 @@ void aes_set_iv(uint8_t *nonce, uint32_t iv_ctr)
#endif
/**
* @brief Determine the partition address type.
*
* This function determines the partition type based on the provided address.
* If the address belongs to the update partition or swap partition (if defined),
* the corresponding partition type is returned.
* Otherwise, PART_NONE is returned.
*
* @param a The address to check for its partition type.
*
* @return The partition type (PART_UPDATE, PART_SWAP, or PART_NONE).
*/
static uint8_t RAMFUNCTION part_address(uintptr_t a)
{
#ifdef WOLFBOOT_FIXED_PARTITIONS
@ -1257,6 +1611,18 @@ static uint8_t RAMFUNCTION part_address(uintptr_t a)
}
#ifdef EXT_FLASH
/**
* @brief Write encrypted data to an external flash.
*
* This function encrypts the provided data using the AES encryption algorithm
* and writes it to the external flash.
*
* @param address The address in the external flash to write the data to.
* @param data Pointer to the data buffer to be written.
* @param len The length of the data to be written.
*
* @return int 0 if successful, -1 on failure.
*/
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
{
uint8_t block[ENCRYPT_BLOCK_SIZE];
@ -1322,7 +1688,20 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
return ext_flash_write(address, ENCRYPT_CACHE, step);
}
/**
* @brief Read and decrypt data from an external flash.
*
* This function reads the encrypted data from the external flash,
* decrypts it using the AES decryption algorithm, and stores the decrypted data
* in the provided buffer.
* @param address The address in the external flash to read the encrypted data from.
* @param data Pointer to the buffer to store the decrypted data.
* @param len The length of the data to be read and decrypted.
*
* @return The number of decrypted bytes read, or -1 on failure.
*
*/
int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len)
{
uint8_t block[ENCRYPT_BLOCK_SIZE];
@ -1407,6 +1786,17 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
#endif /* __WOLFBOOT */
#if defined(MMU)
/**
* @brief Decrypt data from RAM.
*
* This function decrypts data from the RAM using the AES decryption algorithm.
*
* @param src Pointer to the source buffer containing the encrypted data.
* @param dst Pointer to the destination buffer to store the decrypted data.
*
* @return int 0 if successful, -1 on failure.
*
*/
int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst)
{
uint8_t block[ENCRYPT_BLOCK_SIZE];

View File

@ -18,6 +18,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/**
* @file loader.c
*
* @brief Loader implementation for wolfBoot.
*
* This file contains the implementation of the loader for wolfBoot. It includes
* functions to initialize the hardware, probe SPI flash,
* initialize UART (if applicable), initialize TPM2 (if applicable), and
* start the wolfBoot process.
*/
#include "loader.h"
#include "image.h"
@ -27,16 +37,51 @@
#include "wolfboot/wolfboot.h"
#ifdef RAM_CODE
/**
* @brief Start address of the text section in RAM code.
*/
extern unsigned int _start_text;
/**
* @brief wolfBoot version number (used in RAM code).
*/
static volatile const uint32_t __attribute__((used)) wolfboot_version = WOLFBOOT_VERSION;
/**
* @brief RAM Interrupt Vector table.
*/
extern void (** const IV_RAM)(void);
#endif
#ifdef PLATFORM_sim
/**
* @brief Command line arguments for the test-app in sim mode.
*/
extern char **main_argv;
/**
* @brief Number of command line arguments for the test-app in sim mode.
*/
extern int main_argc;
/**
* @brief Main function in sim platform.
*
* This function is the entry point for the simulator platform. It forwards the
* command line arguments to the test-app for testing purposes.
*
* @param argc Number of command line arguments.
* @param argv Array of command line arguments.
* @return The return code of the test-app.
*/
int main(int argc, char *argv[])
#elif defined(WOLFBOOT_LOADER_MAIN)
/**
* @brief Main function for the wolfBoot loader.
*
* This function is the entry point for the wolfBoot loader. It initializes
* the hardware, probes SPI flash, initializes UART (if applicable), initializes
* TPM2 (if applicable), and starts the wolfBoot process.
*
* @return The return code of the wolfBoot process (should not return).
*/
int loader_main(void)
#else
int main(void)

View File

@ -22,7 +22,20 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/**
* @file update_disk.c
*
* @brief Implementation for RAM based updater, for systems that provide
* drives and partition mapping.
*
* This file contains the implementation for the RAM-based updater for systems
* that offer drives and partition mapping. It includes functions to read
* and load OS images from disk partitions, validate their integrity and
* authenticity, and perform the boot process.
*/
#ifndef UPDATE_DISK_H_
#define UPDATE_DISK_H_
#include "image.h"
#include "loader.h"
#include "hal.h"
@ -50,7 +63,13 @@
#define MAX_FAILURES 4
#define IMAGE_PRELOAD_ADDRESS 0x5000100
/**
* @brief RAM function for starting the boot process.
*
* This function starts the boot process by attempting to read and load
* the OS image from disk partitions. It then verifies the integrity and
* authenticity of the loaded image before initiating the boot.
*/
void RAMFUNCTION wolfBoot_start(void)
{
struct wolfBoot_image os_image;
@ -170,3 +189,4 @@ void RAMFUNCTION wolfBoot_start(void)
do_boot((uint32_t*)os_image.fw_base);
}
#endif /* UPDATE_DISK_H_ */

View File

@ -19,7 +19,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
*/
/**
* @file ahci.c
*
* @brief AHCI (Advanced Host Controller Interface) Implementation.
*
* This file contains the implementation of the AHCI (Advanced Host Controller
* Interface) driver. It includes functions to enable and disable the AHCI
* controller, detect SATA disks, and initialize ATA drives for detected disks.
*/
#ifndef AHCI_H_
#define AHCI_H_
#include <stdint.h>
#include <x86/common.h>
@ -60,13 +71,32 @@
#define AHCI_DEBUG_PRINTF(...) do {} while(0)
#endif /* DEBUG_AHCI */
/**
* @brief Sets the AHCI Base Address Register (ABAR) for the given device.
*
* @param bus The PCI bus number of the AHCI device.
* @param dev The PCI device number of the AHCI device.
* @param fun The PCI function number of the AHCI device.
* @param addr The address to set as the ABAR.
*/
static inline void ahci_set_bar(uint32_t bus, uint32_t dev,
uint32_t func, uint32_t addr)
{
pci_config_write32(bus, dev, func, AHCI_ABAR_OFFSET, addr);
}
/**
* @brief Initializes the SATA controller for the given device.
*
* This function initializes the SATA controller for the specified AHCI device
* and detects connected SATA disks. It sets up the necessary registers and
* configurations for the controller to function properly.
*
* @param bus The PCI bus number of the AHCI device.
* @param dev The PCI device number of the AHCI device.
* @param fun The PCI function number of the AHCI device.
* @return 0 on success, or a negative value on failure.
*/
int init_sata_controller(uint32_t bus, uint32_t dev, uint32_t fun)
{
uint16_t reg16;
@ -89,6 +119,17 @@ int init_sata_controller(uint32_t bus, uint32_t dev, uint32_t fun)
return 0;
}
/**
* @brief Enables the AHCI controller for the given device.
*
* This function enables the AHCI controller for the specified AHCI device
* and returns the AHCI Base Address Register (ABAR) for accessing AHCI registers.
*
* @param bus The PCI bus number of the AHCI device.
* @param dev The PCI device number of the AHCI device.
* @param fun The PCI function number of the AHCI device.
* @return The ABAR address on success, or 0 on failure.
*/
uint32_t ahci_enable(uint32_t bus, uint32_t dev, uint32_t fun)
{
uint16_t reg16;
@ -118,6 +159,15 @@ uint32_t ahci_enable(uint32_t bus, uint32_t dev, uint32_t fun)
return bar;
}
/**
* @brief Dumps the status of the specified AHCI port.
*
* This function dumps the status of the AHCI port with the given index.
* It prints the status of various port registers for debugging purposes.
*
* @param base The AHCI Base Address Register (ABAR) for accessing AHCI registers.
* @param i The index of the AHCI port to dump status for.
*/
void ahci_dump_port(uint32_t base, int i)
{
uint32_t cmd, ci, is, tfd, serr, ssst;
@ -132,6 +182,14 @@ void ahci_dump_port(uint32_t base, int i)
i, cmd, ci, is, tfd, serr, ssst);
}
/**
* @brief Enables SATA ports and detects connected SATA disks.
*
* This function enables SATA ports in the AHCI controller and detects connected SATA disks.
* It initializes the ATA drives for the detected disks.
*
* @param base The AHCI Base Address Register (ABAR) for accessing AHCI registers.
*/
void sata_enable(uint32_t base) {
volatile uint32_t count;
uint32_t cap, ports_impl;
@ -337,6 +395,14 @@ void sata_enable(uint32_t base) {
}
}
/**
* @brief Disables SATA ports in the AHCI controller.
*
* This function disables SATA ports in the AHCI controller and stops any DMA operation.
* It clears status registers and puts the AHCI ports into an inactive state.
*
* @param base The AHCI Base Address Register (ABAR) for accessing AHCI registers.
*/
void sata_disable(uint32_t base)
{
uint32_t i, reg;
@ -398,3 +464,5 @@ void sata_disable(uint32_t base)
/* mmio_or32(AHCI_HBA_GHC(base), HBA_GHC_HR | HBA_GHC_IE); */
/* memset((void *)SATA_BASE, 0, 0x1000000); */
}
#endif /* AHCI_H_ */

View File

@ -19,7 +19,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
*/
/**
* @file ata.c
* @brief This file contains the implementation of the ATA
* (Advanced Technology Attachment) driver used for interacting with AHCI
* (Advanced Host Controller Interface) based SATA drives.
* It supports functions for drive initialization, read and write operations,
* and device identification.
*/
#ifndef ATA_C
#define ATA_C
#include <stdint.h>
#include <x86/common.h>
#include <x86/ahci.h>
@ -33,6 +42,14 @@
#define CACHE_INVALID 0xBADF00DBADC0FFEEULL
#ifdef DEBUG_ATA
/**
* @brief This macro is used to conditionally print debug messages for the ATA
* driver. If DEBUG_ATA is defined, it calls the wolfBoot_printf function with
* the specified format and arguments. Otherwise, it is defined as an empty
* do-while loop.
*
* @param[in] ... Format and arguments for the debug printf.
*/
#define ATA_DEBUG_PRINTF(...) wolfBoot_printf(__VA_ARGS__)
#else
#define ATA_DEBUG_PRINTF(...) do {} while(0)
@ -41,6 +58,10 @@
static int ata_drive_count = -1;
/**
* @brief This structure holds the necessary information for an ATA drive,
* including AHCI base address, AHCI port number, and sector cache.
*/
struct ata_drive {
uint32_t ahci_base;
unsigned ahci_port;
@ -52,9 +73,17 @@ struct ata_drive {
uint64_t cached;
};
/**
* @brief This array holds instances of the `struct ata_drive` representing
* multiple ATA drives (up to `MAX_ATA_DRIVES`).
*/
struct ata_drive ATA_Drv[MAX_ATA_DRIVES];
/**
* @brief This packed structure defines a single entry in the HBA
* (Host Bus Adapter) HBA PRDT (Physical Region Descriptor Table) used for
* DMA data transfer.
*/
struct __attribute__((packed)) hba_prdt_entry {
uint32_t dba;
uint32_t dbau;
@ -63,6 +92,10 @@ struct __attribute__((packed)) hba_prdt_entry {
};
/**
* @brief This packed structure defines the layout of an HBA command table,
* which contains command headers and PRDT entries for DMA data transfer.
*/
struct __attribute__((packed)) hba_cmd_table {
uint8_t cfis[64];
uint8_t acmd[16];
@ -70,6 +103,10 @@ struct __attribute__((packed)) hba_cmd_table {
struct hba_prdt_entry prdt_entry[8];
};
/**
* @brief This packed structure defines the format of an H2D Register FIS
* used for ATA commands.
*/
struct __attribute__((packed)) fis_reg_h2d {
uint8_t fis_type;
@ -95,6 +132,10 @@ struct __attribute__((packed)) fis_reg_h2d {
uint32_t _res1;
};
/**
* @brief This packed structure defines the format of a D2H Register FIS
* used for ATA commands completion.
*/
struct __attribute__((packed)) fis_reg_d2h {
uint8_t fis_type;
@ -119,6 +160,10 @@ struct __attribute__((packed)) fis_reg_d2h {
uint32_t _res4;
};
/**
* @brief This packed structure defines the format of a Data FIS used for
* data transfer.
*/
struct __attribute__((packed)) fis_data {
uint8_t fis_type;
uint8_t pmport:4, _res0:4;
@ -126,6 +171,19 @@ struct __attribute__((packed)) fis_data {
uint32_t data[0];
};
/**
* @brief This function initializes a new ATA drive instance with the provided
* parameters and stores it in the ATA_Drv array.
*
* @param[in] ahci_base The base address of the AHCI controller.
* @param[in] ahci_port The port number of the AHCI controller.
* @param[in] clb The command list base address for the drive.
* @param[in] ctable The command table base address for the drive.
* @param[in] fis The FIS base address for the drive.
*
* @return The index of the new ATA drive if successful, or -1 if the maximum
* number of drives has been reached.
*/
int ata_drive_new(uint32_t ahci_base, unsigned ahci_port, uint32_t clb,
uint32_t ctable, uint32_t fis)
{
@ -144,6 +202,15 @@ int ata_drive_new(uint32_t ahci_base, unsigned ahci_port, uint32_t clb,
return ata_drive_count;
}
/**
* @brief This static function finds an available command slot for the specified
* ATA drive and returns the slot number.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
*
* @return The index of the available command slot if found, or -1 if no slot is
* available.
*/
static int find_cmd_slot(int drv)
{
struct ata_drive *ata = &ATA_Drv[drv];
@ -161,6 +228,17 @@ static int find_cmd_slot(int drv)
return -1;
}
/**
* @brief This static function prepares a command slot for DMA data transfer by
* initializing the command header and command table entries.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
* @param[in] buf The buffer containing the data to be transferred.
* @param[in] sz The size of the data to be transferred in bytes.
*
* @return The index of the prepared command slot if successful, or -1 if an error
* occurs.
*/
static int prepare_cmd_slot(int drv, const uint8_t *buf, int sz)
{
struct hba_cmd_header *cmd;
@ -185,6 +263,16 @@ static int prepare_cmd_slot(int drv, const uint8_t *buf, int sz)
return slot;
}
/**
* @brief This static function executes the command in the specified command
* slot for the ATA drive and waits for the command to complete.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
* @param[in] slot The index of the command slot to execute.
*
* @return 0 on success, or -1 if an error occurs during command execution.
*/
static int exec_cmd_slot(int drv, int slot)
{
struct ata_drive *ata = &ATA_Drv[drv];
@ -229,6 +317,16 @@ static void invert_buf(uint8_t *src, uint8_t *dst, unsigned len)
#define ATA_ID_MODEL_NO_POS 54
#define ATA_ID_MODEL_NO_LEN 40
/**
* @brief This function identifies the ATA device connected to the specified
* ATA drive and retrieves its device information, such as serial number and
* model name.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
*
* @return 0 on success, or -1 if an error occurs during device identification.
*/
int ata_identify_device(int drv)
{
struct ata_drive *ata = &ATA_Drv[drv];
@ -352,6 +450,18 @@ static void ata_cache_commit(int drv)
ata_drive_write_sector(drv, ata->cached, 1, ata->sector_cache);
}
/**
* @brief This function reads data from the specified ATA drive starting from
* the given sector and copies it into the provided buffer. It handles partial
* reads and multiple sector transfers.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
* @param[in] start The starting sector number to read from.
* @param[in] size The size of the data to read in bytes.
* @param[out] buf The buffer to store the read data.
*
* @return The number of bytes read into the buffer, or -1 if an error occurs.
*/
int ata_drive_read(int drv, uint64_t start, uint32_t size, uint8_t *buf)
{
uint64_t sect_start, sect_off;
@ -390,6 +500,18 @@ int ata_drive_read(int drv, uint64_t start, uint32_t size, uint8_t *buf)
return buffer_off;
}
/**
* @brief This function writes data from the provided buffer to the specified ATA
* drive starting from the given sector. It handles partial writes and multiple
* sector transfers.
*
* @param[in] drv The index of the ATA drive in the ATA_Drv array.
* @param[in] start The starting sector number to write to.
* @param[in] size The size of the data to write in bytes.
* @param[in] buf The buffer containing the data to write.
*
* @return The number of bytes written to the drive, or -1 if an error occurs.
*/
int ata_drive_write(int drv, uint64_t start, uint32_t size,
const uint8_t *buf)
{
@ -430,3 +552,4 @@ int ata_drive_write(int drv, uint64_t start, uint32_t size,
}
return buffer_off;
}
#endif /* ATA_C */

View File

@ -19,6 +19,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
*/
/**
* @file common.c
*
* @brief Common functions and macros for wolfBoot
*
* This file contains common functions and macros used in wolfBoot for
* x86 architecture. These functions include memory-mapped I/O access,
* I/O port access, CPUID instruction, and reset control functions.
*/
#ifndef COMMON_H_
#define COMMON_H_
#include <stdint.h>
@ -39,6 +50,12 @@
#define NULL 0
#endif
/**
* @brief Memory-mapped write access to a 32-bit register.
*
* @param address The memory address of the register to write to.
* @param value The 32-bit value to write.
*/
void mmio_write32(uintptr_t address, uint32_t value)
{
volatile uint32_t *_addr = (uint32_t*)address;
@ -46,6 +63,13 @@ void mmio_write32(uintptr_t address, uint32_t value)
barrier();
}
/**
* @brief Memory-mapped read access to a 32-bit register.
*
* @param address The memory address of the register to read from.
* @return The 32-bit value read from the register.
*/
uint32_t mmio_read32(uintptr_t address)
{
volatile uint32_t *_addr = (uint32_t*)address;
@ -55,6 +79,13 @@ uint32_t mmio_read32(uintptr_t address)
barrier();
return ret;
}
/**
* @brief Memory-mapped write access to a 16-bit register.
*
* @param address The memory address of the register to write to.
* @param value The 16-bit value to write.
*/
void mmio_write16(uintptr_t address, uint16_t value)
{
volatile uint16_t *_addr = (uint16_t*)address;
@ -63,6 +94,12 @@ void mmio_write16(uintptr_t address, uint16_t value)
barrier();
}
/**
* @brief Memory-mapped read access to a 16-bit register.
*
* @param address The memory address of the register to read from.
* @return The 16-bit value read from the register.
*/
uint16_t mmio_read16(uintptr_t address)
{
volatile uint16_t *_addr = (uint16_t*)address;
@ -73,6 +110,12 @@ uint16_t mmio_read16(uintptr_t address)
return ret;
}
/**
* @brief Memory-mapped write access to an 8-bit register.
*
* @param address The memory address of the register to write to.
* @param value The 8-bit value to write.
*/
void mmio_write8(uintptr_t address, uint8_t value)
{
volatile uint8_t *_addr = (uint8_t*)address;
@ -81,6 +124,12 @@ void mmio_write8(uintptr_t address, uint8_t value)
barrier();
}
/**
* @brief Memory-mapped read access to an 8-bit register.
*
* @param address The memory address of the register to read from.
* @return The 8-bit value read from the register.
*/
uint8_t mmio_read8(uintptr_t address)
{
volatile uint8_t *_addr = (uint8_t*)address;
@ -91,16 +140,34 @@ uint8_t mmio_read8(uintptr_t address)
return ret;
}
/**
* @brief I/O port write access to an 8-bit register.
*
* @param port The I/O port address of the register to write to.
* @param value The 8-bit value to write.
*/
void io_write8(uint16_t port, uint8_t value)
{
asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}
/**
* @brief I/O port write access to a 32-bit register.
*
* @param port The I/O port address of the register to write to.
* @param value The 32-bit value to write.
*/
void io_write32(uint16_t port, uint32_t value)
{
__asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
}
/**
* @brief I/O port read access to a 32-bit register.
*
* @param port The I/O port address of the register to read from.
* @return The 32-bit value read from the register.
*/
uint32_t io_read32(uint16_t port)
{
unsigned int _v;
@ -109,11 +176,23 @@ uint32_t io_read32(uint16_t port)
return _v;
}
/**
* @brief I/O port write access to a 16-bit register.
*
* @param port The I/O port address of the register to write to.
* @param value The 16-bit value to write.
*/
void io_write16(uint16_t port, uint16_t value)
{
__asm__ __volatile__ ("outw %0,%w1": :"a" (value), "Nd" (port));
}
/**
* @brief I/O port read access to a 16-bit register.
*
* @param port The I/O port address of the register to read from.
* @return The 16-bit value read from the register.
*/
uint16_t io_read16(uint16_t port)
{
uint16_t _v;
@ -122,6 +201,16 @@ uint16_t io_read16(uint16_t port)
return _v;
}
/**
* @brief Memory-mapped OR operation with a 32-bit register.
*
* Reads the 32-bit register at the given address, performs a bitwise OR operation
* with the provided value, and writes the result back to the register.
*
* @param address The memory address of the register.
* @param value The 32-bit value to OR with the register contents.
* @return The updated 32-bit value of the register after the OR operation.
*/
uint32_t mmio_or32(uintptr_t address, uint32_t value)
{
uint32_t reg;
@ -140,6 +229,11 @@ uint8_t io_read8(uint16_t port)
return v;
}
/**
* @brief Reset the system.
*
* @param warm Set to 1 for a warm reset, 0 for a cold reset.
*/
void reset(uint8_t warm)
{
uint8_t value;
@ -150,6 +244,11 @@ void reset(uint8_t warm)
while(1){};
}
/**
* @brief Delay the execution for a specified number of milliseconds.
*
* @param msec The number of milliseconds to delay.
*/
void delay(int msec)
{
int i;
@ -157,6 +256,12 @@ void delay(int msec)
io_write8(0x80, 0x41);
}
/**
* @brief Enter an infinite loop, causing a panic state.
*
* This function is used for error handling when the system encounters an unrecoverable issue.
* It enters an infinite loop, causing a panic state.
*/
void panic()
{
while (1) {
@ -164,6 +269,15 @@ void panic()
}
}
/**
* @brief Execute the CPUID instruction and retrieve the result.
*
* @param eax_param The value to set in the EAX register before executing CPUID.
* @param eax Pointer to store the output value of the EAX register.
* @param ebx Pointer to store the output value of the EBX register.
* @param ecx Pointer to store the output value of the ECX register.
* @param edx Pointer to store the output value of the EDX register.
*/
void cpuid(uint32_t eax_param,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
@ -189,6 +303,11 @@ void cpuid(uint32_t eax_param,
*edx = _edx;
}
/**
* @brief Check if 1GB page is supported by the CPU.
*
* @return 1 if 1GB page is supported, 0 otherwise.
*/
int cpuid_is_1gb_page_supported()
{
uint32_t edx;
@ -200,7 +319,15 @@ int cpuid_is_1gb_page_supported()
/* Needs to match the code_sel_long offset inside the GDT. The GDT is populated
* in src/x86 */
#define CODE_SEL_LONG 0x18
/**
* @brief Switch the CPU to long mode.
*
* This function switches the CPU to long mode with the provided entry point
* and page table.
*
* @param entry The entry point of the long mode code.
* @param page_table The page table address to use in long mode.
*/
void switch_to_long_mode(uint64_t *entry, uint32_t page_table)
{
/* refer to Intel Software Developer's Manual Vol 3 sec 9.8.5*/
@ -235,3 +362,4 @@ void switch_to_long_mode(uint64_t *entry, uint32_t page_table)
_entry();
}
#endif /* BUILD_LOADER_STAGE1 */
#endif /* COMMON_H_ */

View File

@ -19,6 +19,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
*/
/**
* @file gpt.c
* @brief GPT (GUID Partition Table) driver implementation.
*
* This file contains the implementation of the GPT driver used for interacting
* with GPT partitioned disks. It provides functions for disk initialization,
* partition reading, and writing.
*/
#ifndef GPT_C
#define GPT_C
#include <x86/common.h>
#include <x86/ahci.h>
#include <x86/ata.h>
@ -36,7 +46,10 @@
#define P_ENTRY_START 0x01BE
#define P_BOOTSIG_OFFSET 0x01FE
/**
* @brief This packed structure defines the layout of an MBR partition table entry
* used to identify GPT partitions.
*/
struct __attribute__((packed)) mbr_ptable_entry {
uint8_t stat;
uint8_t chs_first[3];
@ -46,6 +59,9 @@ struct __attribute__((packed)) mbr_ptable_entry {
uint32_t lba_size;
};
/**
* @brief Structure representing a GPT (GUID Partition Table) header.
*/
struct __attribute__((packed)) guid_ptable
{
uint64_t signature;
@ -65,6 +81,10 @@ struct __attribute__((packed)) guid_ptable
uint8_t res1[SECTOR_SIZE - 0x5C];
};
/**
* @brief This packed structure defines the layout of a GPT partition entry
* used to describe individual partitions on the disk.
*/
struct __attribute__((packed)) guid_part_array
{
uint64_t type[2];
@ -75,6 +95,10 @@ struct __attribute__((packed)) guid_part_array
int16_t name[72];
};
/**
* @brief This structure holds information about a disk partition, including
* the drive it belongs to, partition number, start, and end offsets.
*/
struct disk_partition
{
int drv;
@ -83,6 +107,11 @@ struct disk_partition
uint64_t end;
};
/**
* @brief This structure holds information about a disk drive, including its
* drive number, open status, the number of partitions, and an array of disk
* partitions.
*/
struct disk_drive {
int drv;
int is_open;
@ -90,8 +119,24 @@ struct disk_drive {
struct disk_partition part[MAX_PARTITIONS];
};
static struct disk_drive Drives[MAX_DISKS] = { };
/**
* @brief This array holds instances of the `struct disk_drive` representing
* multiple disk drives (up to `MAX_DISKS`).
*/
static struct disk_drive Drives[MAX_DISKS] = {0};
/**
* @brief Opens a disk drive and initializes its partitions.
*
* This function opens a disk drive with the specified drive number, reads its
* MBR (Master Boot Record) to identify GPT partitions, and initializes the
* disk_drive structure for further operations.
*
* @param[in] drv The drive number to open (0 to `MAX_DISKS - 1`).
*
* @return The number of partitions found and initialized on success, or -1 if
* the drive cannot be opened or no valid GPT partition table is found.
*/
int disk_open(int drv)
{
int r;
@ -185,7 +230,19 @@ int disk_open(int drv)
wolfBoot_printf("Total partitions on disk%u: %u\r\n", drv, Drives[drv].n_parts);
return Drives[drv].n_parts;
}
/**
* @brief Opens a disk partition and returns a pointer to its structure.
*
* This function opens a disk partition with the specified drive number and
* partition number and returns a pointer to its disk_partition structure.
* It is a static helper function used internally by the disk_read and disk_write
* functions to validate the partition before performing read/write operations.
*
* @param[in] drv The drive number of the disk containing the partition (0 to `MAX_DISKS - 1`).
* @param[in] part The partition number on the disk (0 to `MAX_PARTITIONS - 1`).
*
* @return A pointer to the disk_partition structure on success, or NULL if an error occurs.
*/
static struct disk_partition *open_part(int drv, int part)
{
if ((drv < 0) || (drv > MAX_DISKS)) {
@ -207,6 +264,20 @@ static struct disk_partition *open_part(int drv, int part)
return &Drives[drv].part[part];
}
/**
* @brief Reads data from a disk partition into the provided buffer.
*
* This function reads data from the specified disk partition starting from the
* given offset and copies it into the provided buffer.
*
* @param[in] drv The drive number of the disk containing the partition (0 to `MAX_DISKS - 1`).
* @param[in] part The partition number on the disk (0 to `MAX_PARTITIONS - 1`).
* @param[in] off The offset in bytes from the start of the partition to read from.
* @param[in] sz The size of the data to read in bytes.
* @param[out] buf The buffer to store the read data.
*
* @return The number of bytes read into the buffer on success, or -1 if an error occurs.
*/
int disk_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf)
{
struct disk_partition *p = open_part(drv, part);
@ -225,6 +296,20 @@ int disk_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf)
return ret;
}
/**
* @brief Writes data to a disk partition from the provided buffer.
*
* This function writes data from the provided buffer to the specified disk
* partition starting from the given offset.
*
* @param[in] drv The drive number of the disk containing the partition (0 to `MAX_DISKS - 1`).
* @param[in] part The partition number on the disk (0 to `MAX_PARTITIONS - 1`).
* @param[in] off The offset in bytes from the start of the partition to write to.
* @param[in] sz The size of the data to write in bytes.
* @param[in] buf The buffer containing the data to write.
*
* @return The number of bytes written to the partition on success, or -1 if an error occurs.
*/
int disk_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf)
{
struct disk_partition *p = open_part(drv, part);
@ -242,3 +327,4 @@ int disk_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf)
ret = ata_drive_write(drv, p->start + off, len, buf);
return ret;
}
#endif /* GPT_C */

View File

@ -20,7 +20,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef HOB_C
#define HOB_C
#include <stdint.h>
#include <x86/hob.h>
#include <string.h>
@ -37,16 +38,44 @@ static struct efi_guid hob_fsp_reserved_guid = {
{ 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e }
};
/**
* @brief Retrieves the HOB type from the provided HOB structure.
*
* This function takes a pointer to an EFI_HOB structure and returns the HOB type
* as a uint16_t.
*
* @param[in] hob Pointer to the EFI_HOB structure.
* @return The HOB type as a uint16_t.
*/
uint16_t hob_get_type(struct efi_hob *hob)
{
return hob->u.header.hob_type;
}
/**
* @brief Retrieves the length of the HOB structure from the provided HOB structure.
*
* This function takes a pointer to an EFI_HOB structure and returns the length
* of the HOB structure as a uint16_t.
*
* @param[in] hob Pointer to the EFI_HOB structure.
* @return The length of the HOB structure as a uint16_t.
*/
uint16_t hob_get_length(struct efi_hob *hob)
{
return hob->u.header.hob_length;
}
/**
* @brief Retrieves the next HOB structure in the HOB list.
*
* This function takes a pointer to an EFI_HOB structure and returns a pointer to
* the next HOB structure in the HOB list.
*
* @param[in] hob Pointer to the EFI_HOB structure.
* @return A pointer to the next HOB structure or NULL if the end of the list is
* reached.
*/
struct efi_hob *hob_get_next(struct efi_hob *hob)
{
struct efi_hob *ret;
@ -54,11 +83,32 @@ struct efi_hob *hob_get_next(struct efi_hob *hob)
return ret;
}
/**
* @brief Compares two EFI_GUID structures for equality.
*
* This function takes two pointers to EFI_GUID structures and compares them
* for equality. It returns 1 if the GUIDs are equal and 0 otherwise.
*
* @param[in] a Pointer to the first EFI_GUID structure.
* @param[in] b Pointer to the second EFI_GUID structure.
* @return 1 if the GUIDs are equal, 0 otherwise.
*/
int hob_guid_equals(struct efi_guid *a, struct efi_guid *b)
{
return memcmp(a, b, sizeof(*a)) == 0;
}
/**
* @brief Finds an EFI_HOB_RESOURCE_DESCRIPTOR with a specific owner GUID.
*
* This function searches the HOB list for an EFI_HOB_RESOURCE_DESCRIPTOR with
* the specified owner GUID. If found, it returns a pointer to the descriptor,
* otherwise, it returns NULL.
*
* @param[in] hoblist Pointer to the beginning of the HOB list.
* @param[in] guid Pointer to the owner GUID to search for.
* @return A pointer to the EFI_HOB_RESOURCE_DESCRIPTOR or NULL if not found.
*/
struct efi_hob_resource_descriptor *
hob_find_resource_by_guid(struct efi_hob *hoblist, struct efi_guid *guid)
{
@ -78,12 +128,35 @@ hob_find_resource_by_guid(struct efi_hob *hoblist, struct efi_guid *guid)
return NULL;
}
/**
* @brief Finds the EFI_HOB_RESOURCE_DESCRIPTOR with the FSP reserved GUID.
*
* This function searches the HOB list for the EFI_HOB_RESOURCE_DESCRIPTOR
* with the FSP reserved GUID and returns a pointer to the descriptor if found.
* If not found, it returns NULL.
*
* @param[in] hoblist Pointer to the beginning of the HOB list.
* @return A pointer to the EFI_HOB_RESOURCE_DESCRIPTOR or NULL if not found.
*/
struct efi_hob_resource_descriptor *
hob_find_fsp_reserved(struct efi_hob *hoblist)
{
return hob_find_resource_by_guid(hoblist, &hob_fsp_reserved_guid);
}
/**
* @brief Iterates through the memory map in the HOB list and calls a callback
* function for each resource descriptor.
*
* This function iterates through the memory map in the HOB list and calls the
* specified callback function for each EFI_HOB_RESOURCE_DESCRIPTOR found
* in the list.
*
* @param[in] hobList Pointer to the beginning of the HOB list.
* @param[in] cb Callback function to be called for each resource descriptor.
* @param[in] ctx User-defined context to be passed to the callback function.
* @return 0 on success, or an error code if an error occurs during iteration.
*/
int hob_iterate_memory_map(struct efi_hob *hobList, hob_mem_map_cb cb,
void *ctx)
{
@ -103,3 +176,4 @@ int hob_iterate_memory_map(struct efi_hob *hobList, hob_mem_map_cb cb,
return 0;
}
#endif /* HOB_C */

View File

@ -20,6 +20,18 @@
*
* Machine dependent code for TigerLake x86 with FSP
*/
/**
* @file tgl_fsp.c
*
* @brief Machine dependent code for TigerLake x86 with FSP
*
* This file contains machine dependent code for TigerLake x86 platform
* with Firmware Support Package (FSP).
*/
#ifndef TGL_FSP_H
#define TGL_FSP_H
#include <stdint.h>
#include <stddef.h>
#include <x86/hob.h>
@ -405,6 +417,15 @@ static int disable_watchdog_tco()
return 0;
}
/**
* @brief Update S parameters in FSPS_UPD structure.
*
* This function updates the S parameters in the FSPS_UPD structure for
* TigerLake x86 platform with FSP.
*
* @param[in,out] default_s_params Pointer to the default S parameters data.
* @return 0 on success, -1 on failure.
*/
int fsp_machine_update_s_parameters(uint8_t *default_s_params)
{
FSP_S_CONFIG *upd;
@ -442,7 +463,16 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params)
upd->EnableMultiPhaseSiliconInit = 0;
return 0;
}
/**
* @brief Configure GPIO settings for a specific device.
*
* This function configures GPIO settings for a specific device on TigerLake x86
* platform.
*
* @param[in,out] gpio Pointer to the tgl_gpio_info structure containing GPIO
* information.
* @return void
*/
static int tgl_setup_lpc_decode(uint32_t address, uint32_t length,
uint32_t range)
{
@ -477,6 +507,15 @@ struct tgl_gpio_info {
uint8_t pad_reset:2;
};
/**
* @brief Configure GPIO settings for a specific device.
* @details This function configures GPIO settings for a specific device on
* TigerLake x86 platform.
*
* @param[in,out] gpio Pointer to the tgl_gpio_info structure containing
* GPIO information.
* @return void
*/
static void tgl_gpio_configure(struct tgl_gpio_info *gpio)
{
uint16_t off;
@ -495,6 +534,13 @@ static void tgl_gpio_configure(struct tgl_gpio_info *gpio)
}
#ifdef TARGET_kontron_vx3060_s2
/**
* @brief Set up ECE1200 device on Kontron VX3060-S2 board.
*
* This function sets up the ECE1200 device on the Kontron VX3060-S2 board.
*
* @return void
*/
static void setup_ece1200()
{
uint8_t reg;
@ -515,7 +561,14 @@ static void setup_ece1200()
io_write8(ECE1200_DATA, reg);
io_write8(ECE1200_INDEX, 0xaa); /* close conf mode */
}
/**
* @brief Configure Kontron CPLD for special settings.
*
* This function configures the Kontron CPLD for special settings on the Kontron
* VX3060-S2 board.
*
* @return 0 on success, -1 on failure.
*/
static int configure_kontron_cpld()
{
uint8_t reg;
@ -543,6 +596,13 @@ static int configure_kontron_cpld()
#define CPLD_I2C_MISC 0x78
#define CPLD_I2C_MISC_FORCE_RESCUE (1 << 7)
/**
* @brief Ask for recovery mode using CPLD.
*
* This function asks for recovery mode using CPLD on the Kontron VX3060-S2 board.
*
* @return void
*/
static void kontron_ask_for_recovery() {
uint32_t reg;
uint8_t ch;
@ -566,6 +626,13 @@ static void kontron_ask_for_recovery() {
}
#endif /* TARGET_kontron_vx3060_s2 */
/**
* @brief Callback function after temporary RAM initialization.
*
* This function is a callback after temporary RAM initialization on TigerLake x86.
*
* @return 0 on success, -1 on failure.
*/
int post_temp_ram_init_cb(void)
{
disable_watchdog_tco();
@ -598,6 +665,17 @@ int post_temp_ram_init_cb(void)
return 0;
}
/**
* @brief Update M parameters in FSPM_UPD structure.
*
* This function updates the M parameters in the FSPM_UPD structure for
* TigerLake x86 platform with FSP.
*
* @param[in,out] default_m_params Pointer to the default M parameters data.
* @param[in] mem_base Base address of memory.
* @param[in] mem_size Size of memory.
* @return 0 on success, -1 on failure.
*/
int fsp_machine_update_m_parameters(uint8_t *default_m_params,
uint32_t mem_base,
uint32_t mem_size)
@ -619,3 +697,5 @@ int fsp_machine_update_m_parameters(uint8_t *default_m_params,
return 0;
}
#endif /* TGL_FSP_H */