From a29b78d680769ea377178754828edee4c57f64c3 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Wed, 16 Aug 2023 19:07:06 -0700 Subject: [PATCH] Add function headers --- hal/x86_fsp_tgl.c | 3 + lib/wolfTPM | 2 +- src/boot_x86_fsp.c | 81 +++++++- src/boot_x86_fsp_payload.c | 34 +++- src/image.c | 236 ++++++++++++++++++++- src/libwolfboot.c | 408 ++++++++++++++++++++++++++++++++++++- src/loader.c | 45 ++++ src/update_disk.c | 22 +- src/x86/ahci.c | 70 ++++++- src/x86/ata.c | 127 +++++++++++- src/x86/common.c | 130 +++++++++++- src/x86/gpt.c | 92 ++++++++- src/x86/hob.c | 76 ++++++- src/x86/tgl_fsp.c | 84 +++++++- 14 files changed, 1382 insertions(+), 28 deletions(-) diff --git a/hal/x86_fsp_tgl.c b/hal/x86_fsp_tgl.c index b79d0973..3d6ed82c 100644 --- a/hal/x86_fsp_tgl.c +++ b/hal/x86_fsp_tgl.c @@ -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; diff --git a/lib/wolfTPM b/lib/wolfTPM index bbbafd68..7c9391eb 160000 --- a/lib/wolfTPM +++ b/lib/wolfTPM @@ -1 +1 @@ -Subproject commit bbbafd68d09c6d453a5ef93214c9296dd7bc93b3 +Subproject commit 7c9391ebf3341ac10c8357adedd96ff42d59c845 diff --git a/src/boot_x86_fsp.c b/src/boot_x86_fsp.c index 49a219e3..ad9f433e 100644 --- a/src/boot_x86_fsp.c +++ b/src/boot_x86_fsp.c @@ -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) { diff --git a/src/boot_x86_fsp_payload.c b/src/boot_x86_fsp_payload.c index 785ad5dd..238d9603 100644 --- a/src/boot_x86_fsp_payload.c +++ b/src/boot_x86_fsp_payload.c @@ -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 #include @@ -35,7 +45,13 @@ #include #include +/** + * @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_ */ diff --git a/src/image.c b/src/image.c index 4bf63deb..75680814 100644 --- a/src/image.c +++ b/src/image.c @@ -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 +/** + * @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_ */ diff --git a/src/libwolfboot.c b/src/libwolfboot.c index e3f7db8e..350e26a4 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -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 @@ -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]; diff --git a/src/loader.c b/src/loader.c index cba60cb3..50d16329 100644 --- a/src/loader.c +++ b/src/loader.c @@ -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) diff --git a/src/update_disk.c b/src/update_disk.c index 64d444ac..b7863d96 100644 --- a/src/update_disk.c +++ b/src/update_disk.c @@ -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_ */ diff --git a/src/x86/ahci.c b/src/x86/ahci.c index 3b76c5ce..32413410 100644 --- a/src/x86/ahci.c +++ b/src/x86/ahci.c @@ -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 #include @@ -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_ */ + diff --git a/src/x86/ata.c b/src/x86/ata.c index a6774602..fec9bac0 100644 --- a/src/x86/ata.c +++ b/src/x86/ata.c @@ -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 #include #include @@ -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 */ diff --git a/src/x86/common.c b/src/x86/common.c index 29c36578..742f4b75 100644 --- a/src/x86/common.c +++ b/src/x86/common.c @@ -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 @@ -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_ */ diff --git a/src/x86/gpt.c b/src/x86/gpt.c index d9a91e35..5a18968e 100644 --- a/src/x86/gpt.c +++ b/src/x86/gpt.c @@ -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 #include #include @@ -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 */ diff --git a/src/x86/hob.c b/src/x86/hob.c index c21d6fdc..96f33e7c 100644 --- a/src/x86/hob.c +++ b/src/x86/hob.c @@ -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 #include #include @@ -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 */ diff --git a/src/x86/tgl_fsp.c b/src/x86/tgl_fsp.c index ffbbee61..d2210a67 100644 --- a/src/x86/tgl_fsp.c +++ b/src/x86/tgl_fsp.c @@ -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 #include #include @@ -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 */