Skip to content
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,15 @@ tools/unit-tests/nxp_ls1028a_host.c
tools/unit-tests/nxp_p1021_host.c
tools/unit-tests/nxp_t10xx_fixup_extract.h
tools/unit-tests/sama5d3_read_extract.h
tools/unit-tests/samr21_erase_extract.h
tools/unit-tests/samr21_erase_fn_extract.h
tools/unit-tests/sdhci_host.c
tools/unit-tests/stm32l5_write_extract.h
tools/unit-tests/stm32u5_write_extract.h
tools/unit-tests/t10xx_qe_firmware_extract.h
tools/unit-tests/t2080_fman_extract.h
tools/unit-tests/ti_hercules_write_extract.h
tools/unit-tests/update_trigger_scrub_extract.h
tools/unit-tests/versal_ext_write_extract.h
tools/unit-tests/versal_host.c
tools/unit-tests/versal_host.h
Expand Down
9 changes: 6 additions & 3 deletions hal/nxp_t10xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1796,10 +1796,13 @@ static int hal_pcie_init(void)
memset(&enum_info, 0, sizeof(enum_info));
enum_info.curr_bus_number = 0;
enum_info.mem = CONFIG_PCIE_MEM_BUS;
enum_info.mem_limit = enum_info.mem + (CONFIG_PCIE_MEM_LENGTH - 1);
/* Pool limits are exclusive ends (the allocator accepts a
* region when its end is <= limit). */
enum_info.mem_limit = (uint64_t)enum_info.mem +
CONFIG_PCIE_MEM_LENGTH;
enum_info.mem_pf = (enum_info.mem + CONFIG_PCIE_MEM_PREFETCH_LENGTH);
enum_info.mem_pf_limit = enum_info.mem_pf +
(CONFIG_PCIE_MEM_PREFETCH_LENGTH - 1);
enum_info.mem_pf_limit = (uint64_t)enum_info.mem_pf +
CONFIG_PCIE_MEM_PREFETCH_LENGTH;
enum_info.io = CONFIG_PCIE_IO_BASE;

/* Setup PCIe Output Windows */
Expand Down
8 changes: 6 additions & 2 deletions hal/samr21.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#define FLASH_SIZE (256 * 1024)
#define FLASH_PAGESIZE 64
#define FLASH_N_PAGES 4096
/* NVMCMD_ERASE (0x02) is the NVMCTRL row erase: one command erases a
* 256-byte row (4 pages), so erase loops stride by the row size. */
#define FLASH_ROW_SIZE (4 * FLASH_PAGESIZE)

#define WDT_CTRL *((volatile uint8_t *)(0x40001000))
#define WDT_EN (1 << 1)
Expand Down Expand Up @@ -210,8 +213,9 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
while (len > 0) {
NVMCTRL_ADDR = (address >> 1); /* This register holds the address of a 16-bit row */
NVMCTRLA_REG = NVMCMD_ERASE | NVMCMD_KEY;
while(!(NVMCTRL_INTFLAG & NVMCTRL_INTFLAG_NVMREADY))
len -= FLASH_PAGESIZE;
while (!(NVMCTRL_INTFLAG & NVMCTRL_INTFLAG_NVMREADY)) { }
address += FLASH_ROW_SIZE;
len -= FLASH_ROW_SIZE;
}
return 0;
}
Expand Down
14 changes: 9 additions & 5 deletions include/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,15 @@ typedef struct {
} pci_ctrlr_info_t;

struct pci_enum_info {
uint32_t mem;
uint32_t mem_limit;
uint32_t io;
uint32_t mem_pf;
uint32_t mem_pf_limit;
/* Allocation cursors and exclusive pool ends. All 64-bit: a pool
* may end exactly at 4 GiB (0x100000000), which a 32-bit value
* cannot represent, and an exhausted cursor must stay at the pool
* end instead of wrapping to 0 and re-allocating over address 0. */
uint64_t mem;
uint64_t mem_limit;
uint64_t io;
uint64_t mem_pf;
uint64_t mem_pf_limit;
uint8_t curr_bus_number;
};

Expand Down
5 changes: 5 additions & 0 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,11 @@ void RAMFUNCTION wolfBoot_update_trigger(void)
/* erase the previously selected sector */
hal_flash_erase(lastSector - WOLFBOOT_SECTOR_SIZE * selSec,
WOLFBOOT_SECTOR_SIZE);
/* The staged sector may hold the firmware key/nonce (see
* ENCRYPT_CACHE under NVM_FLASH_WRITEONCE): scrub it, as the
* partition-trailer helpers do, before releasing the flash
* lock. */
nvm_cache_scrub();
#endif
}

Expand Down
86 changes: 57 additions & 29 deletions src/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,18 @@
static int pci_enum_is_64bit(uint32_t value);
static int pci_enum_is_mmio(uint32_t value);

static inline uint32_t align_up(uint32_t address, uint32_t alignment) {
return (address + alignment - 1) & ~(alignment - 1);
static inline uint64_t align_up(uint64_t address, uint32_t alignment) {
return (address + alignment - 1) & ~(uint64_t)(alignment - 1);
}

static inline uint32_t align_down(uint32_t address, uint32_t alignment) {
return address & ~(alignment - 1);
}

static int pci_align_check_up(uint32_t address, uint32_t alignment,
uint32_t limit, uint32_t *aligned)
static int pci_align_check_up(uint64_t address, uint32_t alignment,
uint64_t limit, uint64_t *aligned)
{
uint32_t a;
uint64_t a;
a = align_up(address, alignment);
if (a < address || a >= limit)
return -1;
Expand Down Expand Up @@ -363,17 +363,20 @@ static int pci_enum_is_mmio(uint32_t value)
return (value & PCI_ENUM_MMIND_MASK) == 0;
}

static int pci_enum_next_aligned32(uint32_t address, uint32_t *next,
uint32_t align, uint32_t limit)
static int pci_enum_next_aligned32(uint64_t address, uint32_t *next,
uint32_t align, uint64_t limit)
{
uintptr_t addr;
uint64_t addr;

addr = (uintptr_t)address;
/* 64-bit on purpose: an exhausted pool leaves the cursor at
* 0x100000000, which a 32-bit type (uintptr_t included on 32-bit
* targets) would truncate back to 0. */
addr = address;
align = align-1;
addr = (addr + align) & (~align);
addr = (addr + align) & (~(uint64_t)align);
if (addr > 0xffffffff)
return -1;
if (addr < (uintptr_t)address)
if (addr < address)
return -1;
if (addr >= limit)
return -1;
Expand Down Expand Up @@ -421,8 +424,8 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun,
uint32_t length, align;
uint8_t bar_off;
int is_prefetch;
uint32_t *base;
uint32_t limit;
uint64_t *base;
uint64_t limit;
uint32_t reg;
int is_mmio;
int ret = 0;
Expand Down Expand Up @@ -524,7 +527,7 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun,
pci_config_write32(bus, dev, fun, bar_off, bar_value);
if (*is_64bit)
pci_config_write32(bus, dev, fun, bar_off + 4, 0x0);
*base = bar_value + length;
*base = (uint64_t)bar_value + length;
PCI_DEBUG_PRINTF("PCI enum: %s bus: %x:%x.%x bar: %d [%x,%x] (0x%x %s %s)\r\n",
(is_mmio ? "mm" : "io"), bus, dev, fun, bar_idx, bar_value,
bar_value + length, length, (*is_64bit) ? "64bit" : "",
Expand Down Expand Up @@ -617,14 +620,14 @@ static inline void pci_dump_bridge(uint8_t bus, uint8_t dev, uint8_t fun)
static int pci_program_bridge(uint8_t bus, uint8_t dev, uint8_t fun,
struct pci_enum_info *info)
{
uint32_t prefetch_start;
uint32_t mem_start;
uint32_t io_start;
uint64_t prefetch_start;
uint64_t mem_start;
uint64_t io_start;
uint32_t orig_cmd;
uint8_t saved_bus;
uint32_t saved_mem;
uint32_t saved_pf;
uint32_t saved_io;
uint64_t saved_mem;
uint64_t saved_pf;
uint64_t saved_io;
int ret;

saved_bus = info->curr_bus_number;
Expand All @@ -635,6 +638,13 @@ static int pci_program_bridge(uint8_t bus, uint8_t dev, uint8_t fun,
orig_cmd = pci_config_read16(bus, dev, fun, PCI_COMMAND_OFFSET);
pci_config_write16(bus, dev, fun, PCI_COMMAND_OFFSET, 0);

/* curr_bus_number is one bus per bridge level; at 0xFF the next
* increment wraps to 0, which would write SECONDARY_BUS 0 and
* re-enumerate bus 0 over the already configured tree. Disable
* this bridge instead. */
if (info->curr_bus_number == 0xFF)
goto err;

info->curr_bus_number++;
PCI_DEBUG_PRINTF("Bridge: %x.%x.%x (using bus number: %d)\r\n",
(int)bus, (int)dev, (int)fun, info->curr_bus_number);
Expand Down Expand Up @@ -926,11 +936,28 @@ int pci_enum_do(void)
struct pci_enum_info enum_info;
int ret;

/* Pool limits are exclusive ends: the allocator accepts a region
* when its end is <= limit (pci_enum_next_aligned32, the BAR end
* check, pci_align_check_up) and the IO limit is the 16-bit IO
* ceiling, not the last usable address. A region ending exactly
* at base + length must fit, so initialize base + length. The
* limit fields are 64-bit because a pool may end exactly at
* 0x100000000 (4 GiB), the top of the 32-bit space; reject only
* pools whose end is above it. */
if ((uint64_t)PCI_MMIO32_BASE + PCI_MMIO32_LENGTH > 0x100000000ULL ||
(uint64_t)PCI_MMIO32_PREFETCH_BASE +
PCI_MMIO32_PREFETCH_LENGTH > 0x100000000ULL)
{
PCI_DEBUG_PRINTF("PCI MMIO pool overflows the 32-bit address "
"space\r\n");
return -1;
}

enum_info.mem = PCI_MMIO32_BASE;
enum_info.mem_limit = enum_info.mem + (PCI_MMIO32_LENGTH - 1);
enum_info.mem_limit = (uint64_t)enum_info.mem + PCI_MMIO32_LENGTH;
enum_info.mem_pf = PCI_MMIO32_PREFETCH_BASE;
enum_info.mem_pf_limit = enum_info.mem_pf +
(PCI_MMIO32_PREFETCH_LENGTH - 1);
enum_info.mem_pf_limit = (uint64_t)enum_info.mem_pf +
PCI_MMIO32_PREFETCH_LENGTH;
enum_info.io = PCI_IO32_BASE;
enum_info.curr_bus_number = 0;

Expand All @@ -943,16 +970,17 @@ int pci_enum_do(void)
ret = pci_enum_bus(0, &enum_info);

PCI_DEBUG_PRINTF("PCI Memory Mapped I/O range [0x%x,0x%x] (0x%x)\r\n",
(uint32_t)PCI_MMIO32_BASE, enum_info.mem,
enum_info.mem - PCI_MMIO32_BASE);
(uint32_t)PCI_MMIO32_BASE, (uint32_t)enum_info.mem,
(uint32_t)(enum_info.mem - PCI_MMIO32_BASE));

PCI_DEBUG_PRINTF("PCI Memory Mapped I/O range (prefetch) [0x%x,0x%x] (0x%x)\r\n",
(uint32_t)PCI_MMIO32_PREFETCH_BASE, enum_info.mem_pf,
enum_info.mem_pf - PCI_MMIO32_PREFETCH_BASE);
(uint32_t)PCI_MMIO32_PREFETCH_BASE,
(uint32_t)enum_info.mem_pf,
(uint32_t)(enum_info.mem_pf - PCI_MMIO32_PREFETCH_BASE));

PCI_DEBUG_PRINTF("PCI I/O range [0x%x,0x%x] (0x%x)\r\n",
(uint32_t)PCI_IO32_BASE, enum_info.io,
enum_info.io - PCI_IO32_BASE);
(uint32_t)PCI_IO32_BASE, (uint32_t)enum_info.io,
(uint32_t)(enum_info.io - PCI_IO32_BASE));

return ret;
}
Expand Down
21 changes: 19 additions & 2 deletions src/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,13 @@ static int sdcard_card_init(uint32_t acmd41_arg, uint32_t *ocr_reg)
static int sdcard_set_bus_width(uint32_t bus_width);
static int sdcard_set_function(uint32_t function_number, uint32_t group_number);

/* A card that answers ACMD41 forever without setting OCR ready must
* not hold the boot. The budget matches the sdhci_wait_busy() wait;
* a healthy card reports ready in milliseconds. */
#ifndef SDCARD_ACMD41_TIMEOUT_MS
#define SDCARD_ACMD41_TIMEOUT_MS 30000
#endif

/* Full SD card initialization sequence
* Returns 0 on success */
static int sdcard_card_full_init(void)
Expand Down Expand Up @@ -898,6 +905,9 @@ static int sdcard_card_full_init(void)
}

if (status == 0) {
uint64_t start = hal_get_timer_us();
const uint64_t timeout_us =
(uint64_t)SDCARD_ACMD41_TIMEOUT_MS * 1000U;
/* configure operating conditions */
uint32_t cmd_arg = SDCARD_ACMD41_HCS;
cmd_arg |= card_volts;
Expand All @@ -911,10 +921,17 @@ static int sdcard_card_full_init(void)
wolfBoot_printf("sdcard_init: sending OCR arg: 0x%08X\n", cmd_arg);
#endif

/* retry until OCR ready */
/* retry until OCR ready; a card that never sets it must not
* hold the boot, so bound the poll like sdhci_wait_busy() and
* service the watchdog inside it */
do {
status = sdcard_card_init(cmd_arg, &reg);
} while (status == 0 && (reg & SDCARD_REG_OCR_READY) == 0);
if (status != 0 || (reg & SDCARD_REG_OCR_READY) != 0)
break;
sdhci_platform_wdt_pet();
if (hal_get_timer_us() - start > timeout_us)
status = -1;
} while (status == 0);
}

if (status == 0) {
Expand Down
Loading
Loading