Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc improvements #374

Merged
merged 4 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/x86/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
29 changes: 19 additions & 10 deletions src/boot_x86_fsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,34 @@ 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);
}

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);
}

/*!
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
#if defined(DEBUG) || defined(ELF_PARSER)
#if DEBUG_ELF == 0
#undef DEBUG_ELF
#else
#define DEBUG_ELF
#endif
#endif

Expand Down
9 changes: 5 additions & 4 deletions src/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions src/update_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

Expand Down
135 changes: 84 additions & 51 deletions src/x86/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -502,20 +542,18 @@ 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));
ipm = (ssts >> 8) & 0x0F;
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) {
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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)) {
Expand All @@ -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_ */

Loading