123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*++
- Copyright (c) 2014 Minoca Corp. All Rights Reserved
- Module Name:
- serial.c
- Abstract:
- This module implements basic serial support for the first stage loader.
- Author:
- Evan Green 18-Dec-2014
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <uefifw.h>
- #include "init.h"
- #include "util.h"
- //
- // --------------------------------------------------------------------- Macros
- //
- #define AM335_WRITE_UART(_Register, _Value) \
- AM3_WRITE32(AM335_UART_0_BASE + (_Register), (_Value))
- #define AM335_READ_UART(_Register) \
- AM3_READ32(AM335_UART_0_BASE + (_Register))
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define STAGE1_SERIAL_CLOCK_HZ 48000000
- #define STAGE1_SERIAL_BAUD_RATE 115200
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- VOID
- EfipAm335EnableUart (
- VOID
- )
- /*++
- Routine Description:
- This routine performs rudimentary initialization so that UART0 can be used
- as a debug console.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- UINT32 Divisor;
- UINT32 Register;
- UINT32 Value;
- //
- // Set the pad configuration for UART0.
- //
- Register = AM335_SOC_CONTROL_REGISTERS + AM335_PAD_UART_RXD(0);
- Value = AM335_SOC_CONTROL_UART0_RXD_PULLUP |
- AM335_SOC_CONTROL_UART0_RXD_RX_ACTIVE;
- AM3_WRITE32(Register, Value);
- Register = AM335_SOC_CONTROL_REGISTERS + AM335_PAD_UART_TXD(0);
- Value = AM335_SOC_CONTROL_UART0_TXD_PULLUP;
- AM3_WRITE32(Register, Value);
- //
- // Reset the UART module.
- //
- Value = AM335_READ_UART(AM335_UART_SYSTEM_CONTROL);
- Value |= AM335_UART_SYSTEM_CONTROL_RESET;
- AM335_WRITE_UART(AM335_UART_SYSTEM_CONTROL, Value);
- do {
- Value = AM335_READ_UART(AM335_UART_SYSTEM_STATUS);
- } while ((Value & AM335_UART_SYSTEM_STATUS_RESET_DONE) == 0);
- //
- // Configure the UART.
- //
- Divisor = STAGE1_SERIAL_CLOCK_HZ / 16 / STAGE1_SERIAL_BAUD_RATE;
- AM335_WRITE_UART(AM335_UART_IER, 0x00);
- AM335_WRITE_UART(AM335_UART_MDR1, 0x07);
- AM335_WRITE_UART(AM335_UART_LCR, 0x83);
- AM335_WRITE_UART(AM335_UART_DLL, (UINT8)Divisor);
- AM335_WRITE_UART(AM335_UART_DLM, (UINT8)(Divisor >> 8));
- AM335_WRITE_UART(AM335_UART_LCR, 0x03);
- AM335_WRITE_UART(AM335_UART_MCR, 0x03);
- AM335_WRITE_UART(AM335_UART_FCR, 0x07);
- AM335_WRITE_UART(AM335_UART_MDR1, 0x00);
- return;
- }
- VOID
- EfipSerialPrintBuffer32 (
- CHAR8 *Title,
- VOID *Buffer,
- UINT32 Size
- )
- /*++
- Routine Description:
- This routine prints a buffer of 32-bit hex integers.
- Arguments:
- Title - Supplies an optional pointer to a string to title the buffer.
- Buffer - Supplies the buffer to print.
- Size - Supplies the size of the buffer. This is assumed to be divisible by
- 4.
- Return Value:
- None.
- --*/
- {
- UINT32 *Buffer32;
- UINTN Index;
- if (Title != NULL) {
- EfipSerialPrintString(Title);
- }
- Buffer32 = Buffer;
- for (Index = 0; Index < (Size >> 2); Index += 1) {
- if ((Index & 0x7) == 0) {
- EfipSerialPrintString("\r\n");
- }
- EfipSerialPrintHexInteger(Buffer32[Index]);
- EfipSerialPrintString(" ");
- }
- EfipSerialPrintString("\r\n");
- return;
- }
- VOID
- EfipSerialPrintString (
- CHAR8 *String
- )
- /*++
- Routine Description:
- This routine prints a string to the serial console.
- Arguments:
- String - Supplies a pointer to the string to send.
- Return Value:
- None.
- --*/
- {
- while (*String != '\0') {
- if (*String == '\n') {
- EfipSerialPutCharacter('\r');
- }
- EfipSerialPutCharacter(*String);
- String += 1;
- }
- return;
- }
- VOID
- EfipSerialPrintHexInteger (
- UINT32 Value
- )
- /*++
- Routine Description:
- This routine prints a hex integer to the console.
- Arguments:
- Value - Supplies the value to print.
- Return Value:
- None.
- --*/
- {
- UINT32 Digit;
- UINTN Index;
- for (Index = 0; Index < 8; Index += 1) {
- Digit = ((Value & 0xF0000000) >> 28) & 0x0000000F;
- if (Digit >= 0xA) {
- EfipSerialPutCharacter(Digit - 0xA + 'A');
- } else {
- EfipSerialPutCharacter(Digit + '0');
- }
- Value = Value << 4;
- }
- return;
- }
- VOID
- EfipSerialPutCharacter (
- CHAR8 Character
- )
- /*++
- Routine Description:
- This routine prints a character to the serial console.
- Arguments:
- Character - Supplies the character to send.
- Return Value:
- None.
- --*/
- {
- while (TRUE) {
- if ((AM335_READ_UART(AM335_UART_LSR) & 0x20) != 0) {
- break;
- }
- }
- AM335_WRITE_UART(AM335_UART_THR, Character);
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|