mirror of
https://github.com/memtest86plus/memtest86plus
synced 2025-03-12 08:53:02 +03:00
Add support for MMIO UART console (#300)
8/16/32-bit MMIO supported, with configuration options as kernel parameters.
This commit is contained in:
parent
acea409a51
commit
9e3958714b
@ -162,6 +162,12 @@ recognised:
|
||||
* 57600
|
||||
* 115200 (default if not specified or invalid)
|
||||
* 230400
|
||||
* console=*x*,*y*
|
||||
* activate MMIO UART console, where *x* is the MMIO stride (reg. width)
|
||||
* mmio = 8-bit MMIO
|
||||
* mmio16 = 16-bit MMIO
|
||||
* mmio32 = 32-bit MMIO
|
||||
* and *y* is the MMIO address in hex. with `0x` prefix (eg: 0xFEDC9000)
|
||||
|
||||
## Keyboard Selection
|
||||
|
||||
|
47
app/config.c
47
app/config.c
@ -104,11 +104,14 @@ bool pause_at_start = true;
|
||||
power_save_t power_save = POWER_SAVE_HIGH;
|
||||
|
||||
bool enable_tty = false;
|
||||
int tty_params_port = SERIAL_PORT_0x3F8;
|
||||
int tty_params_baud = SERIAL_DEFAULT_BAUDRATE;
|
||||
int tty_update_period = 2; // Update TTY every 2 seconds (default)
|
||||
uintptr_t tty_address = 0x3F8; // Legacy IO or MMIO Address accepted
|
||||
int tty_baud_rate = 115200;
|
||||
int tty_update_period = 2; // Update TTY every 2 seconds (default)
|
||||
|
||||
bool err_banner_redraw = false; // Redraw banner on new errors (if previsouly removed)
|
||||
uint32_t tty_mmio_ref_clk = UART_REF_CLK_MMIO; // Reference clock for MMIO (in Hz)
|
||||
int tty_mmio_stride = 4; // Stride for MMIO (register width in bytes)
|
||||
|
||||
bool err_banner_redraw = false; // Redraw banner on new errors
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Functions
|
||||
@ -123,6 +126,28 @@ static void parse_serial_params(const char *params)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if console is MMIO and grab address and stride
|
||||
uintptr_t mmio_adr = 0;
|
||||
if (strncmp(params, "mmio,0x", 7) == 0) {
|
||||
mmio_adr = hexstr2int(params+7);
|
||||
tty_mmio_stride = 1;
|
||||
} else if (strncmp(params, "mmio16,0x", 9) == 0) {
|
||||
mmio_adr = hexstr2int(params+9);
|
||||
tty_mmio_stride = 2;
|
||||
} else if (strncmp(params, "mmio32,0x", 9) == 0) {
|
||||
mmio_adr = hexstr2int(params+9);
|
||||
tty_mmio_stride = 4;
|
||||
}
|
||||
|
||||
if(strncmp(params, "mmio", 4) == 0) {
|
||||
if (mmio_adr > 0xFFFF) {
|
||||
tty_address = mmio_adr;
|
||||
} else {
|
||||
enable_tty = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// No TTY port passed, use default ttyS0
|
||||
if (strncmp(params, "ttyS", 5) == 0) {
|
||||
return;
|
||||
@ -130,7 +155,7 @@ static void parse_serial_params(const char *params)
|
||||
|
||||
// Configure TTY port or use default
|
||||
if (params[4] >= '0' && params[4] <= '3') {
|
||||
tty_params_port = params[4] - '0';
|
||||
tty_address = serial_io_ports[params[4] - '0'];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -145,27 +170,27 @@ static void parse_serial_params(const char *params)
|
||||
default:
|
||||
return;
|
||||
case '1':
|
||||
tty_params_baud = (params[7] == '9') ? 19200 : 115200;
|
||||
tty_baud_rate = (params[7] == '9') ? 19200 : 115200;
|
||||
tty_update_period = (params[7] == '9') ? 4 : 2;
|
||||
break;
|
||||
case '2':
|
||||
tty_params_baud = 230400;
|
||||
tty_baud_rate = 230400;
|
||||
tty_update_period = 2;
|
||||
break;
|
||||
case '3':
|
||||
tty_params_baud = 38400;
|
||||
tty_baud_rate = 38400;
|
||||
tty_update_period = 4;
|
||||
break;
|
||||
case '5':
|
||||
tty_params_baud = 57600;
|
||||
tty_baud_rate = 57600;
|
||||
tty_update_period = 3;
|
||||
break;
|
||||
case '7':
|
||||
tty_params_baud = 76800;
|
||||
tty_baud_rate = 76800;
|
||||
tty_update_period = 3;
|
||||
break;
|
||||
case '9':
|
||||
tty_params_baud = 9600;
|
||||
tty_baud_rate = 9600;
|
||||
tty_update_period = 5;
|
||||
break;
|
||||
}
|
||||
|
@ -64,9 +64,12 @@ extern bool pause_at_start;
|
||||
|
||||
extern power_save_t power_save;
|
||||
|
||||
extern int tty_params_port;
|
||||
extern int tty_params_baud;
|
||||
extern int tty_update_period;
|
||||
extern uintptr_t tty_address;
|
||||
extern int tty_baud_rate;
|
||||
extern int tty_update_period;
|
||||
|
||||
extern uint32_t tty_mmio_ref_clk;
|
||||
extern int tty_mmio_stride;
|
||||
|
||||
extern bool err_banner_redraw;
|
||||
|
||||
|
16
lib/string.c
16
lib/string.c
@ -9,6 +9,7 @@
|
||||
// By Chris Brady
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
@ -92,3 +93,18 @@ char *itoa(int num, char *str)
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
uint32_t hexstr2int(const char *hexstr) {
|
||||
uint32_t ival = 0;
|
||||
while (*hexstr) {
|
||||
uint8_t b = *hexstr++;
|
||||
|
||||
if (b >= '0' && b <= '9') b = b - '0';
|
||||
else if (b >= 'a' && b <='f') b = b - 'a' + 10;
|
||||
else if (b >= 'A' && b <='F') b = b - 'A' + 10;
|
||||
else return 0;
|
||||
|
||||
ival = (ival << 4) | (b & 0xF);
|
||||
}
|
||||
return ival;
|
||||
}
|
||||
|
@ -96,4 +96,11 @@ char *strstr(const char *haystack, const char *needle);
|
||||
|
||||
char *itoa(int num, char *str);
|
||||
|
||||
/**
|
||||
* Convert a hex string to the corresponding 32-bit uint value.
|
||||
* returns 0 if a non-hex char is found (not 0-9/a-f/A-F).
|
||||
*/
|
||||
|
||||
uint32_t hexstr2int(const char *hexstr);
|
||||
|
||||
#endif // STRING_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2004-2022 Sam Demeulemeester
|
||||
// Copyright (C) 2004-2023 Sam Demeulemeester
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -101,13 +101,21 @@ void tty_init(void)
|
||||
unsigned char lcr;
|
||||
|
||||
console_serial.enable = true;
|
||||
console_serial.is_mmio = false;
|
||||
console_serial.base_addr = tty_address;
|
||||
console_serial.baudrate = tty_baud_rate;
|
||||
console_serial.parity = SERIAL_DEFAULT_PARITY;
|
||||
console_serial.bits = SERIAL_DEFAULT_BITS;
|
||||
console_serial.baudrate = tty_params_baud;
|
||||
console_serial.reg_width = 1;
|
||||
console_serial.refclk = UART_REF_CLK;
|
||||
console_serial.base_addr = serial_base_ports[tty_params_port];
|
||||
|
||||
// UART MMIO Address is usually above TOLUD and never < 1MB
|
||||
if (console_serial.base_addr > 0xFFFF) {
|
||||
console_serial.is_mmio = true;
|
||||
console_serial.reg_width = tty_mmio_stride;
|
||||
console_serial.refclk = tty_mmio_ref_clk;
|
||||
} else {
|
||||
console_serial.is_mmio = false;
|
||||
console_serial.reg_width = 1;
|
||||
console_serial.refclk = UART_REF_CLK_IO;
|
||||
}
|
||||
|
||||
/* read the Divisor Latch */
|
||||
uart_status = serial_read_reg(&console_serial, UART_LCR);
|
||||
@ -130,6 +138,12 @@ void tty_init(void)
|
||||
uart_status = serial_read_reg(&console_serial, UART_RX); /* COM? RBR */
|
||||
serial_write_reg(&console_serial, UART_IER, 0x00); /* Disable all interrupts */
|
||||
|
||||
/* In case of MMIO UART, set up FIFO Reg */
|
||||
if (console_serial.is_mmio) {
|
||||
serial_write_reg(&console_serial, UART_FCR, 0x00);
|
||||
serial_write_reg(&console_serial, UART_FCR, (0xFF) & (UART_FCR_ENA | UART_FCR_THR));
|
||||
}
|
||||
|
||||
tty_clear_screen();
|
||||
tty_disable_cursor();
|
||||
}
|
||||
|
@ -7,10 +7,9 @@
|
||||
* display via Serial/UART.
|
||||
*
|
||||
*//*
|
||||
* Copyright (C) 2004-2022 Sam Demeulemeester.
|
||||
* Copyright (C) 2004-2023 Sam Demeulemeester.
|
||||
*/
|
||||
|
||||
#define SERIAL_DEFAULT_BAUDRATE 115200
|
||||
#define SERIAL_DEFAULT_BITS 8
|
||||
#define SERIAL_DEFAULT_PARITY 0
|
||||
|
||||
@ -19,7 +18,7 @@
|
||||
#define SERIAL_PORT_0x3E8 2
|
||||
#define SERIAL_PORT_0x2E8 3
|
||||
|
||||
static const uint16_t serial_base_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
static const uint16_t serial_io_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
|
||||
struct serial_port {
|
||||
bool enable;
|
||||
@ -49,7 +48,8 @@ struct serial_port {
|
||||
* Definitions for the Base UART Registers
|
||||
*/
|
||||
|
||||
#define UART_REF_CLK 1843200
|
||||
#define UART_REF_CLK_IO 1843200
|
||||
#define UART_REF_CLK_MMIO 48000000
|
||||
|
||||
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
|
||||
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
|
||||
@ -103,6 +103,12 @@ struct serial_port {
|
||||
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
|
||||
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
|
||||
|
||||
/*
|
||||
* Definitions for the FIFO Control Register
|
||||
*/
|
||||
#define UART_FCR_ENA 0x01 /* FIFO Enable */
|
||||
#define UART_FCR_THR 0x20 /* FIFO Threshold */
|
||||
|
||||
/*
|
||||
* Definitions for the Interrupt Enable Register
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user