⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_au1000.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

/************************************************************************
 *
 *      SERIAL_Au1000.c
 *
 *      The 'SERIAL_Au1000' module implements the SERIAL-Au1000C
 *      device driver as an IO device with following services:
 *
 *        1) init  device:  configure and initialize serial driver
 *        2) open  device:  not used
 *        3) close device:  not used
 *        4) read  device:  read character from serial device
 *        5) write device:  write character to serial device
 *        6) ctrl  device:  statistics and poll for ctrl/c
 *
 *
 *
 * ######################################################################
 *
 * Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved. 
 * 
 * Unpublished rights reserved under the Copyright Laws of the United States of 
 * America. 
 * 
 * This document contains information that is proprietary to MIPS Technologies, 
 * Inc. ("MIPS Technologies"). Any copying, modifying or use of this information
 * (in whole or in part) which is not expressly permitted in writing by MIPS 
 * Technologies or a contractually-authorized third party is strictly 
 * prohibited. At a minimum, this information is protected under unfair 
 * competition laws and the expression of the information contained herein is 
 * protected under federal copyright laws. Violations thereof may result in 
 * criminal penalties and fines. 
 * MIPS Technologies or any contractually-authorized third party reserves the 
 * right to change the information contained in this document to improve 
 * function, design or otherwise. MIPS Technologies does not assume any 
 * liability arising out of the application or use of this information. Any 
 * license under patent rights or any other intellectual property rights owned 
 * by MIPS Technologies or third parties shall be conveyed by MIPS Technologies 
 * or any contractually-authorized third party in a separate license agreement 
 * between the parties. 
 * The information contained in this document constitutes one or more of the 
 * following: commercial computer software, commercial computer software 
 * documentation or other commercial items. If the user of this information, or 
 * any related documentation of any kind, including related technical data or 
 * manuals, is an agency, department, or other entity of the United States 
 * government ("Government"), the use, duplication, reproduction, release, 
 * modification, disclosure, or transfer of this information, or any related 
 * documentation of any kind, is restricted in accordance with Federal 
 * Acquisition Regulation 12.212 for civilian agencies and Defense Federal 
 * Acquisition Regulation Supplement 227.7202 for military agencies. The use of 
 * this information by the Government is further restricted in accordance with 
 * the terms of the license agreement(s) and/or applicable contract terms and 
 * conditions covering this information from MIPS Technologies or any 
 * contractually-authorized third party. 
 *
 ************************************************************************/


/************************************************************************
 *      Include files
 ************************************************************************/

#include <sysdefs.h>
#include <syserror.h>
#include <sysdev.h>
#include <io_api.h>
#include <syscon_api.h>
#include <sys_api.h>
#include <serial_api.h>
#include <string.h>

#include <serial_au1000_api.h>
#include <excep_api.h>

#include <pb1000.h>
#include <uart.h>

/************************************************************************
 *  Definitions
*************************************************************************/

/*
 * Alchemy UARTs:
 * UART0 @ 0xB1100000
 * UART1 @ 0xB1200000
 * UART2 @ 0xB1300000
 * UART3 @ 0xB1400000
 *
 * Au1000: 4 UARTs (UART0, UART1, UART2, UART3)
 * Au1500: 2 UARTs (UART0, UART3)
 * Au1100: 3 UARTs (UART0, UART1, UART3)
 * Au1550: 3 UARTs (UART0, UART1, UART3)
 * Au1200: 2 UARTS (UART0, UART1)
 */
#define SERIAL_MAX_AU1x00_DEVICES 4  /* max num Au1x00 async UARTs supported */

/************************************************************************
 *      Public variables
 ************************************************************************/

/* syscon_platform_tty.c */
extern UINT32 pb1000_major_tty0;
extern UINT32 pb1000_minor_tty0;
extern UINT32 pb1000_major_tty1;
extern UINT32 pb1000_minor_tty1;

//extern UINT32 intline_pb1000_tty0;
//extern UINT32 intline_pb1000_tty1;
#define PB1000_INTLINE_TTY0	 0x02
#define PB1000_INTLINE_TTY1 	0x03


/************************************************************************
 *      Static variables
 ************************************************************************/

/*  Databit conversion table. */
static const UINT8 serial_databits[SERIAL_DATABITS_MAX] = {

    SERIAL_ILLEGAL,   /* 0, undefined  */
    UART_LINECTRL_WLS_7,	/* 1, 7 databits */
    UART_LINECTRL_WLS_8,	/* 2, 8 databits */
};


/*  Parity conversion table.  */
static const UINT8 serial_parity[SERIAL_PARITY_MAX] = {

    SERIAL_ILLEGAL,        /* 0, undefined  */
    0x00, /* 1, none ~UART_LINECTRL_PE */
    UART_LINECTRL_PE|UART_LINECTRL_PAR_O, /* 2, odd        */
    UART_LINECTRL_PE|UART_LINECTRL_PAR_E, /* 3, even       */
};


/*  Stopbits conversion table. */
static const UINT8 serial_stopbits[SERIAL_STOPBITS_MAX] = {

    SERIAL_ILLEGAL,     /* 0, undefined   */
    0x00, /* 1, 1 stopbit ~UART_LINECTRL_ST */
    UART_LINECTRL_ST, /* 2, 1.5 stopbit */
    UART_LINECTRL_ST, /* 3, 2 stopbit   */

};

static t_UART_statistics  uart_statistics[SERIAL_MAX_AU1x00_DEVICES];
static UINT32		  poll_retcode[SERIAL_MAX_AU1x00_DEVICES];
static UINT32		  shadow_ier[SERIAL_MAX_AU1x00_DEVICES];
static UINT32		  shadow_mcr[SERIAL_MAX_AU1x00_DEVICES];


/*  Receive buffer operation:
 *
 *  putptr points to the next free location
 *  When a byte is polled from the uart, it is stored by putptr,
 *  which is then cyclic incremented UNLESS it gets equal to getptr.
 *
 *  That way, getptr == putptr means buffer empty, and
 *            the buffer can hold POLLSIZE-1 bytes.
 */ 

#define POLLSIZE	0x800   /* Must be power of 2 and at least 128 */
#define HW_LIMIT_STOP	(POLLSIZE-64)  /* RTS OFF when 64 chars in buf */
#define HW_LIMIT_START	(POLLSIZE-32)  /* RTS  ON when 32 chars in buf */

static UINT16 *recv_putptr[SERIAL_MAX_AU1x00_DEVICES];
static UINT16 *recv_getptr[SERIAL_MAX_AU1x00_DEVICES];
static UINT16 *recv_flushptr[SERIAL_MAX_AU1x00_DEVICES];
static UINT16  recv_buffer[SERIAL_MAX_AU1x00_DEVICES][POLLSIZE];

//static UINT32 minor_numbers[SERIAL_MAX_AU1x00_DEVICES];

/* reverse-lookup table from t_SERIAL_baudrate_ids back to integer bps rates */
/* (this must match up with indexes to t_SERIAL_baudrate_ids typedef.) */
static UINT32 SERIAL_baudrate_rates[] =
{
	0,
	75,
	110,
	150,
	300,
	600,
	1200,
	1800,
	2400,
	4800,
	7200,
	9600,
	14400,
	19200,
	38400,
	57600,
	115200,
	230400,
	460800,
	921600
};

/*  Boolean indicating whether interrupt handlers are registered or not.
 *  Initial value is 0 (FALSE) since data is in BSS.
 */
static bool  registered[SERIAL_MAX_AU1x00_DEVICES];

/************************************************************************
 *      Static function prototypes
 ************************************************************************/

static INT32 
SERIAL_Au1000_init(
    UINT32 major,          /* IN: major device number             */
    UINT32 minor,          /* IN: minor device number             */
    UINT32 *port );        /* IN: port mapping			  */

static INT32 
SERIAL_Au1000_read(
    UINT32 major,          /* IN: major device number             */
    UINT32 minor,          /* IN: minor device number             */
    UINT8  *p_param );     /* OUT: character been read            */

static UINT32 
SERIAL_Au1000_irqpoll( 
    UINT32 minor );

static UINT32 
SERIAL_Au1000_irq( 
    UINT32 minor,
    UINT32 in_intrpt );

static INT32 
SERIAL_Au1000_write(
    UINT32 major,          /* IN: major device number             */
    UINT32 minor,          /* IN: minor device number             */
    UINT8  *p_param );     /* IN: character to write              */

static INT32 
SERIAL_Au1000_ctrl(
    UINT32 major,          /* IN: major device number             */
    UINT32 minor,          /* IN: minor device number             */
    t_SERIAL_ctrl_descriptor *p_param );/* INOUT: IOCTL structure */

static void
serial_int_handler(
    void *data );	/* Holds the minor device number		*/


/************************************************************************
 *      Implementation : Public functions
 ************************************************************************/

static AU1X00_UART *
minor2base( int minor )
{    
    AU1X00_UART *p;

	switch (minor)
	{
		default:
		case SERIAL_MINOR_AU1x00_UART0: p = (AU1X00_UART *)UART0_BASE; break;
		case SERIAL_MINOR_AU1x00_UART1: p = (AU1X00_UART *)UART1_BASE; break;
		case SERIAL_MINOR_AU1x00_UART2: p = (AU1X00_UART *)UART2_BASE; break;
		case SERIAL_MINOR_AU1x00_UART3: p = (AU1X00_UART *)UART3_BASE; break;
	}

	return p;
}

/************************************************************************
 *
 *                          SERIAL_Au1000_install
 *  Description :
 *  -------------
 *
 *  Installs the serial Au1000 serial device drivers services in 
 *  the IO system at the reserved device slot, found in the
 *  'sysdev.h' file, which defines all major device numbers.
 *
 *  Note:
 *  This service is the only public declared interface function; all
 *  provided device driver services are static declared, but this
 *  function installs the function pointers in the io-system to
 *  enable the provided public driver services.
 *
 *  Parameters :
 *  ------------
 *
 *  None
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *  'ERROR_IO_ILLEGAL_MAJOR':  Illegal major device number
 *  'ERROR_IO_NO_SPACE':       Device slot already allocated
 *
 ************************************************************************/
INT32 
SERIAL_AU1000_install( void )
{    
    UINT32 i;
	UINT32	prid;

	prid = CP0_prid_read();

/* FIX!!! need interrupt numbers also */

	/*
	 * UART0 and UART3 are common to all Alchemy processors and are
	 * pinned out on all Alchemy development platforms. So use
	 * UART0 and UART3 as YAMON's TTY0 and TTY1.
	 * (Except on Au1200, TTY1 is UART1)
	 */
	pb1000_major_tty0 = SYS_MAJOR_SERIAL_AU1x00;
	pb1000_major_tty1 = SYS_MAJOR_SERIAL_AU1x00;
	pb1000_minor_tty0 = SERIAL_MINOR_AU1x00_UART0;
	pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART3;

#if 0
	if ((prid & 0xFF000000) == 0x00000000 ) // Au1000
	{
		pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART3;
	}
	else if( (prid & 0xff000000) == 0x01000000 ) // Au1500
	{
		pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART3;
	}
	else if ((prid & 0xFF000000) == 0x02000000 ) // Au1100
	{
		pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART3;
	}
	else if ((prid & 0xFF000000) == 0x03000000 ) // Au1550
	{
		pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART3;
	}
	else
#endif
	if ((prid & 0xFF000000) == 0x04000000 ) // Au1200
	{
		pb1000_minor_tty1 = SERIAL_MINOR_AU1x00_UART1;
	}

    /* Initialise variables */
    for( i=0; i<SERIAL_MAX_AU1x00_DEVICES; i++ )
    {
        //minor_numbers[i] = i;
    }

    /* pre-initialize local variables and install device services */
    return( IO_install( SYS_MAJOR_SERIAL_AU1x00, /* major device number */
         (t_io_service) SERIAL_Au1000_init,      /* 'init'  service     */
                        NULL,                     /* 'open'  service  na */
                        NULL,                     /* 'close' service  na */
         (t_io_service) SERIAL_Au1000_read,      /* 'read'  service     */
         (t_io_service) SERIAL_Au1000_write,     /* 'write' service     */
         (t_io_service) SERIAL_Au1000_ctrl ) );  /* 'ctrl' service      */
}

/************************************************************************
 *      Implementation : Static functions
 ************************************************************************/

/************************************************************************
 *      Implementation : Local helper functions
 ************************************************************************/

/************************************************************************
 *
 *                          SERIAL_Au1000_checkbaudrate
 *  Description :
 *  -------------
 *  This functions validates the specified baudrate for this type of device.
 *
 *  Parameters :
 *  ------------
 *
 *  'baudrate',   IN,    baudrate to be validated. 
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -