diff --git a/Makefile b/Makefile index aff528326..f7ad8a09d 100644 --- a/Makefile +++ b/Makefile @@ -212,7 +212,7 @@ factory_wstage1.bin: $(BINASSEMBLE) stage1/loader_stage1.bin wolfboot.bin $(BOOT $(WOLFBOOT_PARTITION_BOOT_ADDRESS) test-app/image_v1_signed.bin # stage1 linker script embed wolfboot.bin inside stage1/loader_stage1.bin -wolfboot_stage1.bin: wolfboot.bin stage1/loader_stage1.bin +wolfboot_stage1.bin: wolfboot.elf stage1/loader_stage1.bin $(Q) cp stage1/loader_stage1.bin wolfboot_stage1.bin wolfboot.elf: include/target.h $(LSCRIPT) $(OBJS) $(LIBS) $(BINASSEMBLE) FORCE diff --git a/include/x86/common.h b/include/x86/common.h index f687c78f6..3c82cca54 100644 --- a/include/x86/common.h +++ b/include/x86/common.h @@ -66,4 +66,5 @@ void cpuid(uint32_t eax_param, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); int cpuid_is_1gb_page_supported(); void switch_to_long_mode(uint64_t *entry, uint32_t page_table); +void x86_log_memory_load(uint32_t start, uint32_t end, const char *name); #endif /* COMMON_H */ diff --git a/src/boot_x86_fsp.c b/src/boot_x86_fsp.c index 627e11bba..6d6d2f24f 100644 --- a/src/boot_x86_fsp.c +++ b/src/boot_x86_fsp.c @@ -200,18 +200,22 @@ static int check_memory_ranges() static void load_wolfboot(void) { size_t wolfboot_size, bss_size; + uint32_t wolfboot_start; if (check_memory_ranges() != 0) { wolfBoot_printf("wolfboot overlaps with loader data...stop" ENDLINE); panic(); } - wolfBoot_printf("loading wolfboot at %x..." ENDLINE, - (uint32_t)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE); + wolfboot_start = (uint32_t)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE; wolfboot_size = _wolfboot_flash_end - _wolfboot_flash_start; - memcpy((uint8_t*)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE, - _wolfboot_flash_start, wolfboot_size); + x86_log_memory_load(wolfboot_start, wolfboot_start + wolfboot_size, + "wolfboot"); + memcpy((uint8_t*)wolfboot_start,_wolfboot_flash_start, wolfboot_size); bss_size = wb_end_bss - wb_start_bss; + x86_log_memory_load((uint32_t)(uintptr_t)wb_start_bss, + (uint32_t)(uintptr_t)(wb_start_bss + bss_size), + "wolfboot .bss"); memset(wb_start_bss, 0, bss_size); wolfBoot_printf("load wolfboot end" ENDLINE); } @@ -219,11 +223,11 @@ static void load_wolfboot(void) static void load_fsp_s_to_ram(void) { size_t fsp_s_size; - wolfBoot_printf("loading FSP_S at %x..." ENDLINE, - (uint32_t)(FSP_S_LOAD_BASE - IMAGE_HEADER_SIZE)); + uint32_t fsp_start; + fsp_start = FSP_S_LOAD_BASE - IMAGE_HEADER_SIZE; fsp_s_size = _end_fsp_s - _fsp_s_hdr; - memcpy((uint8_t*)FSP_S_LOAD_BASE - IMAGE_HEADER_SIZE, - _fsp_s_hdr, fsp_s_size); + x86_log_memory_load(fsp_start, fsp_start + fsp_s_size, "FSPS"); + memcpy((uint8_t*)fsp_start, _fsp_s_hdr, fsp_s_size); } /*! @@ -252,8 +256,8 @@ static void jump_into_wolfboot(void) uint32_t cr3; int ret; - wolfBoot_printf("building identity map at %x...\r\n", - (uint32_t)params->page_table); + x86_log_memory_load((uint32_t)(uintptr_t)params->page_table,params->page_table + x86_paging_get_page_table_size(), + "IdentityPageTablePage"); ret = x86_paging_build_identity_mapping(MEMORY_4GB, (uint8_t*)(uintptr_t)params->page_table); if (ret != 0) { @@ -334,11 +338,15 @@ static inline void memory_init_data_bss(void) { uint32_t *datamem_p; uint32_t *dataflash_p; + x86_log_memory_load((uint32_t)(uintptr_t)_start_data, + (uint32_t)(uintptr_t)_end_data, "stage1 .data"); datamem_p = (uint32_t *)_start_data; dataflash_p = (uint32_t *)_stored_data; while(datamem_p < (uint32_t *)_end_data) { *(datamem_p++) = *(dataflash_p++); } + x86_log_memory_load((uint32_t)(uintptr_t)_start_bss, + (uint32_t)(uintptr_t)_end_bss, "stage1 .bss"); memset(_start_bss, 0, (_end_bss - _start_bss)); } @@ -696,6 +704,7 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, stage2_params->tpm_policy_size); #endif + wolfBoot_printf("TOLUM: 0x%x\r\n", stage2_params->tolum); /* change_stack_and_invoke() never returns. * * Execution here is eventually transferred to memory_ready_entry diff --git a/src/elf.c b/src/elf.c index 713aa21f7..d85882385 100644 --- a/src/elf.c +++ b/src/elf.c @@ -36,8 +36,6 @@ #if defined(DEBUG) || defined(ELF_PARSER) #if DEBUG_ELF == 0 #undef DEBUG_ELF -#else -#define DEBUG_ELF #endif #endif diff --git a/src/pci.c b/src/pci.c index 9e0e44a4f..7ff6e671d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -424,7 +424,7 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun, orig_bar = pci_config_read32(bus, dev, fun, bar_off); pci_config_write32(bus, dev, fun, bar_off, 0xffffffff); bar_value = pci_config_read32(bus, dev,fun, bar_off); - PCI_DEBUG_PRINTF("bar value: 0x%x\r\n", bar_value); + PCI_DEBUG_PRINTF("bar value after writing 0xff..ff: 0x%x\r\n", bar_value); if (bar_value == 0) { PCI_DEBUG_PRINTF("PCI enum: %x:%x.%x bar: %d val: %x - skipping\r\n", @@ -437,13 +437,12 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun, bar_align = bar_value & PCI_ENUM_MM_BAR_MASK; is_prefetch = pci_enum_is_prefetch(bar_value); if (pci_enum_is_64bit(bar_value)) { - PCI_DEBUG_PRINTF("bar is 64bit\r\n"); orig_bar2 = pci_config_read32(bus, dev, fun, bar_off + 4); pci_config_write32(bus, dev, fun, bar_off + 4, 0xffffffff); reg = pci_config_read32(bus, dev, fun, bar_off + 4); PCI_DEBUG_PRINTF("bar high 32bit: %d\r\n", reg); if (reg != 0xffffffff) { - PCI_DEBUG_PRINTF("Too big BAR, skipping\r\n"); + PCI_DEBUG_PRINTF("Device wants too much memory, skipping\r\n"); pci_config_write32(bus, dev, fun, bar_off + 4, orig_bar2); goto restore_bar; } @@ -477,8 +476,10 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun, /* check max length */ ret = pci_enum_next_aligned32(*base, &bar_value, align, limit); - if (ret != 0) + if (ret != 0) { + wolfBoot_printf("Not memory space for mapping the PCI device... skipping\r\n"); goto restore_bar; + } pci_config_write32(bus, dev, fun, bar_off, bar_value); if (*is_64bit) diff --git a/src/update_disk.c b/src/update_disk.c index 58a462d62..771eb7c7b 100644 --- a/src/update_disk.c +++ b/src/update_disk.c @@ -132,7 +132,7 @@ void RAMFUNCTION wolfBoot_start(void) stage2_params = stage2_get_parameters(); /* load the image just after wolfboot */ load_address = (uint32_t *)(_end_wb); - wolfBoot_printf("Load address %x\r\n", load_address); + wolfBoot_printf("Load address 0x%x\r\n", load_address); do { failures++; if (selected) @@ -161,6 +161,9 @@ void RAMFUNCTION wolfBoot_start(void) } /* Read the image into RAM */ + x86_log_memory_load((uint32_t)(uintptr_t)load_address, + (uint32_t)(uintptr_t)load_address + img_size, + "ELF"); wolfBoot_printf("Loading image from disk..."); load_off = 0; do { @@ -210,9 +213,9 @@ void RAMFUNCTION wolfBoot_start(void) panic(); } + sata_disable(sata_bar); wolfBoot_printf("Firmware Valid.\r\n"); wolfBoot_printf("Booting at %08lx\r\n", os_image.fw_base); - sata_disable(sata_bar); hal_prepare_boot(); do_boot((uint32_t*)os_image.fw_base); diff --git a/src/x86/ahci.c b/src/x86/ahci.c index d568cf9cb..71e289a99 100644 --- a/src/x86/ahci.c +++ b/src/x86/ahci.c @@ -97,6 +97,9 @@ __attribute__((aligned(HBA_TBL_ALIGN))); #define PCI_REG_MAP_AHCI_MODE (0x1 << 6) #define PCI_REG_MAP_ALL_PORTS (0x1 << 5) +#define SATA_MAX_TRIES (5) +#define SATA_DELAY (100) + #ifdef DEBUG_AHCI #define AHCI_DEBUG_PRINTF(...) wolfBoot_printf(__VA_ARGS__) #else @@ -416,6 +419,40 @@ static int sata_unlock_disk(int drv) return 0; } #endif /* WOLFBOOT_ATA_DISK_LOCK */ + +/** + * @brief Waits until a specific address is cleared by a given mask. + * + * This function waits until a specific 32-bit PCI memory address is cleared by a given + * mask. After SATA_DELAY * SATA_MAX_TRIES ms, if the address in memory is not + * cleared, the function returns -1. * + * @param[in] address The memory address to monitor. + * @param[in] mask The mask to apply to the value at the address. + * + * @return 0 if the masked bits are cleared within the specified number of + * tries, 1 otherwise. + */ +static int sata_wait_until_clear(uint32_t address, uint32_t mask) +{ + int count = SATA_MAX_TRIES; + uint32_t reg; + int ret = -1; + + while (1) { + if (count-- == 0) + break; + + reg = mmio_read32(address); + if ((reg & mask) == 0) { + ret = 0; + break; + } + delay(SATA_DELAY); + } + + return ret; +} + /** * @brief Enables SATA ports and detects connected SATA disks. * @@ -451,12 +488,15 @@ void sata_enable(uint32_t base) mmio_or32(AHCI_HBA_GHC(base), HBA_GHC_HR | HBA_GHC_IE); /* Wait until reset is complete */ - while ((mmio_read32(AHCI_HBA_GHC(base)) & HBA_GHC_HR) != 0) - ; - + r = sata_wait_until_clear(AHCI_HBA_GHC(base), HBA_GHC_HR); + if (r != 0) { + wolfBoot_printf("ACHI: timeout waiting reset\r\n"); + panic(); + } + /* Wait until enabled. */ if ((mmio_read32(AHCI_HBA_GHC(base)) & HBA_GHC_AE) == 0) - mmio_or32(AHCI_HBA_GHC(base), HBA_GHC_AE);; + mmio_or32(AHCI_HBA_GHC(base), HBA_GHC_AE); AHCI_DEBUG_PRINTF("AHCI reset complete.\r\n"); @@ -502,8 +542,6 @@ void sata_enable(uint32_t base) mmio_or32(AHCI_PxSCTL(base, i), (0x03 << 8)); /* Disable interrupt reporting to SW */ - //mmio_write32(AHCI_PxIE(base, i), 0); - count = 0; while (1) { ssts = mmio_read32(AHCI_PxSSTS(base, i)); @@ -511,11 +549,11 @@ void sata_enable(uint32_t base) ssts &= AHCI_SSTS_DET_MASK; if (ssts == AHCI_PORT_SSTS_DET_PCE) break; - if (count++ > 5) { + if (count++ > SATA_MAX_TRIES) { AHCI_DEBUG_PRINTF("AHCI port %d: Timeout occurred.\r\n", i); break; } - delay(1000); + delay(SATA_DELAY); }; if (ssts == 0) { @@ -544,15 +582,12 @@ void sata_enable(uint32_t base) AHCI_DEBUG_PRINTF("AHCI port: Sending STOP ...\r\n"); /* Wait for CR to be cleared */ - count = 0; - do { - reg = mmio_read32(AHCI_PxCMD(base, i)); - if (count++ > 5) { - AHCI_DEBUG_PRINTF("AHCI Error: Port did not clear CR!\r\n"); - break; - } - delay(1000); - } while ((reg & AHCI_PORT_CMD_CR) != 0); + r = sata_wait_until_clear(AHCI_PxCMD(base, i), AHCI_PORT_CMD_CR); + if (r != 0) { + wolfBoot_printf("AHCI Error: Port did not clear CR!\r\n"); + panic(); + } + AHCI_DEBUG_PRINTF("AHCI port: Sent STOP.\r\n"); AHCI_DEBUG_PRINTF("AHCI port: Disabling FIS ...\r\n"); @@ -566,15 +601,12 @@ void sata_enable(uint32_t base) } /* Wait for FR to be cleared */ - count = 0; - do { - reg = mmio_read32(AHCI_PxCMD(base, i)); - if (count++ > 5) { - wolfBoot_printf("AHCI Error: Port did not clear FR!\r\n"); - break; - } - delay(1000); - } while ((reg & AHCI_PORT_CMD_FR) != 0); + r = sata_wait_until_clear(AHCI_PxCMD(base, i), AHCI_PORT_CMD_FR); + if (r != 0 ) { + wolfBoot_printf("AHCI Error: Port did not clear FR!\r\n"); + panic(); + } + AHCI_DEBUG_PRINTF("AHCI port: FIS disabled.\r\n"); clb = (uint32_t)(uintptr_t)(ahci_hba_clb + i * HBA_CLB_SIZE); @@ -594,9 +626,11 @@ void sata_enable(uint32_t base) memset((uint8_t*)(uintptr_t)fis, 0, HBA_FIS_SIZE); /* Wait until CR is cleared */ - do { - reg = mmio_read32(AHCI_PxCMD(base, i)); - } while(reg & AHCI_PORT_CMD_CR); + r = sata_wait_until_clear(AHCI_PxCMD(base, i), AHCI_PORT_CMD_CR); + if (r != 0) { + wolfBoot_printf("AHCI error: CR clear error\r\n"); + panic(); + } reg |= AHCI_PORT_CMD_FRE | AHCI_PORT_CMD_START; mmio_write32(AHCI_PxCMD(base, i), reg); @@ -646,10 +680,19 @@ void sata_enable(uint32_t base) */ void sata_disable(uint32_t base) { + uint32_t ports_impl; uint32_t i, reg; volatile uint32_t count; + int r; + + AHCI_DEBUG_PRINTF("SATA: disabling sata controller at 0x%x\r\n", base); + + ports_impl = mmio_read32(AHCI_HBA_PI(base)); for (i = 0; i < AHCI_MAX_PORTS; i++) { + if ((ports_impl & (1 << i)) == 0) + continue; + AHCI_DEBUG_PRINTF("AHCI: disabling port %d\r\n", i); /* Clear port SERR */ reg = mmio_read32(AHCI_PxSERR(base, i)); mmio_write32(AHCI_PxSERR(base,i), reg); @@ -667,15 +710,12 @@ void sata_disable(uint32_t base) } /* Wait for CR to be cleared */ - count = 0; - do { - reg = mmio_read32(AHCI_PxCMD(base, i)); - if (count++ > 5) { - break; - } - delay(1000); - } while ((reg & AHCI_PORT_CMD_CR) != 0); - + r = sata_wait_until_clear(AHCI_PxCMD(base, i), AHCI_PORT_CMD_CR); + if (r != 0) { + wolfBoot_printf("AHCI error: CR clear error\r\n"); + panic(); + } + /* Disable FIS RX */ reg = mmio_read32(AHCI_PxCMD(base, i)); if (reg & (AHCI_PORT_CMD_CR | AHCI_PORT_CMD_START)) { @@ -686,24 +726,17 @@ void sata_disable(uint32_t base) } /* Wait for FR to be cleared */ - count = 0; - do { - reg = mmio_read32(AHCI_PxCMD(base, i)); - if (count++ > 5) { - wolfBoot_printf("AHCI Error: Port did not clear FR!\r\n"); - break; - } - delay(1000); - } while ((reg & AHCI_PORT_CMD_FR) != 0); + r = sata_wait_until_clear(AHCI_PxCMD(base, i), AHCI_PORT_CMD_FR); + if (r != 0) { + wolfBoot_printf("AHCI error: FR clear error\r\n"); + panic(); + } reg = mmio_read32(AHCI_PxCMD(base, i)); mmio_write32(AHCI_PxCMD(base, i), reg & (~AHCI_PORT_CMD_ICC_ACTIVE)); } - /* reg = mmio_read32(AHCI_HBA_GHC(base)); */ - /* mmio_write32(AHCI_HBA_GHC(base), reg & (~HBA_GHC_AE)); */ - /* 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/common.c b/src/x86/common.c index 742f4b753..74bd33c0d 100644 --- a/src/x86/common.c +++ b/src/x86/common.c @@ -31,6 +31,7 @@ #ifndef COMMON_H_ #define COMMON_H_ +#include #include #include @@ -362,4 +363,9 @@ void switch_to_long_mode(uint64_t *entry, uint32_t page_table) _entry(); } #endif /* BUILD_LOADER_STAGE1 */ + +void x86_log_memory_load(uint32_t start, uint32_t end, const char *name) +{ + wolfBoot_printf("mem: [ 0x%x, 0x%x ] - %s (0x%x) \n\r", start, end, name, end - start); +} #endif /* COMMON_H_ */ diff --git a/src/x86/mptable.c b/src/x86/mptable.c index d9554ce74..06773a27a 100644 --- a/src/x86/mptable.c +++ b/src/x86/mptable.c @@ -496,6 +496,9 @@ void mptable_setup(void) struct mptable *_mp; _mp = (struct mptable *)MPTABLE_LOAD_BASE; + x86_log_memory_load((uint32_t)MPTABLE_LOAD_BASE, + (uint32_t)MPTABLE_LOAD_BASE + sizeof(struct mptable), + "MPTABLE"); memcpy(_mp, (void*)&_mptable, sizeof(struct mptable)); apic_id = mmio_read32(LOCAL_APIC_ID); apic_ver = mmio_read32(LOCAL_APIC_VER);