first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,139 @@
|
||||
/* -*- tab-width: 8; Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-
|
||||
*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <drivers/uart.h>
|
||||
#include <platform/soc/hwclocks.h>
|
||||
#include <platform/soc/hwregbase.h>
|
||||
|
||||
#include "16x50.h"
|
||||
|
||||
static const uint32_t uart_ports[] = {
|
||||
#ifdef UART0_BASE_ADDR
|
||||
UART0_BASE_ADDR,
|
||||
# ifdef UART1_BASE_ADDR
|
||||
UART1_BASE_ADDR,
|
||||
# endif
|
||||
#else
|
||||
# error No UARTs configured
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* uart_hw_init
|
||||
*
|
||||
* Initialise the port for the requested baudrate.
|
||||
*/
|
||||
int
|
||||
uart_hw_init(uint32_t port, uint32_t baudrate)
|
||||
{
|
||||
return(uart_hw_init_extended(port, baudrate, 8, PARITY_NONE, 1));
|
||||
}
|
||||
|
||||
int
|
||||
uart_hw_init_extended(uint32_t port,
|
||||
uint32_t baudrate,
|
||||
uint32_t databits,
|
||||
enum uart_parity parity,
|
||||
uint32_t stopbits)
|
||||
{
|
||||
uint32_t divisor;
|
||||
uint8_t rv;
|
||||
|
||||
/* wait for the UART to be idle before talking to it */
|
||||
while (!(rLSR(port) & LSR_THRE))
|
||||
;
|
||||
|
||||
/* this can happen if the plaform defines more ports than the target */
|
||||
if (port >= sizeof(uart_ports) / sizeof(uart_ports[0]))
|
||||
return(-1);
|
||||
|
||||
/* disable interrupts, we poll */
|
||||
rIER(port) = 0;
|
||||
|
||||
/* compute LCR */
|
||||
rv = LCR_WLS_8;
|
||||
switch(parity) {
|
||||
case PARITY_EVEN:
|
||||
rv |= LCR_PEN | LCR_EPS;
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
rv |= LCR_PEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch(stopbits) {
|
||||
default:
|
||||
case 1:
|
||||
rv |= LCR_1_STB;
|
||||
break;
|
||||
case 2:
|
||||
rv |= LCR_2_STB;
|
||||
break;
|
||||
}
|
||||
|
||||
divisor = clock_get_frequency(CLK_UART) / (baudrate * 16);
|
||||
rLCR(port) = rv | LCR_DLAB; /* enable the divisor latch */
|
||||
rDLL(port) = divisor & 0xff;
|
||||
rDLM(port) = (divisor >> 8) & 0xff;
|
||||
rLCR(port) = rv; /* disable the divisor latch */
|
||||
|
||||
/* reset & re-enble FIFO with trigger at 1 byte */
|
||||
rFCR(port) = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR | FCR_TL1;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
uart_hw_set_rx_buf(uint32_t port, bool interrupt, size_t buffer_len)
|
||||
{
|
||||
/* optional interface not implemented */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_hw_getc
|
||||
*
|
||||
* Get a byte from the port. Returns -1 if there isn't one ready.
|
||||
*/
|
||||
int
|
||||
uart_hw_getc(uint32_t port)
|
||||
{
|
||||
ASSERT((unsigned)port < (sizeof(uart_ports) / sizeof(uart_ports[0])));
|
||||
|
||||
/* if data ready, return it */
|
||||
if (rLSR(port) & LSR_DR)
|
||||
return(rRBR(port));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_hw_putc
|
||||
*
|
||||
* Write a byte to the port.
|
||||
*/
|
||||
int
|
||||
uart_hw_putc(uint32_t port, char c)
|
||||
{
|
||||
|
||||
ASSERT((unsigned)port < (sizeof(uart_ports) / sizeof(uart_ports[0])));
|
||||
|
||||
/* if we can send the byte, do it */
|
||||
if (rLSR(port) & LSR_THRE) {
|
||||
rTHR(port) = c;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* can't send now, caller will yield and retry */
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/* -*- tab-width: 8; Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-
|
||||
*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Computer, Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Computer, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register layout for a memory-mapped 16x50-style UART.
|
||||
*
|
||||
* Register and bit names/definitions from the National Semiconductor PC16550D datasheet.
|
||||
*
|
||||
* Note that the register set described here is a subset containing just those registers
|
||||
* useful for the iBoot environment. In particular, no modem support registers/definitions
|
||||
* are included.
|
||||
*/
|
||||
|
||||
#ifndef __UART_16x50_H
|
||||
#define __UART_16x50_H
|
||||
|
||||
/* allow an override of the spacing between registers */
|
||||
#ifndef UART16x50_REGISTER_STRIDE
|
||||
# define UART16x50_REGISTER_STRIDE 4
|
||||
#endif
|
||||
|
||||
/* allow an override of the datatype used for reading/writing the registers */
|
||||
#ifndef UART16x50_REGISTER_TYPE
|
||||
# define UART16x50_REGISTER_TYPE uint32_t
|
||||
#endif
|
||||
|
||||
/* produce a pointer to a UART register, assuming base registers in uart_ports */
|
||||
#define UART_REG(_port, _offset) \
|
||||
(*(volatile UART16x50_REGISTER_TYPE *)((uint8_t *)uart_ports[(_port)] + ((_offset) * UART16x50_REGISTER_STRIDE)))
|
||||
|
||||
//
|
||||
// UART Registers for UART _port
|
||||
//
|
||||
#define rRBR(_port) UART_REG(_port, 0) // receiver buffer register (RO)
|
||||
#define rTHR(_port) UART_REG(_port, 0) // transmitter holding register (WO)
|
||||
#define rIER(_port) UART_REG(_port, 1) // interrupt enable register
|
||||
#define rIIR(_port) UART_REG(_port, 2) // interrupt ident. register (RO)
|
||||
#define rFCR(_port) UART_REG(_port, 2) // FIFO control register (WO)
|
||||
#define rLCR(_port) UART_REG(_port, 3) // line control register
|
||||
#define rLSR(_port) UART_REG(_port, 5) // line status register
|
||||
#define rDLL(_port) UART_REG(_port, 0) // divisor latch (LS)
|
||||
#define rDLM(_port) UART_REG(_port, 1) // divisor latch (MS)
|
||||
|
||||
// IER
|
||||
#define IER_ERBFI (1<<0) // enable received data available interrupt
|
||||
#define IER_ETBEI (1<<1) // enable transmit holding register empty interrupt
|
||||
#define IER_ELSI (1<<2) // enable receiver line status interrupt
|
||||
|
||||
// IIR
|
||||
#define IIR_NOTPEND (1<<0) // interrupt not pending
|
||||
#define IIR_IID_MASK 0xe // interrupt pending/ID mask
|
||||
#define IIR_IID_THRE 0x2 // transmitter holding register empty
|
||||
#define IIR_IID_RBF 0x4 // received data available
|
||||
#define IIR_IID_LSR 0x6 // receiver line status
|
||||
#define IIR_IID_CTI 0xc // character timeout indication
|
||||
|
||||
// FCR
|
||||
#define FCR_FIFO_EN (1<<0) // FIFO enable
|
||||
#define FCR_RXSR (1<<1) // reciever fifo reset
|
||||
#define FCR_TXSR (1<<2) // transmitter fifo reset
|
||||
#define FCR_TL1 (0<<6) // RCVR FIFO trigger level - 1 byte
|
||||
#define FCR_TL4 (1<<6) // 4 bytes
|
||||
#define FCR_TL8 (2<<6) // 8 bytes
|
||||
#define FCR_TL14 (3<<6) // 14 bytes
|
||||
|
||||
// LCR
|
||||
#define LCR_WLS_8 (3<<0) // 8 bit data (seriously, who uses anything else?)
|
||||
#define LCR_1_STB (0<<2) // 1 stop bit
|
||||
#define LCR_2_STB (1<<2) // 2 stop bits
|
||||
#define LCR_PEN (1<<3) // parity enable
|
||||
#define LCR_EPS (1<<4) // even parity select
|
||||
#define LCR_STICK (1<<5) // stick parity
|
||||
#define LCR_SBRK (1<<6) // set break
|
||||
#define LCR_DLAB (1<<7) // divisor latch access bit
|
||||
|
||||
// LSR
|
||||
#define LSR_DR (1<<0) // data ready
|
||||
#define LSR_OE (1<<1) // overrun
|
||||
#define LSR_PE (1<<2) // parity error
|
||||
#define LSR_FE (1<<3) // framing error
|
||||
#define LSR_BI (1<<4) // break
|
||||
#define LSR_THRE (1<<5) // transmit holding register empty
|
||||
#define LSR_TEMT (1<<6) // transmitter empty
|
||||
#define LSR_RFERR (1<<7) // error in receiver FIFO
|
||||
|
||||
#endif /* __UART_16x50_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2010 Apple Computer, Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Computer, Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Computer, Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
MODULES += drivers/uart
|
||||
|
||||
OPTIONS += WITH_UART_16X50=1 \
|
||||
WITH_HW_UART=1
|
||||
|
||||
ALL_OBJS += $(LOCAL_DIR)/16x50.o
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2009 Apple Computer, Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Computer, Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Computer, Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
OPTIONS += \
|
||||
WITH_UART=1
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/uart.o
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <sys/task.h>
|
||||
#include <sys.h>
|
||||
|
||||
#include <drivers/power.h>
|
||||
#include <drivers/uart.h>
|
||||
|
||||
#include <target/uartconfig.h>
|
||||
|
||||
/*
|
||||
* Hardware-independent UART support.
|
||||
*/
|
||||
|
||||
#define UART_BAUDRATE 115200
|
||||
|
||||
static int uart_reader_task(void *arg);
|
||||
|
||||
/*
|
||||
* uart_init
|
||||
*
|
||||
* Initalise UARTs in the system.
|
||||
*
|
||||
* Starts the debug input polling threads as well.
|
||||
*/
|
||||
int
|
||||
uart_init(void)
|
||||
{
|
||||
u_int32_t port;
|
||||
|
||||
/* do base hardware init */
|
||||
for (port = 0; port < UARTS_COUNT; port++)
|
||||
uart_hw_init(port, UART_BAUDRATE);
|
||||
|
||||
#ifdef DEBUG_SERIAL_PORT
|
||||
/* regular console port */
|
||||
task_start(task_create("uart reader", uart_reader_task, (void *)DEBUG_SERIAL_PORT, 0x200));
|
||||
#ifdef DEBUG_SERIAL_PORT2
|
||||
/* alternate console port */
|
||||
task_start(task_create("uart reader", uart_reader_task, (void *)DEBUG_SERIAL_PORT2, 0x200));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DEBUG_UART_ENABLE_DEFAULT
|
||||
/* enable console ports early */
|
||||
DebugUartReady |= kPowerNVRAMiBootDebugIAPSerial | kPowerNVRAMiBootDebugAltSerial;
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_getc
|
||||
*
|
||||
* Read a byte from the port, optionally waiting.
|
||||
* If not waiting, returns -1 if a byte is not available.
|
||||
*/
|
||||
int
|
||||
uart_getc(int port, bool wait)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
/* grab a byte */
|
||||
c = uart_hw_getc(port);
|
||||
|
||||
/* if we got one, or we're not waiting, return */
|
||||
if ((-1 != c) || !wait)
|
||||
return(c);
|
||||
|
||||
/* give up cycles */
|
||||
task_yield();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_puts
|
||||
*
|
||||
* Write a nul-terminated string to the port.
|
||||
*/
|
||||
int
|
||||
uart_puts(int port, const char *s)
|
||||
{
|
||||
while(*s)
|
||||
uart_putc(port, *(s++));
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_putc
|
||||
*
|
||||
* Write a byte to the port.
|
||||
*/
|
||||
int
|
||||
uart_putc(int port, char c)
|
||||
{
|
||||
/* spin until the byte can be sent */
|
||||
while (-1 == uart_hw_putc(port, c))
|
||||
task_yield();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* uart_debug_reader_task
|
||||
*
|
||||
* This helper task polls the configured serial port and
|
||||
* feeds bytes read from it into the console input queue.
|
||||
*/
|
||||
static int
|
||||
uart_reader_task(void *arg)
|
||||
{
|
||||
int port = (int)arg;
|
||||
u_int8_t port_mask;
|
||||
int c;
|
||||
|
||||
/* work out what the enable mask is for this port */
|
||||
switch (port) {
|
||||
#if defined(DEBUG_SERIAL_PORT)
|
||||
case DEBUG_SERIAL_PORT:
|
||||
port_mask = kPowerNVRAMiBootDebugIAPSerial;
|
||||
break;
|
||||
#if defined(DEBUG_SERIAL_PORT2)
|
||||
case DEBUG_SERIAL_PORT2:
|
||||
port_mask = kPowerNVRAMiBootDebugAltSerial;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
ASSERT(false);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* loop reading bytes */
|
||||
for(;;) {
|
||||
/* ask the port for a byte, waiting if required */
|
||||
c = uart_getc(port, true);
|
||||
|
||||
/* if our port is enabled, feed it to the input queue */
|
||||
if (DebugUartReady & port_mask)
|
||||
debug_pushchar(c);
|
||||
|
||||
/* yield to avoid hogging */
|
||||
task_yield();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user