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

@ -157,20 +157,9 @@ 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<Uart_sysc::Softreset>(1);
while (!read<Uart_syss::Resetdone>()) ;
/* disable UART */
write<Uart_mdr1::Mode_select>(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_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'
*/

View File

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

View File

@ -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;

View File

@ -48,12 +48,18 @@ 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)
{
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;

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>(); }
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_ */

View File

@ -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.

View File

@ -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");

View File

@ -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