mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
parent
f4e0230dde
commit
5b8a0e5423
@ -33,8 +33,8 @@ namespace Genode
|
||||
* \param baud_rate targeted transfer baud-rate
|
||||
*/
|
||||
Serial_log(unsigned const baud_rate) :
|
||||
Tl16c750_base(Board::TL16C750_3_MMIO_BASE,
|
||||
Board::TL16C750_3_CLOCK, baud_rate)
|
||||
Tl16c750_base(Board::TL16C750_MMIO_BASE,
|
||||
Board::TL16C750_CLOCK, baud_rate)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* core UART */
|
||||
{ Board::TL16C750_3_MMIO_BASE, Board::TL16C750_3_MMIO_SIZE }
|
||||
{ Board::TL16C750_3_MMIO_BASE, Board::TL16C750_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
@ -27,120 +27,137 @@ namespace Genode
|
||||
*/
|
||||
class Tl16c750_base : public Mmio
|
||||
{
|
||||
/**
|
||||
* Least significant divisor part
|
||||
*/
|
||||
struct Uart_dll : Register<0x0, 32>
|
||||
{
|
||||
struct Clock_lsb : Bitfield<0, 8> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmit holding register
|
||||
*/
|
||||
struct Uart_thr : Register<0x0, 32>
|
||||
{
|
||||
struct Thr : Bitfield<0, 8> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Most significant divisor part
|
||||
*/
|
||||
struct Uart_dlh : Register<0x4, 32>
|
||||
{
|
||||
struct Clock_msb : Bitfield<0, 6> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Interrupt enable register
|
||||
*/
|
||||
struct Uart_ier : Register<0x4, 32>
|
||||
{
|
||||
struct Rhr_it : Bitfield<0, 1> { };
|
||||
struct Thr_it : Bitfield<1, 1> { };
|
||||
struct Line_sts_it : Bitfield<2, 1> { };
|
||||
struct Modem_sts_it : Bitfield<3, 1> { };
|
||||
struct Sleep_mode : Bitfield<4, 1> { };
|
||||
struct Xoff_it : Bitfield<5, 1> { };
|
||||
struct Rts_it : Bitfield<6, 1> { };
|
||||
struct Cts_it : Bitfield<7, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* FIFO control register
|
||||
*/
|
||||
struct Uart_fcr : Register<0x8, 32>
|
||||
{
|
||||
struct Fifo_enable : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Line control register
|
||||
*/
|
||||
struct Uart_lcr : Register<0xc, 32>
|
||||
{
|
||||
struct Char_length : Bitfield<0, 2>
|
||||
protected:
|
||||
/**
|
||||
* Least significant divisor part
|
||||
*/
|
||||
struct Uart_dll : Register<0x0, 32>
|
||||
{
|
||||
enum { _8_BIT = 3 };
|
||||
struct Clock_lsb : Bitfield<0, 8> { };
|
||||
};
|
||||
struct Nb_stop : Bitfield<2, 1>
|
||||
|
||||
/**
|
||||
* Transmit holding register
|
||||
*/
|
||||
struct Uart_thr : Register<0x0, 32>
|
||||
{
|
||||
enum { _1_STOP_BIT = 0 };
|
||||
struct Thr : Bitfield<0, 8> { };
|
||||
};
|
||||
struct Parity_en : Bitfield<3, 1> { };
|
||||
struct Break_en : Bitfield<6, 1> { };
|
||||
struct Div_en : Bitfield<7, 1> { };
|
||||
struct Reg_mode : Bitfield<0, 8>
|
||||
|
||||
/**
|
||||
* Receiver holding register
|
||||
*/
|
||||
struct Uart_rhr : Register<0x0, 32>
|
||||
{
|
||||
enum { OPERATIONAL = 0, CONFIG_A = 0x80, CONFIG_B = 0xbf };
|
||||
struct Rhr : Bitfield<0, 8> { };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Modem control register
|
||||
*/
|
||||
struct Uart_mcr : Register<0x10, 32>
|
||||
{
|
||||
struct Tcr_tlr : Bitfield<6, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Line status register
|
||||
*/
|
||||
struct Uart_lsr : Register<0x14, 32>
|
||||
{
|
||||
struct Tx_fifo_empty : Bitfield<5, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Mode definition register 1
|
||||
*/
|
||||
struct Uart_mdr1 : Register<0x20, 32>
|
||||
{
|
||||
struct Mode_select : Bitfield<0, 3>
|
||||
/**
|
||||
* Most significant divisor part
|
||||
*/
|
||||
struct Uart_dlh : Register<0x4, 32>
|
||||
{
|
||||
enum { UART_16X = 0, DISABLED = 7 };
|
||||
struct Clock_msb : Bitfield<0, 6> { };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* System control register
|
||||
*/
|
||||
struct Uart_sysc : Register<0x54, 32>
|
||||
{
|
||||
struct Softreset : Bitfield<1, 1> { };
|
||||
};
|
||||
/**
|
||||
* Interrupt enable register
|
||||
*/
|
||||
struct Uart_ier : Register<0x4, 32>
|
||||
{
|
||||
struct Rhr_it : Bitfield<0, 1> { };
|
||||
struct Thr_it : Bitfield<1, 1> { };
|
||||
struct Line_sts_it : Bitfield<2, 1> { };
|
||||
struct Modem_sts_it : Bitfield<3, 1> { };
|
||||
struct Sleep_mode : Bitfield<4, 1> { };
|
||||
struct Xoff_it : Bitfield<5, 1> { };
|
||||
struct Rts_it : Bitfield<6, 1> { };
|
||||
struct Cts_it : Bitfield<7, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* System status register
|
||||
*/
|
||||
struct Uart_syss : Register<0x58, 32>
|
||||
{
|
||||
struct Resetdone : Bitfield<0, 1> { };
|
||||
};
|
||||
/**
|
||||
* Interrupt identification register
|
||||
*/
|
||||
struct Uart_iir : Register<0x8, 32>
|
||||
{
|
||||
struct It_pending : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* FIFO control register
|
||||
*/
|
||||
struct Uart_fcr : Register<0x8, 32>
|
||||
{
|
||||
struct Fifo_enable : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Line control register
|
||||
*/
|
||||
struct Uart_lcr : Register<0xc, 32>
|
||||
{
|
||||
struct Char_length : Bitfield<0, 2>
|
||||
{
|
||||
enum { _8_BIT = 3 };
|
||||
};
|
||||
struct Nb_stop : Bitfield<2, 1>
|
||||
{
|
||||
enum { _1_STOP_BIT = 0 };
|
||||
};
|
||||
struct Parity_en : Bitfield<3, 1> { };
|
||||
struct Break_en : Bitfield<6, 1> { };
|
||||
struct Div_en : Bitfield<7, 1> { };
|
||||
struct Reg_mode : Bitfield<0, 8>
|
||||
{
|
||||
enum { OPERATIONAL = 0, CONFIG_A = 0x80, CONFIG_B = 0xbf };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Modem control register
|
||||
*/
|
||||
struct Uart_mcr : Register<0x10, 32>
|
||||
{
|
||||
struct Tcr_tlr : Bitfield<6, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Line status register
|
||||
*/
|
||||
struct Uart_lsr : Register<0x14, 32>
|
||||
{
|
||||
struct Rx_fifo_empty : Bitfield<0, 1> { };
|
||||
struct Tx_fifo_empty : Bitfield<5, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Mode definition register 1
|
||||
*/
|
||||
struct Uart_mdr1 : Register<0x20, 32>
|
||||
{
|
||||
struct Mode_select : Bitfield<0, 3>
|
||||
{
|
||||
enum { UART_16X = 0, DISABLED = 7 };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* System control register
|
||||
*/
|
||||
struct Uart_sysc : Register<0x54, 32>
|
||||
{
|
||||
struct Softreset : Bitfield<1, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* System status register
|
||||
*/
|
||||
struct Uart_syss : Register<0x58, 32>
|
||||
{
|
||||
struct Resetdone : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -36,11 +36,19 @@ namespace Genode
|
||||
/* clocks */
|
||||
MPU_DPLL_CLOCK = 200*1000*1000,
|
||||
|
||||
/* UART */
|
||||
TL16C750_3_MMIO_BASE = 0x48020000,
|
||||
TL16C750_3_MMIO_SIZE = 0x00002000,
|
||||
TL16C750_3_CLOCK = 48*1000*1000,
|
||||
/* UARTs */
|
||||
TL16C750_1_MMIO_BASE = MMIO_0_BASE + 0x6a000,
|
||||
TL16C750_2_MMIO_BASE = MMIO_0_BASE + 0x6c000,
|
||||
TL16C750_3_MMIO_BASE = MMIO_0_BASE + 0x20000,
|
||||
TL16C750_4_MMIO_BASE = MMIO_0_BASE + 0x6e000,
|
||||
|
||||
TL16C750_MMIO_SIZE = 0x2000,
|
||||
TL16C750_CLOCK = 48*1000*1000,
|
||||
|
||||
TL16C750_1_IRQ = 72,
|
||||
TL16C750_2_IRQ = 73,
|
||||
TL16C750_3_IRQ = 74,
|
||||
TL16C750_4_IRQ = 70,
|
||||
|
||||
/* CPU */
|
||||
CORTEX_A9_PRIVATE_MEM_BASE = 0x48240000,
|
||||
|
39
os/include/platform/panda/uart_defs.h
Normal file
39
os/include/platform/panda/uart_defs.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* \brief OMAP4 UART definitions
|
||||
* \author Ivan Loskutov <ivan.loskutov@ksyslabs.org>
|
||||
* \date 2012-11-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Ksys Labs LLC
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__PANDABOARD__UART_DEFS_H_
|
||||
#define _INCLUDE__PLATFORM__PANDABOARD__UART_DEFS_H_
|
||||
|
||||
#include <platform/panda/drivers/board.h>
|
||||
|
||||
enum {
|
||||
/** Number of UARTs */
|
||||
UARTS_NUM = 4,
|
||||
|
||||
BAUD_115200 = 26,
|
||||
};
|
||||
|
||||
|
||||
static struct Omap_uart_cfg {
|
||||
Genode::addr_t mmio_base;
|
||||
Genode::size_t mmio_size;
|
||||
int irq_number;
|
||||
} omap_uart_cfg[UARTS_NUM] = {
|
||||
{ Genode::Board::TL16C750_1_MMIO_BASE, Genode::Board::TL16C750_MMIO_SIZE, Genode::Board::TL16C750_1_IRQ + 32 },
|
||||
{ Genode::Board::TL16C750_2_MMIO_BASE, Genode::Board::TL16C750_MMIO_SIZE, Genode::Board::TL16C750_2_IRQ + 32 },
|
||||
{ Genode::Board::TL16C750_3_MMIO_BASE, Genode::Board::TL16C750_MMIO_SIZE, Genode::Board::TL16C750_3_IRQ + 32 },
|
||||
{ Genode::Board::TL16C750_4_MMIO_BASE, Genode::Board::TL16C750_MMIO_SIZE, Genode::Board::TL16C750_4_IRQ + 32 },
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__PANDABOARD__UART_DEFS_H_ */
|
72
os/run/panda_uart4_echo.run
Normal file
72
os/run/panda_uart4_echo.run
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# Build
|
||||
#
|
||||
assert_spec foc
|
||||
assert_spec platform_panda
|
||||
|
||||
# generic components
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer drivers/uart
|
||||
test/terminal_echo
|
||||
}
|
||||
|
||||
build $build_components
|
||||
create_boot_directory
|
||||
|
||||
|
||||
#
|
||||
# Config
|
||||
#
|
||||
|
||||
set config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
<start name="uart_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Terminal"/></provides>
|
||||
<config>
|
||||
<policy label="test-terminal_echo" uart="3"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="test-terminal_echo">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init
|
||||
timer uart_drv test-terminal_echo
|
||||
}
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
88
os/src/drivers/uart/omap4/main.cc
Normal file
88
os/src/drivers/uart/omap4/main.cc
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* \brief Driver for OMAP4 UARTs
|
||||
* \author Ivan Loskutov <ivan.loskutov@ksyslabs.org>
|
||||
* \date 2012-11-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Ksys Labs LLC
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <os/config.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
|
||||
#include <uart_defs.h>
|
||||
|
||||
/* local includes */
|
||||
#include "omap_uart.h"
|
||||
#include "uart_component.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
PDBG("--- OMAP4 UART driver started ---\n");
|
||||
|
||||
/**
|
||||
* Factory used by 'Terminal::Root' at session creation/destruction time
|
||||
*/
|
||||
struct Omap_uart_driver_factory : Uart::Driver_factory
|
||||
{
|
||||
Omap_uart *created[UARTS_NUM];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Omap_uart_driver_factory()
|
||||
{
|
||||
for (unsigned i = 0; i < UARTS_NUM; i++)
|
||||
created[i] = 0;
|
||||
}
|
||||
|
||||
Uart::Driver *create(unsigned index,
|
||||
Uart::Char_avail_callback &callback)
|
||||
{
|
||||
if (index > UARTS_NUM)
|
||||
throw Uart::Driver_factory::Not_available();
|
||||
|
||||
Omap_uart_cfg *cfg = &omap_uart_cfg[index];
|
||||
Omap_uart *uart = created[index];
|
||||
|
||||
Genode::Attached_io_mem_dataspace *uart_mmio = new (env()->heap())
|
||||
Genode::Attached_io_mem_dataspace(cfg->mmio_base, cfg->mmio_size);
|
||||
|
||||
if (!uart) {
|
||||
uart = new (env()->heap())
|
||||
Omap_uart(uart_mmio, cfg->irq_number, BAUD_115200, callback);
|
||||
|
||||
/* update 'created' table */
|
||||
created[index] = uart;
|
||||
}
|
||||
|
||||
return uart;
|
||||
}
|
||||
|
||||
void destroy(Uart::Driver *driver) { /* TODO */ }
|
||||
|
||||
} driver_factory;
|
||||
|
||||
enum { STACK_SIZE = 0x2000 };
|
||||
static Cap_connection cap;
|
||||
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "uart_ep");
|
||||
|
||||
static Uart::Root uart_root(&ep, env()->heap(), driver_factory);
|
||||
env()->parent()->announce(ep.manage(&uart_root));
|
||||
|
||||
sleep_forever();
|
||||
return 0;
|
||||
}
|
101
os/src/drivers/uart/omap4/omap_uart.h
Normal file
101
os/src/drivers/uart/omap4/omap_uart.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* \brief Driver for OMAP4 UARTs
|
||||
* \author Ivan Loskutov <ivan.loskutov@ksyslabs.org>
|
||||
* \date 2012-11-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Ksys Labs LLC
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _OMAP_UART_H_
|
||||
#define _OMAP_UART_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/irq_activation.h>
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
|
||||
#include <drivers/uart/tl16c750_base.h>
|
||||
|
||||
/* local includes */
|
||||
#include "uart_driver.h"
|
||||
|
||||
class Omap_uart : public Genode::Tl16c750_base, public Uart::Driver, public Genode::Irq_handler
|
||||
{
|
||||
private:
|
||||
Genode::Attached_io_mem_dataspace _uart_mmio;
|
||||
|
||||
Uart::Char_avail_callback &_char_avail_callback;
|
||||
|
||||
enum { IRQ_STACK_SIZE = 4096 };
|
||||
Genode::Irq_activation _irq_activation;
|
||||
|
||||
void _enable_rx_interrupt()
|
||||
{
|
||||
/* enable access to 'Uart_fcr' and 'Uart_ier' */
|
||||
write<Uart_lcr::Reg_mode>(Uart_lcr::Reg_mode::OPERATIONAL);
|
||||
|
||||
/* enable rx interrupt, disable other interrupts and sleep mode */
|
||||
write<Uart_ier>(Uart_ier::Rhr_it::bits(1)
|
||||
| Uart_ier::Thr_it::bits(0)
|
||||
| Uart_ier::Line_sts_it::bits(0)
|
||||
| Uart_ier::Modem_sts_it::bits(0)
|
||||
| Uart_ier::Sleep_mode::bits(0)
|
||||
| Uart_ier::Xoff_it::bits(0)
|
||||
| Uart_ier::Rts_it::bits(0)
|
||||
| Uart_ier::Cts_it::bits(0));
|
||||
/*
|
||||
* Configure protocol formatting and thereby return to
|
||||
* operational mode.
|
||||
*/
|
||||
write<Uart_lcr>(Uart_lcr::Char_length::bits(Uart_lcr::Char_length::_8_BIT)
|
||||
| Uart_lcr::Nb_stop::bits(Uart_lcr::Nb_stop::_1_STOP_BIT)
|
||||
| Uart_lcr::Parity_en::bits(0)
|
||||
| Uart_lcr::Break_en::bits(0)
|
||||
| Uart_lcr::Div_en::bits(0));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Omap_uart(Genode::Attached_io_mem_dataspace *uart_mmio, int irq_number,
|
||||
unsigned baud_rate, Uart::Char_avail_callback &callback)
|
||||
:
|
||||
Tl16c750_base((Genode::addr_t)uart_mmio->local_addr<void>(), Genode::Board::TL16C750_CLOCK, baud_rate),
|
||||
_uart_mmio(*uart_mmio),
|
||||
_char_avail_callback(callback),
|
||||
_irq_activation(irq_number, *this, IRQ_STACK_SIZE)
|
||||
{
|
||||
_enable_rx_interrupt();
|
||||
}
|
||||
|
||||
/**
|
||||
* * IRQ handler interface **
|
||||
*/
|
||||
void handle_irq(int irq_number)
|
||||
{
|
||||
/* inform client about the availability of data */
|
||||
unsigned int iir = read<Uart_iir::It_pending>();
|
||||
if (iir) return;
|
||||
_char_avail_callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* * UART driver interface **
|
||||
*/
|
||||
void put_char(char c) { Tl16c750_base::put_char(c); }
|
||||
|
||||
bool char_avail() { return read<Uart_lsr::Rx_fifo_empty>(); }
|
||||
|
||||
char get_char() { return read<Uart_rhr::Rhr>(); }
|
||||
};
|
||||
|
||||
#endif /* _OMAP_UART_H_ */
|
6
os/src/drivers/uart/omap4/target.mk
Normal file
6
os/src/drivers/uart/omap4/target.mk
Normal file
@ -0,0 +1,6 @@
|
||||
TARGET = uart_drv
|
||||
REQUIRES = omap4
|
||||
SRC_CC = main.cc
|
||||
LIBS = cxx env server signal
|
||||
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..
|
Loading…
x
Reference in New Issue
Block a user