Commit d04c0b5c authored by Timothy Pearson's avatar Timothy Pearson

Add support for optional high speed UART mode

Note that this is not useable on most hardware due to RS-232 transfer timing constraints
parent 9d32dc3d
......@@ -33,6 +33,7 @@
#define AST2400_SCU_APB_BRIDGE_OFFSET (AST2400_SCU_APB_ADDR & 0xffff)
#define AST2400_SCU_PROT_KEY 0x00
#define AST2400_SCU_MISC_CTL 0x2c
#define AST2400_SCU_MISC_2_CTL 0x4c
#define AST2400_SCU_HW_STRAP 0x70
#define AST2400_SCU_PASSWORD 0x1688a8a8
......@@ -352,6 +353,10 @@ int ast2400_init(void)
char *serial_port = NULL;
char *ast2400_backdoor_password = NULL;
// Serial backdoor settings
int expected_rate = 1;
int detected_rate = 0;
ast2400_serial_backdoor_access = 0;
serial_port = extract_programmer_param("serial");
if (serial_port) {
......@@ -364,6 +369,11 @@ int ast2400_init(void)
ast2400_backdoor_password = strdup(AST2400_DEFAULT_PASSWORD);
msg_pinfo("No password specified with aspeed_vendor_backdoor_password, falling back to default.\n");
}
arg = extract_programmer_param("high_speed_uart");
if (arg && !strcmp(arg,"true"))
expected_rate = 2;
free(arg);
}
ast2400_device_spi_bus = 0;
......@@ -411,6 +421,24 @@ int ast2400_init(void)
return 1;
}
ast2400_serialport_write("q\r\n", 3);
programmer_delay(500);
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 alternate baud rate!\n");
return 1;
}
sp_fd = sp_openserport(serial_port, 921600);
if (sp_fd == SER_INV_FD) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Unable to reopen serial port at alternate baud rate!\n");
return 1;
}
ast2400_serialport_write("q\r\n", 3);
programmer_delay(500);
ast2400_serialport_write("q\r\n", 3);
if (serialport_shutdown(NULL)) {
free(serial_port);
free(ast2400_backdoor_password);
......@@ -460,29 +488,90 @@ int ast2400_init(void)
return 1;
}
free(serial_port);
free(ast2400_backdoor_password);
// Detect baud rate
sp_flush_incoming();
ast2400_serialport_write("\r\n", 2);
programmer_delay(500);
sp_flush_incoming();
ast2400_serialport_write("\r\n", 2);
unsigned char read_buffer[48];
memset(read_buffer, 0, sizeof read_buffer);
if (!serialport_read_nonblock(read_buffer, 2 + 3, 2000, NULL)) {
if (read_buffer[(2 + 3) - 1] == '$') {
msg_pinfo("Detected 115200 baud interface\n");
detected_rate = 1;
}
}
if (!detected_rate) {
if (serialport_shutdown(NULL)) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Unable to close serial port prior to reopening at alternate baud rate!\n");
return 1;
}
sp_fd = sp_openserport(serial_port, 921600);
if (sp_fd == SER_INV_FD) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Unable to reopen serial port at alternate baud rate!\n");
return 1;
}
sp_flush_incoming();
ast2400_serialport_write("\r\n", 2);
programmer_delay(500);
sp_flush_incoming();
ast2400_serialport_write("\r\n", 2);
memset(read_buffer, 0, sizeof read_buffer);
if (!serialport_read_nonblock(read_buffer, 2 + 3, 2000, NULL)) {
if (read_buffer[(2 + 3) - 1] == '$') {
msg_pinfo("Detected 921600 baud interface\n");
detected_rate = 2;
}
}
}
if (!detected_rate) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Device not responding on expected baud rate. Faulty connection / power stability issue?\n");
return 1;
}
}
else {
if (rget_io_perms())
if (rget_io_perms()) {
free(serial_port);
free(ast2400_backdoor_password);
return 1;
}
dev = pcidev_init(bmc_aspeed_ast2400, PCI_BASE_ADDRESS_1);
if (!dev)
if (!dev) {
free(serial_port);
free(ast2400_backdoor_password);
return 1;
}
uintptr_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_1);
if (!io_base_addr)
if (!io_base_addr) {
free(serial_port);
free(ast2400_backdoor_password);
return 1;
}
msg_pinfo("Detected ASPEED MMIO base address: %p.\n", (void*)io_base_addr);
ast2400_device_bar = rphysmap("ASPEED", io_base_addr, ASPEED_MEMMAP_SIZE);
if (ast2400_device_bar == ERROR_PTR)
if (ast2400_device_bar == ERROR_PTR) {
free(serial_port);
free(ast2400_backdoor_password);
return 1;
}
if (register_shutdown(ast2400_shutdown, dev))
if (register_shutdown(ast2400_shutdown, dev)) {
free(serial_port);
free(ast2400_backdoor_password);
return 1;
}
io_base_addr += ASPEED_P2A_OFFSET;
msg_pinfo("ASPEED P2A base address: %p.\n", (void*)io_base_addr);
......@@ -492,6 +581,42 @@ int ast2400_init(void)
ast2400_set_a2b_bridge_scu();
ast2400_write_register_dword(AST2400_SCU_PASSWORD, AST2400_SCU_PROT_KEY);
if (ast2400_serial_backdoor_access) {
if (detected_rate != expected_rate) {
msg_pinfo("Configuring interface baud rate\n");
dword = ast2400_read_register_dword(AST2400_SCU_MISC_2_CTL);
if (expected_rate == 1) {
ast2400_write_register_dword(dword & ~(0x1 << 30), AST2400_SCU_MISC_2_CTL);
}
else if (expected_rate == 2) {
ast2400_write_register_dword(dword | (0x1 << 30), AST2400_SCU_MISC_2_CTL);
}
if (serialport_shutdown(NULL)) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Unable to close serial port prior to reopening at final baud rate!\n");
return 1;
}
if (expected_rate == 1) {
sp_fd = sp_openserport(serial_port, 115200);
}
else if (expected_rate == 2) {
sp_fd = sp_openserport(serial_port, 921600);
}
if (sp_fd == SER_INV_FD) {
free(serial_port);
free(ast2400_backdoor_password);
msg_perr("Unable to reopen serial port at final baud rate!\n");
return 1;
}
}
}
free(serial_port);
free(ast2400_backdoor_password);
dword = ast2400_read_register_dword(AST2400_SCU_MISC_CTL);
ast2400_write_register_dword(dword & ~((0x1 << 24) | (0x2 << 22)), AST2400_SCU_MISC_CTL);
......
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