Add setting baudrate to i8250 and OMAP4 UART drivers

Fixes #445
This commit is contained in:
Ivan Loskutov 2012-12-20 14:49:31 +04:00 committed by Norman Feske
parent 5b8a0e5423
commit f9b82a7b8e
8 changed files with 75 additions and 27 deletions

View File

@ -156,21 +156,10 @@ namespace Genode
{ {
struct Resetdone : Bitfield<0, 1> { }; struct Resetdone : Bitfield<0, 1> { };
}; };
public: void _init(unsigned long const clock, unsigned long const baud_rate)
/**
* 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 disable UART */ /* disable UART */
write<Uart_sysc::Softreset>(1);
while (!read<Uart_syss::Resetdone>()) ;
write<Uart_mdr1::Mode_select>(Uart_mdr1::Mode_select::DISABLED); write<Uart_mdr1::Mode_select>(Uart_mdr1::Mode_select::DISABLED);
/* enable access to 'Uart_fcr' and 'Uart_ier' */ /* enable access to 'Uart_fcr' and 'Uart_ier' */
@ -223,6 +212,23 @@ namespace Genode
write<Uart_mdr1::Mode_select>(Uart_mdr1::Mode_select::UART_16X); write<Uart_mdr1::Mode_select>(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<Uart_sysc::Softreset>(1);
while (!read<Uart_syss::Resetdone>()) ;
_init(clock, baud_rate);
}
/** /**
* Transmit ASCII char 'c' * Transmit ASCII char 'c'
*/ */

View File

@ -137,6 +137,11 @@ class I8250 : public Uart::Driver, public Genode::Irq_handler
{ {
return _inb<TRB>(); return _inb<TRB>();
} }
void baud_rate(int bits_per_second)
{
_init_comport(bits_per_second);
}
}; };
#endif /* _I8250_H_ */ #endif /* _I8250_H_ */

View File

@ -62,7 +62,7 @@ int main(int argc, char **argv)
created[i] = 0; created[i] = 0;
} }
Uart::Driver *create(unsigned index, Uart::Driver *create(unsigned index, unsigned baudrate,
Uart::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
{ {
/* /*
@ -72,14 +72,19 @@ int main(int argc, char **argv)
if (index < 1 || index >= UART_NUM) if (index < 1 || index >= UART_NUM)
throw Uart::Driver_factory::Not_available(); throw Uart::Driver_factory::Not_available();
I8250 *uart = created[index];
enum { BAUD = 115200 }; enum { BAUD = 115200 };
if (baudrate == 0)
{
PDBG("Baudrate is not defined. Use default 115200");
baudrate = BAUD;
}
I8250 *uart = created[index];
if (!uart) { if (!uart) {
uart = new (env()->heap()) uart = new (env()->heap())
I8250(io_port_base(index), irq_number(index), I8250(io_port_base(index), irq_number(index),
BAUD, callback); baudrate, callback);
/* update 'created' table */ /* update 'created' table */
created[index] = uart; created[index] = uart;

View File

@ -48,11 +48,17 @@ int main(int argc, char **argv)
created[i] = 0; created[i] = 0;
} }
Uart::Driver *create(unsigned index, Uart::Driver *create(unsigned index, unsigned baudrate,
Uart::Char_avail_callback &callback) Uart::Char_avail_callback &callback)
{ {
if (index > UARTS_NUM) if (index > UARTS_NUM)
throw Uart::Driver_factory::Not_available(); 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_cfg *cfg = &omap_uart_cfg[index];
Omap_uart *uart = created[index]; Omap_uart *uart = created[index];
@ -62,7 +68,7 @@ int main(int argc, char **argv)
if (!uart) { if (!uart) {
uart = new (env()->heap()) 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 */ /* update 'created' table */
created[index] = uart; created[index] = uart;

View File

@ -96,6 +96,12 @@ class Omap_uart : public Genode::Tl16c750_base, public Uart::Driver, public Geno
bool char_avail() { return read<Uart_lsr::Rx_fifo_empty>(); } bool char_avail() { return read<Uart_lsr::Rx_fifo_empty>(); }
char get_char() { return read<Uart_rhr::Rhr>(); } char get_char() { return read<Uart_rhr::Rhr>(); }
void baud_rate(int bits_per_second)
{
_init(Genode::Board::TL16C750_CLOCK, bits_per_second);
_enable_rx_interrupt();
}
}; };
#endif /* _OMAP_UART_H_ */ #endif /* _OMAP_UART_H_ */

View File

@ -45,9 +45,10 @@ int main(int argc, char **argv)
created[i] = 0; created[i] = 0;
} }
Uart::Driver *create(unsigned index, Uart::Driver *create(unsigned index, unsigned /* baudrate */,
Uart::Char_avail_callback &callback) 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 * We assume the underlying kernel uses UART0 and, therefore, start at
* index 1 for the user-level driver. * index 1 for the user-level driver.

View File

@ -66,11 +66,11 @@ namespace Uart {
* Constructor * Constructor
*/ */
Session_component(Uart::Driver_factory &driver_factory, Session_component(Uart::Driver_factory &driver_factory,
unsigned index) unsigned index, unsigned baudrate)
: :
_io_buffer(Genode::env()->ram_session(), IO_BUFFER_SIZE), _io_buffer(Genode::env()->ram_session(), IO_BUFFER_SIZE),
_driver_factory(driver_factory), _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) 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; unsigned uart_index = 0;
policy.attribute("uart").value(&uart_index); 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()) return new (md_alloc())
Session_component(_driver_factory, uart_index); Session_component(_driver_factory, uart_index, uart_baudrate);
} catch (Xml_node::Nonexistent_attribute) { } catch (Xml_node::Nonexistent_attribute) {
PERR("Missing \"uart\" attribute in policy definition"); PERR("Missing \"uart\" attribute in policy definition");

View File

@ -40,6 +40,14 @@ namespace Uart {
* Read character from UART * Read character from UART
*/ */
virtual char get_char() = 0; 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 * Construct new driver
* *
* \param index index of UART to access * \param index index of UART to access
* \param baudrate baudrate of UART
* \param callback functor called when data becomes available for * \param callback functor called when data becomes available for
* reading * reading
* *
@ -62,7 +71,7 @@ namespace Uart {
* handler. Hence, the operations performed by the registered * handler. Hence, the operations performed by the registered
* function must be properly synchronized. * 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 * Destroy driver