From f9b82a7b8eeff5866c605fead809129eb0951212 Mon Sep 17 00:00:00 2001 From: Ivan Loskutov Date: Thu, 20 Dec 2012 14:49:31 +0400 Subject: [PATCH] Add setting baudrate to i8250 and OMAP4 UART drivers Fixes #445 --- base/include/drivers/uart/tl16c750_base.h | 34 +++++++++++++---------- os/src/drivers/uart/i8250/i8250.h | 5 ++++ os/src/drivers/uart/i8250/main.cc | 13 ++++++--- os/src/drivers/uart/omap4/main.cc | 12 ++++++-- os/src/drivers/uart/omap4/omap_uart.h | 6 ++++ os/src/drivers/uart/pl011/main.cc | 3 +- os/src/drivers/uart/uart_component.h | 18 +++++++++--- os/src/drivers/uart/uart_driver.h | 11 +++++++- 8 files changed, 75 insertions(+), 27 deletions(-) diff --git a/base/include/drivers/uart/tl16c750_base.h b/base/include/drivers/uart/tl16c750_base.h index d0ac05892..3445715d6 100644 --- a/base/include/drivers/uart/tl16c750_base.h +++ b/base/include/drivers/uart/tl16c750_base.h @@ -156,21 +156,10 @@ namespace Genode { struct Resetdone : Bitfield<0, 1> { }; }; - - public: - /** - * Constructor - * - * \param base MMIO base address - * \param clock reference clock - * \param baud_rate targeted baud rate - */ - Tl16c750_base(addr_t const base, unsigned long const clock, - unsigned long const baud_rate) : Mmio(base) + + void _init(unsigned long const clock, unsigned long const baud_rate) { - /* reset and disable UART */ - write(1); - while (!read()) ; + /* disable UART */ write(Uart_mdr1::Mode_select::DISABLED); /* enable access to 'Uart_fcr' and 'Uart_ier' */ @@ -223,6 +212,23 @@ namespace Genode write(Uart_mdr1::Mode_select::UART_16X); } + public: + /** + * Constructor + * + * \param base MMIO base address + * \param clock reference clock + * \param baud_rate targeted baud rate + */ + Tl16c750_base(addr_t const base, unsigned long const clock, + unsigned long const baud_rate) : Mmio(base) + { + /* reset and init UART */ + write(1); + while (!read()) ; + _init(clock, baud_rate); + } + /** * Transmit ASCII char 'c' */ diff --git a/os/src/drivers/uart/i8250/i8250.h b/os/src/drivers/uart/i8250/i8250.h index f7e35209b..8f0038698 100644 --- a/os/src/drivers/uart/i8250/i8250.h +++ b/os/src/drivers/uart/i8250/i8250.h @@ -137,6 +137,11 @@ class I8250 : public Uart::Driver, public Genode::Irq_handler { return _inb(); } + + void baud_rate(int bits_per_second) + { + _init_comport(bits_per_second); + } }; #endif /* _I8250_H_ */ diff --git a/os/src/drivers/uart/i8250/main.cc b/os/src/drivers/uart/i8250/main.cc index 262a5b0d0..d3b01b797 100644 --- a/os/src/drivers/uart/i8250/main.cc +++ b/os/src/drivers/uart/i8250/main.cc @@ -62,7 +62,7 @@ int main(int argc, char **argv) created[i] = 0; } - Uart::Driver *create(unsigned index, + Uart::Driver *create(unsigned index, unsigned baudrate, Uart::Char_avail_callback &callback) { /* @@ -72,14 +72,19 @@ int main(int argc, char **argv) if (index < 1 || index >= UART_NUM) throw Uart::Driver_factory::Not_available(); - I8250 *uart = created[index]; - enum { BAUD = 115200 }; + if (baudrate == 0) + { + PDBG("Baudrate is not defined. Use default 115200"); + baudrate = BAUD; + } + + I8250 *uart = created[index]; if (!uart) { uart = new (env()->heap()) I8250(io_port_base(index), irq_number(index), - BAUD, callback); + baudrate, callback); /* update 'created' table */ created[index] = uart; diff --git a/os/src/drivers/uart/omap4/main.cc b/os/src/drivers/uart/omap4/main.cc index 2be9b3577..2c7060794 100644 --- a/os/src/drivers/uart/omap4/main.cc +++ b/os/src/drivers/uart/omap4/main.cc @@ -48,11 +48,17 @@ int main(int argc, char **argv) created[i] = 0; } - Uart::Driver *create(unsigned index, - Uart::Char_avail_callback &callback) + Uart::Driver *create(unsigned index, unsigned baudrate, + Uart::Char_avail_callback &callback) { if (index > UARTS_NUM) throw Uart::Driver_factory::Not_available(); + + if (baudrate == 0) + { + PDBG("Baudrate is not defined. Use default 115200"); + baudrate = BAUD_115200; + } Omap_uart_cfg *cfg = &omap_uart_cfg[index]; Omap_uart *uart = created[index]; @@ -62,7 +68,7 @@ int main(int argc, char **argv) if (!uart) { uart = new (env()->heap()) - Omap_uart(uart_mmio, cfg->irq_number, BAUD_115200, callback); + Omap_uart(uart_mmio, cfg->irq_number, baudrate, callback); /* update 'created' table */ created[index] = uart; diff --git a/os/src/drivers/uart/omap4/omap_uart.h b/os/src/drivers/uart/omap4/omap_uart.h index 549422c12..b981a5a90 100644 --- a/os/src/drivers/uart/omap4/omap_uart.h +++ b/os/src/drivers/uart/omap4/omap_uart.h @@ -96,6 +96,12 @@ class Omap_uart : public Genode::Tl16c750_base, public Uart::Driver, public Geno bool char_avail() { return read(); } char get_char() { return read(); } + + void baud_rate(int bits_per_second) + { + _init(Genode::Board::TL16C750_CLOCK, bits_per_second); + _enable_rx_interrupt(); + } }; #endif /* _OMAP_UART_H_ */ diff --git a/os/src/drivers/uart/pl011/main.cc b/os/src/drivers/uart/pl011/main.cc index 40793a1f2..a4c27c2c2 100644 --- a/os/src/drivers/uart/pl011/main.cc +++ b/os/src/drivers/uart/pl011/main.cc @@ -45,9 +45,10 @@ int main(int argc, char **argv) created[i] = 0; } - Uart::Driver *create(unsigned index, + Uart::Driver *create(unsigned index, unsigned /* baudrate */, Uart::Char_avail_callback &callback) { + PINF("Setting baudrate is not supported yet. Use default 115200."); /* * We assume the underlying kernel uses UART0 and, therefore, start at * index 1 for the user-level driver. diff --git a/os/src/drivers/uart/uart_component.h b/os/src/drivers/uart/uart_component.h index d309b46f8..80d6f8bff 100644 --- a/os/src/drivers/uart/uart_component.h +++ b/os/src/drivers/uart/uart_component.h @@ -66,11 +66,11 @@ namespace Uart { * Constructor */ Session_component(Uart::Driver_factory &driver_factory, - unsigned index) + unsigned index, unsigned baudrate) : _io_buffer(Genode::env()->ram_session(), IO_BUFFER_SIZE), _driver_factory(driver_factory), - _driver(*_driver_factory.create(index, _char_avail_callback)) + _driver(*_driver_factory.create(index, baudrate, _char_avail_callback)) { } @@ -80,7 +80,7 @@ namespace Uart { void baud_rate(Genode::size_t bits_per_second) { - PWRN("Setting the baud rate is not supported."); + _driver.baud_rate(bits_per_second); } @@ -160,8 +160,18 @@ namespace Uart { unsigned uart_index = 0; policy.attribute("uart").value(&uart_index); + + unsigned uart_baudrate = 0; + try { + policy.attribute("baudrate").value(&uart_baudrate); + } catch (Xml_node::Nonexistent_attribute) { + PDBG("Missing \"baudrate\" attribute in policy definition"); + } + + PDBG("UART%d %d", uart_index, uart_baudrate); + return new (md_alloc()) - Session_component(_driver_factory, uart_index); + Session_component(_driver_factory, uart_index, uart_baudrate); } catch (Xml_node::Nonexistent_attribute) { PERR("Missing \"uart\" attribute in policy definition"); diff --git a/os/src/drivers/uart/uart_driver.h b/os/src/drivers/uart/uart_driver.h index 674b9bd15..975eaf936 100644 --- a/os/src/drivers/uart/uart_driver.h +++ b/os/src/drivers/uart/uart_driver.h @@ -40,6 +40,14 @@ namespace Uart { * Read character from UART */ virtual char get_char() = 0; + + /** + * Set baud rate for terminal + */ + virtual void baud_rate(int /*bits_per_second*/) + { + PINF("Setting baudrate is not supported yet. Use default 115200."); + } }; /** @@ -53,6 +61,7 @@ namespace Uart { * Construct new driver * * \param index index of UART to access + * \param baudrate baudrate of UART * \param callback functor called when data becomes available for * reading * @@ -62,7 +71,7 @@ namespace Uart { * handler. Hence, the operations performed by the registered * function must be properly synchronized. */ - virtual Driver *create(unsigned index, Char_avail_callback &callback) = 0; + virtual Driver *create(unsigned index, unsigned baudrate, Char_avail_callback &callback) = 0; /** * Destroy driver