From 31ad67abd71bd044ab80a66534f3995fd10f3edc Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 3 Aug 2016 07:58:51 -0700 Subject: [PATCH 1/2] x86: Support configurable UART baud rate This patch extends the Intel Quark X1000 SoC UART initialization API to accept a numeric baud rate specification. --- cpu/x86/drivers/quarkX1000/uart.c | 13 ++++++++----- cpu/x86/drivers/quarkX1000/uart.h | 2 +- platform/galileo/contiki-main.c | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/cpu/x86/drivers/quarkX1000/uart.c b/cpu/x86/drivers/quarkX1000/uart.c index 341e31cf7..c78a04ca1 100644 --- a/cpu/x86/drivers/quarkX1000/uart.c +++ b/cpu/x86/drivers/quarkX1000/uart.c @@ -35,10 +35,10 @@ PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart0); PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1); -/* Divisor setting for 115200 baud from section 18.2.2 of Intel Quark SoC - * X1000 Datasheet. +/* UART base frequency from section 18.2.2 of Intel Quark SoC X1000 + * Datasheet. */ -#define QUARK_X1000_UART_DL_115200 24 +#define QUARK_X1000_UART_FBASE 44236800 /*---------------------------------------------------------------------------*/ /** @@ -46,8 +46,9 @@ PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1); * \param dev Device to initialize. */ void -quarkX1000_uart_init(quarkX1000_uart_dev_t dev) +quarkX1000_uart_init(quarkX1000_uart_dev_t dev, unsigned baud) { + uint16_t dl; pci_config_addr_t pci_addr; uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *drv; @@ -67,7 +68,9 @@ quarkX1000_uart_init(quarkX1000_uart_dev_t dev) drv = &quarkX1000_uart1; PROT_DOMAINS_INIT_ID(quarkX1000_uart1); } - uart_16x50_init(drv, pci_addr, QUARK_X1000_UART_DL_115200); + /* Divisor setting from section 18.2.2 of Intel Quark SoC X1000 Datasheet. */ + dl = QUARK_X1000_UART_FBASE / (16 * baud); + uart_16x50_init(drv, pci_addr, dl); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/x86/drivers/quarkX1000/uart.h b/cpu/x86/drivers/quarkX1000/uart.h index 8b545d8cd..2eec5c103 100644 --- a/cpu/x86/drivers/quarkX1000/uart.h +++ b/cpu/x86/drivers/quarkX1000/uart.h @@ -38,7 +38,7 @@ typedef enum { QUARK_X1000_UART_1 } quarkX1000_uart_dev_t; -void quarkX1000_uart_init(quarkX1000_uart_dev_t dev); +void quarkX1000_uart_init(quarkX1000_uart_dev_t dev, unsigned baud); void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c); #endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */ diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index ccc1f519f..3ac787af7 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -86,8 +86,10 @@ main(void) quarkX1000_imr_conf(); #endif irq_init(); - /* Initialize UART connected to Galileo Gen2 FTDI header */ - quarkX1000_uart_init(QUARK_X1000_UART_1); + /* Initialize UART connected to Galileo Gen1 3.5mm audio-style jack or + * Galileo Gen2 FTDI header + */ + quarkX1000_uart_init(QUARK_X1000_UART_1, 115200); clock_init(); rtimer_init(); From bde8eb35ae360f4e952acf3c26a4c4606e02df11 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Thu, 4 Aug 2016 15:51:37 -0700 Subject: [PATCH 2/2] x86, galileo: Fix UART system call authorization initialization This patch fixes UART system call authorization initialization (when protection domain support is enabled) to only initialize the system call entrypoint and authorization data structures once, prior to per-port setup. Previously, if two UARTs were configured, the setup procedure for the second UART would erase the system call authorization for the first (console) UART, resulting in a crash upon the next attempt to perform console output. --- cpu/x86/drivers/legacy_pc/uart-16x50.c | 20 +++++++++++++++----- cpu/x86/drivers/legacy_pc/uart-16x50.h | 8 +++++--- cpu/x86/drivers/quarkX1000/uart.c | 14 ++++++++++++-- cpu/x86/drivers/quarkX1000/uart.h | 3 ++- platform/galileo/contiki-main.c | 3 ++- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.c b/cpu/x86/drivers/legacy_pc/uart-16x50.c index d17e61498..7d9493c74 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.c +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.c @@ -140,6 +140,18 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c) prot_domains_disable_mmio(); } /*---------------------------------------------------------------------------*/ +/** + * \brief Perform common initialization that must precede per-port + * initialization. + */ +/*---------------------------------------------------------------------------*/ +void +uart_16x50_init(void) +{ + SYSCALLS_INIT(uart_16x50_setup); + SYSCALLS_INIT(uart_16x50_tx); +} +/*---------------------------------------------------------------------------*/ /** * \brief Initialize an MMIO-programmable 16X50 UART. * \param c_this Structure that will be initialized to represent the device. @@ -147,9 +159,9 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c) * \param dl Divisor setting to configure the baud rate. */ void -uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, - pci_config_addr_t pci_addr, - uint16_t dl) +uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + uint16_t dl) { uart_16x50_driver_t loc_c_this; @@ -157,9 +169,7 @@ uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, * firmware during boot. */ pci_init(c_this, pci_addr, UART_MMIO_SZ, 0, 0); - SYSCALLS_INIT(uart_16x50_setup); SYSCALLS_AUTHZ(uart_16x50_setup, *c_this); - SYSCALLS_INIT(uart_16x50_tx); SYSCALLS_AUTHZ(uart_16x50_tx, *c_this); prot_domains_copy_dcd(&loc_c_this, c_this); diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.h b/cpu/x86/drivers/legacy_pc/uart-16x50.h index 4a038b948..8a3ddad49 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.h +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.h @@ -35,9 +35,11 @@ typedef pci_driver_t uart_16x50_driver_t; -void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, - pci_config_addr_t pci_addr, - uint16_t dl); +void uart_16x50_init(void); + +void uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + uint16_t dl); void uart_16x50_tx(uart_16x50_driver_t c_this, uint8_t c); diff --git a/cpu/x86/drivers/quarkX1000/uart.c b/cpu/x86/drivers/quarkX1000/uart.c index c78a04ca1..2044e42e8 100644 --- a/cpu/x86/drivers/quarkX1000/uart.c +++ b/cpu/x86/drivers/quarkX1000/uart.c @@ -40,13 +40,23 @@ PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1); */ #define QUARK_X1000_UART_FBASE 44236800 +/*---------------------------------------------------------------------------*/ +/** + * \brief Perform common initialization that must precede per-port + * initialization. + */ +void +quarkX1000_uart_init(void) +{ + uart_16x50_init(); +} /*---------------------------------------------------------------------------*/ /** * \brief Initialize a UART. * \param dev Device to initialize. */ void -quarkX1000_uart_init(quarkX1000_uart_dev_t dev, unsigned baud) +quarkX1000_uart_init_port(quarkX1000_uart_dev_t dev, unsigned baud) { uint16_t dl; pci_config_addr_t pci_addr; @@ -70,7 +80,7 @@ quarkX1000_uart_init(quarkX1000_uart_dev_t dev, unsigned baud) } /* Divisor setting from section 18.2.2 of Intel Quark SoC X1000 Datasheet. */ dl = QUARK_X1000_UART_FBASE / (16 * baud); - uart_16x50_init(drv, pci_addr, dl); + uart_16x50_init_port(drv, pci_addr, dl); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/x86/drivers/quarkX1000/uart.h b/cpu/x86/drivers/quarkX1000/uart.h index 2eec5c103..6b1312ed8 100644 --- a/cpu/x86/drivers/quarkX1000/uart.h +++ b/cpu/x86/drivers/quarkX1000/uart.h @@ -38,7 +38,8 @@ typedef enum { QUARK_X1000_UART_1 } quarkX1000_uart_dev_t; -void quarkX1000_uart_init(quarkX1000_uart_dev_t dev, unsigned baud); +void quarkX1000_uart_init(void); +void quarkX1000_uart_init_port(quarkX1000_uart_dev_t dev, unsigned baud); void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c); #endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */ diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index 3ac787af7..5e95c4902 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -86,10 +86,11 @@ main(void) quarkX1000_imr_conf(); #endif irq_init(); + quarkX1000_uart_init(); /* Initialize UART connected to Galileo Gen1 3.5mm audio-style jack or * Galileo Gen2 FTDI header */ - quarkX1000_uart_init(QUARK_X1000_UART_1, 115200); + quarkX1000_uart_init_port(QUARK_X1000_UART_1, 115200); clock_init(); rtimer_init();