uboot下的串口初始化分多个步骤完成,在uboot初始化序列init_sequence[]中有三个串口相关的初始化函数。init_baudrate是用来设置串口的波特率,它首先会去uboot的环境变量里面找波特率的定义,如果找到就赋值给全局变量中的baudrate,如果环境变量中没有定义,则使用一个默认的配置值。serial_init跟具体的平台相关,以marvell平台为例,该函数定义在mv_serial.c中。该函数首先根据波特率计算出clock_divisor的值,然后调用mvUartInit()对串口硬件进行初始化。在mvUartInit中就是直接把初始的参数写到串口的寄存器中,从而完成硬件的初始化工作。console_init_f是console初始化的第一阶段,就是设置了全局变量中的have_console变量。
init_fnc_t *init_sequence[] = {
<span style="white-space:pre"> </span>……
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
<span style="white-space:pre"> </span>……
};
static int init_baudrate (void)
{
DECLARE_GLOBAL_DATA_PTR;
uchar tmp[64]; /* long enough for environment variables */
int i = getenv_r ("baudrate", tmp, sizeof (tmp));
gd->bd->bi_baudrate = gd->baudrate = (i > 0)
? (int) simple_strtoul (tmp, NULL, 10)
: CONFIG_BAUDRATE;
return (0);
}
MV_VOID mvUartInit(MV_U32 port, MV_U32 baudDivisor, MV_UART_PORT* base)
{
volatile MV_UART_PORT *pUartPort;
#if defined(MV_UART_OVER_PEX_WA) || defined(MV_UART_OVER_PCI_WA)
uartBase[port] = pUartPort = (volatile MV_UART_PORT *)(base);
return;
#else
uartBase[port] = pUartPort = (volatile MV_UART_PORT *)base;
pUartPort->ier = 0x00;
pUartPort->lcr = LCR_DIVL_EN; /* Access baud rate */
pUartPort->dll = baudDivisor & 0xff; /* 9600 baud */
pUartPort->dlm = (baudDivisor >> 8) & 0xff;
pUartPort->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */
/* Clear & enable FIFOs */
pUartPort->fcr = FCR_