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.
This commit is contained in:
Michael LeMay 2016-08-04 15:51:37 -07:00
parent 31ad67abd7
commit bde8eb35ae
5 changed files with 36 additions and 12 deletions

View file

@ -140,6 +140,18 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c)
prot_domains_disable_mmio(); 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. * \brief Initialize an MMIO-programmable 16X50 UART.
* \param c_this Structure that will be initialized to represent the device. * \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. * \param dl Divisor setting to configure the baud rate.
*/ */
void void
uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
pci_config_addr_t pci_addr, pci_config_addr_t pci_addr,
uint16_t dl) uint16_t dl)
{ {
uart_16x50_driver_t loc_c_this; 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. * firmware during boot.
*/ */
pci_init(c_this, pci_addr, UART_MMIO_SZ, 0, 0); pci_init(c_this, pci_addr, UART_MMIO_SZ, 0, 0);
SYSCALLS_INIT(uart_16x50_setup);
SYSCALLS_AUTHZ(uart_16x50_setup, *c_this); SYSCALLS_AUTHZ(uart_16x50_setup, *c_this);
SYSCALLS_INIT(uart_16x50_tx);
SYSCALLS_AUTHZ(uart_16x50_tx, *c_this); SYSCALLS_AUTHZ(uart_16x50_tx, *c_this);
prot_domains_copy_dcd(&loc_c_this, c_this); prot_domains_copy_dcd(&loc_c_this, c_this);

View file

@ -35,9 +35,11 @@
typedef pci_driver_t uart_16x50_driver_t; typedef pci_driver_t uart_16x50_driver_t;
void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, void uart_16x50_init(void);
pci_config_addr_t pci_addr,
uint16_t dl); 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); void uart_16x50_tx(uart_16x50_driver_t c_this, uint8_t c);

View file

@ -40,13 +40,23 @@ PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1);
*/ */
#define QUARK_X1000_UART_FBASE 44236800 #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. * \brief Initialize a UART.
* \param dev Device to initialize. * \param dev Device to initialize.
*/ */
void 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; uint16_t dl;
pci_config_addr_t pci_addr; 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. */ /* Divisor setting from section 18.2.2 of Intel Quark SoC X1000 Datasheet. */
dl = QUARK_X1000_UART_FBASE / (16 * baud); dl = QUARK_X1000_UART_FBASE / (16 * baud);
uart_16x50_init(drv, pci_addr, dl); uart_16x50_init_port(drv, pci_addr, dl);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**

View file

@ -38,7 +38,8 @@ typedef enum {
QUARK_X1000_UART_1 QUARK_X1000_UART_1
} quarkX1000_uart_dev_t; } 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); void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c);
#endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */ #endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */

View file

@ -86,10 +86,11 @@ main(void)
quarkX1000_imr_conf(); quarkX1000_imr_conf();
#endif #endif
irq_init(); irq_init();
quarkX1000_uart_init();
/* Initialize UART connected to Galileo Gen1 3.5mm audio-style jack or /* Initialize UART connected to Galileo Gen1 3.5mm audio-style jack or
* Galileo Gen2 FTDI header * Galileo Gen2 FTDI header
*/ */
quarkX1000_uart_init(QUARK_X1000_UART_1, 115200); quarkX1000_uart_init_port(QUARK_X1000_UART_1, 115200);
clock_init(); clock_init();
rtimer_init(); rtimer_init();