From 0951d2a2e82782aac7ceb56e670140002e737eae Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 14 Mar 2020 19:08:58 -0500 Subject: Add support for ASpeed serial backdoor on AST2400/AST2500 devices --- ast2400.c | 362 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file 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) { -- cgit v1.1