Add optional DRAM-free mode

parent 10599423
Pipeline #246 passed with stage
in 21 seconds
...@@ -29,8 +29,9 @@ ...@@ -29,8 +29,9 @@
// Performance controls // Performance controls
#define ENABLE_LPC_FW_CYCLE_IRQ_HANDLER 1 // Set to 1 to enable LPC master transfer interrupts to the BMC soft core #define ENABLE_LPC_FW_CYCLE_IRQ_HANDLER 1 // Set to 1 to enable LPC master transfer interrupts to the BMC soft core
#define ENABLE_LPC_FW_CYCLE_DMA 1 // Set to 1 to allow the LPC master to DMA data to/from the Wishbone bus #define ENABLE_LPC_FW_CYCLE_DMA 1 // Set to 1 to allow the LPC master to DMA data to/from the Wishbone bus (not compatible with direct SPI access)
#define ALLOW_SPI_QUAD_MODE 1 // Set to 1 to allow quad-mode SPI transfers if the hardware supports them #define ALLOW_SPI_QUAD_MODE 1 // Set to 1 to allow quad-mode SPI transfers if the hardware supports them
#define WITH_DRAM 1 // Set to 1 to enable the use of attached external DRAM (fast IPL, needs a minimum of 64MB DRAM)
// Debug knobs // Debug knobs
#define DEBUG_HOST_SPI_FLASH_READ 0 // Set to 1 to enable verbose logging of SPI flash read process #define DEBUG_HOST_SPI_FLASH_READ 0 // Set to 1 to enable verbose logging of SPI flash read process
...@@ -43,6 +44,8 @@ ...@@ -43,6 +44,8 @@
// Host platform configuration // Host platform configuration
#define HOST_PLATFORM_FPGA_I2C_ADDRESS 0x31 #define HOST_PLATFORM_FPGA_I2C_ADDRESS 0x31
uint8_t host_flash_write_buffer[FLASH_MAX_WR_WINDOW_BYTES];
extern uint32_t irq_unhandled_vector; extern uint32_t irq_unhandled_vector;
extern uint32_t irq_unhandled_source; extern uint32_t irq_unhandled_source;
extern uint8_t irq_unhandled_vector_valid; extern uint8_t irq_unhandled_vector_valid;
...@@ -344,11 +347,13 @@ void lpc_slave_isr(void) ...@@ -344,11 +347,13 @@ void lpc_slave_isr(void)
#endif #endif
uint32_t dword; uint32_t dword;
uint32_t ev_status; uint32_t ev_status;
#if (ENABLE_LPC_FW_CYCLE_IRQ_HANDLER)
uint32_t address; uint32_t address;
uint32_t physical_flash_address; uint32_t physical_flash_address;
uint8_t write_not_read; uint8_t write_not_read;
uint32_t status1_reg; uint32_t status1_reg;
uint32_t status2_reg; uint32_t status2_reg;
#endif
uint32_t status4_reg; uint32_t status4_reg;
uint32_t vuart_status; uint32_t vuart_status;
volatile ipmi_request_message_t *ipmi_bt_request_ptr; volatile ipmi_request_message_t *ipmi_bt_request_ptr;
...@@ -390,16 +395,34 @@ void lpc_slave_isr(void) ...@@ -390,16 +395,34 @@ void lpc_slave_isr(void)
{ {
for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++) for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++)
{ {
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) = if ((WITH_DRAM) || ((!WITH_DRAM) && (hiomap_config.window_type != HIOMAP_WINDOW_TYPE_WRITE)))
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))); {
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) =
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4)));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) = *(
(uint32_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + (word * 4)));
}
} }
} }
else else
{ {
for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++) for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++)
{ {
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) = if ((WITH_DRAM) || ((!WITH_DRAM) && (hiomap_config.window_type != HIOMAP_WINDOW_TYPE_WRITE)))
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)); {
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) =
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) =
*((uint8_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + byte));
}
} }
} }
...@@ -414,16 +437,34 @@ void lpc_slave_isr(void) ...@@ -414,16 +437,34 @@ void lpc_slave_isr(void)
{ {
for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++) for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++)
{ {
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))) = if (WITH_DRAM)
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))); {
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))) =
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4)));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((uint32_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + (word * 4))) =
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4)));
}
} }
} }
else else
{ {
for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++) for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++)
{ {
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)) = if (WITH_DRAM)
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)); {
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)) =
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((uint8_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + byte)) =
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte));
}
} }
} }
...@@ -1010,34 +1051,52 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1010,34 +1051,52 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
break; break;
} }
#if (ENABLE_LPC_FW_CYCLE_DMA) if (ENABLE_LPC_FW_CYCLE_DMA)
// Disable DMA engine
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
// Reconfigure LPC firmware cycle DMA ranges
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG2, (uintptr_t)host_flash_buffer);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG3, FLASH_SIZE_BYTES);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG4, hiomap_config.window_start_address);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG5,
hiomap_config.window_start_address + hiomap_config.window_length_bytes);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG6, FLASH_SIZE_BYTES - 1);
// Enable DMA engine
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
if (hiomap_config.window_type == HIOMAP_WINDOW_TYPE_WRITE)
{ {
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT); // Disable DMA engine
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
if (WITH_DRAM || (hiomap_config.window_type != HIOMAP_WINDOW_TYPE_WRITE))
{
// Reconfigure LPC firmware cycle DMA ranges
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG2, (uintptr_t)host_flash_buffer);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG3, FLASH_SIZE_BYTES);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG4, hiomap_config.window_start_address);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG5,
hiomap_config.window_start_address + hiomap_config.window_length_bytes);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG6, FLASH_SIZE_BYTES - 1);
// Enable DMA engine
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
if (hiomap_config.window_type == HIOMAP_WINDOW_TYPE_WRITE)
{
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
}
else
{
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
}
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
}
} }
else if ((!WITH_DRAM) && (hiomap_config.window_type == HIOMAP_WINDOW_TYPE_WRITE))
{ {
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT); // Flush the window (if dirty)
for (i = 0; i < hiomap_config.dirty_range_count; i++)
{
write_data_to_flash(((uint8_t *)(host_flash_write_buffer)), hiomap_config.dirty_ranges[i].bytes,
hiomap_config.dirty_ranges[i].start_address, !hiomap_config.dirty_ranges[i].erased);
}
hiomap_config.dirty_range_count = 0;
// Copy data from Flash into cache buffer
memcpy(host_flash_write_buffer, (uint8_t *)(HOSTSPIFLASH_BASE + hiomap_config.window_start_address),
FLASH_MAX_WR_WINDOW_BYTES);
} }
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
#endif
// Generate response // Generate response
switch (hiomap_config.protocol_version) switch (hiomap_config.protocol_version)
...@@ -1096,11 +1155,14 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1096,11 +1155,14 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
break; break;
} }
// Record dirty page if (hiomap_config.window_type == HIOMAP_WINDOW_TYPE_WRITE)
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].start_address = offset_bytes; {
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].bytes = length_bytes; // Record dirty page
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].erased = flags & 0x1; hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].start_address = offset_bytes;
hiomap_config.dirty_range_count++; hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].bytes = length_bytes;
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].erased = flags & 0x1;
hiomap_config.dirty_range_count++;
}
response.data[0] = ipmi_bt_current_request.data[0]; response.data[0] = ipmi_bt_current_request.data[0];
response.data[1] = ipmi_bt_current_request.data[1]; response.data[1] = ipmi_bt_current_request.data[1];
...@@ -1119,18 +1181,29 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1119,18 +1181,29 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
((((uint32_t)ipmi_bt_current_request.data[7]) << 24) | (((uint32_t)ipmi_bt_current_request.data[6]) << 16) | ((((uint32_t)ipmi_bt_current_request.data[7]) << 24) | (((uint32_t)ipmi_bt_current_request.data[6]) << 16) |
(((uint32_t)ipmi_bt_current_request.data[5]) << 8) | ipmi_bt_current_request.data[4]); (((uint32_t)ipmi_bt_current_request.data[5]) << 8) | ipmi_bt_current_request.data[4]);
// Record dirty page if (hiomap_config.window_type == HIOMAP_WINDOW_TYPE_WRITE)
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].start_address = offset_bytes; {
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].bytes = length_bytes; // Record dirty page
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].erased = 0; hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].start_address = offset_bytes;
hiomap_config.dirty_range_count++; hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].bytes = length_bytes;
hiomap_config.dirty_ranges[hiomap_config.dirty_range_count].erased = 0;
hiomap_config.dirty_range_count++;
}
} }
for (i = 0; i < hiomap_config.dirty_range_count; i++) for (i = 0; i < hiomap_config.dirty_range_count; i++)
{ {
write_data_to_flash(((uint8_t *)(host_flash_buffer + hiomap_config.dirty_ranges[i].start_address)), if (WITH_DRAM)
hiomap_config.dirty_ranges[i].bytes, hiomap_config.dirty_ranges[i].start_address, {
!hiomap_config.dirty_ranges[i].erased); write_data_to_flash(((uint8_t *)(host_flash_buffer + hiomap_config.dirty_ranges[i].start_address)),
hiomap_config.dirty_ranges[i].bytes, hiomap_config.dirty_ranges[i].start_address,
!hiomap_config.dirty_ranges[i].erased);
}
else
{
write_data_to_flash(((uint8_t *)(host_flash_write_buffer)), hiomap_config.dirty_ranges[i].bytes,
hiomap_config.dirty_ranges[i].start_address, !hiomap_config.dirty_ranges[i].erased);
}
} }
hiomap_config.dirty_range_count = 0; hiomap_config.dirty_range_count = 0;
...@@ -1208,7 +1281,7 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1208,7 +1281,7 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
} }
#if !(ENABLE_LPC_FW_CYCLE_IRQ_HANDLER) #if !(ENABLE_LPC_FW_CYCLE_IRQ_HANDLER)
static uint32_t previous_fw_read_address; static uint32_t previous_fw_read_address = 0xdeadbeef;
#endif #endif
static void process_interrupts_stage2(void) static void process_interrupts_stage2(void)
...@@ -1357,21 +1430,22 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1357,21 +1430,22 @@ static void run_pre_ipl_bmc_peripheral_setup(void)
hiomap_config.window_type = HIOMAP_WINDOW_TYPE_READ; hiomap_config.window_type = HIOMAP_WINDOW_TYPE_READ;
hiomap_config.dirty_range_count = 0; hiomap_config.dirty_range_count = 0;
#if (ENABLE_LPC_FW_CYCLE_DMA) if (ENABLE_LPC_FW_CYCLE_DMA)
// Configure and enable LPC firmware cycle DMA {
// Set up default window with address masking based on physical ROM size // Configure and enable LPC firmware cycle DMA
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG2, (uintptr_t)host_flash_buffer); // Set up default window with address masking based on physical ROM size
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG3, FLASH_SIZE_BYTES); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG2, (uintptr_t)host_flash_buffer);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG4, 0x0); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG3, FLASH_SIZE_BYTES);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG5, FLASH_SIZE_BYTES); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG4, 0x0);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG6, FLASH_SIZE_BYTES - 1); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG5, FLASH_SIZE_BYTES);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG6, FLASH_SIZE_BYTES - 1);
// Enable DMA engine
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1); // Enable DMA engine
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT); dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT); dword |= ((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword); dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
#endif write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
}
// Enable host background service task // Enable host background service task
host_background_service_task_active = 1; host_background_service_task_active = 1;
...@@ -1400,13 +1474,14 @@ static void run_post_shutdown_bmc_peripheral_teardown(void) ...@@ -1400,13 +1474,14 @@ static void run_post_shutdown_bmc_peripheral_teardown(void)
} }
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_IPMI_BT_STATUS, dword); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_IPMI_BT_STATUS, dword);
#if (ENABLE_LPC_FW_CYCLE_DMA) if (ENABLE_LPC_FW_CYCLE_DMA)
// Disable DMA engine {
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1); // Disable DMA engine
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT); dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1);
dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT); dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_R_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_R_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword); dword &= ~((1 & AQUILA_LPC_CTL_EN_FW_DMA_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
#endif write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
}
#if (ENABLE_LPC_FW_CYCLE_IRQ_HANDLER) #if (ENABLE_LPC_FW_CYCLE_IRQ_HANDLER)
// Disable LPC firmware cycle IRQ // Disable LPC firmware cycle IRQ
...@@ -1744,6 +1819,9 @@ static void host_background_service_task_event_loop(void) ...@@ -1744,6 +1819,9 @@ static void host_background_service_task_event_loop(void)
int byte; int byte;
int word; int word;
uint32_t physical_flash_address; uint32_t physical_flash_address;
#if (ENABLE_LPC_FW_CYCLE_NONCONTIGUOUS_DEBUG)
uint8_t noncontiguous_access;
#endif
#endif #endif
// IRQ debugging routines // IRQ debugging routines
...@@ -1776,6 +1854,17 @@ static void host_background_service_task_event_loop(void) ...@@ -1776,6 +1854,17 @@ static void host_background_service_task_event_loop(void)
// Limit firmware address to 64MB (wrap around) // Limit firmware address to 64MB (wrap around)
address &= 0x3ffffff; address &= 0x3ffffff;
#if (ENABLE_LPC_FW_CYCLE_NONCONTIGUOUS_DEBUG)
if ((previous_fw_read_address + 4) != address)
{
noncontiguous_access = 1;
printf("[DEBG] Non-contiguous firmware access to address 0x%08x\n", address);
}
else
{
noncontiguous_access = 0;
}
#endif
previous_fw_read_address = address; previous_fw_read_address = address;
physical_flash_address = address; physical_flash_address = address;
if ((address >= hiomap_config.window_start_address) && ((address - hiomap_config.window_start_address) < hiomap_config.window_length_bytes)) if ((address >= hiomap_config.window_start_address) && ((address - hiomap_config.window_start_address) < hiomap_config.window_length_bytes))
...@@ -1786,16 +1875,41 @@ static void host_background_service_task_event_loop(void) ...@@ -1786,16 +1875,41 @@ static void host_background_service_task_event_loop(void)
{ {
for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++) for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++)
{ {
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) = #if (ENABLE_LPC_FW_CYCLE_NONCONTIGUOUS_DEBUG)
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))); if (noncontiguous_access)
{
printf("[DEBG] Non-contiguous firmware access returning read data 0x%08x from physical flash address 0x%08x\n",
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))), physical_flash_address);
}
#endif
if ((WITH_DRAM) || ((!WITH_DRAM) && (hiomap_config.window_type != HIOMAP_WINDOW_TYPE_WRITE)))
{
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) =
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4)));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))) =
*((uint32_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + (word * 4)));
}
} }
} }
else else
{ {
for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++) for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++)
{ {
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) = if ((WITH_DRAM) || ((!WITH_DRAM) && (hiomap_config.window_type != HIOMAP_WINDOW_TYPE_WRITE)))
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)); {
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) =
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)) =
*((uint8_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + byte));
}
} }
} }
...@@ -1810,16 +1924,34 @@ static void host_background_service_task_event_loop(void) ...@@ -1810,16 +1924,34 @@ static void host_background_service_task_event_loop(void)
{ {
for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++) for (word = 0; word < (lpc_fw_msize_to_bytes(fw_cycle_msize) / 4); word++)
{ {
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))) = if (WITH_DRAM)
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4))); {
*((uint32_t *)(host_flash_buffer + physical_flash_address + (word * 4))) =
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4)));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((uint32_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + (word * 4))) =
*((volatile uint32_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + (word * 4)));
}
} }
} }
else else
{ {
for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++) for (byte = 0; byte < lpc_fw_msize_to_bytes(fw_cycle_msize); byte++)
{ {
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)) = if (WITH_DRAM)
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte)); {
*((uint8_t *)(host_flash_buffer + physical_flash_address + byte)) =
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte));
}
else if ((physical_flash_address >= hiomap_config.window_start_address) &&
((physical_flash_address - hiomap_config.window_start_address) < FLASH_MAX_WR_WINDOW_BYTES))
{
*((uint8_t *)(host_flash_write_buffer + (physical_flash_address - hiomap_config.window_start_address) + byte)) =
*((volatile uint8_t *)(HOSTLPCSLAVE_BASE + AQUILA_LPC_FW_DATA_BLOCK_OFFSET + byte));
}
} }
} }
...@@ -2288,6 +2420,7 @@ static void memcpy32(uint32_t *destination, uint32_t *source, int words) ...@@ -2288,6 +2420,7 @@ static void memcpy32(uint32_t *destination, uint32_t *source, int words)
} }
} }
#if (WITH_DRAM)
static void memset32(uint32_t *destination, uint32_t value, int words) static void memset32(uint32_t *destination, uint32_t value, int words)
{ {
int word; int word;
...@@ -2297,6 +2430,7 @@ static void memset32(uint32_t *destination, uint32_t value, int words) ...@@ -2297,6 +2430,7 @@ static void memset32(uint32_t *destination, uint32_t value, int words)
destination++; destination++;
} }
} }
#endif
#if (WITH_SPI) #if (WITH_SPI)
static uint32_t read_host_spi_flash_id(void) static uint32_t read_host_spi_flash_id(void)
...@@ -2606,6 +2740,7 @@ int main(void) ...@@ -2606,6 +2740,7 @@ int main(void)
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1, dword); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1, dword);
} }
#if (WITH_DRAM)
// Allocate internal host SPI Flash ROM buffer // Allocate internal host SPI Flash ROM buffer
host_flash_buffer = (uint8_t *)(MAIN_RAM_BASE + 0x3e00000); host_flash_buffer = (uint8_t *)(MAIN_RAM_BASE + 0x3e00000);
...@@ -2613,6 +2748,7 @@ int main(void) ...@@ -2613,6 +2748,7 @@ int main(void)
printf("Clearing host ROM internal buffer..."); printf("Clearing host ROM internal buffer...");
memset32((uint32_t *)host_flash_buffer, 0xdeadbeef, 0x4000000 / 4); memset32((uint32_t *)host_flash_buffer, 0xdeadbeef, 0x4000000 / 4);
printf("\rInternal host ROM buffer cleared \n"); printf("\rInternal host ROM buffer cleared \n");
#endif
display_character('1', 0); // STATUS CODE: 1 display_character('1', 0); // STATUS CODE: 1
...@@ -2625,6 +2761,7 @@ int main(void) ...@@ -2625,6 +2761,7 @@ int main(void)
reset_flash_device(); reset_flash_device();
configure_flash_device(); configure_flash_device();
#if (WITH_DRAM)
// Copy external SPI Flash ROM contents to internal host SPI Flash ROM buffer // Copy external SPI Flash ROM contents to internal host SPI Flash ROM buffer
copy_spi_flash_to_internal_buffer(HOSTSPIFLASH_BASE, HOSTSPIFLASHCFG_BASE, host_flash_buffer); copy_spi_flash_to_internal_buffer(HOSTSPIFLASH_BASE, HOSTSPIFLASHCFG_BASE, host_flash_buffer);
...@@ -2663,6 +2800,10 @@ int main(void) ...@@ -2663,6 +2800,10 @@ int main(void)
} }
printf("CRC of HBBL region: %08x\n", crc32(host_flash_buffer + 0x206200ULL, 4488)); printf("CRC of HBBL region: %08x\n", crc32(host_flash_buffer + 0x206200ULL, 4488));
#endif #endif
#else
// No DRAM -- direct access only
host_flash_buffer = (uint8_t *)HOSTSPIFLASH_BASE;
#endif
#endif #endif
display_character('2', 0); // STATUS CODE: 2 display_character('2', 0); // STATUS CODE: 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment