[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/3 v3] xen: Add support for initializing 16550 UART using ACPI
Hi, (answering to both Konrad and Bhupinder ...) On 24/11/17 13:50, Konrad Rzeszutek Wilk wrote: > On Fri, Nov 24, 2017 at 05:09:11PM +0530, Bhupinder Thakur wrote: >> Currently, Xen supports only DT based initialization of 16550 UART. >> This patch adds support for initializing 16550 UART using ACPI SPCR table. > > Can you provide the link to the spec you are using. I am wondering > if I am looking at some older one. > >> >> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@xxxxxxxxxx> >> --- >> Changes since v2: >> - renamed UART_MAX_REG to UART_NUM_REGS >> - aligned some assignment statements >> - some coding style changes >> >> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> >> CC: George Dunlap <George.Dunlap@xxxxxxxxxxxxx> >> CC: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> >> CC: Jan Beulich <jbeulich@xxxxxxxx> >> CC: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> >> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx> >> CC: Tim Deegan <tim@xxxxxxx> >> CC: Wei Liu <wei.liu2@xxxxxxxxxx> >> CC: Julien Grall <julien.grall@xxxxxxx> >> >> xen/drivers/char/ns16550.c | 67 >> +++++++++++++++++++++++++++++++++++++++++++++ >> xen/include/xen/8250-uart.h | 1 + >> 2 files changed, 68 insertions(+) >> >> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c >> index c5dfc1e..af4712f 100644 >> --- a/xen/drivers/char/ns16550.c >> +++ b/xen/drivers/char/ns16550.c >> @@ -29,6 +29,10 @@ >> #ifdef CONFIG_X86 >> #include <asm/fixmap.h> >> #endif >> +#ifdef CONFIG_ACPI >> +#include <xen/acpi.h> >> +#endif >> + >> >> /* >> * Configure serial port with a string: >> @@ -1565,6 +1569,69 @@ DT_DEVICE_START(ns16550, "NS16550 UART", >> DEVICE_SERIAL) >> DT_DEVICE_END >> >> #endif /* HAS_DEVICE_TREE */ >> + >> +#if defined(CONFIG_ACPI) && defined(CONFIG_ARM) > > I would remove the CONFIG_ARM as the spec says it is possible to use > this on ARM _and_ x86 hardware. I was thinking the same. Originally the SPCR was x86 only. > But I guess you can't as ACPI_DEVICE_START is defined to be only > on ARM? We could move the #ifdef there. >> + >> +static int ns16550_init_acpi(struct ns16550 **puart) >> +{ >> + struct acpi_table_spcr *spcr; >> + int status; > > hmm, not acpi_status ? >> + struct ns16550 *uart = &ns16550_com[0]; >> + >> + ns16550_init_common(uart); > > I would move this below the error check below.. >> + >> + status = acpi_get_table(ACPI_SIG_SPCR, 0, >> + (struct acpi_table_header **)&spcr); >> + >> + if ( ACPI_FAILURE(status) ) >> + { >> + printk("ns16550: Failed to get SPCR table\n"); >> + return -EINVAL; >> + } >> + >> + uart->baud = BAUD_AUTO; >> + uart->data_bits = 8; > > Are those two assumed from the ACPI spec? I can't find a field for the number of data bits, so I assume it's indeed fixed to 8. > Wait a minute. The > https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx > has Baud Rate at Offset 58? Yes, I see the same. We should use that table. Just wondering what the Moonshot gives you in this table? Is it "7"? >> + uart->parity = spcr->parity; The Spec is a bit weird there, since it only specifies 0 as "No parity", every other value is reserved. Shall we check and bail out if !0 with an error message? >> + uart->stop_bits = spcr->stop_bits; Again if you want to be strict you would need to check against the specified values, which means only "1" is valid. >> + uart->io_base = spcr->serial_port.address; I think this needs to be checked against the address type, because we assume 0 (MMIO) here for ARM, and I guess 1 (PIO) for x86? If I understand the code correctly, we have some wild heuristics to guess the address type at the moment? #ifdef CONFIG_HAS_IOPORTS /* I/O ports are distinguished by their size (16 bits). */ if ( uart->io_base >= 0x10000 ) #endif I wonder if we should store this explicitly, since ACPI (and DT as well) give us this information. >> + uart->irq = spcr->interrupt; > > You need to check if the 'Interrupt Type' field is set before > you look at this? > >> + uart->reg_width = spcr->serial_port.bit_width / 8; I am a bit confused about the SPCR field here. Shouldn't this be encoded in the "Access Size" field instead? "Register Bit Width: The size in bits of the given register. When addressing a data structure, this field must be zero." But I guess the Moonshot gives you 4 in here, but something else in "Access Size"? Cheers, Andre. >> + uart->reg_shift = 0; >> + uart->io_size = UART_NUM_REGS << uart->reg_shift; >> + >> + irq_set_type(spcr->interrupt, spcr->interrupt_type); > > Um, the spec has a whole bunch of other bits set in 'interrupt_type'? > >> + >> + *puart = uart; >> + >> + return 0; >> +} >> + >> +static int __init ns16550_acpi_uart_init(const void *data) >> +{ >> + int ret; >> + struct ns16550 *uart; >> + >> + ret = ns16550_init_acpi(&uart); >> + if ( ret ) >> + return ret; >> + >> + ns16550_vuart_init(uart); >> + >> + ns16550_register_uart(uart); >> + >> + return 0; >> +} >> + >> +ACPI_DEVICE_START(ns16550c, "16550 COMPAT UART", DEVICE_SERIAL) >> + .class_type = ACPI_DBG2_16550_COMPATIBLE, >> + .init = ns16550_acpi_uart_init, >> +ACPI_DEVICE_END >> +ACPI_DEVICE_START(ns16550s, "16550 SUBSET UART", DEVICE_SERIAL) >> + .class_type = ACPI_DBG2_16550_SUBSET, >> + .init = ns16550_acpi_uart_init, >> +ACPI_DEVICE_END >> + >> +#endif >> /* >> * Local variables: >> * mode: C >> diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h >> index 5c3bac3..849a5c0 100644 >> --- a/xen/include/xen/8250-uart.h >> +++ b/xen/include/xen/8250-uart.h >> @@ -35,6 +35,7 @@ >> #define UART_USR 0x1f /* Status register (DW) */ >> #define UART_DLL 0x00 /* divisor latch (ls) (DLAB=1) */ >> #define UART_DLM 0x01 /* divisor latch (ms) (DLAB=1) */ >> +#define UART_NUM_REGS (UART_USR + 1) >> >> /* Interrupt Enable Register */ >> #define UART_IER_ERDAI 0x01 /* rx data recv'd */ >> -- >> 2.7.4 >> >> _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |