Add support for RCS Arctic Tern and Sparrowhawk platforms

parent 3c4cfe74
Pipeline #251 passed with stage
in 19 seconds
...@@ -98,7 +98,7 @@ ppc64le_add_executable(${PROJECT_NAME} ...@@ -98,7 +98,7 @@ ppc64le_add_executable(${PROJECT_NAME}
) )
ppc64le_linker_script(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") ppc64le_linker_script(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")
target_link_libraries(${PROJECT_NAME} PRIVATE libbase) target_link_libraries(${PROJECT_NAME} PRIVATE libbase)
target_link_libraries(${PROJECT_NAME} PRIVATE "--defsym=STACK_SIZE=4096") target_link_libraries(${PROJECT_NAME} PRIVATE "--defsym=STACK_SIZE=3072")
target_compile_definitions(${PROJECT_NAME} PRIVATE "-DNO_FLINT") # Disable linting target_compile_definitions(${PROJECT_NAME} PRIVATE "-DNO_FLINT") # Disable linting
format_target_sources(${PROJECT_NAME}) format_target_sources(${PROJECT_NAME})
......
...@@ -63,7 +63,7 @@ SECTIONS ...@@ -63,7 +63,7 @@ SECTIONS
. = ALIGN(8); . = ALIGN(8);
_ebss = .; _ebss = .;
_end = .; _end = .;
} > sram } > main_ram
.stack ALIGN(8) (NOLOAD): .stack ALIGN(8) (NOLOAD):
{ {
......
// © 2020 - 2021 Raptor Engineering, LLC // © 2020 - 2022 Raptor Engineering, LLC
// //
// Released under the terms of the GPL v3 // Released under the terms of the GPL v3
// See the LICENSE file for full details // See the LICENSE file for full details
#ifndef PLATFORM_VERSA_ECP5
#define PLATFORM_VERSA_ECP5 1
#endif
#ifndef PLATFORM_SPARROWHAWK
#define PLATFORM_SPARROWHAWK 0
#endif
#ifndef PLATFORM_ARCTIC_TERN
#define PLATFORM_ARCTIC_TERN 0
#endif
// Configuration sanity checks
#if (PLATFORM_VERSA_ECP5)
#if (PLATFORM_SPARROWHAWK || PLATFORM_ARCTIC_TERN)
#error Invalid platform configuration
#endif
#endif
#if (PLATFORM_SPARROWHAWK)
#if (PLATFORM_VERSA_ECP5 || PLATFORM_ARCTIC_TERN)
#error Invalid platform configuration
#endif
#endif
#if (PLATFORM_ARCTIC_TERN)
#if (PLATFORM_VERSA_ECP5 || PLATFORM_SPARROWHAWK)
#error Invalid platform configuration
#endif
#endif
// Platform specific global configuration
#if (PLATFORM_VERSA_ECP5)
#define CPU0_I2C_MASTER_BASE_ADDR I2CMASTER1_BASE
#define CPU1_I2C_MASTER_BASE_ADDR I2CMASTER2_BASE
#define P9PS_I2C_MASTER_BASE_ADDR I2CMASTER4_BASE
#define WITH_DRAM 1
#endif
#if (PLATFORM_SPARROWHAWK)
#define CPU0_I2C_MASTER_BASE_ADDR I2CMASTER1_BASE
#define CPU1_I2C_MASTER_BASE_ADDR I2CMASTER2_BASE
#define P9PS_I2C_MASTER_BASE_ADDR I2CMASTER4_BASE
#define HDMI_I2C_MASTER_BASE_ADDR I2CMASTER6_BASE
#define WITH_DRAM 0 // Sparrowhawk EC 1.00 does not have functional DDR3 DRAM
#endif
#if (PLATFORM_ARCTIC_TERN)
#define CPU0_I2C_MASTER_BASE_ADDR I2CMASTER0_BASE
#define CPU1_I2C_MASTER_BASE_ADDR I2CMASTER1_BASE
#define P9PS_I2C_MASTER_BASE_ADDR I2CMASTER4_BASE
#define HDMI_I2C_MASTER_BASE_ADDR I2CMASTER4_BASE
#define WITH_DRAM 1
#endif
#define WITH_SPI 1 #define WITH_SPI 1
#include "fsi.h" #include "fsi.h"
...@@ -31,11 +84,12 @@ ...@@ -31,11 +84,12 @@
#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 (not compatible with direct SPI access) #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) #define ALLOW_FLASH_WRITES 0 // Allow writes to PNOR Flash device
// 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
#define SPI_FLASH_TRIPLE_READ 0 // Set to 1 to enable triple-read data checks (slow) #define SPI_FLASH_TRIPLE_READ 0 // Set to 1 to enable triple-read data checks (slow)
#define ENABLE_LPC_FW_CYCLE_NONCONTIGUOUS_DEBUG 0 // Set to 1 to print a message whenever a non-sequential LPC read is detected
// General RCS platform registers // General RCS platform registers
#define HOST_PLATFORM_FPGA_I2C_REG_STATUS 0x7 #define HOST_PLATFORM_FPGA_I2C_REG_STATUS 0x7
...@@ -43,6 +97,7 @@ ...@@ -43,6 +97,7 @@
// Host platform configuration // Host platform configuration
#define HOST_PLATFORM_FPGA_I2C_ADDRESS 0x31 #define HOST_PLATFORM_FPGA_I2C_ADDRESS 0x31
#define HDMI_TRANSCEIVER_I2C_ADDRESS 0x4c
uint8_t host_flash_write_buffer[FLASH_MAX_WR_WINDOW_BYTES]; uint8_t host_flash_write_buffer[FLASH_MAX_WR_WINDOW_BYTES];
...@@ -120,9 +175,10 @@ typedef struct ...@@ -120,9 +175,10 @@ typedef struct
uint8_t vdn_smbus_addr; uint8_t vdn_smbus_addr;
} cpu_info_t; } cpu_info_t;
static const cpu_info_t g_cpu_info[] = { static const cpu_info_t g_cpu_info[] = {
#ifdef CPU0_I2C_MASTER_BASE_ADDR
{ {
.index = 0, .index = 0,
.i2c_master = (uint8_t *)I2CMASTER1_BASE, .i2c_master = (uint8_t *)CPU0_I2C_MASTER_BASE_ADDR,
.i2c_frequency = 100000, .i2c_frequency = 100000,
.vdd_regulator_addr = 0x70, .vdd_regulator_addr = 0x70,
.vdd_regulator_page = 0x00, .vdd_regulator_page = 0x00,
...@@ -134,10 +190,11 @@ static const cpu_info_t g_cpu_info[] = { ...@@ -134,10 +190,11 @@ static const cpu_info_t g_cpu_info[] = {
.vdn_smbus_addr = 0x2b, .vdn_smbus_addr = 0x2b,
}, },
#ifdef I2CMASTER2_BASE #endif
#ifdef CPU1_I2C_MASTER_BASE_ADDR
{ {
.index = 1, .index = 1,
.i2c_master = (uint8_t *)I2CMASTER2_BASE, .i2c_master = (uint8_t *)CPU1_I2C_MASTER_BASE_ADDR,
.i2c_frequency = 100000, .i2c_frequency = 100000,
.vdd_regulator_addr = 0x70, .vdd_regulator_addr = 0x70,
.vdd_regulator_page = 0x00, .vdd_regulator_page = 0x00,
...@@ -262,6 +319,7 @@ static void reboot(void) ...@@ -262,6 +319,7 @@ static void reboot(void)
ctrl_reset_write(1); ctrl_reset_write(1);
} }
#if (PLATFORM_VERSA_ECP5)
static void display_character(char character, int dp) static void display_character(char character, int dp)
{ {
uint16_t value; uint16_t value;
...@@ -307,24 +365,151 @@ static void display_character(char character, int dp) ...@@ -307,24 +365,151 @@ static void display_character(char character, int dp)
gpio3_out_write(~(value | ((dp == 0) ? 0x0000 : 0x4000))); gpio3_out_write(~(value | ((dp == 0) ? 0x0000 : 0x4000)));
} }
static void set_led_bank_display(uint8_t bitfield) static void set_led_bank_display(uint16_t value)
{ {
uint8_t bitfield;
// Convert POST code to 8 bit value
bitfield = 0;
bitfield |= ((value >> 8) & 0xf) << 4;
bitfield |= value & 0xf;
gpio1_out_write(~bitfield); gpio1_out_write(~bitfield);
} }
static void gpio_init(void) static void gpio_init(void)
{ {
// Set up discrete LED bank // Set up discrete LED bank
set_led_bank_display(0x00); set_led_bank_display(0x0000);
gpio1_oe_write(0xff); gpio1_oe_write(0xff);
}
#endif
#if (PLATFORM_SPARROWHAWK)
static void display_character(char character, int dp)
{
// Not available on Sparrowhawk
}
static void set_led_bank_display(uint16_t value)
{
// FIXME
// Display value on LEDs attached to platform control FPGA
}
static void gpio_init(void)
{
// Set up GPIO 1
// BMC_FP_ID_BTN | PM_CP0_ATTENTION_B | BMC_INTRUDER_N | SYS_PWROK_BUF | DBG_FSI0_EN | BP_SYSRESET_N | BMC_BOOT_PHASE | BMC_POWER_UP
gpio1_out_write(gpio1_out_read() & ~0x01); // Set platform power request to 0
gpio1_out_write(gpio1_out_read() | 0x08); // Disable FSI secure mode
gpio1_out_write(gpio1_out_read() | 0x02); // Set BMC boot phase to 1
gpio1_oe_write(0x0b);
}
#endif
#if (PLATFORM_ARCTIC_TERN)
static void display_character(char character, int dp)
{
uint8_t value;
// Convert digit to hex value
value = ((uint8_t)character) - 0x30;
// Display value on the upper segment of the alphanumeric LED display
gpio2_out_write((gpio2_out_read() & ~(0xf << 12)) | ((value & 0xf) << 12));
}
static void set_led_bank_display(uint16_t value)
{
uint16_t display_value;
// Convert POST code to 12 bit value
display_value = 0;
display_value |= ((value >> 8) & 0xff) << 4;
display_value |= value & 0xf;
// Display value on the lower three segments of the alphanumeric LED display
gpio2_out_write((gpio2_out_read() & ~0xfff) | (display_value & 0xfff));
}
static void gpio_init(void)
{
// Disable LPC clock buffer
gpio1_out_write(gpio1_out_read() & ~(0x01 << 12));
gpio1_oe_write(gpio1_oe_read() | (0x01 << 12));
}
#endif
#if (PLATFORM_SPARROWHAWK || PLATFORM_ARCTIC_TERN)
static void configure_hdmi_transceiver(uint8_t *i2c_master_base_addr)
{
// ***** Set up the ITE HDMI transceiver *****
printf("Setting up HDMI transceiver...");
// ***** GENERAL *****
// Reset device
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x4, 0x1c);
// ***** VIDEO *****
// Set bank 0
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x0f, 0x08); // 0x0f[1:0] = 0
// AVMute output
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0xc1, 0x01); // 0xc1[0] = 1
// Set up alphanumeric display // Take device out of reset
gpio3_out_write(0xefff); i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x04, 0x00);
gpio3_oe_write(0xefff);
// Enable HDMI transmitter reset
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x61, 0x10);
// Configure input signal
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x70,
0x00); // RGB mode, I/O latch at TxClk, non-CCIR656, non-embedded sync, single edge, no PCLK delay
i2c_write_register_byte(
i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x90,
0x00); // PG horizontal total = 0, H/V sync provided by external driver, active low VSYNC, active low HSYNC, Data Enable provided by external driver
// Enable DVI mode (works for HDMI as well, host should configure HDMI later in the boot process)
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0xc0, 0x00); // 0xc0[0] = 0
// Release HDMI transmitter reset
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0x61, 0x00); // 0x61[4] = 0
// Un-AVMute output
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0xc1, 0x00); // 0xc1[0] = 0
// ***** AUDIO *****
// Disable audio channel
i2c_write_register_byte(i2c_master_base_addr, HDMI_TRANSCEIVER_I2C_ADDRESS, 0xe0, 0x08); // 0xe0[3:0] = 0
printf("done!\n");
} }
#endif
#if (PLATFORM_SPARROWHAWK)
static void sparrowhawk_base_platform_init(void)
{
#ifdef P9PS_I2C_MASTER_BASE_ADDR
uint8_t byte;
// ***** Set up the platform control FPGA *****
printf("Setting up platform control FPGA...");
// Set HDD LED to inverted mode for NVMe drives
byte = i2c_read_register_byte((uint8_t *)P9PS_I2C_MASTER_BASE_ADDR, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x11, NULL);
byte |= 0x03;
i2c_write_register_byte((uint8_t *)P9PS_I2C_MASTER_BASE_ADDR, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x11, byte);
printf("done!\n");
#endif
}
#endif
static void set_lpc_slave_irq_enable(uint8_t enabled) static void set_lpc_slave_irq_enable(uint8_t enabled)
{ {
#ifdef HOSTLPCSLAVE_BASE
if (!enabled) if (!enabled)
{ {
hostlpcslave_ev_enable_write(0); hostlpcslave_ev_enable_write(0);
...@@ -339,10 +524,12 @@ static void set_lpc_slave_irq_enable(uint8_t enabled) ...@@ -339,10 +524,12 @@ static void set_lpc_slave_irq_enable(uint8_t enabled)
hostlpcslave_ev_enable_write(AQUILA_EV_MASTER_IRQ); hostlpcslave_ev_enable_write(AQUILA_EV_MASTER_IRQ);
irq_setmask(irq_getmask() | (1 << HOSTLPCSLAVE_INTERRUPT)); irq_setmask(irq_getmask() | (1 << HOSTLPCSLAVE_INTERRUPT));
} }
#endif
} }
void lpc_slave_isr(void) void lpc_slave_isr(void)
{ {
#ifdef HOSTLPCSLAVE_BASE
#if (ENABLE_LPC_FW_CYCLE_IRQ_HANDLER) #if (ENABLE_LPC_FW_CYCLE_IRQ_HANDLER)
int byte; int byte;
int word; int word;
...@@ -387,6 +574,9 @@ void lpc_slave_isr(void) ...@@ -387,6 +574,9 @@ void lpc_slave_isr(void)
// Limit firmware address to 64MB (wrap around) // Limit firmware address to 64MB (wrap around)
address &= 0x3ffffff; address &= 0x3ffffff;
// Show address lower bytes on display for debugging
// gpio2_out_write((address >> 8) & 0xffff);
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))
{ {
...@@ -585,14 +775,17 @@ void lpc_slave_isr(void) ...@@ -585,14 +775,17 @@ void lpc_slave_isr(void)
} }
hostlpcslave_ev_pending_write(AQUILA_EV_MASTER_IRQ); hostlpcslave_ev_pending_write(AQUILA_EV_MASTER_IRQ);
#endif
} }
uint8_t uart_register_bank[8]; uint8_t uart_register_bank[8];
static uint8_t ipmi_bt_transaction_state; static uint8_t ipmi_bt_transaction_state;
#if (WITH_SPI)
static void configure_flash_write_enable(uint8_t enable_writes) static void configure_flash_write_enable(uint8_t enable_writes)
{ {
#ifdef HOSTSPIFLASHCFG_BASE
// Set user mode // Set user mode
write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1, write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1,
read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) | read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) |
...@@ -613,10 +806,13 @@ static void configure_flash_write_enable(uint8_t enable_writes) ...@@ -613,10 +806,13 @@ static void configure_flash_write_enable(uint8_t enable_writes)
write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1, write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1,
read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) & read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) &
~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT)); ~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
#endif
} }
#if (ALLOW_FLASH_WRITES)
static uint8_t read_flash_flag_status_register(void) static uint8_t read_flash_flag_status_register(void)
{ {
#ifdef HOSTSPIFLASHCFG_BASE
uint8_t flag_status = 0; uint8_t flag_status = 0;
// Set user mode // Set user mode
...@@ -636,10 +832,15 @@ static uint8_t read_flash_flag_status_register(void) ...@@ -636,10 +832,15 @@ static uint8_t read_flash_flag_status_register(void)
~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT)); ~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
return flag_status; return flag_status;
#else
return 0;
#endif
} }
#endif
static void reset_flash_device(void) static void reset_flash_device(void)
{ {
#ifdef HOSTSPIFLASHCFG_BASE
// Set user mode // Set user mode
write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1, write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1,
read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) | read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) |
...@@ -665,10 +866,12 @@ static void reset_flash_device(void) ...@@ -665,10 +866,12 @@ static void reset_flash_device(void)
write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1, write_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1,
read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) & read_tercel_register(HOSTSPIFLASHCFG_BASE, TERCEL_SPI_REG_SYS_CORE_CTL1) &
~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT)); ~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
#endif
} }
static void configure_flash_device(void) static void configure_flash_device(void)
{ {
#ifdef HOSTSPIFLASHCFG_BASE
uint8_t config_byte; uint8_t config_byte;
// Set user mode // Set user mode
...@@ -708,10 +911,13 @@ static void configure_flash_device(void) ...@@ -708,10 +911,13 @@ static void configure_flash_device(void)
~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT)); ~(TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
configure_flash_write_enable(0); configure_flash_write_enable(0);
#endif
} }
#if (ALLOW_FLASH_WRITES)
static void erase_flash_subsector(uint32_t address) static void erase_flash_subsector(uint32_t address)
{ {
#ifdef HOSTSPIFLASHCFG_BASE
// Limit Flash address to active memory // Limit Flash address to active memory
address = address & 0x0fffffff; address = address & 0x0fffffff;
...@@ -743,10 +949,14 @@ static void erase_flash_subsector(uint32_t address) ...@@ -743,10 +949,14 @@ static void erase_flash_subsector(uint32_t address)
{ {
// Wait for pending operation to complete // Wait for pending operation to complete
} }
#endif
} }
#endif
#endif
static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t flash_offset, uint8_t erase_before_write) static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t flash_offset, uint8_t erase_before_write)
{ {
#if defined(HOSTSPIFLASHCFG_BASE) && (ALLOW_FLASH_WRITES)
uint32_t flash_address; uint32_t flash_address;
uint32_t bytes_remaining; uint32_t bytes_remaining;
...@@ -791,6 +1001,9 @@ static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t f ...@@ -791,6 +1001,9 @@ static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t f
{ {
return 0; return 0;
} }
#else
return -1;
#endif
} }
// NOTE // NOTE
...@@ -802,6 +1015,7 @@ static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t f ...@@ -802,6 +1015,7 @@ static int write_data_to_flash(uint8_t *write_buffer, uint32_t bytes, uint32_t f
// timeframe, e.g. 10ms // timeframe, e.g. 10ms
static void process_host_to_bmc_ipmi_bt_transactions(void) static void process_host_to_bmc_ipmi_bt_transactions(void)
{ {
#ifdef HOSTLPCSLAVE_BASE
uint32_t dword; uint32_t dword;
static uint8_t unhandled_ipmi_command; static uint8_t unhandled_ipmi_command;
...@@ -1095,9 +1309,11 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1095,9 +1309,11 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
} }
hiomap_config.dirty_range_count = 0; hiomap_config.dirty_range_count = 0;
#ifdef HOSTSPIFLASH_BASE
// Copy data from Flash into cache buffer // Copy data from Flash into cache buffer
memcpy(host_flash_write_buffer, (uint8_t *)(HOSTSPIFLASH_BASE + hiomap_config.window_start_address), memcpy(host_flash_write_buffer, (uint8_t *)(HOSTSPIFLASH_BASE + hiomap_config.window_start_address),
FLASH_MAX_WR_WINDOW_BYTES); FLASH_MAX_WR_WINDOW_BYTES);
#endif
} }
// Generate response // Generate response
...@@ -1280,6 +1496,7 @@ static void process_host_to_bmc_ipmi_bt_transactions(void) ...@@ -1280,6 +1496,7 @@ static void process_host_to_bmc_ipmi_bt_transactions(void)
ipmi_bt_transaction_state = 0; ipmi_bt_transaction_state = 0;
break; break;
} }
#endif
} }
#if !(ENABLE_LPC_FW_CYCLE_IRQ_HANDLER) #if !(ENABLE_LPC_FW_CYCLE_IRQ_HANDLER)
...@@ -1288,6 +1505,7 @@ static uint32_t previous_fw_read_address = 0xdeadbeef; ...@@ -1288,6 +1505,7 @@ static uint32_t previous_fw_read_address = 0xdeadbeef;
static void process_interrupts_stage2(void) static void process_interrupts_stage2(void)
{ {
#ifdef HOSTLPCSLAVE_BASE
uint32_t dword; uint32_t dword;
int read_position; int read_position;
...@@ -1369,6 +1587,7 @@ static void process_interrupts_stage2(void) ...@@ -1369,6 +1587,7 @@ static void process_interrupts_stage2(void)
// Re-activate interupts on exiting critical section // Re-activate interupts on exiting critical section
irq_setie(1); irq_setie(1);
#endif
} }
static void run_pre_ipl_bmc_peripheral_setup(void) static void run_pre_ipl_bmc_peripheral_setup(void)
...@@ -1378,7 +1597,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1378,7 +1597,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void)
// Reset POST codes and display // Reset POST codes and display
post_code_high = 0; post_code_high = 0;
post_code_low = 0; post_code_low = 0;
set_led_bank_display(0x00); set_led_bank_display(0x0000);
// Deactivate interrupts on entering critical section // Deactivate interrupts on entering critical section
irq_setie(0); irq_setie(0);
...@@ -1394,6 +1613,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1394,6 +1613,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void)
// Re-activate interupts on exiting critical section // Re-activate interupts on exiting critical section
irq_setie(1); irq_setie(1);
#ifdef HOSTLPCSLAVE_BASE
// Configure VUART1 // Configure VUART1
dword = 0; dword = 0;
dword |= (1 & AQUILA_LPC_VUART_FIFO_TRIG_LVL_MASK) << AQUILA_LPC_VUART_FIFO_TRIG_LVL_SHIFT; dword |= (1 & AQUILA_LPC_VUART_FIFO_TRIG_LVL_MASK) << AQUILA_LPC_VUART_FIFO_TRIG_LVL_SHIFT;
...@@ -1422,6 +1642,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1422,6 +1642,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void)
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1); dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1);
dword |= ((1 & AQUILA_LPC_CTL_EN_FW_CYCLE_IRQ_MASK) << AQUILA_LPC_CTL_EN_FW_CYCLE_IRQ_SHIFT); dword |= ((1 & AQUILA_LPC_CTL_EN_FW_CYCLE_IRQ_MASK) << AQUILA_LPC_CTL_EN_FW_CYCLE_IRQ_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1, dword); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_CONTROL1, dword);
#endif
#endif #endif
// Reset HIOMAP windows // Reset HIOMAP windows
...@@ -1432,6 +1653,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1432,6 +1653,7 @@ 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;
#ifdef HOSTLPCSLAVE_BASE
if (ENABLE_LPC_FW_CYCLE_DMA) if (ENABLE_LPC_FW_CYCLE_DMA)
{ {
// Configure and enable LPC firmware cycle DMA // Configure and enable LPC firmware cycle DMA
...@@ -1448,6 +1670,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void) ...@@ -1448,6 +1670,7 @@ static void run_pre_ipl_bmc_peripheral_setup(void)
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_W_MASK) << AQUILA_LPC_CTL_EN_FW_DMA_W_SHIFT);
write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword); write_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_DMA_CONFIG1, dword);
} }
#endif
// Enable host background service task // Enable host background service task
host_background_service_task_active = 1; host_background_service_task_active = 1;
...@@ -1467,6 +1690,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void) ...@@ -1467,6 +1690,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void)
// Reset internal state variables // Reset internal state variables
ipmi_bt_transaction_state = 0; ipmi_bt_transaction_state = 0;
#ifdef HOSTLPCSLAVE_BASE
// Set IPMI BT B_BUSY flag // Set IPMI BT B_BUSY flag
dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_IPMI_BT_STATUS) & (1 << IPMI_BT_CTL_B_BUSY_SHIFT); dword = read_aquila_register(HOSTLPCSLAVE_BASE, AQUILA_LPC_REG_IPMI_BT_STATUS) & (1 << IPMI_BT_CTL_B_BUSY_SHIFT);
if (!(dword & (1 << IPMI_BT_CTL_B_BUSY_SHIFT))) if (!(dword & (1 << IPMI_BT_CTL_B_BUSY_SHIFT)))
...@@ -1499,6 +1723,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void) ...@@ -1499,6 +1723,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void)
// Disable LPC slave IRQs // Disable LPC slave IRQs
set_lpc_slave_irq_enable(0); set_lpc_slave_irq_enable(0);
#endif
// Reset HIOMAP windows // Reset HIOMAP windows
hiomap_config.protocol_version = 0; hiomap_config.protocol_version = 0;
...@@ -1511,7 +1736,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void) ...@@ -1511,7 +1736,7 @@ static void run_post_shutdown_bmc_peripheral_teardown(void)
// Reset POST codes and display // Reset POST codes and display
post_code_high = 0; post_code_high = 0;
post_code_low = 0; post_code_low = 0;
set_led_bank_display(0x00); set_led_bank_display(0x0000);
} }
static int apply_avsbus_workarounds_cpu(const cpu_info_t *cpu) static int apply_avsbus_workarounds_cpu(const cpu_info_t *cpu)
...@@ -1656,50 +1881,61 @@ static int disable_avsbus_pmbus(const cpu_info_t *cpu_info, int cpu_count) ...@@ -1656,50 +1881,61 @@ static int disable_avsbus_pmbus(const cpu_info_t *cpu_info, int cpu_count)
static void power_off_chassis(void) static void power_off_chassis(void)
{ {
#if (PLATFORM_ARCTIC_TERN)
// Disable LPC clock buffer
gpio1_out_write(gpio1_out_read() & ~(0x01 << 12));
#endif
// Disable PMBUS // Disable PMBUS
if (disable_avsbus_pmbus(g_cpu_info, configured_cpu_count)) if (disable_avsbus_pmbus(g_cpu_info, configured_cpu_count))
{ {
printf("PMBUS disable failed!\n"); printf("PMBUS disable failed!\n");
} }
#ifdef P9PS_I2C_MASTER_BASE_ADDR
// Power off host via platform FPGA commands // Power off host via platform FPGA commands
i2c_write_register_byte((uint8_t *)I2CMASTER4_BASE, HOST_PLATFORM_FPGA_I2C_ADDRESS, HOST_PLATFORM_FPGA_I2C_REG_MFR_OVR, 0x00); i2c_write_register_byte((uint8_t *)P9PS_I2C_MASTER_BASE_ADDR, HOST_PLATFORM_FPGA_I2C_ADDRESS, HOST_PLATFORM_FPGA_I2C_REG_MFR_OVR, 0x00);
#endif
run_post_shutdown_bmc_peripheral_teardown(); run_post_shutdown_bmc_peripheral_teardown();
} }
static int power_on_chassis(void) static int power_on_chassis(void)
{ {
int cpu_count = 1;
#ifdef P9PS_I2C_MASTER_BASE_ADDR
uint8_t platform_fpga_identifier[4]; uint8_t platform_fpga_identifier[4];
int platform_power_on_timeout_counter; int platform_power_on_timeout_counter;
int cpu_count = 1;
int i2c_read_retcode; int i2c_read_retcode;
uint8_t byte; uint8_t byte;
// Verify communication with platform control FPGA // Verify communication with platform control FPGA
platform_fpga_identifier[0] = i2c_read_register_byte((uint8_t *)I2CMASTER4_BASE, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x0c, NULL); platform_fpga_identifier[0] = i2c_read_register_byte((uint8_t *)P9PS_I2C_MASTER_BASE_ADDR, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x0c, NULL);
if (platform_fpga_identifier[0] == 0xff) if (platform_fpga_identifier[0] == 0xff)
{ {
return -1; return -1;
}