summaryrefslogtreecommitdiffstats
path: root/ast2400.c
diff options
context:
space:
mode:
Diffstat (limited to 'ast2400.c')
-rw-r--r--ast2400.c362
1 files changed, 288 insertions, 74 deletions
diff --git a/ast2400.c b/ast2400.c
index 01cee76..4f71414 100644
--- a/ast2400.c
+++ b/ast2400.c
@@ -1,7 +1,7 @@
/*
* This file is part of the flashrom project.
*
- * Copyright (C) 2016 - 2017 Raptor Engineering, LLC
+ * Copyright (C) 2016 - 2020 Raptor Engineering, LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -79,6 +79,8 @@ uint8_t ast2400_device_tickle_fw = 0;
uint32_t ast2400_device_flash_mmio_offset = 0;
uint32_t ast2400_device_host_mode = 0;
uint32_t ast2400_original_wdt_conf = 0;
+uint32_t ast2400_serial_backdoor_access = 0;
+uint32_t ast2400_active_peripheral_addr = 0;
const struct dev_entry bmc_aspeed_ast2400[] = {
{PCI_VENDOR_ID_ASPEED, 0x2000, OK, "ASPEED", "AST2400" },
@@ -102,56 +104,168 @@ static const struct spi_master spi_master_ast2400 = {
.write_aai = default_spi_write_aai,
};
+static int ast2400_serialport_write(const char *buf, unsigned int writecnt)
+{
+ return serialport_write((const unsigned char*)buf, writecnt);
+}
+
+static uint32_t ast2400_read_register_dword(uint32_t address)
+{
+ if (ast2400_serial_backdoor_access) {
+ char command_string[32];
+ int command_string_len = 0;
+ snprintf(command_string, 32, "r %x\r\n", ast2400_active_peripheral_addr + address);
+ command_string_len = strlen(command_string);
+ sp_flush_incoming();
+ ast2400_serialport_write(command_string, command_string_len);
+ unsigned char read_buffer[48];
+ memset(read_buffer, 0, sizeof read_buffer);
+ if (!serialport_read_nonblock(read_buffer, command_string_len + 8 + 3, 2000, NULL)) {
+ if (read_buffer[(command_string_len + 8 + 3) - 1] == '$') {
+ read_buffer[command_string_len + 8] = 0;
+ }
+ return strtol((const char *)(read_buffer + command_string_len), NULL, 16);
+ }
+ return 0;
+ }
+ else {
+ uint32_t extra_offset = 0;
+ if (ast2400_active_peripheral_addr == AST2400_SCU_APB_ADDR) {
+ extra_offset = AST2400_SCU_APB_BRIDGE_OFFSET;
+ }
+ else if (ast2400_active_peripheral_addr == AST2400_WDT_APB_ADDR) {
+ extra_offset = AST2400_WDT_APB_BRIDGE_OFFSET;
+ }
+ return pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + extra_offset + address);
+ }
+}
+
+static void ast2400_write_register_dword(uint32_t data, uint32_t address)
+{
+ if (ast2400_serial_backdoor_access) {
+ char command_string[32];
+ int command_string_len = 0;
+ snprintf(command_string, 32, "w %x %x\r\n", ast2400_active_peripheral_addr + address, data);
+ command_string_len = strlen(command_string);
+ sp_flush_incoming();
+ ast2400_serialport_write(command_string, command_string_len);
+ unsigned char read_buffer[48];
+ memset(read_buffer, 0, sizeof read_buffer);
+ if (!serialport_read_nonblock(read_buffer, command_string_len + 3, 2000, NULL)) {
+ if (read_buffer[(command_string_len + 3) - 1] == '$') {
+ read_buffer[command_string_len] = 0;
+ }
+ }
+ }
+ else {
+ uint32_t extra_offset = 0;
+ if (ast2400_active_peripheral_addr == AST2400_SCU_APB_ADDR) {
+ extra_offset = AST2400_SCU_APB_BRIDGE_OFFSET;
+ }
+ else if (ast2400_active_peripheral_addr == AST2400_WDT_APB_ADDR) {
+ extra_offset = AST2400_WDT_APB_BRIDGE_OFFSET;
+ }
+ pci_mmio_writel(data, ast2400_device_bar + ASPEED_P2A_OFFSET + extra_offset + address);
+ }
+}
+
+static void ast2400_write_register_byte(uint8_t data, uint32_t address)
+{
+ if (ast2400_serial_backdoor_access) {
+ char command_string[32];
+ int command_string_len = 0;
+ snprintf(command_string, 32, "o %x %x\r\n", ast2400_active_peripheral_addr + address, data);
+ command_string_len = strlen(command_string);
+ sp_flush_incoming();
+ ast2400_serialport_write(command_string, command_string_len);
+ unsigned char read_buffer[48];
+ memset(read_buffer, 0, sizeof read_buffer);
+ if (!serialport_read_nonblock(read_buffer, command_string_len + 3, 2000, NULL)) {
+ if (read_buffer[(command_string_len + 3) - 1] == '$') {
+ read_buffer[command_string_len] = 0;
+ }
+ }
+ }
+ else {
+ uint32_t extra_offset = 0;
+ if (ast2400_active_peripheral_addr == AST2400_SCU_APB_ADDR) {
+ extra_offset = AST2400_SCU_APB_BRIDGE_OFFSET;
+ }
+ else if (ast2400_active_peripheral_addr == AST2400_WDT_APB_ADDR) {
+ extra_offset = AST2400_WDT_APB_BRIDGE_OFFSET;
+ }
+ pci_mmio_writeb(data, ast2400_device_bar + ASPEED_P2A_OFFSET + extra_offset + address);
+ }
+}
+
static int ast2400_set_a2b_bridge_scu(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_SCU_APB_ADDR & 0xffff0000, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_SCU_APB_ADDR & 0xffff0000, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_SCU_APB_ADDR;
return 0;
}
static int ast2400_set_a2b_bridge_wdt(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_WDT_APB_ADDR & 0xffff0000, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_WDT_APB_ADDR & 0xffff0000, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_WDT_APB_ADDR;
return 0;
}
static int ast2400_set_a2b_bridge_smc(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_SMC_APB_ADDR, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_SMC_APB_ADDR, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_SMC_APB_ADDR;
return 0;
}
static int ast2400_set_a2b_bridge_spi(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_SPI_APB_ADDR, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_SPI_APB_ADDR, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_SPI_APB_ADDR;
return 0;
}
static int ast2400_set_a2b_bridge_smc_flash(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_SMC_FLASH_MMIO_ADDR + ast2400_device_flash_mmio_offset, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_SMC_FLASH_MMIO_ADDR + ast2400_device_flash_mmio_offset, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_SMC_FLASH_MMIO_ADDR;
return 0;
}
static int ast2400_set_a2b_bridge_spi_flash(void)
{
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
- pci_mmio_writel(AST2400_SPI_FLASH_MMIO_ADDR, ast2400_device_bar + 0xf004);
- pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ if (!ast2400_serial_backdoor_access) {
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ pci_mmio_writel(AST2400_SPI_FLASH_MMIO_ADDR, ast2400_device_bar + 0xf004);
+ pci_mmio_writel(0x1, ast2400_device_bar + 0xf000);
+ }
+ ast2400_active_peripheral_addr = AST2400_SPI_FLASH_MMIO_ADDR;
return 0;
}
@@ -160,11 +274,11 @@ static int ast2400_disable_cpu(void) {
uint32_t dword;
if (ast2400_device_halt_cpu) {
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_HW_STRAP);
+ dword = ast2400_read_register_dword(AST2400_SCU_HW_STRAP);
if (((dword & AST2400_SCU_BOOT_SRC_MASK) != AST2400_SCU_BOOT_SPI)
&& ((dword & AST2400_SCU_BOOT_SRC_MASK) != AST2400_SCU_BOOT_NONE)) { /* NONE permitted to allow for BMC recovery after Ctrl+C or crash */
msg_perr("CPU halt requested but CPU firmware source is not SPI.\n");
- pci_mmio_writel(0x0, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_PROT_KEY);
+ ast2400_write_register_dword(0x0, AST2400_SCU_PROT_KEY);
ast2400_device_halt_cpu = 0;
return 1;
}
@@ -174,12 +288,12 @@ static int ast2400_disable_cpu(void) {
*/
msg_pinfo("Configuring P2A bridge for WDT access\n");
ast2400_set_a2b_bridge_wdt();
- ast2400_original_wdt_conf = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_WDT_APB_BRIDGE_OFFSET + AST2400_WDT1_CTL);
- pci_mmio_writel((ast2400_original_wdt_conf & ~AST2400_WDT_RESET_MODE_MASK) | AST2400_WDT_RESET_CPU_ONLY, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_WDT_APB_BRIDGE_OFFSET + AST2400_WDT1_CTL);
+ ast2400_original_wdt_conf = ast2400_read_register_dword(AST2400_WDT1_CTL);
+ ast2400_write_register_dword((ast2400_original_wdt_conf & ~AST2400_WDT_RESET_MODE_MASK) | AST2400_WDT_RESET_CPU_ONLY, AST2400_WDT1_CTL);
/* Disable CPU */
ast2400_set_a2b_bridge_scu();
- pci_mmio_writel((dword & ~AST2400_SCU_BOOT_SRC_MASK) | AST2400_SCU_BOOT_NONE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_HW_STRAP);
+ ast2400_write_register_dword((dword & ~AST2400_SCU_BOOT_SRC_MASK) | AST2400_SCU_BOOT_NONE, AST2400_SCU_HW_STRAP);
}
return 0;
@@ -191,23 +305,35 @@ static int ast2400_enable_cpu(void) {
if (ast2400_device_halt_cpu && ast2400_device_resume_cpu) {
/* Re-enable CPU */
ast2400_set_a2b_bridge_scu();
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_HW_STRAP);
- pci_mmio_writel((dword & ~AST2400_SCU_BOOT_SRC_MASK) | AST2400_SCU_BOOT_SPI, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_HW_STRAP);
+ dword = ast2400_read_register_dword(AST2400_SCU_HW_STRAP);
+ ast2400_write_register_dword((dword & ~AST2400_SCU_BOOT_SRC_MASK) | AST2400_SCU_BOOT_SPI, AST2400_SCU_HW_STRAP);
/* Reset WDT configuration */
ast2400_set_a2b_bridge_wdt();
- pci_mmio_writel((ast2400_original_wdt_conf & ~AST2400_WDT_RESET_MODE_MASK) | AST2400_WDT_RESET_CPU_ONLY, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_WDT_APB_BRIDGE_OFFSET + AST2400_WDT1_CTL);
+ ast2400_write_register_dword((ast2400_original_wdt_conf & ~AST2400_WDT_RESET_MODE_MASK) | AST2400_WDT_RESET_CPU_ONLY, AST2400_WDT1_CTL);
}
return 0;
}
+static void ast2400_disable_backdoor_access()
+{
+ if (ast2400_serial_backdoor_access) {
+ /* Disable backdoor serial console */
+ ast2400_serialport_write("q\r\n", 3);
+ }
+ else {
+ /* Disable backdoor APB access */
+ pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ }
+}
+
static int ast2400_shutdown(void *data) {
/* Reactivate CPU if previously deactivated */
ast2400_enable_cpu();
- /* Disable backdoor APB access */
- pci_mmio_writel(0x0, ast2400_device_bar + 0xf000);
+ /* Shut down the backdoor access method(s) */
+ ast2400_disable_backdoor_access();
return 0;
}
@@ -217,8 +343,26 @@ int ast2400_init(void)
struct pci_dev *dev = NULL;
uint32_t dword;
uint8_t divisor;
+ int timeout;
char *arg;
+ char *serial_port = NULL;
+ char *ast2400_backdoor_password = NULL;
+
+ ast2400_serial_backdoor_access = 0;
+ serial_port = extract_programmer_param("serial");
+ if (serial_port) {
+ ast2400_serial_backdoor_access = 1;
+ }
+
+ if (ast2400_serial_backdoor_access) {
+ ast2400_backdoor_password = extract_programmer_param("aspeed_vendor_backdoor_password");
+ if (!ast2400_backdoor_password) {
+ free(serial_port);
+ msg_perr("Cannot program over serial without ASpeed's vendor backdoor password! Specify with aspeed_vendor_backdoor_password=\n");
+ return 1;
+ }
+ }
ast2400_device_spi_bus = 0;
arg = extract_programmer_param("spibus");
@@ -246,43 +390,112 @@ int ast2400_init(void)
free(arg);
if ((ast2400_device_host_mode == 0) && ((ast2400_device_spi_bus < 0) || (ast2400_device_spi_bus > 4))) {
+ if (ast2400_serial_backdoor_access) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ }
msg_perr("SPI bus number out of range! Valid values are 0 - 4.\n");
return 1;
}
- if (rget_io_perms())
- return 1;
+ if (ast2400_serial_backdoor_access) {
+ sp_fd = sp_openserport(serial_port, 115200);
+ if (sp_fd == SER_INV_FD) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Unable to open specified serial port!\n");
+ return 1;
+ }
+ ast2400_serialport_write("q\r\n", 3);
+ if (serialport_shutdown(NULL)) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Unable to close serial port prior to reopening at backdoor password transmission baud rate!\n");
+ return 1;
+ }
+ sp_fd = sp_openserport(serial_port, 1200);
+ if (sp_fd == SER_INV_FD) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Unable to reopen serial port at backdoor password transmission baud rate!\n");
+ return 1;
+ }
+ msg_pinfo("Sending vendor serial backdoor password... ");
+ ast2400_serialport_write(ast2400_backdoor_password, strlen(ast2400_backdoor_password));
+ msg_pinfo("done.\n");
+ msg_pinfo("Waiting for response... ");
+ timeout = 2000; // 2 seconds
+ while (1) {
+ unsigned char read_buffer[1];
+ if (!serialport_read_nonblock(read_buffer, 1, 1, NULL)) {
+ if (read_buffer[0] == '$') {
+ break;
+ }
+ }
+ timeout--;
+ if (timeout <= 0) {
+ msg_pinfo("timeout!\n");
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Device not responding! Not connected or in lockdown mode (SCU2C bit 10 set)?\n");
+ return 1;
+ }
+ }
+ msg_pinfo("done.\n");
+ if (serialport_shutdown(NULL)) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Unable to close serial port prior to reopening at transfer baud rate!\n");
+ return 1;
+ }
+ sp_fd = sp_openserport(serial_port, 115200);
+ if (sp_fd == SER_INV_FD) {
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ msg_perr("Unable to reopen serial port at transfer baud rate!\n");
+ return 1;
+ }
- dev = pcidev_init(bmc_aspeed_ast2400, PCI_BASE_ADDRESS_1);
- if (!dev)
- return 1;
+ free(serial_port);
+ free(ast2400_backdoor_password);
+ }
+ else {
+ if (rget_io_perms())
+ return 1;
- uintptr_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_1);
- if (!io_base_addr)
- return 1;
+ dev = pcidev_init(bmc_aspeed_ast2400, PCI_BASE_ADDRESS_1);
+ if (!dev)
+ return 1;
- msg_pinfo("Detected ASPEED MMIO base address: %p.\n", (void*)io_base_addr);
+ uintptr_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_1);
+ if (!io_base_addr)
+ return 1;
- ast2400_device_bar = rphysmap("ASPEED", io_base_addr, ASPEED_MEMMAP_SIZE);
- if (ast2400_device_bar == ERROR_PTR)
- return 1;
+ msg_pinfo("Detected ASPEED MMIO base address: %p.\n", (void*)io_base_addr);
- if (register_shutdown(ast2400_shutdown, dev))
- return 1;
+ ast2400_device_bar = rphysmap("ASPEED", io_base_addr, ASPEED_MEMMAP_SIZE);
+ if (ast2400_device_bar == ERROR_PTR)
+ return 1;
+
+ if (register_shutdown(ast2400_shutdown, dev))
+ return 1;
- io_base_addr += ASPEED_P2A_OFFSET;
- msg_pinfo("ASPEED P2A base address: %p.\n", (void*)io_base_addr);
+ io_base_addr += ASPEED_P2A_OFFSET;
+ msg_pinfo("ASPEED P2A base address: %p.\n", (void*)io_base_addr);
+ }
msg_pinfo("Configuring P2A bridge for SCU access\n");
ast2400_set_a2b_bridge_scu();
- pci_mmio_writel(AST2400_SCU_PASSWORD, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_PROT_KEY);
+ ast2400_write_register_dword(AST2400_SCU_PASSWORD, AST2400_SCU_PROT_KEY);
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_MISC_CTL);
- pci_mmio_writel(dword & ~((0x1 << 24) | (0x2 << 22)), ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SCU_APB_BRIDGE_OFFSET + AST2400_SCU_MISC_CTL);
+ dword = ast2400_read_register_dword(AST2400_SCU_MISC_CTL);
+ ast2400_write_register_dword(dword & ~((0x1 << 24) | (0x2 << 22)), AST2400_SCU_MISC_CTL);
/* Halt CPU if requested */
- if (ast2400_disable_cpu())
+ if (ast2400_disable_cpu()) {
+ ast2400_disable_backdoor_access();
return 1;
+ }
msg_pinfo("Configuring P2A bridge for SMC access\n");
ast2400_set_a2b_bridge_smc();
@@ -293,26 +506,27 @@ int ast2400_init(void)
divisor = 0; /* Slowest speed for now */
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
+ dword = ast2400_read_register_dword(AST2400_SPI_CTL);
dword &= ~AST2400_SPI_SPEED_MASK;
dword |= (divisor << 8);
dword &= ~AST2400_SPI_CPOL_1;
dword &= ~AST2400_SPI_LSB_FIRST_CTRL; /* MSB first */
dword &= ~AST2400_SPI_IO_MODE_MASK; /* Single bit I/O mode */
- pci_mmio_writel(dword, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
+ ast2400_write_register_dword(dword, AST2400_SPI_CTL);
}
else {
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_FMC00);
+ dword = ast2400_read_register_dword(AST2400_SMC_FMC00);
if (((dword >> (ast2400_device_spi_bus * 2)) & 0x3) != 0x2) {
msg_perr("CE%01x Flash type is not SPI!\n", ast2400_device_spi_bus);
+ ast2400_disable_backdoor_access();
return 1;
}
msg_pinfo("Enabling CE%01x write\n", ast2400_device_spi_bus);
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_FMC00);
- pci_mmio_writel(dword | (0x1 << (16 + ast2400_device_spi_bus)), ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_FMC00);
+ dword = ast2400_read_register_dword(AST2400_SMC_FMC00);
+ ast2400_write_register_dword(dword | (0x1 << (16 + ast2400_device_spi_bus)), AST2400_SMC_FMC00);
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_SEG(ast2400_device_spi_bus));
+ dword = ast2400_read_register_dword(AST2400_SMC_CE_SEG(ast2400_device_spi_bus));
ast2400_device_flash_mmio_offset = ((dword >> 16) & 0x3f) * 0x800000;
msg_pinfo("Using CE%01x offset 0x%08x\n", ast2400_device_spi_bus, ast2400_device_flash_mmio_offset);
}
@@ -341,13 +555,13 @@ static void ast2400_spi_xfer_data(struct flashctx *flash,
dword |= writearr[i + 1] << 8;
dword |= writearr[i + 2] << 16;
dword |= writearr[i + 3] << 24;
- pci_mmio_writel(dword, ast2400_device_bar + ASPEED_P2A_OFFSET);
+ ast2400_write_register_dword(dword, 0);
}
for (; i < writecnt; i++)
- pci_mmio_writeb(writearr[i], ast2400_device_bar + ASPEED_P2A_OFFSET);
+ ast2400_write_register_byte(writearr[i], 0);
programmer_delay(1);
for (i = 0; i < readcnt;) {
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET);
+ dword = ast2400_read_register_dword(0);
if (i < readcnt)
readarr[i] = dword & 0xff;
i++;
@@ -380,10 +594,10 @@ static int ast2400_spi_send_command(struct flashctx *flash,
if (ast2400_device_host_mode) {
/* Set up user command mode */
ast2400_set_a2b_bridge_spi();
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CFG);
- pci_mmio_writel(dword | AST2400_SPI_CFG_WRITE_EN, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CFG);
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
- pci_mmio_writel(dword | AST2400_SPI_CMD_USER_MODE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
+ dword = ast2400_read_register_dword(AST2400_SPI_CFG);
+ ast2400_write_register_dword(dword | AST2400_SPI_CFG_WRITE_EN, AST2400_SPI_CFG);
+ dword = ast2400_read_register_dword(AST2400_SPI_CTL);
+ ast2400_write_register_dword(dword | AST2400_SPI_CMD_USER_MODE, AST2400_SPI_CTL);
/* Transfer data */
ast2400_set_a2b_bridge_spi_flash();
@@ -391,18 +605,18 @@ static int ast2400_spi_send_command(struct flashctx *flash,
/* Tear down user command mode */
ast2400_set_a2b_bridge_spi();
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
- pci_mmio_writel((dword & ~AST2400_SPI_CMD_MASK) | AST2400_SPI_CMD_FAST_R_MODE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CTL);
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CFG);
- pci_mmio_writel(dword & ~AST2400_SPI_CFG_WRITE_EN, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SPI_CFG);
+ dword = ast2400_read_register_dword(AST2400_SPI_CTL);
+ ast2400_write_register_dword((dword & ~AST2400_SPI_CMD_MASK) | AST2400_SPI_CMD_FAST_R_MODE, AST2400_SPI_CTL);
+ dword = ast2400_read_register_dword(AST2400_SPI_CFG);
+ ast2400_write_register_dword(dword & ~AST2400_SPI_CFG_WRITE_EN, AST2400_SPI_CFG);
}
else {
/* Set up user command mode */
ast2400_set_a2b_bridge_smc();
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- pci_mmio_writel(dword | AST2400_SPI_CMD_USER_MODE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- pci_mmio_writel(dword & ~AST2400_SPI_STOP_CE_ACTIVE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ dword = ast2400_read_register_dword(AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ ast2400_write_register_dword(dword | AST2400_SPI_CMD_USER_MODE, AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ dword = ast2400_read_register_dword(AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ ast2400_write_register_dword(dword & ~AST2400_SPI_STOP_CE_ACTIVE, AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
/* Transfer data */
ast2400_set_a2b_bridge_smc_flash();
@@ -410,10 +624,10 @@ static int ast2400_spi_send_command(struct flashctx *flash,
/* Tear down user command mode */
ast2400_set_a2b_bridge_smc();
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- pci_mmio_writel(dword | AST2400_SPI_STOP_CE_ACTIVE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- dword = pci_mmio_readl(ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
- pci_mmio_writel((dword & ~AST2400_SPI_CMD_MASK) | AST2400_SPI_CMD_FAST_R_MODE, ast2400_device_bar + ASPEED_P2A_OFFSET + AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ dword = ast2400_read_register_dword(AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ ast2400_write_register_dword(dword | AST2400_SPI_STOP_CE_ACTIVE, AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ dword = ast2400_read_register_dword(AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
+ ast2400_write_register_dword((dword & ~AST2400_SPI_CMD_MASK) | AST2400_SPI_CMD_FAST_R_MODE, AST2400_SMC_CE_CTL(ast2400_device_spi_bus));
}
if (ast2400_device_tickle_fw) {
OpenPOWER on IntegriCloud