/* * Copyright (c) 2012, ARM Limited. All rights reserved. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of ARM nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. */ /* * uart.c - boot code to output characters on a PL011 uart * Not SMP-safe, so make sure you only call these functions * from one CPU at a time. * Call config_uart first. * Implements fputc() so you can use printf() in your code. */ #include #include "bootwrapper.h" #include "helpers.h" //* PL011 Registers Offsets from UART Base adress */ #define PL011_DR 0x0 #define PL011_RSR 0x4 #define PL011_ECR 0x4 #define PL011_FR 0x18 #define PL011_ILPR 0x20 #define PL011_IBRD 0x24 #define PL011_FBRD 0x28 #define PL011_LCRH 0x2C #define PL011_CR 0x30 #define PL011_IFLS 0x34 #define PL011_IMSC 0x38 #define PL011_RIS 0x3C #define PL011_MIS 0x40 #define PL011_ICR 0x44 #define PL011_DMACR 0x48 #define PL011_TXFE 0x80 #define PL011_TXFF 0x20 static unsigned uart_base = NULL; void config_uart(void) { uart_base = UART0_BASE; write32(uart_base + PL011_CR, 0); write32(uart_base + PL011_FBRD, 0x01); write32(uart_base + PL011_IBRD, 0x27); write32(uart_base + PL011_LCRH, 0x70); write32(uart_base + PL011_CR, 0xf01); /* TXE|RXE|En|DTR|CTS */ } void drain_uart_fifo(void) { while (!(read32(uart_base + PL011_FR) & PL011_TXFE)) { /* Do nothing */ } } static __inline void wait_for_space(void) { while ((read32(uart_base + PL011_FR) & PL011_TXFF)) { /* Do nothing */ } } void output_char(int c) { if (c == '\n') { wait_for_space(); write32(uart_base + PL011_DR, '\r'); } wait_for_space(); write32(uart_base + PL011_DR, c); } void output_string(const char *string) { int i; for (i = 0; string[i]; ++i) { output_char(string[i]); } } void hexword(unsigned value) { printf(" 0x%8.8x", value); drain_uart_fifo(); } typedef struct __FILE { int dummy; } FILE; FILE __stdout; int fputc(int c, FILE * f) { output_char(c); return c; }