[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/devdrv/uart/inc/uart_gpd.h b/mcu/driver/devdrv/uart/inc/uart_gpd.h
new file mode 100644
index 0000000..eb9c1d7
--- /dev/null
+++ b/mcu/driver/devdrv/uart/inc/uart_gpd.h
@@ -0,0 +1,122 @@
+#ifndef __UART_GPD_H__
+#define __UART_GPD_H__
+
+#define HDMA_MAX_GPD_EXT_LEN		0xFF
+#define HDMA_MAX_BD_EXT_LEN		0xFF
+
+typedef enum{
+	HDMA_BUF0,
+	HDMA_BUF1,
+	HDMA_BUF_BOTH,
+} hdma_buf_mode_t;
+
+typedef enum{
+	HDMA_TST_TX,
+	HDMA_TST_RX,
+} hdma_tst_mode_t;
+
+typedef struct hdma_tgpd_s {
+	kal_uint8 hwo:1;
+	kal_uint8 bdp:1;
+	kal_uint8 bps:1;
+	kal_uint8 resv1:4;
+	kal_uint8 ioc:1;
+	kal_uint8 cksum;
+	kal_uint16 resv2;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint16 bufLen;
+	kal_uint8 extLen;
+	kal_uint8 resv3;
+	kal_uint8 extBuf[HDMA_MAX_GPD_EXT_LEN + 1];	// Extension field
+} hdma_tgpd_t;
+
+typedef struct hdma_rgpd_s {
+	kal_uint8 hwo:1;
+	kal_uint8 bdp:1;
+	kal_uint8 bps:1;
+	kal_uint8 resv1:4;
+	kal_uint8 ioc:1;
+	kal_uint8 cksum;
+	kal_uint16 allowBufLen;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint16 bufLen;
+	kal_uint16 resv2;
+} hdma_rgpd_t;
+
+typedef struct hdma_tbd_s {
+	kal_uint8 eol:1;
+	kal_uint8 resv1:7;
+	kal_uint8 cksum;
+	kal_uint16 resv2;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint16 bufLen;
+	kal_uint8 extLen;
+	kal_uint8 resv3;
+	kal_uint8 extBuf[HDMA_MAX_BD_EXT_LEN + 1];	// Extension field
+} hdma_tbd_t;
+
+typedef struct hdma_rbd_s {
+	kal_uint8 eol:1;
+	kal_uint8 resv1:7;
+	kal_uint8 cksum;
+	kal_uint16 allowBufLen;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint16 bufLen;
+	kal_uint16 resv2;
+} hdma_rbd_t;
+
+typedef struct hdma_tx_queue_s {
+	hdma_tgpd_t *gpdHeadPtr;
+	hdma_tgpd_t *lastLoadedGpdPtr;
+	kal_uint32 count;
+} hdma_tx_queue_t;
+
+typedef struct hdma_rx_queue_s {
+	hdma_rgpd_t *gpdHeadPtr;
+	hdma_rgpd_t *lastLoadedGpdPtr;
+	kal_uint32 count;
+} hdma_rx_queue_t;
+
+typedef struct hdma_tgpd_pool_s{
+	kal_uint32 gpdUsed;
+	kal_uint32 gpdMax;
+	hdma_tgpd_t *gpd;
+} hdma_tgpd_pool_t;
+
+typedef struct hdma_rgpd_pool_s{
+	kal_uint32 gpdUsed;
+	kal_uint32 gpdMax;
+	hdma_rgpd_t *gpd;
+} hdma_rgpd_pool_t;
+
+typedef struct hdma_tbd_pool_s{
+	kal_uint32 bdUsed;
+	kal_uint32 bdMax;
+	hdma_tbd_t *bd;
+} hdma_tbd_pool_t;
+
+typedef struct hdma_rbd_pool_s{
+	kal_uint32 bdUsed;
+	kal_uint32 bdMax;
+	hdma_rbd_t *bd;
+} hdma_rbd_pool_t;
+
+typedef struct hdma_gpd_bd_param_s{
+	kal_uint32 gpdLenLimit;
+	kal_uint32 gpdExtLen;
+	kal_uint32 bdLenLimit;
+	kal_uint32 bdExtLen;
+	kal_uint32 bdNumLimit;
+} hdma_gpd_bd_param_t;
+
+typedef struct hdma_gpd_config_s{
+	kal_uint8 bps:1;
+	kal_uint8 ioc:1;
+	kal_uint8 resv:6;
+} hdma_gpd_config_t;
+
+#endif
diff --git a/mcu/driver/devdrv/uart/inc/uart_hw.h b/mcu/driver/devdrv/uart/inc/uart_hw.h
new file mode 100644
index 0000000..dc20607
--- /dev/null
+++ b/mcu/driver/devdrv/uart/inc/uart_hw.h
@@ -0,0 +1,585 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    uart_hw.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This file is intends for UART driver.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef UART_HW_H
+#define UART_HW_H
+
+#if __LTE_TBC__
+#include "dma_hw.h"
+#endif
+#include "drv_comm.h"
+
+#if !defined(DRV_UART_OFF)
+
+/*used in Task or normal function*/
+#define UART_RBR(_baseaddr)		(_baseaddr+0x0)		/* Read only */
+#define UART_THR(_baseaddr)		(_baseaddr+0x0)		/* Write only */
+#define UART_IER(_baseaddr)		(_baseaddr+0x4)
+#define UART_IIR(_baseaddr)		(_baseaddr+0x8)		/* Read only */
+#define UART_FCR(_baseaddr)		(_baseaddr+0x8)		/* Write only */
+#define UART_LCR(_baseaddr)		(_baseaddr+0xc)
+#define UART_MCR(_baseaddr)		(_baseaddr+0x10)
+#define UART_LSR(_baseaddr)		(_baseaddr+0x14)
+#define UART_MSR(_baseaddr)		(_baseaddr+0x18)
+#define UART_SCR(_baseaddr)		(_baseaddr+0x1c)
+#define UART_DLL(_baseaddr)		(_baseaddr+0x0)
+#define UART_DLH(_baseaddr)		(_baseaddr+0x4)
+#define UART_EFR(_baseaddr)		(_baseaddr+0x8)		/* Only when LCR = 0xbf */
+#define UART_XON1(_baseaddr)		(_baseaddr+0x10)	/* Only when LCR = 0xbf */
+#define UART_XON2(_baseaddr)		(_baseaddr+0x14)	/* Only when LCR = 0xbf */
+#define UART_XOFF1(_baseaddr)		(_baseaddr+0x18)	/* Only when LCR = 0xbf */
+#define UART_XOFF2(_baseaddr)		(_baseaddr+0x1c)	/* Only when LCR = 0xbf */
+
+#define	UART_RATE_STEP(_baseaddr)	(_baseaddr+0x24)
+#define	UART_STEP_COUNT(_baseaddr)	(_baseaddr+0x28)
+#define	UART_SAMPLE_COUNT(_baseaddr)	(_baseaddr+0x2c)
+#define	UART_RATE_FIX_REG(_baseaddr)	(_baseaddr+0x34)
+#define	UART_AUTO_BAUDSAMPLE(_baseaddr)	(_baseaddr+0x38)
+#define	UART_GUARD(_baseaddr)		(_baseaddr+0x3C)
+#define	UART_ESCAPE_DAT(_baseaddr)	(_baseaddr+0x40)
+#define	UART_ESCAPE_EN(_baseaddr)	(_baseaddr+0x44)
+#define	UART_SLEEP_EN(_baseaddr)	(_baseaddr+0x48)
+#define	UART_DMA_EN(_baseaddr)		(_baseaddr+0x4c)
+#define UART_RXTRI(_baseaddr)		(_baseaddr+0x50)
+#define	UART_DMA_ACK(_baseaddr)	(_baseaddr+0xb8)
+
+//IER
+#if defined(DRV_UART_FIFO_FLOW_CONTROL)
+#define UART_IER_ERBFI			0x0001
+#define UART_IER_ETBEI			0x0002
+#define UART_IER_ELSI			0x0004
+#define UART_IER_EDSSI			0x0008
+#define UART_IER_XOFFI			0x0020
+#define UART_IER_RTSI			0x0040
+#define UART_IER_CTSI			0x0080
+
+#define IER_HW_NORMALINTS		0x001d
+#define IER_HW_ALLINTS			0x001f
+#define IER_SW_NORMALINTS		0x003d
+#define IER_SW_ALLINTS			0x003f
+
+#define UART_IER_ALLOFF			0x0010 //because of UART_IER_VFF_FC_EN not one of interrupt masks
+#define UART_IER_VFIFO			0x0011	
+#else //#if defined(DRV_UART_FIFO_FLOW_CONTROL)
+#define UART_IER_ERBFI			0x0001
+#define UART_IER_ETBEI			0x0002
+#define UART_IER_ELSI			0x0004
+#define UART_IER_EDSSI			0x0008
+#define UART_IER_XOFFI			0x0020
+#define UART_IER_RTSI			0x0040
+#define UART_IER_CTSI			0x0080
+
+#define IER_HW_NORMALINTS		0x000d
+#define IER_HW_ALLINTS			0x000f
+#define IER_SW_NORMALINTS		0x002d
+#define IER_SW_ALLINTS			0x002f
+
+#define UART_IER_ALLOFF			0x0000
+#define UART_IER_VFIFO			0x0001	
+#endif //#if defined(DRV_UART_FIFO_FLOW_CONTROL)
+
+
+
+#define	UART_RATE_STEP_16		0x0000   /* baud = clock/UART_RATE_STEP/divisor */
+#define	UART_RATE_STEP_8		0x0001
+#define	UART_RATE_STEP_4		0x0002
+#define	UART_RATE_STEP_COUNT		0x0003   /* baud = clock/UART_RATE_STEP_COUNT */
+#define UART_STEP_COUNT_MASK		0x00ff
+#define UART_SAMPLE_COUNT_MASK		0x00ff
+
+
+//FCR
+#define UART_FCR_FIFOEN			0x0001
+#define UART_FCR_CLRR			0x0002
+#define UART_FCR_CLRT			0x0004
+#define UART_FCR_FIFOINI		0x0007
+#define UART_FCR_RX1Byte_Level		0x0000
+#define UART_FCR_RX6Byte_Level		0x0040
+#define UART_FCR_RX12Byte_Level	0x0080
+#define UART_FCR_RXTRIG_Level		0x00c0
+
+#define UART_FCR_TX0Byte_Level		0x0000
+#define UART_FCR_TX4Byte_Level		0x0010
+#define UART_FCR_TX8Byte_Level		0x0020
+#define UART_FCR_TX14Byte_Level	0x0030
+
+#define   UART_FCR_Normal		(UART_FCR_TX0Byte_Level | UART_FCR_RX12Byte_Level | UART_FCR_FIFOINI)
+#define   UART_FCR_RX_Normal		(UART_FCR_RX12Byte_Level | UART_FCR_FIFOINI) //VFIFO single channel
+#define   UART_FCR_TX_Normal		(UART_FCR_TX0Byte_Level   | UART_FCR_FIFOINI) //VFIFO single channel
+#define   UART1_TxFIFO_DEPTH		32
+#define   UART1_RxFIFO_DEPTH		32
+#define   UART2_TxFIFO_DEPTH		32	
+#define   UART2_RxFIFO_DEPTH		32
+
+#if defined(DRV_UART_FIFO_FLOW_CONTROL) //Use larger size of RX FIFO, because it can trigger flow CONTROL_CHANNEL_MSG
+#define	 UART_VFIFO_DEPTH		(UART_FCR_FIFOINI | UART_FCR_RX16Byte_Level)
+#else
+#define	 UART_VFIFO_DEPTH		7
+#endif      
+
+//IIR,RO
+#define UART_IIR_INT_INVALID		0x0001
+#define UART_IIR_RLS			0x0006  // Receiver Line Status
+#define UART_IIR_RDA			0x0004  // Receive Data Available
+#define UART_IIR_CTI			0x000C  // Character Timeout Indicator
+#define UART_IIR_THRE			0x0002  // Transmit Holding Register Empty
+#define UART_IIR_MS			0x0000  // Check Modem Status Register
+#define UART_IIR_SWFlowCtrl		0x0010  // Receive XOFF characters
+#define UART_IIR_HWFlowCtrl		0x0020  // CTS or RTS Rising Edge
+#define UART_IIR_FIFOS_ENABLED		0x00c0
+#define UART_IIR_NO_INTERRUPT_PENDING   0x0001
+#define UART_IIR_INT_MASK		0x001f
+
+//===============================LCR================================
+//WLS
+#define UART_WLS_8			0x0003
+#define UART_WLS_7			0x0002
+#define UART_WLS_6			0x0001
+#define UART_WLS_5			0x0000
+#define UART_DATA_MASK			0x0003
+
+//Parity
+#define UART_NONE_PARITY		0x0000
+#define UART_ODD_PARITY			0x0008
+#define UART_EVEN_PARITY		0x0018
+#define UART_MARK_PARITY		0x0028
+#define UART_SPACE_PARITY		0x0038
+#define UART_PARITY_MASK		0x0038
+
+//Stop bits
+#define UART_1_STOP			0x0000
+#define UART_1_5_STOP			0x0004  // Only valid for 5 data bits
+#define UART_2_STOP			0x0004
+#define UART_STOP_MASK			0x0004
+
+#define UART_LCR_DLAB			0x0080
+#define UART_LCR_BREAK			0x0040
+//===============================LCR================================
+
+//MCR
+#define UART_MCR_DTR			0x0001
+#define UART_MCR_RTS			0x0002
+#define UART_MCR_LOOPB			0x0010
+#define UART_MCR_IRE			0x0040	//Enable IrDA modulation/demodulation
+#define UART_MCR_XOFF			0x0080
+#define UART_MCR_Normal			(UART_MCR_DTR | UART_MCR_RTS)
+#define UART_MCR_DCM_EN			0x0020
+
+
+//LSR
+#define UART_LSR_DR			0x0001
+#define UART_LSR_OE			0x0002
+#define UART_LSR_PE			0x0004
+#define UART_LSR_FE			0x0008
+#define UART_LSR_BI			0x0010
+#define UART_LSR_THRE			0x0020
+#define UART_LSR_TEMT			0x0040
+#define UART_LSR_FIFOERR		0x0080
+
+//MSR
+#define UART_MSR_DCTS			0x0001
+#define UART_MSR_DDSR			0x0002
+#define UART_MSR_TERI			0x0004
+#define UART_MSR_DDCD			0x0008
+#define UART_MSR_CTS			0x0010
+#define UART_MSR_DSR			0x0020
+#define UART_MSR_RI			0x0040
+#define UART_MSR_DCD			0x0080
+
+//DLL
+//DLM
+//EFR
+#define UART_EFR_AutoCTS		0x0080
+#define UART_EFR_AutoRTS		0x0040
+#define UART_EFR_Enchance		0x0010
+#define UART_EFR_SWCtrlMask		0x000f
+#define UART_EFR_NoSWFlowCtrl		0x0000
+#define UART_EFR_ALLOFF			0x0000
+#define UART_EFR_AutoRTSCTS		0x00c0
+
+#if defined(DRV_UART_FIFO_FLOW_CONTROL) //add 0x10 RX FIFO flow control in all values.
+//Tx/Rx XON1/Xoff1 as flow control word
+#define UART_EFR_SWFlowCtrlX1		0x001a	
+//Tx/Rx XON2/Xoff2 as flow control word
+#define UART_EFR_SWFlowCtrlX2		0x0015
+//Tx/Rx XON1&XON2/Xoff1&Xoff2 as flow control word
+#define UART_EFR_SWFlowCtrlXAll		0x001f
+#else //#if defined(DRV_UART_FIFO_FLOW_CONTROL)
+#define UART_EFR_SWFlowCtrlX1		0x000a
+#define UART_EFR_SWFlowCtrlX2		0x0005
+#define UART_EFR_SWFlowCtrlXAll		0x000f
+#endif//#if defined(DRV_UART_FIFO_FLOW_CONTROL)
+
+//DMA_EN
+#define	UART_TXRXDMA_ON			0x0003
+#define 	UART_TO_CNT_AUTORST		0x0004
+#define 	UART_FIFO_LSR_SEL			0x0008
+#define UART_TXRXDMA_OFF		0x0000
+
+//DMA_ACK
+#define	UART_DMA_ACK_TX			0x0002
+#define	UART_DMA_ACK_RX			0x0001
+#define	UART_DMA_ACK_DIS			0x0000
+
+#define UART_RXTRI_VALUE		0x16
+
+#if defined(DRV_UART_VFIFO_V2)
+
+#ifdef DMA_POP
+#undef DMA_POP
+#endif
+
+#ifdef DMA_PUSH
+#undef DMA_PUSH
+#endif
+
+#define DMA_POP(_n)                 DRV_Reg8(DRV_Reg(DMA_VFF_RPT(_n))+DRV_Reg32(DMA_SRC(_n)));\
+	if(DRV_Reg(DMA_VFF_RPT(_n)) == (DRV_Reg(DMA_VFF_SIZE(_n))-1))\
+		DRV_WriteReg32(DMA_VFF_RPT(_n), (~DRV_Reg32(DMA_VFF_RPT(_n)))&0x10000);\
+	else \
+		DRV_WriteReg32(DMA_VFF_RPT(_n), DRV_Reg32(DMA_VFF_RPT(_n))+1);
+
+#define DMA_PUSH(_n,_data)          while(DRV_Reg(DMA_W_INT_BUF_SIZE(_n))>=64);*(volatile kal_uint8*)DMA_VPORT(_n) = (kal_uint8)_data;
+#define DMA_PUSH32(_n,_data)      while(DRV_Reg(DMA_W_INT_BUF_SIZE(_n))>60);*(volatile kal_uint32*)DMA_VPORT(_n) = (kal_uint32)_data;
+
+#endif //#if defined(DRV_UART_VFIFO_V2)
+
+#if defined(DRV_UART_VFIFO_V3)
+
+#ifdef DMA_POP
+#undef DMA_POP
+#endif
+
+#ifdef DMA_PUSH
+#undef DMA_PUSH
+#endif
+
+#define DMA_POP(_n)                 DRV_Reg8(DRV_Reg(DMA_VFF_RPT(_n))+DRV_Reg32(DMA_SRC(_n)));\
+	if(DRV_Reg(DMA_VFF_RPT(_n)) == (DRV_Reg(DMA_VFF_SIZE(_n))-1))\
+		DRV_WriteReg32(DMA_VFF_RPT(_n), (~DRV_Reg32(DMA_VFF_RPT(_n)))&0x10000);\
+	else \
+		DRV_WriteReg32(DMA_VFF_RPT(_n), DRV_Reg32(DMA_VFF_RPT(_n))+1);
+
+#define DMA_PUSH(_n,_data) \
+		DRV_WriteReg8(DRV_Reg(DMA_VFF_WPT(_n))+DRV_Reg32(DMA_SRC(_n)),_data);\
+		if(DRV_Reg(DMA_VFF_WPT(_n)) == (DRV_Reg(DMA_VFF_SIZE(_n))-1))\
+		DRV_WriteReg32(DMA_VFF_WPT(_n), (~DRV_Reg32(DMA_VFF_WPT(_n)))&0x10000);\
+		else \
+		DRV_WriteReg32(DMA_VFF_WPT(_n), DRV_Reg32(DMA_VFF_WPT(_n))+1);
+
+#endif //#if defined(DRV_UART_VFIFO_V3)
+
+
+
+#endif /*#if !defined(DRV_UART_OFF)*/
+#endif /*UART_HW_H*/
+
+
diff --git a/mcu/driver/devdrv/uart/inc/uart_internal.h b/mcu/driver/devdrv/uart/inc/uart_internal.h
new file mode 100644
index 0000000..cb0c0f7
--- /dev/null
+++ b/mcu/driver/devdrv/uart/inc/uart_internal.h
@@ -0,0 +1,665 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2001
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   dcl_uart.h
+ *
+ * Project:
+ * --------
+ *   Maui
+ *
+ * Description:
+ * ------------
+ *   Header file of DCL (Driver Common Layer) for UART.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ ****************************************************************************/
+#ifndef __UART_INTERNAL_H__
+#define __UART_INTERNAL_H__
+
+#include "uart_sw.h"
+#include "dcl.h"
+
+#include "kal_general_types.h"
+#include "drv_comm.h"
+
+#include "qmu_bm.h"
+#include "qmu_bm_size.h"
+#include "qmu_bm_util.h"
+
+typedef enum {
+      UART_ON_VFIFO,
+	UART_ON_DMA,
+      UART_ON_MCU,
+      UART_ON_UNKNOWN
+} UART_WORKING_MODE;
+
+#define  UART_STAT_EscDet        0x01
+#define  UART_STAT_Break         0x02
+
+#define  UART_RecNormal          0
+#define  UART_Get3EscChar        1
+#define  UART_StartCheckESC      2
+
+#define UART1_HDMA_TX_CHANNEL		2
+#define UART1_HDMA_RX_CHANNEL		3
+
+/*TY adds these to expand flexibility 2004/10/15*/
+typedef void (*UART_TX_FUNC)(UART_PORT port); 
+typedef void (*UART_RX_FUNC)(UART_PORT port) ; 
+
+
+typedef struct
+{
+      UART_PORT                      port_no;
+      kal_bool                       initialized;
+      kal_bool                       power_on;
+      module_type                    ownerid;
+      module_type                    UART_id;
+      kal_bool                       breakDet;
+      kal_bool                       EscFound;
+      UARTDCBStruct                  DCB;
+      UART_RingBufferStruct          RingBuffers;
+      UART_ESCDetectStruct           ESCDet;
+      BUFFER_INFO                    Tx_Buffer_ISR; /* receive buffer */
+      BUFFER_INFO                    Rx_Buffer;  /* receive buffer */
+      BUFFER_INFO                    Tx_Buffer;  /* transmit buffer */
+      kal_hisrid                     hisr;
+      IO_level                       DSR;
+      /*detect Escape*/
+      DCL_HANDLE                      handle;    /*GPT handle*/
+      kal_uint8                      EscCount;
+      kal_uint8                      Rec_state; /**/
+      UART_SLEEP_ON_TX               sleep_on_tx;
+      kal_bool               		EnableTX;
+      /*TY adds these to expand flexibility 2004/10/15*/
+      UART_TX_FUNC                  tx_cb;
+      UART_RX_FUNC                  rx_cb;
+      //#ifdef __DMA_UART_VIRTUAL_FIFO__
+	kal_uint8 			Rx_DMA_Ch;
+	kal_uint8 			Tx_DMA_Ch;
+      //#endif
+      
+#if defined(DRV_UART_VFIFO_V2)
+#if defined(DRV_UART_VFIFO_V2_USE_GPT)
+	DCL_HANDLE uart_flush_timer_handle;    /*GPT handle*/
+	DCL_HANDLE uart_isr_flush_timer_handle;    /*GPT handle*/
+#else
+	kal_timerid   uart_flush_timer_id;
+#endif //DRV_UART_VFIFO_V2_USE_GPT
+#endif /* defined(DRV_UART_VFIFO_V1) */
+
+
+	// added by ansel for new TTY API
+	kal_bool		need_tx_done_cb;
+} UARTStruct;
+
+// for uart dispatch table 
+typedef enum
+{
+	UART_TYPE = 0,
+	IRDA_TYPE,
+	USB_TYPE,
+	BLUETOOTH_TYPE,
+	CMUX_TYPE
+}UartType_enum;
+
+typedef struct
+{
+	kal_uint32 timer_old;
+	kal_uint32 timer_now;
+	kal_uint32 timer_during;
+	kal_uint32 timer_start;
+}UART_ecpt_timer_t;
+
+typedef struct _uartdriver
+{
+	
+	kal_bool (*Open)(UART_PORT port, module_type ownerid);
+	void (*Close)(UART_PORT port, module_type ownerid);
+	kal_uint16 (*GetBytes)(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+	kal_uint16 (*PutBytes)(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+	kal_uint16 (*GetRxAvail)(UART_PORT port);
+	kal_uint16 (*GetTxAvail)(UART_PORT port);
+	kal_uint16 (*PutISRBytes)(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+	kal_uint16 (*GetISRTxAvail)(UART_PORT port);
+	void (*Purge)(UART_PORT port, UART_buffer dir, module_type ownerid);	
+	//void (*SetOwner)(UART_PORT port, kal_uint8 ownerid);
+	void (*SetOwner)(UART_PORT port, module_type ownerid);
+	void (*SetFlowCtrl)(UART_PORT port, kal_bool XON, module_type ownerid);
+	void (*ConfigEscape)(UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid);
+	void (*SetDCBConfig)(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid);
+	void (*CtrlDCD)(UART_PORT port, IO_level SDCD, module_type ownerid);
+	void (*CtrlBreak)(UART_PORT port, IO_level SBREAK, module_type ownerid);
+	void (*ClrRxBuffer)(UART_PORT port, module_type ownerid);
+	void (*ClrTxBuffer)(UART_PORT port, module_type ownerid);	
+	void (*SetBaudRate)(UART_PORT port, UART_baudrate baudrate, module_type ownerid);	
+	kal_uint16 (*SendISRData)(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid);
+	kal_uint16 (*SendData)(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid);
+	module_type (*GetOwnerID)(UART_PORT port);	
+	void (*SetAutoBaud_Div)(UART_PORT port, module_type ownerid);			
+	/*TY adds these to expand flexibility 2004/10/15*/
+	void (*UART_Register_TX_cb)(UART_PORT port, module_type ownerid, UART_TX_FUNC func);
+	void (*UART_Register_RX_cb)(UART_PORT port, module_type ownerid, UART_RX_FUNC func);	
+	/*TY adds these to let virtual COM port can retrive exception log 2005/3/8*/
+	kal_uint8 (*GetUARTByte)(UART_PORT port);	
+	void (*PutUARTByte)(UART_PORT port, kal_uint8 data);	
+	void (*PutUARTBytes)(UART_PORT port, kal_uint8 *data, kal_uint16 len);		
+	/*for virtual com port to return DCB configuration*/
+	void (*ReadDCBConfig)(UART_PORT port, UARTDCBStruct *UART_Config);	
+	void (*CtrlRI)(UART_PORT port, IO_level SRI, module_type ownerid);	
+	void (*CtrlDTR)(UART_PORT port, IO_level SDTR, module_type ownerid);	
+	void (*ReadHWStatus)(UART_PORT port, IO_level *SDSR, IO_level *SCTS);	
+	kal_uint8 (*GetUARTByte_WithTimeOut)(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value);
+}UartDriver_strcut;
+
+/*Function Declaration*/
+extern UartDriver_strcut UartDriver;	
+
+
+extern kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM];
+#ifdef __DMA_UART_VIRTUAL_FIFO__	
+extern UartDriver_strcut UartDriver_VFIFO;
+#endif
+
+extern UartDriver_strcut* pUart_CMD_FUNC[];
+
+
+
+extern void UART1_PDN_ENABLE(void);
+extern void UART1_PDN_DISABLE(void);
+extern void UART2_PDN_ENABLE(void);
+extern void UART2_PDN_DISABLE(void);
+
+/*ISR handler for VFIFO*/
+extern void UART_RecTimeOutHandler(UART_PORT port);
+extern void UART_TrxHandler_VFIFO(UART_PORT port);
+extern void UART_RecHandler_VFIFO(UART_PORT port);
+extern void UART_THRE_hdr_VFIFO(UART_PORT port);
+/*API for VFIFO*/
+extern void U_configure_DMA_VFIFO(void);
+extern kal_uint16 U_GetTxISRRoomLeft_VFIFO(UART_PORT port);
+extern kal_uint16 U_GetTxRoomLeft_VFIFO(UART_PORT port);
+extern kal_uint16 U_GetBytesAvail_VFIFO(UART_PORT port);
+extern kal_uint8 U_GetUARTByte_VFIFO(UART_PORT port);
+extern void U_PutUARTByte_VFIFO(UART_PORT port, kal_uint8 data);
+extern void PutUARTData_VFIFO(UART_PORT port, kal_uint8 escape_char, kal_uint8 data);
+extern kal_uint16 U_GetBytes_VFIFO(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+extern kal_uint16 U_PutBytes_VFIFO(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+extern kal_uint16 U_PutISRBytes_VFIFO(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+extern kal_uint16 U_SendData_VFIFO(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid);
+extern kal_uint16 U_SendISRData_VFIFO(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid);
+extern kal_bool UART_UseVFIFO(UART_PORT port, kal_bool use_vfifo);
+
+extern void UART_DriverInit(UART_PORT port);
+extern void UART_set_FIFO_trigger(UART_PORT port, kal_uint16 tx_level, kal_uint16 rx_level);
+
+/* Note: for ROM code start */
+#ifdef __ROMSA_SUPPORT__
+/*for mcu rom*/
+extern kal_uint16 U_GetTxISRRoomLeft(UART_PORT port);
+extern kal_uint16 U_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+extern kal_uint16 U_ROM_GetTxISRRoomLeft(UART_PORT port);
+extern UARTStruct *U_ROM_GetUARTPort(UART_PORT port);
+extern kal_uint8 *U_ROM_GetUART_TXilm(UART_PORT port);
+extern void U_ROM_InformUARTOwner(UART_PORT port);
+extern void U_ROM_PushDataToBuf(UART_PORT port, kal_uint8 *data, kal_uint32 real_count);
+extern void U_ROM_EnableTxIntr(UART_PORT port);
+//extern void DRVPDN_Disable(kal_uint32 addr,kal_uint16 code,kal_uint8 handle);
+#endif
+/* Note: for ROM code end */
+
+// Used under ASSERT condition
+// This has effect only when the port does NOT support VFIFO and used as Catcher port
+extern void UART_AssertWaitPrevDataSentOut(UART_PORT port);
+
+
+extern kal_bool UART1DMA_Ini(kal_bool Tx);
+extern kal_bool UART2DMA_Ini(kal_bool Tx);
+extern kal_uint8 GetUARTByte(UART_PORT port);
+extern void PutUARTByte(UART_PORT port, kal_uint8 data);
+extern void UART_SetBaudRate(UART_PORT port, UART_baudrate baud_rate, module_type ownerid);
+extern void UART_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid);
+extern void UART_ReadDCBConfig (UART_PORT port, UARTDCBStruct *DCB);
+extern void UART_loopback(UART_PORT port);
+extern void UART_HWInit(UART_PORT port);
+extern kal_bool UART_Open(UART_PORT port, module_type ownerid);
+extern void UART_Close(UART_PORT port, module_type ownerid);
+//extern void UART_SetOwner (UART_PORT port, kal_uint8 ownerid);
+extern void UART_SetOwner (UART_PORT port, module_type ownerid);
+extern void UART_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid);
+extern void UART_CtrlDTR (UART_PORT port, IO_level SDTR, module_type ownerid);
+extern void UART_ReadHWStatus(UART_PORT port, IO_level *SDSR, IO_level *SCTS);
+extern void UART_CtrlBreak(UART_PORT port, IO_level SBREAK, module_type ownerid);
+extern void UART_Purge(UART_PORT port, UART_buffer dir, module_type ownerid);
+extern void UART_Register_RX_cb(UART_PORT port, module_type ownerid, UART_RX_FUNC func);
+extern void UART_Register_TX_cb(UART_PORT port, module_type ownerid, UART_TX_FUNC func);
+
+//API for single tunnel VFIFO
+extern kal_uint16 U_GetBytesAvail(UART_PORT port);
+extern kal_uint16 U_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+extern kal_uint8  U_GetUARTByte(UART_PORT port);
+extern kal_uint16 U_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid );
+extern kal_uint16 U_GetTxRoomLeft(UART_PORT port);
+extern kal_uint16 U_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid);
+extern kal_uint16 U_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid);
+extern void       U_PutUARTByte(UART_PORT port, kal_uint8 data);
+
+extern void UART_Boot_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len);
+extern void UART_Bootup_Init(void);
+extern kal_uint16 UART_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+extern kal_uint16 UART_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+extern kal_uint16 UART_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid);
+extern kal_uint16 UART_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid);
+extern kal_uint16 UART_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid );
+extern void UART_SetFlowCtrl(UART_PORT port, kal_bool XON, module_type ownerid);
+extern void UART_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid);
+extern void UART_CtrlRI (UART_PORT port, IO_level SRI, module_type ownerid);
+extern kal_uint16 UART_GetBytesAvail(UART_PORT port);
+extern void UART_SleepOnTx_Enable(UART_PORT port, UART_SLEEP_ON_TX enable_flag);
+extern void UART_SetSleepEnable(UART_PORT port, kal_bool enable);
+extern void UART_SwitchPort(UART_PORT *APP_port, UART_PORT new_uart_port);
+extern void UART_dafault_tx_cb(UART_PORT port);
+extern void UART_dafault_rx_cb(UART_PORT port);
+extern void UART_TurnOnPower(UART_PORT port, kal_bool enable);
+extern kal_bool UART_CheckTxBufferEmpty(UART_PORT port);
+extern kal_bool UART_CheckTxAllSentOut(UART_PORT port);
+extern void UART_GetTxBufferSize(UART_PORT port, kal_uint32 *total_size, kal_uint32 *rest_size);
+extern void UART1_HISR(void);
+extern void UART2_HISR(void);
+extern void UART3_HISR(void);
+extern void UART1_LISR(kal_uint32 vector);
+extern void UART2_LISR(kal_uint32 vector);
+extern void UART3_LISR(kal_uint32 vector);
+extern void uart_hdma_lisr(kal_uint32 vector);
+extern void uart_hdma_hisr(void);
+extern kal_bool uart_support_autoescape(void);
+
+extern void uart_ecpt_timer_reset(UART_PORT port);
+extern void uart_ecpt_timer_start(UART_PORT port);
+extern kal_uint32 uart_ecpt_get_timer_during(UART_PORT port);
+
+void UART_VFIFO_TX_DMA_Enable(UART_PORT port,kal_bool enable);
+void UART_dsp_dafault_rx_cb(UART_PORT port);
+void UART_dsp_dafault_tx_cb(UART_PORT port);
+kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length);
+kal_uint32 UART_Get_Maxbaudrate(UART_PORT port);
+
+kal_uint32 UART_PutBytesIor(UART_PORT port, void *putIor);
+kal_uint32 UART_PutBytesIor_LIGHT(UART_PORT port, void *putIor);
+kal_uint32 UART_GetBytesIor(UART_PORT port, void *ior);
+void UART_SetNeedTxDoneCb(UART_PORT port, kal_bool needTxDoneCb, module_type ownerid);
+
+kal_uint32 U_GetFlowCtrl(UART_PORT port, module_type ownerid);
+kal_uint32 uart_cal_tgpd_buf_length(void *head, void *tail);
+void uart_en_q_de_q_with_mutex(UART_PORT port, kal_bool tx_or_rx, kal_uint8 en_q_or_de_q, void *p_ior_head, void *p_ior_tail);
+DCL_STATUS uart_en_q_de_q_for_ecpt(UART_PORT port, kal_bool tx_or_rx, kal_uint8 en_q_or_de_q, void **p_ior_head, void **p_ior_tail, kal_uint32 *num);
+void uart_cal_chksum_and_flush_gpd_list(void *gpd_head, void *gpd_tail);
+void uart_clear_hwo_of_gpd_list(void *gpd_head, void *gpd_tail);
+
+DCL_STATUS uart_ecpt_init_hif(UART_PORT port);
+DCL_STATUS uart_ecpt_clear_ch(UART_PORT port);
+DCL_STATUS uart_ecpt_tx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd);
+DCL_STATUS uart_ecpt_tx_done_info(UART_PORT port, void **p_first_gpd, void **p_last_gpd, kal_uint32 *gpd_num);
+DCL_STATUS uart_ecpt_assign_rx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd);
+DCL_STATUS uart_ecpt_get_rx_gpd(UART_PORT port, void **p_first_gpd, void **p_last_gpd, kal_uint32 *gpd_num);
+
+/*end of local parameter struct */
+#define EnableRxIntr(_baseaddr)   \
+{\
+      kal_uint32 _savedMask;\
+      kal_uint16 _IER;\
+      _savedMask = SaveAndSetIRQMask();\
+      _IER = DRV_Reg(UART_IER(_baseaddr));\
+      _IER |= (UART_IER_ERBFI | UART_IER_ELSI);\
+      DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+      RestoreIRQMask(_savedMask);\
+}
+
+#define DisableRxIntr(_baseaddr)   \
+{\
+   kal_uint16 _IER;\
+   kal_uint32 _savedMask;\
+   _savedMask = SaveAndSetIRQMask();\
+   _IER = DRV_Reg(UART_IER(_baseaddr));\
+   _IER &= ~(UART_IER_ERBFI|UART_IER_ELSI);\
+   DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+   RestoreIRQMask(_savedMask);\
+}
+
+
+#define EnableTxIntr(_baseaddr)   \
+{\
+   kal_uint16 _IER;\
+   kal_uint32 _savedMask;\
+   _savedMask = SaveAndSetIRQMask();\
+   _IER = DRV_Reg(UART_IER(_baseaddr));\
+   _IER |= UART_IER_ETBEI;\
+   DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+   RestoreIRQMask(_savedMask);\
+}
+
+#define DisableTxIntr(_baseaddr)   \
+{\
+   kal_uint16 _IER;\
+   kal_uint32 _savedMask;\
+   _savedMask = SaveAndSetIRQMask();\
+   _IER = DRV_Reg(UART_IER(_baseaddr));\
+   _IER &= ~UART_IER_ETBEI;\
+   DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+   RestoreIRQMask(_savedMask);\
+}
+
+#define UART_SetDMAIntr(_baseaddr) \
+{\
+   kal_uint16 _IER;\
+   kal_uint32 _savedMask;\
+   _savedMask = SaveAndSetIRQMask();\
+   _IER = DRV_Reg(UART_IER(_baseaddr));\
+   _IER &= ~(UART_IER_ETBEI);\
+   DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+   RestoreIRQMask(_savedMask);\
+}
+
+#define DisableRLSIntr(_baseaddr)   \
+{\
+   kal_uint16 _IER;\
+   kal_uint32 _savedMask;\
+   _savedMask = SaveAndSetIRQMask();\
+   _IER = DRV_Reg(UART_IER(_baseaddr));\
+   _IER &= ~(UART_IER_ELSI);\
+   DRV_WriteReg(UART_IER(_baseaddr),_IER);\
+   RestoreIRQMask(_savedMask);\
+}
+
+
+extern UART_WORKING_MODE UART_GetTxWorkingMode(UART_PORT port);
+
+#if defined(__MTK_INTERNAL__) && !defined(__MAUI_BASIC__) && defined(__DRV_DBG_MEMORY_TRACE_SUPPORT__)
+#define DRV_UART_MEMORY_TRACE
+typedef struct{
+   kal_uint16      tag;
+   kal_uint32      time;
+   kal_uint32      data1;
+   kal_uint32      data2;
+}UART_DRV_DBG_DATA;
+#define MAX_UART_DRV_DBG_INFO_SIZE 512
+typedef struct{
+   UART_DRV_DBG_DATA   dbg_data[MAX_UART_DRV_DBG_INFO_SIZE];
+   kal_uint16          dbg_data_idx;
+}UART_DRV_DBG_STRUCT;
+extern void uart_drv_dbg_trace(kal_uint16 index, kal_uint32 time, kal_uint32 data1, kal_uint32 data2);
+#define UART_DBG(a,b,c,d) uart_drv_dbg_trace(a,b,c,d);
+#include "us_timer.h"
+extern kal_uint32 L1I_GetTimeStamp(void);
+#define UART_GetTimeStamp L1I_GetTimeStamp
+#else //#if defined(__MTK_INTERNAL__) && !defined(LOW_COST_SUPPORT)
+#define UART_DBG(a,b,c,d) ;
+#endif //#if defined(__MTK_INTERNAL__) && !defined(LOW_COST_SUPPORT)
+
+
+
+#if defined(__DRV_COMM_REG_DBG__) && defined(__DRV_UART_REG_DBG__)
+#define DRV_UART_WriteReg(addr,data)              DRV_DBG_WriteReg(addr,data)
+#define DRV_UART_Reg(addr)                        DRV_DBG_Reg(addr)                      
+#define DRV_UART_WriteReg32(addr,data)            DRV_DBG_WriteReg32(addr,data)          
+#define DRV_UART_Reg32(addr)                      DRV_DBG_Reg32(addr)                    
+#define DRV_UART_WriteReg8(addr,data)             DRV_DBG_WriteReg8(addr,data)           
+#define DRV_UART_Reg8(addr)                       DRV_DBG_Reg8(addr)                     
+#define DRV_UART_ClearBits(addr,data)             DRV_DBG_ClearBits(addr,data)           
+#define DRV_UART_SetBits(addr,data)               DRV_DBG_SetBits(addr,data)             
+#define DRV_UART_SetData(addr, bitmask, value)    DRV_DBG_SetData(addr, bitmask, value)  
+#define DRV_UART_ClearBits32(addr,data)           DRV_DBG_ClearBits32(addr,data)         
+#define DRV_UART_SetBits32(addr,data)             DRV_DBG_SetBits32(addr,data)           
+#define DRV_UART_SetData32(addr, bitmask, value)  DRV_DBG_SetData32(addr, bitmask, value)
+#define DRV_UART_ClearBits8(addr,data)            DRV_DBG_ClearBits8(addr,data)          
+#define DRV_UART_SetBits8(addr,data)              DRV_DBG_SetBits8(addr,data)            
+#define DRV_UART_SetData8(addr, bitmask, value)   DRV_DBG_SetData8(addr, bitmask, value) 
+#else
+#define DRV_UART_WriteReg(addr,data)              DRV_WriteReg(addr,data)
+#define DRV_UART_Reg(addr)                        DRV_Reg(addr)                      
+#define DRV_UART_WriteReg32(addr,data)            DRV_WriteReg32(addr,data)          
+#define DRV_UART_Reg32(addr)                      DRV_Reg32(addr)                    
+#define DRV_UART_WriteReg8(addr,data)             DRV_WriteReg8(addr,data)           
+#define DRV_UART_Reg8(addr)                       DRV_Reg8(addr)                     
+#define DRV_UART_ClearBits(addr,data)             DRV_ClearBits(addr,data)           
+#define DRV_UART_SetBits(addr,data)               DRV_SetBits(addr,data)             
+#define DRV_UART_SetData(addr, bitmask, value)    DRV_SetData(addr, bitmask, value)  
+#define DRV_UART_ClearBits32(addr,data)           DRV_ClearBits32(addr,data)         
+#define DRV_UART_SetBits32(addr,data)             DRV_SetBits32(addr,data)           
+#define DRV_UART_SetData32(addr, bitmask, value)  DRV_SetData32(addr, bitmask, value)
+#define DRV_UART_ClearBits8(addr,data)            DRV_ClearBits8(addr,data)          
+#define DRV_UART_SetBits8(addr,data)              DRV_SetBits8(addr,data)            
+#define DRV_UART_SetData8(addr, bitmask, value)   DRV_SetData8(addr, bitmask, value) 
+#endif //#if defined(__DRV_COMM_REG_DBG__) && defined(__DRV_UART_REG_DBG__)
+
+
+
+#define GDMA_BASE_ADDR				BASE_ADDR_MDGDMA
+#define APGDMA_BASE_ADDR			BASE_ADDR_APGDMA
+
+#if defined(__MD93__) ||defined(__MD95__) 
+#define UART_HDMA_INTR_ID   MD_IRQID_MDGDMA3
+#elif defined(MT6297) 
+#define UART_HDMA_INTR_ID   MD_IRQID_MDGDMA5
+#elif defined(MT6885) ||defined(__MD97P__) ||defined(MT6873) ||defined(MT6853)||defined(MT6893)||defined(MT6833)||defined(MT6877)||defined(CHIP10992)
+#define UART_HDMA_INTR_ID   MD_IRQID_MDGDMA_HDMA2_3
+#endif
+
+#define HDMA_BURST_SIZE_DEFAULT			(HDMA_BURST_SIZE_16B)
+#define HDMA_DEV_BUS_WIDTH_DEFAULT		(HDMA_DEV_BUS_WIDTH_1B)
+#define HDMA_MEM_BUS_WIDTH_DEFAULT		(HDMA_MEM_BUS_WIDTH_4B)
+#define HDMA_MODE_DEFAULT			(HDMA_BASIC_MODE)
+#define HDMA_CKSUM_EN_DEFAULT			(HDMA_CKSUM_ON)
+#define HDMA_CKSUM_MODE_DEFAULT			(HDMA_CKSUM_16B)
+
+/* HDMA registers */
+#define GDMA_HDCSR(_n)				(GDMA_BASE_ADDR + 0x100 + (_n/2 * 0x4))
+#define GDMA_HDSR                               (GDMA_BASE_ADDR + 0x120)
+#define GDMA_HDCPR                              (GDMA_BASE_ADDR + 0x124)
+#define GDMA_HDCTRR(_n)				(GDMA_BASE_ADDR + 0x140 + (_n * 0x20))
+#define GDMA_HDC0R(_n)				(GDMA_BASE_ADDR + 0x144 + (_n * 0x20))
+#define GDMA_HDC1R(_n)				(GDMA_BASE_ADDR + 0x148 + (_n * 0x20))
+#define GDMA_HPRGA0R(_n)			(GDMA_BASE_ADDR + 0x14C + (_n * 0x20))
+#define GDMA_HPRGA1R(_n)			(GDMA_BASE_ADDR + 0x150 + (_n * 0x20))
+#define GDMA_HCCR(_n)				(GDMA_BASE_ADDR + 0x154 + (_n * 0x20))
+#define GDMA_HDCPRN(_n)				(GDMA_BASE_ADDR + 0x158 + (_n * 0x20))
+#if defined(__MD93__)|| defined(__MD95__)
+#define GDMA_GISAR_UART				(GDMA_BASE_ADDR + 0x60c)                                        //GDMA_GISAR3
+#define GDMA_GIMRK_UART				(GDMA_BASE_ADDR + 0x62c)                                        //GDMA_GIMRK3
+#elif defined(__MD97__)||defined(__MD97P__)
+#define GDMA_GISAR_UART				(GDMA_BASE_ADDR + 0x614)                                        //GDMA_GISAR5
+#define GDMA_GIMRK_UART				(GDMA_BASE_ADDR + 0x634)                                        //GDMA_GIMRK5
+#endif
+#define APGDMA_HDCSR(_n)			(APGDMA_BASE_ADDR + 0x100 + (_n/2 * 0x4))
+#define APGDMA_HDSR				(APGDMA_BASE_ADDR + 0x120)
+#define APGDMA_HDCPR				(APGDMA_BASE_ADDR + 0x124)
+#define APGDMA_HDCTRR(_n)			(APGDMA_BASE_ADDR + 0x140 + (_n * 0x20))
+#define APGDMA_HDC0R(_n)			(APGDMA_BASE_ADDR + 0x144 + (_n * 0x20))
+#define APGDMA_HDC1R(_n)			(APGDMA_BASE_ADDR + 0x148 + (_n * 0x20))
+#define APGDMA_HPRGA0R(_n)			(APGDMA_BASE_ADDR + 0x14C + (_n * 0x20))
+#define APGDMA_HPRGA1R(_n)			(APGDMA_BASE_ADDR + 0x150 + (_n * 0x20))
+#define APGDMA_HCCR(_n)				(APGDMA_BASE_ADDR + 0x154 + (_n * 0x20))
+#define APGDMA_HDCPRN(_n)			(APGDMA_BASE_ADDR + 0x158 + (_n * 0x20))
+#define APGDMA_GISAR_UART			(APGDMA_BASE_ADDR + 0x60C)                                        //GDMA_GISAR3
+#define APGDMA_GIMRK_UART			(APGDMA_BASE_ADDR + 0x62C)                                        //GDMA_GIMRK3
+
+#define HDMA_START_BIT				(0x1)
+#define HDMA_STOP_BIT				(0x4)
+#define HDMA_RESUME_BIT				(0x2)
+
+#define HDMA_STAT				(0x1)
+#define HDMA_RX_SEL_MASK            (0xC0000000)
+#define HDMA_CONFIG_MASK			(0x3FFFF)
+#define HDMA_MODE_MASK(_n)			(0xFFFF << (16 *(_n %2)))
+
+#define HDMA_INTR_CHL_MASK(_n)			(1 << (_n -2))
+
+typedef enum{
+	HDMA_BURST_SIZE_4B = 2,
+	HDMA_BURST_SIZE_8B = 3,
+	HDMA_BURST_SIZE_16B = 4,
+	HDMA_BURST_SIZE_MAX,
+}drv_uart_hdma_burst_size_t;
+
+typedef enum{
+	HDMA_DEV_BUS_WIDTH_1B = 0,
+	HDMA_DEV_BUS_WIDTH_MAX,	
+}drv_uart_hdma_dev_bus_width;
+
+typedef enum{
+	HDMA_MEM_BUS_WIDTH_1B = 0,
+	HDMA_MEM_BUS_WIDTH_2B = 1,
+	HDMA_MEM_BUS_WIDTH_4B = 2,
+	HDMA_MEM_BUS_WIDTH_MAX,	
+}drv_uart_hdma_mem_bus_width;
+
+typedef enum{
+	HDMA_LIST_MODE = 0,
+	HDMA_BASIC_MODE = 1,
+	HDMA_DESCRIPTOR_MODE = 2,	
+}drv_uart_hdma_mode;
+
+typedef enum{
+	HDMA_CKSUM_OFF	= 0,
+	HDMA_CKSUM_ON	= 1,
+}drv_uart_hdma_cksum_en;
+
+typedef enum{
+	HDMA_CKSUM_12B = 0,
+	HDMA_CKSUM_16B = 1,
+}drv_uart_hdma_cksum_mode;
+
+typedef enum{
+	UART_EN_Q = 0,
+	UART_DE_Q = 1,
+	UART_EN_Q_LIGHT = 2,
+	UART_DE_Q_ALL = 3,
+} drv_uart_en_q_or_de_q;
+
+typedef struct{
+	drv_uart_hdma_burst_size_t			bst_size;
+	drv_uart_hdma_dev_bus_width 			dev_bus_width;
+	drv_uart_hdma_mem_bus_width 			mem_bus_width;
+	drv_uart_hdma_mode				mode;
+	drv_uart_hdma_cksum_en				cksum_en;
+	drv_uart_hdma_cksum_mode			cksum_mode;
+}drv_uart_hdma_config_t;
+
+#define HDMA_CONFIG_INIT(_bst, _devbus, _membus, _mode, _cksum_en,_cksum) \
+	{ _bst, _devbus, _membus, _mode, _cksum_en, _cksum}
+
+typedef enum{
+	GDMA_MODE_HDMA = 0,
+	GDMA_MODE_VDMA = 1,
+}drv_uart_gdma_mode;
+
+
+/* HDMA commands */
+#define HDMA_CONFIG_RX_SEL(_n, _v) \
+    DRV_WriteReg32(GDMA_HDCTRR(_n), (DRV_Reg32(GDMA_HDCTRR(_n))& ~HDMA_RX_SEL_MASK)|((_v)&0x3)<<30)
+#define HDMA_CONFIG(_n, _bst, _devbus, _membus) \
+	DRV_WriteReg32_NPW(GDMA_HDCTRR(_n), (DRV_Reg32(GDMA_HDCTRR(_n)) & ~HDMA_CONFIG_MASK) | (_bst << 12) |( _devbus << 6) |(_membus << 4))
+#define HDMA_MODE_CONFIG(_n, _cksum_en,_mode, _cksum) \
+	DRV_WriteReg32_NPW(GDMA_HDCSR(_n), (DRV_Reg32(GDMA_HDCSR(_n)) & ~(HDMA_MODE_MASK(_n))) |(_cksum_en << (15 + (16 *(_n %2))))| (_mode << (9 + (16 *(_n %2)))) |(_cksum << (8 + (16 *(_n %2)))))
+#define APHDMA_CONFIG(_n, _bst, _devbus, _membus) \
+	DRV_WriteReg32_NPW(APGDMA_HDCTRR(_n), (DRV_Reg32(APGDMA_HDCTRR(_n)) & ~HDMA_CONFIG_MASK) | (_bst << 13) |( _devbus << 6) |(_membus << 4))
+#define APHDMA_MODE_CONFIG(_n, _cksum_en,_mode, _cksum) \
+	DRV_WriteReg32_NPW(APGDMA_HDCSR(_n), (DRV_Reg32(APGDMA_HDCSR(_n)) & ~(HDMA_MODE_MASK(_n))) |(_cksum_en << (15 + (16 *(_n %2))))| (_mode << (9 + (16 *(_n %2)))) |(_cksum << (8 + (16 *(_n %2)))))
+
+
+#define HDMA_BUF0_XFER_SIZE_CONFIG(_n, _xfer) \
+	DRV_WriteReg32(GDMA_HDC0R(_n), (_xfer << 16))
+#define HDMA_BUF0_PROG_ADDR_CONFIG(_n, _addr) \
+	DRV_WriteReg32(GDMA_HPRGA0R(_n), _addr)
+#define HDMA_BUF0_START(_n) \
+	DRV_WriteReg32_NPW(GDMA_HDC0R(_n), DRV_Reg32(GDMA_HDC0R(_n)) | HDMA_START_BIT)
+#define HDMA_BUF0_RESUME(_n) \
+	DRV_WriteReg32_NPW(GDMA_HDC0R(_n), DRV_Reg32(GDMA_HDC0R(_n)) | HDMA_RESUME_BIT)
+#define HDMA_BUF0_STOP(_n) \
+	DRV_WriteReg32_NPW(GDMA_HDCTRR(_n), DRV_Reg32(GDMA_HDCTRR(_n)) | HDMA_STOP_BIT)
+#define HDMA_BUF0_IS_ACTIVE(_n) \
+	(DRV_Reg32(GDMA_HDSR) & (HDMA_STAT << (_n)))
+#define HDMA_CHANNEL_CUR_BUF(_n) \
+	( (DRV_Reg32(GDMA_HDCPR) >> (_n)) & 0x1 )
+#define HDMA_INT_CLEAR_ALL() \
+	(DRV_WriteReg32(GDMA_GISAR_UART, 0xFFFFFFFF))
+
+#define APHDMA_BUF0_XFER_SIZE_CONFIG(_n, _xfer) \
+	DRV_WriteReg32_NPW(APGDMA_HDC0R(_n), (_xfer << 16))
+#define APHDMA_BUF0_PROG_ADDR_CONFIG(_n, _addr) \
+	DRV_WriteReg32_NPW(APGDMA_HPRGA0R(_n), _addr)
+#define APHDMA_BUF0_START(_n) \
+	DRV_WriteReg32(APGDMA_HDC0R(_n), DRV_Reg32(APGDMA_HDC0R(_n)) | HDMA_START_BIT)
+#define APHDMA_BUF0_RESUME(_n) \
+	DRV_WriteReg32(APGDMA_HDC0R(_n), DRV_Reg32(APGDMA_HDC0R(_n)) | HDMA_RESUME_BIT)
+#define APHDMA_BUF0_STOP(_n) \
+	DRV_WriteReg32(APGDMA_HDCTRR(_n), DRV_Reg32(APGDMA_HDCTRR(_n)) | HDMA_STOP_BIT)
+#define APHDMA_BUF0_IS_ACTIVE(_n) \
+	(DRV_Reg32(APGDMA_HDSR) & (HDMA_STAT << (_n)))
+#define APHDMA_CHANNEL_CUR_BUF(_n) \
+	( (DRV_Reg32(APGDMA_HDCPR) >> (_n)) & 0x1 )
+#define APHDMA_INT_CLEAR_ALL() \
+	(DRV_WriteReg32(APGDMA_GISAR_UART, 0xFFFFFFFF))
+
+/* HDMA Interrupt Related Macros*/
+#define IS_HDMA_DONE_INTR(_val, _chl) \
+	( _val &  HDMA_INTR_CHL_MASK(_chl))
+#define IS_HDMA_QE_INTR(_val, _chl) \
+	( _val &  (HDMA_INTR_CHL_MASK(_chl) << 8))
+#define IS_HDMA_LENERR_INTR(_val, _chl) \
+	( _val &  (HDMA_INTR_CHL_MASK(_chl) << 16))
+#define IS_HDMA_BD_CSERR_INTR(_val, _chl) \
+	( _val &  (HDMA_INTR_CHL_MASK(_chl) << 24))
+#define IS_HDMA_GPD_CSERR_INTR(_val, _chl) \
+	( _val &  (HDMA_INTR_CHL_MASK(_chl) << 28))
+#define HDMA_INTR_MASK_ALL() \
+	(DRV_WriteReg32(GDMA_GIMRK_UART, 0xFFFFFFFF))
+#define HDMA_INTR_UNMASK_ALL() \
+	(DRV_WriteReg32(GDMA_GIMRK_UART, 0x0))
+#define HDMA_DONE_INTR_MASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) | HDMA_INTR_CHL_MASK(_chl))
+#define HDMA_DONE_INTR_UNMASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) & ~(HDMA_INTR_CHL_MASK(_chl)))
+#define HDMA_QE_INTR_MASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) | (HDMA_INTR_CHL_MASK(_chl) << 8))
+#define HDMA_QE_INTR_UNMASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) & ~((HDMA_INTR_CHL_MASK(_chl)) << 8))
+#define HDMA_LENERR_INTR_MASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) | (HDMA_INTR_CHL_MASK(_chl) << 16))
+#define HDMA_LENERR_INTR_UNMASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) & ~((HDMA_INTR_CHL_MASK(_chl)) << 16))
+#define HDMA_BD_CSERR_INTR_MASK(_chl)	\
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) | (HDMA_INTR_CHL_MASK(_chl) << 24))
+#define HDMA_BD_CSERR_INTR_UNMASK(_chl) \
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) & ~((HDMA_INTR_CHL_MASK(_chl)) << 24))
+#define HDMA_GPD_CSERR_INTR_MASK(_chl)	\
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) | (HDMA_INTR_CHL_MASK(_chl) << 28))
+#define HDMA_GPD_CSERR_INTR_UNMASK(_chl)	\
+	DRV_WriteReg32(GDMA_GIMRK_UART, DRV_Reg32(GDMA_GIMRK_UART) & ~((HDMA_INTR_CHL_MASK(_chl)) << 28))
+
+// UART exception mode
+#define UART_ECPT_QBM_BPS_NUM	15
+#define UART_ECPT_QBM_BPS_BUF_SZ	QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TGPD_BPS, UART_ECPT_QBM_BPS_NUM)
+
+typedef struct _uart_bps_gpd{
+	void		*bps_ptr[UART_ECPT_QBM_BPS_NUM];
+	kal_uint32	bps_cur_idx;
+	kal_uint32	remain_bps_gpd;
+} uart_bps_gpd_t;
+
+#endif
+
diff --git a/mcu/driver/devdrv/uart/src/dbgprint.c b/mcu/driver/devdrv/uart/src/dbgprint.c
new file mode 100644
index 0000000..599069b
--- /dev/null
+++ b/mcu/driver/devdrv/uart/src/dbgprint.c
@@ -0,0 +1,989 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2012
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ *   dbgprint.c
+ *
+ * Project:
+ * --------
+ *   TATAKA
+ *
+ * Description:
+ * ------------
+ *   This Module defines debug function for driver.
+ *
+ * Author:
+ * -------
+ * -------
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 11 16 2020 vend_mcd_cienet018
+ * [MOLY00594178] [colgin] porting uart driver code from NR15.R3.T700.MP to NR15.R3.MD700.MP
+ * [colgin]modify build error in dbgprint.c
+ *
+ * 11 12 2020 vend_mcd_cienet018
+ * [MOLY00594178] [colgin] porting uart driver code from NR15.R3.T700.MP to NR15.R3.MD700.MP
+ * [colgin] porting uart driver code from NR15.R3.T700.MP to NR15.R3.MD700.MP
+ *
+ * 11 12 2020 vend_mcd_cienet018
+ * [MOLY00592922] [Montrose] Call for check in:add option in IDC/UART driver
+ * [Colgin] porting code from T700 to MD700 for uart drver
+ *
+ * 11 10 2020 vend_mcd_cienet018
+ * [MOLY00592922] [Montrose] call for check in: add option in UART driver
+ *
+ * 07 15 2020 yao.xue
+ * [MOLY00546509] Palmer /Petrus-p call for check in: update IDC/UART driver
+ * Palmer/Petrus-p call for check in:updateIDC/UART driver
+ *
+ * 02 15 2019 panu.peisa
+ * [MOLY00384803] [Gen97][SystemService][Change Request] KAL Refactoring Phase-in
+ * 	
+ * Added changes to swrd part.
+ *
+ * 04 10 2018 yuke.ren
+ * [MOLY00318981] Merge SLT Code
+ * .
+ *
+ * 11 07 2017 shenghui.shi
+ * [MOLY00288093] update UART driver to remove no needed project option
+ * update uart driver to remove no needed files
+ *
+ * 09 15 2017 da.li
+ * [MOLY00270315] [System Service][KIR] make ex robust before ex steplog work
+ * Replace INT_QueryExceptionStatus  with #include <ex_public.h>.
+ *
+ * 09 08 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * Build warning(error) fix.
+ *
+ * 09 07 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * UART driver porting for Sylvia.
+ *
+ * 09 07 2017 yao.xue
+ * [MOLY00275927] update uart dbg_print init
+ * update dbgprint init
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * fix build error
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * update UART driver
+ *
+ * 04 24 2017 shenghui.shi
+ * [MOLY00243727] update UART PDN feature
+ * update UART pdn feature,to void system could not entry DCM issue.
+ *
+ * 03 06 2017 shenghui.shi
+ * [MOLY00233604] UART print driver update for baudrate
+ * update UART baudrate
+ *
+ * 02 07 2017 shenghui.shi
+ * [MOLY00228102] [Bianco Bring-up]UMOLYA uart driver update
+ * update UART dbgprint driver
+ *
+ * 09 30 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * .
+ *
+ * 09 22 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * set RX SEL for RX channel
+ *
+ * 09 20 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * .
+ *
+ * 07 05 2016 shenghui.shi
+ * [MOLY00184725] UMOLYA ESL/MASE porting
+ * .
+ *
+ * 05 19 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * .
+ *
+ * 03 15 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * update dbgprint driver for SMP
+ *
+ * 08 05 2015 yuke.ren
+ * [MOLY00135235] [6291+] UART Driver Porting
+ * Merging
+ * 	
+ * 	//UMOLY/DEV/MT6291PLUS.PRE_SB.W1517.DEV/mcu/common/driver/devdrv/uart/src/dbgprint.c
+ * 	
+ * 	to //UMOLY/TRUNK/UMOLY/mcu/common/driver/devdrv/uart/src/dbgprint.c
+ *
+ * 08 05 2015 yuke.ren
+ * [MOLY00135235] [6291+] UART Driver Porting
+ * .
+ *
+ * 08 04 2015 yuke.ren
+ * [MOLY00135235] [6291+] UART Driver Porting
+ * .
+ *
+ * 08 04 2015 yuke.ren
+ * [MOLY00135235] [6291+] UART Driver Porting
+ * .
+ *
+ * 05 22 2014 shenghui.shi
+ * [MOLY00065467] [TK6291] update UART driver for TK6291
+ * .
+ *
+ * 05 22 2014 shenghui.shi
+ * [MOLY00065467] [TK6291] update UART driver for TK6291
+ * update dbg_print() API
+ *
+ * 05 19 2014 shenghui.shi
+ * [MOLY00065467] [TK6291] update UART driver for TK6291
+ * Revert uart dbgprint.c to version1. to fixed dbg_print() undefined error.
+ *
+ * 12 10 2013 shenghui.shi
+ * [MOLY00049628] MT6595 UART merge to Trunk
+ * .
+ *
+ * 11 13 2013 shenghui.shi
+ * [MOLY00046360] add SLT UART  logging API
+ * .
+ *
+ * 09 03 2013 shenghui.shi
+ * [MOLY00035768] fix uart build warnning
+ * 	.
+ *
+ * 09 03 2013 shenghui.shi
+ * [MOLY00035768] fix uart build warnning
+ * .
+ *
+ * 07 18 2013 shenghui.shi
+ * [MOLY00027330] [ARM7toMOLY] ARM7 Build/SYSGEN/Functions Update to TRUNK
+ * add dbgprint for ARM7 using SUART0 port.
+ *
+ * 03 06 2013 ansel.liao
+ * [MOLY00006575] add temporary feature: can use CPU mode UART in normal build
+ * Integration change.
+ *
+ * 03 05 2013 ansel.liao
+ * [MOLY00006575] add temporary feature: can use CPU mode UART in normal build
+ * temporary feature
+ *
+ * 11 30 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * add dbg_flush and corresponding drvtest
+ *
+ * 11 23 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Add UART/HDMA driver
+ ****************************************************************************/
+#define MAXCHARS	512
+#define MAXFRACT    	10000
+#define NumFract        4
+
+#include "drv_comm.h"
+#include "stdarg.h"
+#include "dcl.h"
+
+#include "kal_public_api.h"
+#ifdef KTEST_UART_TRACES
+#include "kal_hrt_api.h"
+#endif
+#include "uart_internal.h"
+#include "uart_hw.h"
+#include "drvpdn.h"
+#include "sync_data.h"
+
+#if (defined(DRV_DEBUG) || defined(__IC_SLT__))
+
+#if  defined( DRV_DEBUG)
+#define DBG_PRINT_PORT		uart_port1 // Use UART1 as debug port (UART_MD)
+#define DBG_PRINT_BAUD		UART_BAUD_1500000
+#else   //defined(__IC_SLT__)
+#define DBG_PRINT_PORT		uart_port1 // Use UART1 as debug port (UART_MD)
+#define DBG_PRINT_BAUD		UART_BAUD_1500000
+#endif
+
+#ifndef KTEST_UART_TRACES
+kal_spinlockid dbg_print_lock = 0;
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+extern kal_spinlockid print_buf_lock;
+#endif
+#endif
+
+extern kal_uint32 UART_BaseAddr[MAX_UART_PORT_NUM];
+extern UARTStruct UARTPort[MAX_UART_PORT_NUM];
+kal_bool dbg_init_flag = KAL_FALSE;
+char print_buf[MAXCHARS];
+
+
+extern void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate, module_type ownerid);
+#include <ex_public.h>
+void dbg_uart_init(void); 
+void itof(char **buf, int i);
+static void itoa(char **buf, int i, int base);
+
+static void dbg_UARTPutByte(kal_uint8 data)
+{
+   volatile kal_uint16 LSR;
+   kal_uint32 uart_base = UART_BaseAddr[DBG_PRINT_PORT];
+   while(1)
+   {
+   	  LSR = DRV_Reg32(UART_LSR(uart_base));
+      if((LSR & UART_LSR_THRE))
+      {
+       	 DRV_WriteReg32(UART_THR(uart_base), data);
+         break;
+      }
+   }
+}
+void itof(char **buf, int i)
+{
+	char *s;
+#define LEN	20
+	int rem, j;
+	static char rev[LEN+1];
+
+	rev[LEN] = 0;
+	s = &rev[LEN];
+	for (j= 0 ; j < NumFract ; j++)
+	{
+		rem = i % 10;
+			*--s = rem + '0';
+		i /= 10;
+	}
+	while (*s)
+	{
+		(*buf)[0] = *s++;
+		++(*buf);
+	}
+}
+
+static void itoa(char **buf, int i, int base)
+{
+	char *s;
+#define LEN	20
+	int rem;
+	static char rev[LEN+1];
+
+	rev[LEN] = 0;
+	if (i == 0)
+	{
+		(*buf)[0] = '0';
+		++(*buf);
+		return;
+	}
+	s = &rev[LEN];
+	while (i)
+	{
+		rem = i % base;
+		if (rem < 10)
+			*--s = rem + '0';
+		else if (base == 16)
+			*--s = "abcdef"[rem - 10];
+		i /= base;
+	}
+	while (*s)
+	{
+		(*buf)[0] = *s++;
+		++(*buf);
+	}
+}
+
+void drv_uart_configure_hdma(kal_uint32 uart_port)
+{
+	kal_uint32 uart_hdma_tx_channel, uart_hdma_rx_channel;
+	switch(uart_port){
+		case uart_port1:
+			uart_hdma_tx_channel = UART1_HDMA_TX_CHANNEL;
+			uart_hdma_rx_channel = UART1_HDMA_RX_CHANNEL;
+			// init TX HDMA
+			HDMA_MODE_CONFIG(uart_hdma_tx_channel, HDMA_CKSUM_EN_DEFAULT, HDMA_BASIC_MODE, HDMA_CKSUM_12B);
+			HDMA_CONFIG(UART1_HDMA_TX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+			HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_TX_CHANNEL, 0);
+
+			// init RX HDMA
+			HDMA_CONFIG_RX_SEL(UART1_HDMA_RX_CHANNEL, 0x3);
+			HDMA_MODE_CONFIG(uart_hdma_rx_channel, HDMA_CKSUM_EN_DEFAULT, HDMA_BASIC_MODE, HDMA_CKSUM_12B);
+			HDMA_CONFIG(UART1_HDMA_RX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+			HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_RX_CHANNEL, 0);
+
+			DRV_WriteReg32(UART_DMA_EN(UART_BaseAddr[uart_port]), UART_TXRXDMA_ON|UART_TO_CNT_AUTORST);
+			DRV_WriteReg32(UART_DMA_ACK(UART_BaseAddr[uart_port]),UART_DMA_ACK_DIS);
+			break;
+		case uart_port2:
+			break;
+		default:
+			ASSERT(0);
+			break;
+	} 
+}
+
+extern void UART_PDN_Disable(UART_PORT port);
+
+void drv_uart_IOPAD_configure(DCL_DEV uart_port) {
+
+    // APB Module gpio
+    #define GPIO_BASE   (0xC0005000)
+
+#if defined(MT6893)  // for Petrus-P
+	if(uart_port== uart_port1) {
+		/* GPIO36/37 set to function6 */
+		DRV_WriteReg32((GPIO_BASE+0x348), (0xFF << 16));
+		DRV_WriteReg32((GPIO_BASE+0x344), (0x44 << 16));
+
+		DRV_WriteReg32((0xC1F20000+0x68), (0X3 << 17));
+		DRV_WriteReg32((0xC1F20000+0x84), (0X1 << 17));
+
+	} else if (uart_port== uart_port2) {
+
+		/* GPIO38/GPIO39 set to function4 */
+		DRV_WriteReg32((GPIO_BASE+0x348), (0xFF << 24));
+		DRV_WriteReg32((GPIO_BASE+0x344), (0x44 << 24));
+
+		DRV_WriteReg32((0xC1F20000+0x68), (0X3 << 19));
+		DRV_WriteReg32((0xC1F20000+0x84), (0X1 << 19));
+
+	} else if (uart_port == uart_port3) {
+		/* Do nothing */
+		/*Bianco not have MDUART2 port*/
+	}
+#elif defined(MT6833)  // for PALMER
+	    if(uart_port== uart_port1) {
+	        /* GPIO35/36 set to function6 */
+	        DRV_WriteReg32((GPIO_BASE+0x348), (0xFF << 12));
+	        DRV_WriteReg32((GPIO_BASE+0x344), (0x44 << 12));
+
+		DRV_WriteReg32((0xC1E60000+0xC8), (0X3 << 6));
+		DRV_WriteReg32((0xC1E60000+0xE4), (0X1 << 6));
+
+	    } else if (uart_port== uart_port2) {		
+	        /* GPIO37/38 set to function4 */
+	        DRV_WriteReg32((GPIO_BASE+0x348), (0xFF << 20));
+	        DRV_WriteReg32((GPIO_BASE+0x344), (0x44 << 20));
+
+		DRV_WriteReg32((0xC1E60000+0xC8), (0X3 << 8));
+		DRV_WriteReg32((0xC1E60000+0xE4), (0X1 << 8));
+			
+	    } else if (uart_port == uart_port3) {
+	        /* Do nothing */
+			/*Bianco not have MDUART2 port*/
+	    }
+#elif defined(MT6877)  // for Montrose
+	    if(uart_port== uart_port1) {
+	        /* GPIO98/99 set to function4 */
+	        DRV_WriteReg32((GPIO_BASE+0x3C8), (0xFF << 8));
+	        DRV_WriteReg32((GPIO_BASE+0x3C4), (0x44 << 8));
+
+		DRV_WriteReg32((0xC1D30000+0x58), 1);
+		DRV_WriteReg32((0xC1D30000+0x74), 1);
+		DRV_WriteReg32((0xC1D10000+0x78), 1);
+
+	    } else if (uart_port== uart_port2) {		
+	        /* GPIO100/101 set to function4 */
+	        DRV_WriteReg32((GPIO_BASE+0x3C8), (0xFF << 16));
+	        DRV_WriteReg32((GPIO_BASE+0x3C4), (0x44 << 16));
+
+		DRV_WriteReg32((0xC1D10000+0x78), 2);
+		DRV_WriteReg32((0xC1D10000+0xa4), 2);
+		DRV_WriteReg32((0xC1D30000+0x58), 2);
+			
+	    } else if (uart_port == uart_port3) {
+	        /* Do nothing */
+			/*Bianco not have MDUART2 port*/
+	    }	
+#elif defined(CHIP10992)	// for colgin	
+	if(uart_port == uart_port1) {
+		/* GPIO183/184 set to function4 */
+		DRV_WriteReg32((GPIO_BASE+0x468), 0x70000000);
+		DRV_WriteReg32((GPIO_BASE+0x478), 0x7);
+		DRV_WriteReg32((GPIO_BASE+0x464), 0x20000000);
+		DRV_WriteReg32((GPIO_BASE+0x474), 0x2);
+
+
+		/* URXD/UTXD PULL clear PD */
+		DRV_WriteReg32((0xC1C10000+0x098), 0x8800);
+		/* URXD PULL up Select */		 
+		DRV_WriteReg32((0xC1C10000+0x0C4), 0x8000); 
+	} else if (uart_port == uart_port2) {
+
+	} else if (uart_port == uart_port3) {	
+	}
+#else
+
+#define IOCFG1_BASE (0xC1C10000)
+
+if(uart_port== uart_port1) {
+	/* GPIO184/183 set to function6 */
+	DRV_WriteReg32((GPIO_BASE+0x468), 0X70000000);
+	DRV_WriteReg32((GPIO_BASE+0x478), 0X7);
+DRV_WriteReg32((GPIO_BASE+0x464), 0X20000000);
+	DRV_WriteReg32((GPIO_BASE+0x474), 0X2);
+
+	/* URXD PULL enable */
+	DRV_WriteReg32((IOCFG1_BASE+0x098), 0X8800);
+	/* URXD PULL up Select */		 
+	DRV_WriteReg32((IOCFG1_BASE+0x0C4), 0X8000);
+
+} else if (uart_port== uart_port2) {
+	
+	/* GPIO10/GPIO11 set to function4 */
+	DRV_WriteReg32((0xC0005000+0x318), (0xFF00));
+	DRV_WriteReg32((0xC0005000+0x314), (0x6600));
+	
+	/* URXD PULL enable */
+	DRV_WriteReg32((0xC0002A00+0x054), (0x1 << 1));
+	/* URXD PULL DOWN disable*/
+	DRV_WriteReg32((0xC0002A00+0x048), (0x1 << 1));
+	
+} else if (uart_port == uart_port3) {
+	/* Do nothing */
+	/*Bianco not have MDUART2 port*/
+}		
+#endif
+}
+
+//we must set this init function to driver init stage to void muliti-core access init function at the same time issue.
+#ifndef KTEST_UART_TRACES
+void dbg_uart_create_spinlock(void){
+	if (dbg_print_lock == 0)  {
+		 dbg_print_lock = kal_create_spinlock("printf_");
+	}
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+	if (print_buf_lock == 0){
+	 	print_buf_lock = kal_create_spinlock("printf_buf");
+	}
+#endif
+}
+#endif
+
+void dbg_uart_init(void){
+
+	kal_uint32 port = DBG_PRINT_PORT;
+	kal_uint32 uart_base = UART_BaseAddr[DBG_PRINT_PORT];
+	
+	if((dbg_init_flag == KAL_FALSE)||(DRV_Reg32(UART_RATE_STEP(uart_base)) != 0x3)){
+	UART_PDN_Disable(port);
+
+	drv_uart_IOPAD_configure(port);//for debug
+	if(port == uart_port1){
+		#if defined(DRV_DEBUG_DMA_MODE) || defined(DRV_DEBUG_BUFFER_DMA_MODE)
+			HDMA_DONE_INTR_UNMASK(UART1_HDMA_TX_CHANNEL);
+			drv_uart_configure_hdma(port);
+		#else
+			DRV_WriteReg32(UART_DMA_EN(uart_base), 0x0); //disable DMA
+		#endif			
+	}
+					
+/*	#if defined(__MTK_TARGET__)
+		switch(port){
+			case uart_port1: 
+				PDN_CLR(PDN_UART0);
+				#if defined(DRV_DEBUG_DMA_MODE) || defined(DRV_DEBUG_BUFFER_DMA_MODE)
+                    			HDMA_PDN_CLR(port+2);
+                    			HDMA_PDN_CLR(port+4);
+                   				HDMA_DONE_INTR_UNMASK(2);
+                    			drv_uart_configure_hdma(port);
+				#else
+					DRV_WriteReg32(UART_DMA_EN(uart_base), 0x0); //disable DMA
+				#endif
+				break;
+			case uart_port2: 
+				PDN_CLR(PDN_UART1);
+				DRV_WriteReg32(UART_DMA_EN(uart_base), 0x0); //disable DMA
+				break;
+			default: break;
+		}
+	#endif
+*/
+		DRV_WriteReg(UART_IER(uart_base), UART_IER_ALLOFF);
+		DRV_WriteReg32(UART_LCR(uart_base), 0xBF);
+		DRV_WriteReg32(UART_EFR(uart_base), 0x0);  //no flow control;
+		DRV_WriteReg32(UART_LCR(uart_base), 0x03);  //word len = 8 bit;  stop bit =1; parity = false;
+		DRV_WriteReg32(UART_FCR(uart_base), 0x05);  //set fifo enable ,and clear Tx and Rx  fifo.
+		U_SetBaudRate(DBG_PRINT_PORT, DBG_PRINT_BAUD, (module_type)(DBG_PRINT_PORT));
+
+		dbg_init_flag = KAL_TRUE; 
+	}
+
+}
+
+
+
+#ifdef  DRV_DEBUG
+extern void UART_DMA_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length);
+extern kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length);
+#if !defined(__ESL_DBG_UTIL__)
+void dbg_print(char *fmt,...)
+{
+#if (!defined(IC_MODULE_TEST))
+   va_list ap;
+   double dval;
+   int ival;
+   char *p, *sval;
+   char *bp, cval;
+   int fract;
+   unsigned short len;
+   UART_CTRL_PUT_BYTES_T BMTPutBytes;
+
+
+#ifndef KTEST_UART_TRACES
+    kal_take_spinlock(dbg_print_lock, KAL_INFINITE_WAIT);
+#else
+    kal_hrt_take_itc_lock(KAL_ITC_DBG, KAL_INFINITE_WAIT);
+#endif
+	dbg_uart_init();
+	
+#if defined(DRV_DEBUG_DMA_MODE)
+	while(HDMA_BUF0_IS_ACTIVE(DBG_PRINT_PORT+2));
+#elif defined(DRV_DEBUG_BUFFER_MODE)
+    //no need do anything.
+#else
+    //no need do anything.
+#endif
+
+	bp= print_buf;
+	*bp= 0;
+	
+	va_start (ap, fmt);
+	for (p= fmt; *p; p++)
+	{
+		if (*p != '%')
+		{
+			*bp++= *p;
+			continue;
+		}
+		switch (*++p) {
+		case 'd':
+			ival= va_arg(ap, int);
+			if (ival < 0){
+				*bp++= '-';
+			     ival= -ival;
+			}
+			itoa (&bp, ival, 10);
+			break;
+			
+        	case 'o':
+			ival= va_arg(ap, int);
+			if (ival < 0){
+				*bp++= '-';
+			     ival= -ival;
+			}
+			*bp++= '0';
+			itoa (&bp, ival, 8);
+			break;
+			
+		case 'x':
+			ival= va_arg(ap, int);
+			if (ival < 0){
+			     *bp++= '-';
+			     ival= -ival;
+			}
+			*bp++= '0';
+			*bp++= 'x';
+			itoa (&bp, ival, 16);
+			break;
+			
+		case 'X':
+			ival= va_arg(ap, int);
+			bp += sprintf(bp, "0x%x", ival);
+			break;
+			
+		case 'c':
+			cval= va_arg(ap, int);
+			*bp++= cval;
+			break;
+			
+		case 'f':
+			dval= va_arg(ap, double);
+			if (dval < 0){
+				*bp++= '-';
+				dval= -dval;
+			}
+			if (dval >= 1.0)
+				itoa (&bp, (int)dval, 10);
+		    	else
+				*bp++= '0';
+			*bp++= '.';
+			fract= (int)((dval- (double)(int)dval)*(double)(MAXFRACT));
+            		itof(&bp, fract);
+			break;
+			
+		case 's':
+			for (sval = va_arg(ap, char *) ; *sval ; sval++ )
+			    *bp++= *sval;
+			break;
+		}
+	}
+	va_end (ap);
+        
+	*bp= 0;
+	len = (unsigned short)(bp - print_buf);
+    
+
+	BMTPutBytes.puBuffaddr = (kal_uint8 *)print_buf;
+	BMTPutBytes.u2Length = len;
+#if defined(DRV_DEBUG_DMA_MODE)
+	UART_DMA_PutBytes(DBG_PRINT_PORT, BMTPutBytes.puBuffaddr, BMTPutBytes.u2Length);
+#elif defined(DRV_DEBUG_BUFFER_MODE) || defined(DRV_DEBUG_BUFFER_DMA_MODE)
+	BMT_PutBytes(DBG_PRINT_PORT, BMTPutBytes.puBuffaddr, BMTPutBytes.u2Length);
+#else
+	int i = (int)BMTPutBytes.u2Length;
+	for(i = 0; i < len; i++)
+	{
+		dbg_UARTPutByte(print_buf[i]);		
+	}
+#endif
+
+
+#ifndef KTEST_UART_TRACES
+    kal_give_spinlock(dbg_print_lock);
+#else
+#if !defined (__FPGA__)
+    {   // Have some delay for UART buffer flushing
+        volatile kal_uint32 i=300000;
+        while(i--);
+    }    
+#endif
+    kal_hrt_give_itc_lock(KAL_ITC_DBG);
+#endif
+
+	// Flush the data in uart buffer when exception occurs
+	if(INT_QueryExceptionStatus()){
+		UART_AssertWaitPrevDataSentOut(DBG_PRINT_PORT);
+
+	}
+#endif
+
+}
+#endif
+char print_buf2[MAXCHARS];
+void dbg_printWithTime(char *fmt,...)
+{
+#if !defined(__LTE_REMOVE_TEMPERAL__)
+
+#if (!defined(IC_MODULE_TEST))
+	int i;
+	va_list ap;
+	double dval;
+	int ival;
+	char *p, *sval;
+	char *bp, cval;
+	int fract;
+	unsigned short len;
+
+	bp= print_buf2;
+	*bp= 0;
+
+#ifndef KTEST_UART_TRACES
+    kal_take_spinlock(dbg_print_lock, KAL_INFINITE_WAIT);
+#else
+    kal_hrt_take_itc_lock(KAL_ITC_DBG, KAL_INFINITE_WAIT);
+#endif
+    
+	va_start (ap, fmt);
+	for(p= fmt; *p; p++)
+	{
+		if (*p != '%')
+		{
+			*bp++= *p;
+			continue;
+		}
+		switch (*++p)
+		{
+			case 'd':
+				ival= va_arg(ap, int);
+				if (ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				itoa (&bp, ival, 10);
+				break;
+
+			case 'o':
+				ival= va_arg(ap, int);
+				if (ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				*bp++= '0';
+				itoa (&bp, ival, 8);
+				break;
+
+			case 'x':
+				ival= va_arg(ap, int);
+				if(ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				*bp++= '0';
+				*bp++= 'x';
+				itoa (&bp, ival, 16);
+				break;
+
+			case 'X':
+				ival= va_arg(ap, int);
+				bp += sprintf(bp, "0x%x", ival);
+				break;
+
+			case 'c':
+				cval= va_arg(ap, int);
+				*bp++= cval;
+				break;
+
+			case 'f':
+				dval= va_arg(ap, double);
+				if(dval < 0)
+				{
+					*bp++= '-';
+					dval= -dval;
+				}
+				if(dval >= 1.0)
+					itoa (&bp, (int)dval, 10);
+				else
+					*bp++= '0';
+				*bp++= '.';
+				fract= (int)((dval- (double)(int)dval)*(double)(MAXFRACT));
+				itof(&bp, fract);
+				break;
+
+			case 's':
+				for(sval = va_arg(ap, char *) ; *sval ; sval++ )
+					*bp++= *sval;
+				break;
+		}
+	}
+	*bp= 0;
+	len = (unsigned short)(bp - print_buf2);
+	
+
+	for(i = 0; i < len; i++)
+	{
+		dbg_UARTPutByte(print_buf2[i]);		
+	}
+	
+	va_end (ap);
+	
+#ifndef KTEST_UART_TRACES
+    kal_give_spinlock(dbg_print_lock);
+#else
+    kal_hrt_give_itc_lock(KAL_ITC_DBG);
+#endif
+#endif
+#endif /* !defined(__LTE_REMOVE_TEMPERAL__) */
+
+}
+
+void dbg_flush(void)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+
+#endif
+
+#if defined(__IC_SLT__)
+
+#if !defined(DRV_DEBUG)
+void dbg_printWithTime(char *fmt,...){}
+void dbg_print(char *fmt,...){}
+void dbg_flush(void){}
+#endif
+
+void slt_dbg_print(char *fmt,...)
+{
+
+	int i;
+	va_list ap;
+	double dval;
+	int ival;
+	char *p, *sval;
+	char *bp, cval;
+	int fract;
+	unsigned short len;
+
+	bp= print_buf;
+	*bp= 0;
+	
+#ifndef KTEST_UART_TRACES
+    kal_take_spinlock(dbg_print_lock, KAL_INFINITE_WAIT);
+#else
+    kal_hrt_take_itc_lock(KAL_ITC_DBG, KAL_INFINITE_WAIT);
+#endif
+    dbg_uart_init();
+    
+	va_start (ap, fmt);
+	for(p= fmt; *p; p++)
+	{
+		if (*p != '%')
+		{
+			*bp++= *p;
+			continue;
+		}
+		switch (*++p)
+		{
+			case 'd':
+				ival= va_arg(ap, int);
+				if (ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				itoa (&bp, ival, 10);
+				break;
+
+			case 'o':
+				ival= va_arg(ap, int);
+				if (ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				*bp++= '0';
+				itoa (&bp, ival, 8);
+				break;
+
+			case 'x':
+				ival= va_arg(ap, int);
+				if(ival < 0)
+				{
+					*bp++= '-';
+					ival= -ival;
+				}
+				*bp++= '0';
+				*bp++= 'x';
+				itoa (&bp, ival, 16);
+				break;
+
+			case 'X':
+				ival= va_arg(ap, int);
+				bp += sprintf(bp, "0x%x", ival);
+				break;
+
+			case 'c':
+				cval= va_arg(ap, int);
+				*bp++= cval;
+				break;
+
+			case 'f':
+				dval= va_arg(ap, double);
+				if(dval < 0)
+				{
+					*bp++= '-';
+					dval= -dval;
+				}
+				if(dval >= 1.0)
+					itoa (&bp, (int)dval, 10);
+				else
+					*bp++= '0';
+				*bp++= '.';
+				fract= (int)((dval- (double)(int)dval)*(double)(MAXFRACT));
+				itof(&bp, fract);
+				break;
+
+			case 's':
+				for(sval = va_arg(ap, char *) ; *sval ; sval++ )
+					*bp++= *sval;
+				break;
+		}
+	}
+	*bp= 0;
+	len = (unsigned short)(bp - print_buf);
+    
+	for(i = 0; i < len; i++)
+	{
+		dbg_UARTPutByte(print_buf[i]);		
+	}
+	
+	va_end (ap);
+	
+#ifndef KTEST_UART_TRACES
+    kal_give_spinlock(dbg_print_lock);
+#else
+    kal_hrt_give_itc_lock(KAL_ITC_DBG);
+#endif
+
+}
+#endif
+
+#else
+void dbg_printWithTime(char *fmt,...){}
+void dbg_print(char *fmt,...){}
+void dbg_flush(void){}
+void dbg_uart_init(void){}
+void slt_dbg_flush(void){};
+void slt_dbg_print(char *fmt,...){}
+
+#endif
diff --git a/mcu/driver/devdrv/uart/src/uart.c b/mcu/driver/devdrv/uart/src/uart.c
new file mode 100644
index 0000000..a04bbf0
--- /dev/null
+++ b/mcu/driver/devdrv/uart/src/uart.c
@@ -0,0 +1,4149 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2012
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ *   uart.c
+ *
+ * Project:
+ * --------
+ *   TATAKA
+ *
+ * Description:
+ * ------------
+ *   This Module defines the uart1 driver and the adaption layer
+ *   between driver and TATAKA protocol.
+ * Author:
+ * -------
+ * -------
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 07 02 2019 yao.xue
+ * [MOLY00418070] ISR Centralization : remove UART &  WDT & Logseq IRQSensitivity/IRQ_Register_LISR
+ * ISR Centralization : remove UART &  WDT & Logseq IRQSensitivity/IRQ_Register_LISR
+ *
+ * 04 11 2019 yao.xue
+ * [MOLY00397471] [VMOLY]Use API ust_us_duration take place ust_get_duration
+ * modify API ust_us_duration takeplace ust_get_duration in uart/slt code
+ *
+ * 02 15 2019 panu.peisa
+ * [MOLY00384803] [Gen97][SystemService][Change Request] KAL Refactoring Phase-in
+ * 	
+ * Added changes to swrd part.
+ *
+ * 10 29 2018 yao.xue
+ * [MOLY00360949] [SWRD] DRVTEST maintain
+ * Fix DRVTEST build pass in SWRD
+ *
+ * 03 13 2018 shenghui.shi
+ * [MOLY00309657] UMOLYE driver warning fix
+ * update UART driver
+ *
+ * 11 21 2017 shenghui.shi
+ * [MOLY00290848] [UMOLYA] Usage of INT_SW_SecVersion
+ * removed no used API INT_SW_SecVersion
+ *
+ * 11 21 2017 shenghui.shi
+ * [MOLY00290848] [UMOLYA] Usage of INT_SW_SecVersion
+ * remove INT_SW_SecVersion API from UART driver. This API is not used in 93/95
+ *
+ *
+ * 11 07 2017 shenghui.shi
+ * [MOLY00288093] update UART driver to remove no needed project option
+ * .
+ *
+ * 11 07 2017 shenghui.shi
+ * [MOLY00288093] update UART driver to remove no needed project option
+ * update uart driver to remove no needed files
+ *
+ * 11 03 2017 shenghui.shi
+ * [MOLY00287577] UMOLYA HISR coding change for UART part
+ * .
+ *
+ * 10 24 2017 yao.xue
+ * [MOLY00284920] [Cervino] UART driver porting for Cervino.
+ *
+ * 09 15 2017 da.li
+ * [MOLY00270315] [System Service][KIR] make ex robust before ex steplog work
+ * Replace INT_QueryExceptionStatus  with #include <ex_public.h>.
+ *
+ * 09 08 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * Build warning(error) fix.
+ *
+ * 09 07 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * UART driver porting for Sylvia.
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * fix build error
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * update UART driver
+ *
+ * 06 12 2017 flamingo.wang
+ * [MOLY00244966] [ZION][IDC] add chip define of MT6739 in idc driver
+ * Add MT6739 define
+ *
+ * 06 12 2017 flamingo.wang
+ * [MOLY00254599] Normal mode UARTDriver���ܳ�Log
+ * norm uart mode print log fix
+ *
+ * 04 24 2017 shenghui.shi
+ * [MOLY00243727] update UART PDN feature
+ * update UART pdn feature,to void system could not entry DCM issue.
+ *
+ * 03 07 2017 shenghui.shi
+ * [MOLY00233604] UART print driver update for baudrate
+ * update UART driver for uart include.
+ *
+ * 02 07 2017 shenghui.shi
+ * [MOLY00228102] [Bianco Bring-up]UMOLYA uart driver update
+ * update UART dbgprint driver
+ *
+ * 09 22 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * set RX SEL for RX channel
+ *
+ *
+ * 09 20 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * .
+ *
+ * 07 15 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * update UART cloclk to 26MHz  (after GEN93 Bitfile 2016071380)
+ *
+ * 05 19 2016 shenghui.shi
+ * [MOLY00175766] NVRAM update for UMOLYA
+ * modify UART 26MHz macro to 20.8MHz to match real clock freq.
+ *
+ * 03 30 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * update uart driver for 93.
+ *
+ * 01 27 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * use sst_get_exception_count() to replace INT_Exception_Enter.
+ *
+ * 01 22 2016 shenghui.shi
+ * [MOLY00162415] [Coverity inspect] driver coding issue fix
+ * [coverity inspect]driver coding issue fix
+ *
+ * 01 15 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * Merging
+ * 	
+ * update UART debug driver to use HMDA mode.
+ *
+ * 10 13 2015 shenghui.shi
+ * [MOLY00145129] fixed EWS build error which caused by UART IRQ naming exchange on ELBRUS
+ * .
+ *
+ * 10 13 2015 shenghui.shi
+ * [MOLY00145129] fixed EWS build error which caused by UART IRQ naming exchange on ELBRUS
+ * .
+ *
+ * 08 17 2015 shenghui.shi
+ * [MOLY00137551] [MOLY_LINUX_DOWNLOADBIN notify] ELBRUS_FPGA(BASIC) build error
+ * <saved by Perforce>
+ *
+ * 06 18 2015 da.li
+ * [MOLY00121478] [UMOLY][JADE]UART driver compile error fix
+ * Compile error fix on JADE(MT6755).
+ *
+ * 06 15 2015 da.li
+ * [MOLY00121478] [UMOLY][JADE]UART driver compile error fix
+ * UART driver compile error fix on MT6755(JADE).
+ *
+ * 05 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * pdn clear UART/GDMA clock before use UART driver
+ *
+ * 04 02 2015 tero.jarkko
+ * [MOLY00094214] [System Service][MOLY Kernel Internal Request]Modify driver HISR to individual HISR
+ *
+ * 03 25 2015 shenghui.shi
+ * [MOLY00104131] [UMOLY][Klocwork] Fix potential code defect in uart driver
+ * .
+ *
+ * 02 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * fix ews build error
+ *
+ * 02 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * 1. add sw escape feature to UMOLY
+ * 2. phase out VFIFO hw code in devdrv_common.c
+ *
+ * 12 18 2014 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * .
+ *
+ * 11 17 2014 shenghui.shi
+ * [MOLY00084720] update UMOLY HDMA HISR
+ * move GDMA2 to DEVDRV share HISR
+ *
+ * 11 17 2014 shenghui.shi
+ * [MOLY00084720] update UMOLY HDMA HISR
+ * .
+ *
+ * 05 13 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * .
+ *
+ * 05 13 2014 shenghui.shi
+ * [MOLY00065467] [TK6291] update UART driver for TK6291
+ * update UART clock to 26MHZ for TK6291
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * .
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062003] [MakeFile] [Modify Common Makefile] Disable __CUST_NEW__
+ * update a patch for no __FPGA__ macro
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * update uart driver to fix ews error
+ *
+ * 01 10 2014 shenghui.shi
+ * [MOLY00043671] [klocwork_95][LTE] in uart.c, line 428
+ * .
+ *
+ * 01 10 2014 shenghui.shi
+ * [MOLY00043674] [klocwork_95][LTE] in uart.c, line 2247
+ * update uart driver to fix uninitial risk.
+ *
+ * 01 09 2014 shenghui.shi
+ * [MOLY00052974] MT6595 UART driver merge to Trunk
+ * MT6595 uart driver merge to MOLY TRUNK
+ *
+ * 12 10 2013 shenghui.shi
+ * [MOLY00049628] MT6595 UART merge to Trunk
+ * .
+ *
+ * 10 29 2013 shenghui.shi
+ * [MOLY00044172] uart all memory dump
+ * .
+ *
+ * 10 02 2013 vend_brandon-hy.lin
+ * [MOLY00040071] [MT6290] SRCLKEN cannot be toggled when LTE sleep feature is enable
+ * Fix SRCLEN_OUT0 cannot be toggle when LTE sleep feature is enable.
+ * Solution: enlarge transmission time of dummy fdma patch.
+ *
+ * 09 13 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * move uart pdn_clr from dcl_tty.c to uart.c
+ *
+ * 09 03 2013 shenghui.shi
+ * [MOLY00036272] open UART SlEEP_EN feature
+ * open uart SLEEP_EN feature when MTK_SLEEP_EN enable.
+ *
+ * 08 29 2013 shenghui.shi
+ * [MOLY00035659] [MOLY] [MT6290][SLT] SLT Tool Communication API for driver test
+ * .
+ *
+ * 08 29 2013 shenghui.shi
+ * [MOLY00035768] fix uart build warnning
+ * .
+ *
+ * 08 26 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * add uart PDN feature
+ *
+ * 08 14 2013 shenghui.shi
+ * [MOLY00033671] update exception uart driver for void use qbm_dest_q
+ * .
+ *
+ * 08 12 2013 shenghui.shi
+ * [MOLY00033396] update dummy_fdma() patch
+ * .
+ *
+ * 08 02 2013 shenghui.shi
+ * [MOLY00032203] update dummy_fdma for GDMA sleep ack issue
+ * update dummy_fdma() for GDMA sleep ack issue
+ * 08/02/2013 shenghui.shi
+ * [MOLY00032203]update dummy_fdma() for GDMA sleep ack issue
+ *
+ * 07 29 2013 shenghui.shi
+ * [MOLY00030921] [MT6290]Low Power Feature patch back from CBr
+ * merge UART dummy_fdma() patch from Branch to Trunk.
+ *
+ * 04 24 2013 shenghui.shi
+ * [MOLY00020330] MT6290 UART driver update
+ * uart driver update: modify the uart_hdma_isr().
+ *
+ * 04 03 2013 shenghui.shi
+ * [MOLY00012769] IOMUX driver
+ * update UART driver: add ASIC version for UART_CLOCK
+ *
+ * 02 04 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * rename: 7208 -> 6290
+ *
+ * 01 29 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 01 22 2013 ansel.liao
+ * [MOLY00006575] USIM driver modification
+ * *: remove an en-Q situation which won't occur
+ *
+ * 01 15 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: recover U_GetUARTByte function, WCP3/SE7/SD9 Chuanbo need this function to verify MSDC driver (port from MT6280)
+ *
+ * 01 14 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 01 04 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: clear rx data timeout counter periodly to prevent XON/XOFF of sw flow control to destroy rx data timeout mechanism
+ *
+ * 01 02 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: does not destroy rx queue when head of queue is null
+ *
+ * 12 26 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 12 25 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: free all TGPD/RGPD when TTY_CMD_EXCEPTION_CLEAR_CHANNEL is get
+ *
+ * 12 19 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 12 06 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 11 30 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * add dbg_flush and corresponding drvtest
+ *
+ * 11 27 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * update stress test
+ *
+ * 11 25 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * update UART stress test
+ *
+ * 11 23 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Add UART/HDMA driver
+ ****************************************************************************/
+#include "drv_features.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#ifdef KTEST_UART_TRACES
+#include "kal_hrt_api.h"
+#endif
+#include "kal_public_defs.h"
+#include "hisr_config.h"
+#include "stack_msgs.h"
+#include "stack_ltlcom.h"       /* Task message communiction */
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "uart_hw.h"
+#include "bmd.h"
+#include "intrCtrl.h"
+#include "drvpdn.h"
+#include "stack_config.h"        /*MOD_UART1_HISR,MOD_UART2_HISR*/
+#include "uart_sw.h"
+#include "uart_internal.h"
+#include "dcl.h"
+#include "uart_gpd.h"
+#include "drv_msgid.h"
+#include "devdrv_ls.h"
+#include "pll.h"
+#include "drv_gdma.h"
+// for HDMA
+#include "qmu_bm.h"
+#include "qmu_bm_size.h"
+#include "qmu_bm_util.h"
+#include "init.h"
+#include "cpu.h"
+#include "cache_sw.h"
+#include <ex_item.h>
+#include <ex_public.h>
+#if defined(__HMU_ENABLE__)
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#endif
+#include "us_timer.h"
+
+#if !defined(DRV_UART_OFF)
+
+#define UART_CLOCK  (26*1000000)
+
+#ifndef MD_IRQID_MDGDMA2
+#define MD_IRQID_MDGDMA2      PS_IRQID_MDGDMA2
+#endif
+
+// To enable or disable META Mode SW Escaping, defined this macro to enable it
+#define META_MODE_SW_ESCAPING
+#define UART_ESCAPE_CHAR 0x77
+#define UART_ECPT_MAX_TIMEOUT 5000   //5s
+
+kal_uint8 UART_handle;
+
+tty_excp_hif_state uart_ecpt_tx_state[MAX_UART_PORT_NUM] = 
+{
+   HIF_STATE_NORMAL,
+   HIF_STATE_NORMAL,
+};
+UART_ecpt_timer_t uart_ecpt_timer[MAX_UART_PORT_NUM];
+UARTStruct UARTPort[MAX_UART_PORT_NUM];
+
+#ifdef DRV_DEBUG
+kal_uint8 uart_initialize[MAX_UART_PORT_NUM];
+#endif /*DRV_DEBUG*/
+
+#define DEBUG_PORT		uart_port1 // Use UART1 as debug port
+#define DEBUG_BAUDRATE		115200
+kal_int32 init_log_fail_count = 0;
+kal_bool mutex_status = KAL_FALSE;
+kal_mutexid mutexid = 0;
+
+#if __LTE_ONLY__
+#define MCU_BOOT_SPEED 40040000
+#else
+//MCU booting speed 26M/baudrate(bits/second) = 260M/baudrate(bytes/second) = MCU tick/bytes
+#define MCU_BOOT_SPEED 260000000 //Currently all chips use 26M, 260M because of count [MCU ticks/byte]
+#endif
+
+kal_bool send_Txilm[MAX_UART_PORT_NUM] = {// change from kal_uint8 to kal_bool, avoid Warning 641: Converting enum 'kal_bool' to int"
+   KAL_FALSE,
+   KAL_FALSE,
+};
+
+kal_bool send_Rxilm[MAX_UART_PORT_NUM] = {// change from kal_uint8 to kal_bool, avoid Warning 641: Converting enum 'kal_bool' to int"
+   KAL_TRUE,
+   KAL_TRUE,
+};
+
+const VOID_FUNC UART_HISR[MAX_UART_PORT_NUM] =
+{
+   UART1_HISR,
+   UART2_HISR,
+};
+
+const kal_uint32 UART_BaseAddr[MAX_UART_PORT_NUM] =
+{
+   UART1_base,
+   UART2_base,
+};
+#ifdef __DMA_UART_VIRTUAL_FIFO__
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{ 
+   KAL_TRUE, 
+   KAL_TRUE,
+};
+
+#else
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{
+   KAL_FALSE,
+   KAL_FALSE,
+};
+#endif/*__DMA_UART_VIRTUAL_FIFO__*/
+
+//Add for new internal func
+void UART2_TrxHandler(void);
+kal_uint8 UART_GetIRQCode(UART_PORT port);
+void uart_qbm_virt_to_phy(void** pp_gpd_head, void** pp_gpd_tail);
+void uart_qbm_phy_to_virt(void**pp_gpd_head, void**pp_gpd_tail);
+void UART_META_PutBytes(UART_PORT port, void * gpd_head, void * gpd_tail);
+kal_uint16 U_ExBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+void UART_META_ExBytes(UART_PORT port, void * gpd_head, void * gpd_tail);
+
+
+
+kal_uint8 uart_escape_state=0;
+
+extern UartDriver_strcut* pUart_CMD_FUNC[];
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE) && !defined(KTEST_UART_TRACES)
+kal_spinlockid print_buf_lock = 0;
+#endif
+//void dummy_fdma(kal_uint32 gdma_start);
+
+
+void UART_Calback(void *parameter);
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid);
+void UART_TrxHandler(void *parameter);
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done);
+/*UART Customization */
+extern const UART_customize_function_struct *UART_GetFunc(void);
+const UART_customize_function_struct *UartCustomFunc;
+const UART_rings_struct *UART_rings;
+kal_bool WaitForUARTTx[MAX_UART_PORT_NUM] = {KAL_FALSE};
+
+#define ASSERT_WAIT_LOOP 0xffffffff
+#define VFIFO_SWITCH_WAIT_LOOP 100000
+kal_uint16 DELAY_FOR_PUTBYTE = 300;
+
+// for HDMA
+void *uart_tgpd_head[3];
+void *uart_rgpd_head[3];
+void *uart_tgpd_tail[3];
+void *uart_rgpd_tail[3];
+
+void *uart_wait_tgpd_head[3];
+void *uart_wait_tgpd_tail[3];
+
+
+// for UART Exception mode
+kal_uint8 uart_ecpt_bps_buf[UART_ECPT_QBM_BPS_BUF_SZ];
+kal_bool uart_ecpt_init = KAL_FALSE;
+uart_bps_gpd_t uart_bps_gpd;
+
+
+#if defined(DRV_UART_MEMORY_TRACE)
+UART_DRV_DBG_STRUCT UART_DRV_DBG_INFO_DATA;
+/*uart_drv_dbg_trace(NAND_READ_START,drv_get_current_time(),0,0);*/
+void uart_drv_dbg_trace(kal_uint16 index, kal_uint32 time, kal_uint32 data1, kal_uint32 data2)
+{
+   kal_uint32        savedMask;
+   savedMask = SaveAndSetIRQMask();
+   {
+      UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].tag = index;
+      UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].time = time;
+      UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].data1 = data1;
+      UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].data2 = data2;
+      UART_DRV_DBG_INFO_DATA.dbg_data_idx++;
+   }
+   RestoreIRQMask(savedMask);
+}
+#endif //#if defined(DRV_UART_MEMORY_TRACE)
+
+
+
+void uart_customize_init(void)
+{
+   /* retreive the function table */
+   UartCustomFunc=UART_GetFunc();
+   /* use the entry in function table to retreive desired information */
+   UART_rings = UartCustomFunc->UART_Get_Data();
+   
+}  
+
+kal_bool UART_IsVfifoSetting(UART_PORT port, UART_TxRx_VFIFO_support vs)
+{
+#ifdef __DMA_UART_VIRTUAL_FIFO__
+   if(port >= MAX_UART_PORT_NUM)
+      return KAL_FALSE;
+   if(vs != NONE_VFIFO)
+      return UART_VFIFO_support[port];
+   else //NONE_VFIFO
+      return (kal_bool)!UART_VFIFO_support[port];
+#else
+   if(vs == NONE_VFIFO)
+      return KAL_TRUE;
+   else //NONE_VFIFO
+      return KAL_FALSE;   
+#endif      
+}
+
+/*check if chip can support auto escape*/
+kal_bool uart_support_autoescape(void)
+{      
+   return KAL_TRUE;	
+}
+
+void UART_sendilm(UART_PORT port, msg_type msgid) {}
+
+//Add for U_ClrRxBuffer and U_ClrTxBuffer, reduce code size
+void UART_Set_NormalFlowControl(UART_PORT port) 
+{
+	if (UARTPort[port].DCB.flowControl == fc_none)
+		DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+	else if (UARTPort[port].DCB.flowControl == fc_hw)
+		DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+	else if (UARTPort[port].DCB.flowControl == fc_sw)
+		DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_SW_NORMALINTS);
+}
+
+void U_ClrRxBuffer(UART_PORT port, module_type ownerid)  /*clear sw buffer*/
+{
+   kal_uint32 savedMask;
+      
+   savedMask = SaveAndSetIRQMask();
+   BWrite_addr(UARTPort[port].Rx_Buffer) = 0;
+   BRead_addr(UARTPort[port].Rx_Buffer) = 0;
+   
+//   UART_Set_NormalFlowControl(port);
+
+   send_Rxilm[port] = KAL_TRUE;
+   RestoreIRQMask(savedMask);
+
+// HDMA procedure
+	uart_en_q_de_q_with_mutex(port, UART_RX, UART_DE_Q_ALL, NULL, NULL);
+// end of HDMA procedure
+   
+}
+
+void U_ClrTxBuffer(UART_PORT port, module_type ownerid)  /*clear sw buffer*/
+{
+
+	kal_uint32 savedMask;
+   
+	savedMask = SaveAndSetIRQMask();
+   
+	BWrite_addr(UARTPort[port].Tx_Buffer) = 0;
+	BRead_addr(UARTPort[port].Tx_Buffer) = 0;
+   
+//	UART_Set_NormalFlowControl(port);
+
+	send_Txilm[port] = KAL_TRUE;
+
+	RestoreIRQMask(savedMask);
+
+
+// HDMA procedure
+	uart_en_q_de_q_with_mutex(port, UART_TX, UART_DE_Q_ALL, NULL, NULL);
+// end of HDMA procedure
+}
+void UART_EnableTX(UART_PORT port, kal_bool enable)
+{  
+      if (port < MAX_UART_PORT_NUM)
+      {
+         UARTPort[port].EnableTX= enable;
+         if(enable == KAL_TRUE){
+            EnableTxIntr(UART_BaseAddr[port]);
+		}else{
+			DisableTxIntr(UART_BaseAddr[port]);
+		}
+      }else{
+		ASSERT(0);
+	  }
+}
+
+void UART_SleepOnTx_Enable(UART_PORT port, UART_SLEEP_ON_TX enable_flag) {}
+
+kal_uint16 U_GetBytesAvail(UART_PORT port)
+{	
+	kal_uint16 real_count;	 
+	
+	Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+
+	return real_count;
+}
+
+kal_uint16 U_GetTxRoomLeft(UART_PORT port)
+{
+   kal_uint16 real_count;   
+
+   Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer),real_count);   
+   return real_count;
+}
+
+#ifndef __ROMSA_SUPPORT__ /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE 
+#else
+kal_uint16
+#endif
+U_GetTxISRRoomLeft(UART_PORT port)
+{
+	return 0;
+}
+
+#endif /* Note: for ROM code */
+
+
+/*
+* FUNCTION
+*  GetUARTByte
+*
+* DESCRIPTION
+*     This function is to read data from UART
+*
+* CALLS
+*  This function is to receive data through UART
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  the data from UART
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint8 U_GetUARTByte(UART_PORT port)
+{
+	kal_uint8 data;
+	kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value);//liming add statement
+	while(!U_GetUARTByteWithTimeOut(port, &data, 0xffffffff)); // for descrease code size  (U_GetUARTByte &U_GetUARTByteTimeout)
+	return data;
+}
+
+
+/*
+* FUNCTION
+*  GetUARTByte
+*
+* DESCRIPTION
+*     This function is to read data from UART
+*
+* CALLS
+*  This function is to receive data through UART
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  the data from UART
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value)
+{
+   kal_uint8 res_byte = 0;
+   kal_uint8 data;
+   
+   while(timeout_value != 0)
+   {
+      kal_uint16 LSR;
+      LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));      
+      if (LSR & UART_LSR_DR)
+      {
+         data = (kal_uint8)DRV_UART_Reg(UART_RBR(UART_BaseAddr[port]));
+         res_byte = 1;
+         //only META port use old flow control escape character,
+         if( (kal_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw && UARTPort[port].ownerid==MOD_DHL_READER)||
+            (uart_support_autoescape()==KAL_FALSE&&UARTPort[port].DCB.flowControl==fc_sw))     
+         {
+            if(uart_escape_state==0)
+            {
+               if(data==0x77)            
+                  uart_escape_state=0x77;
+               else
+               {
+                 *ch = data;
+                 break; 
+               }            
+            }
+            else if (uart_escape_state==0x77)
+            {
+               uart_escape_state=0x0; 
+               
+               if (data == 0x01)
+               {
+                 *ch = UARTPort[port].DCB.xonChar;
+                 break;
+               }
+               else if (data == 0x02)
+               {
+                 *ch = UARTPort[port].DCB.xoffChar;
+                 break;
+               }
+               else if (data == 0x03)
+               {
+                 *ch = 0x77;
+                 break;
+               }                                           
+            }                           
+         }
+         else
+         {
+            *ch = data;
+            break;
+         }
+      }
+      
+      --timeout_value;
+   }
+   
+   return res_byte;
+}
+   
+/*
+* FUNCTION
+*  PutUARTByte
+*
+* DESCRIPTION
+*     This function is to write data to UART
+*
+* CALLS
+*  This function is to transmit data through UART
+*
+* PARAMETERS
+*  None
+*
+* RETURNS
+*  the data from UART
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void PutUARTRingBufferData(UART_PORT port) {}
+
+void UART_PutUARTByte_limited(UART_PORT port, kal_uint8 data)
+{
+   volatile kal_uint16 LSR;
+   kal_uint32 count = 0;
+   
+   if(init_log_fail_count > 3)
+   {
+      DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+      return;
+   }
+   
+   while(1)
+   {
+      LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+      count++;
+      if ( LSR & UART_LSR_THRE )
+      {
+         DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+         break;
+      }
+      else if(count > (MCU_BOOT_SPEED/DEBUG_BAUDRATE) ) 
+      {
+         DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data); //don't care the pending
+         init_log_fail_count++;
+         break;
+   }
+}
+}
+
+void U_PutUARTByte(UART_PORT port, kal_uint8 data) {
+	kal_uint16 LSR;
+	
+	while(1)
+	{
+	   LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+	   if ( LSR & UART_LSR_THRE )
+	   {
+		  DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+		  break;
+	   }
+	}
+}
+void PutUARTData(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
+{
+   if(port >= MAX_UART_PORT_NUM)
+      return;
+
+   //only META port use old flow control escape character,
+if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+			|| (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+   {
+      if (data == UARTPort[port].DCB.xonChar)
+      {
+           pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+         pUart_CMD_FUNC[port]->PutUARTByte(port, 0x01);             
+      }
+      else if (data == UARTPort[port].DCB.xoffChar)
+      {
+         pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+         pUart_CMD_FUNC[port]->PutUARTByte(port, 0x02);            
+      }
+      else if (data == escape_char)
+      {
+         pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+         pUart_CMD_FUNC[port]->PutUARTByte(port, 0x03);            
+      }
+      else
+      {
+         pUart_CMD_FUNC[port]->PutUARTByte(port, data);
+      }         
+   }
+   else
+   {
+      pUart_CMD_FUNC[port]->PutUARTByte(port, data);
+   }   
+}
+
+void PutUARTByteDelay(UART_PORT port, kal_uint8 data)
+{
+   kal_uint16 LSR;
+   kal_uint16 i;
+   if(port >= MAX_UART_PORT_NUM)
+      return;
+   
+   while(1)
+   {
+      LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+      
+      if( LSR & UART_LSR_THRE )
+      {
+         for(i = 0; i < DELAY_FOR_PUTBYTE; i++); //add delay...
+         DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+         break;
+      }
+   }
+}
+
+void PutUARTDataDelay(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
+{
+   if(port >= MAX_UART_PORT_NUM)
+      return;
+
+   if( (kal_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw && UARTPort[port].ownerid==MOD_DHL_READER)||
+      (uart_support_autoescape()==KAL_FALSE))        
+   {
+      if (data == UARTPort[port].DCB.xonChar)
+      {
+         PutUARTByteDelay(port, escape_char);
+         PutUARTByteDelay(port, 0x01);            
+      }
+      else if (data == UARTPort[port].DCB.xoffChar)
+      {
+         PutUARTByteDelay(port, escape_char);
+         PutUARTByteDelay(port, 0x02);            
+      }
+      else if (data == escape_char)
+      {
+         PutUARTByteDelay(port, escape_char);
+         PutUARTByteDelay(port, 0x03);            
+      }
+      else
+      {
+         PutUARTByteDelay(port, data);
+      }         
+   }
+   else
+   {
+      PutUARTByteDelay(port, data);
+   }   
+}
+
+
+kal_uint16 U_ExBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid)
+{
+	kal_uint16 real_count= Length, index;
+	kal_uint16 data_count = 0;
+
+		if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+			|| (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+		//if(0)
+		{  
+			for(index = 0; (index < real_count) && (data_count < Length); index++)
+			{   
+				// The following are for software flow control
+				if(uart_escape_state==0)
+				{
+					if(*(Buffaddr + index) == 0x77)
+					{
+						uart_escape_state=0x77;
+					} else
+					{
+						*(Buffaddr + data_count) = *(Buffaddr + index);
+						data_count++;
+					}
+            
+				} else if(uart_escape_state == 0x77)
+				{
+					switch(*(Buffaddr + index))
+					{
+						case 0x01:
+							*(Buffaddr+data_count) = 0x11;//UARTPort[port].DCB.xonChar;
+							data_count++;
+							break;
+						case 0x02:                  
+							*(Buffaddr+data_count)= 0x13; //UARTPort[port].DCB.xoffChar; 
+							data_count++;
+							break;               
+						case 0x03:                  
+							*(Buffaddr + data_count) = 0x77;
+							data_count++;
+							break;      
+						default:
+							break;
+               
+					}
+					uart_escape_state=0x0;        
+				}
+
+
+			}   
+		}else{
+			for(index = 0; (index < real_count) && (data_count < Length); index++){
+				*(Buffaddr + data_count) = *(Buffaddr + index);
+				data_count++;
+			}
+				
+		}
+
+	return data_count;
+}
+
+void UART_META_ExBytes(UART_PORT port, void * gpd_head, void * gpd_tail){
+	hdma_tbd_t *bd_ptr = NULL, *p_bd_cur =NULL;
+	hdma_tgpd_t *gpd_ptr = NULL;
+	kal_uint32	gpd_data_len=0, gpd_data_real_len = 0, bd_data_len=0, bd_data_real_len = 0;
+	kal_uint8  *gpd_data_ptr=NULL, *bd_data_ptr=NULL;
+
+	
+	gpd_ptr = (hdma_tgpd_t*)gpd_head;
+	while(1){
+		if (QBM_DES_GET_BDP(gpd_ptr)) {
+			bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			p_bd_cur = bd_ptr;
+			while (1) {
+				bd_data_len = QBM_DES_GET_DATALEN(p_bd_cur);
+				if(bd_data_len>0){
+					bd_data_ptr = QBM_DES_GET_DATAPTR(p_bd_cur);
+					QBM_CACHE_INVALID(bd_data_ptr, bd_data_len);
+					bd_data_real_len = U_ExBytes(port,bd_data_ptr ,bd_data_len, NULL, UARTPort[port].ownerid);
+					if (bd_data_len != bd_data_real_len) {
+					    QBM_CACHE_FLUSH(bd_data_ptr, bd_data_real_len);
+    					QBM_DES_SET_DATALEN(p_bd_cur, bd_data_real_len);
+    					QBM_CACHE_FLUSH(p_bd_cur, QBM_SIZE_TGPD);
+					}
+				}
+				if (QBM_DES_GET_EOL(p_bd_cur)) {
+					break;
+				}
+				p_bd_cur =(void *) QBM_DES_GET_NEXT(p_bd_cur);
+
+			}
+		} else{
+			gpd_data_len = QBM_DES_GET_DATALEN(gpd_ptr);
+			if(gpd_data_len>0){
+				gpd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+				QBM_CACHE_INVALID(gpd_data_ptr, gpd_data_len);
+				gpd_data_real_len = U_ExBytes(port,gpd_data_ptr ,gpd_data_len, NULL, UARTPort[port].ownerid);
+				if (gpd_data_len != gpd_data_real_len) {
+                    QBM_CACHE_FLUSH(gpd_data_ptr, gpd_data_real_len);
+                    QBM_DES_SET_DATALEN(gpd_ptr,gpd_data_real_len);
+                    QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+				}
+			}
+		}
+		if(gpd_ptr == gpd_tail)
+		{		
+			break;
+		} else
+		{
+			gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+		}
+	}
+}
+void UART_Boot_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len)
+{
+   volatile kal_uint16 LSR;
+   kal_uint16 index;
+   static kal_uint32 UART_Boot_Send_Count = 0;
+   
+  UART_Boot_Send_Count+=len;
+  
+   for(index=0;index<len;index++)
+      UART_PutUARTByte_limited(port,*(data+index));
+      
+   index = 0;
+   while(1) //make sure tx already send out all data.
+   {
+      LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+      if( LSR & UART_LSR_THRE )
+      {
+         break;
+      }else if( (MCU_BOOT_SPEED/DEBUG_BAUDRATE) < index++)
+      {
+         init_log_fail_count++;
+         break;
+      }
+   }
+}
+
+void U_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len) {
+	kal_uint16 index;
+	
+	for(index=0;index<len;index++)
+	   pUart_CMD_FUNC[port]->PutUARTByte(port,*(data+index));
+
+}
+void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len)
+{
+   kal_uint16 index;
+   if(port >= MAX_UART_PORT_NUM)
+      return;
+
+   if( (sst_get_exception_count() > 0) && (0 == UARTPort[port].Tx_DMA_Ch) && (1500000 == UARTPort[port].DCB.baud))
+      for(index=0;index<len;index++)
+         PutUARTDataDelay(port,escape_char,*(data+index));
+   else   
+      for(index=0;index<len;index++)
+         PutUARTData(port,escape_char,*(data+index));
+}
+
+void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate, module_type ownerid)
+{
+	kal_uint16 byte = 0;
+	kal_uint32 freq_div = 1;
+	kal_uint32 sample_count = 0;
+	kal_uint32 UART_BASE;
+
+	UART_BASE = UART_BaseAddr[port];
+	UARTPort[port].DCB.baud = baudrate;
+
+	if(baudrate)
+	{
+		do {
+			sample_count = (UART_CLOCK + (freq_div * baudrate / 2)) / (freq_div * baudrate);
+			if(sample_count > 0xff) freq_div++;
+		} while(sample_count > 0xff);
+	}
+
+	// configure register
+	DRV_UART_WriteReg(UART_RATE_STEP(UART_BASE), 0x3);
+
+	byte = DRV_Reg32(UART_LCR(UART_BASE));					// DLAB start
+	DRV_WriteReg32(UART_LCR(UART_BASE), byte | UART_LCR_DLAB);
+
+	DRV_WriteReg32(UART_DLL(UART_BASE), freq_div & 0xFF);
+	DRV_WriteReg32(UART_DLH(UART_BASE), (freq_div >> 8) & 0xFF);
+
+	DRV_UART_WriteReg(UART_STEP_COUNT(UART_BASE), sample_count - 1);
+	DRV_UART_WriteReg(UART_SAMPLE_COUNT(UART_BASE), sample_count >> 1);
+	DRV_UART_WriteReg(UART_LCR(UART_BASE), byte);					// DLAB end
+}
+
+
+void UART_Bootup_Init()
+{
+	UARTPort[DEBUG_PORT].ownerid = (module_type)( (kal_uint16)MOD_UART1_HISR + (kal_uint8) DEBUG_PORT);
+
+   //Set SW flow control as equal to catcher default flow control
+   DRV_UART_WriteReg(UART_LCR(UART1_base),0xbf);            /* Enchance setting */
+   DRV_UART_WriteReg(UART_EFR(UART1_base),UART_EFR_SWFlowCtrlX1);
+
+   //always open as new SW flow control, DHL under META will reset to disable
+   {  
+      DRV_UART_WriteReg(UART_ESCAPE_DAT(UART1_base),0x77);
+      DRV_UART_WriteReg(UART_ESCAPE_EN(UART1_base),0x1);
+   }              
+   DRV_UART_WriteReg(UART_XON1(UART1_base),0x11);
+   DRV_UART_WriteReg(UART_XOFF1(UART1_base),0x13);
+   DRV_UART_WriteReg(UART_XON2(UART1_base),0x11);
+   DRV_UART_WriteReg(UART_XOFF2(UART1_base),0x13);
+   DRV_UART_WriteReg(UART_LCR(UART1_base),0x3);
+   
+
+	U_SetBaudRate(DEBUG_PORT, DEBUG_BAUDRATE, (module_type)( (kal_uint16)MOD_UART1_HISR + (kal_uint8) DEBUG_PORT));
+}
+
+/*This function is to cover 6218B/6219 hw bug.
+UART should not send receiving data to its FIFO when doing auto baud*/
+void U_SetAutoBaud_Div(UART_PORT port, module_type ownerid) {}
+
+void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid)
+{
+   kal_uint16   byte;
+   kal_uint16   IER;
+   kal_uint32   savedMask;
+   kal_uint32   UART_BASE;
+
+   UART_BASE = UART_BaseAddr[port];
+   savedMask = SaveAndSetIRQMask();
+   IER = DRV_UART_Reg(UART_IER(UART_BASE));
+   DRV_UART_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
+   RestoreIRQMask(savedMask);
+   
+   U_SetBaudRate(port, UART_Config->baud, ownerid);
+   
+   /* Setup N81 */
+   byte = DRV_UART_Reg(UART_LCR(UART_BASE));     /* DLAB start */
+   byte &= ~UART_DATA_MASK;
+   switch(UART_Config->dataBits)
+   {
+   case len_5:
+      byte |= UART_WLS_5;
+      break;
+      
+   case len_6:
+      byte |= UART_WLS_6;
+      break;
+      
+   case len_7:
+      byte |= UART_WLS_7;
+      break;
+      
+   case len_8:
+      byte |= UART_WLS_8;
+      break;
+      
+   default:
+      break;
+   }
+   byte &= ~UART_STOP_MASK;
+   switch(UART_Config->stopBits)
+   {
+   case sb_1:
+      byte |= UART_1_STOP;
+      break;
+      
+   case sb_2:
+      byte |= UART_2_STOP;
+      break;
+      
+   case sb_1_5:
+      byte |= UART_1_5_STOP;
+      break;
+      
+   default:
+      break;
+   }
+   
+   byte &= ~UART_PARITY_MASK;
+   switch(UART_Config->parity)
+   {
+   case pa_none:
+      byte |= UART_NONE_PARITY;
+      break;
+      
+   case pa_odd:
+      byte |= UART_ODD_PARITY;
+      break;
+      
+   case pa_even:
+      byte |= UART_EVEN_PARITY;
+      break;
+      
+   case pa_space:
+      byte |= UART_SPACE_PARITY;
+      break;
+      
+   default:
+      break;
+   }
+   DRV_UART_WriteReg(UART_LCR(UART_BASE),byte);            /* DLAB End */
+   /* flowControl */
+   byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+
+   DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf);            /* Enchance setting */
+   switch(UART_Config->flowControl)
+   {
+   case fc_none:
+      DRV_UART_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
+      
+      // Disable AutoEscape, we expect to use this functionality for S/W flow control
+      /*For AutoEscape*/
+      DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+      
+      break;
+      
+   case fc_hw:
+      DRV_UART_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
+      
+      // Disable AutoEscape, we expect to use this functionality for S/W flow control
+      /*For AutoEscape*/
+      DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+      break;
+      
+   case fc_sw:
+
+      DRV_UART_WriteReg(UART_EFR(UART_BASE), UART_EFR_SWFlowCtrlX1 |UART_EFR_Enchance); 
+      //reset first
+      DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+      if(uart_support_autoescape()==KAL_TRUE)
+      {  
+         /*For META, Dont use auto escape*/ 
+#if defined(META_MODE_SW_ESCAPING)
+        if(kal_query_boot_mode() != FACTORY_BOOT || UARTPort[port].ownerid != MOD_DHL_READER)
+#endif
+         {
+            /*For AutoEscape*/
+            DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
+            DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
+         }
+      }                  
+      break;
+      
+   default:    
+      break;
+   }
+   /* XON and XOFF characters */
+   DRV_UART_WriteReg(UART_XON1(UART_BASE),UART_Config->xonChar);
+   DRV_UART_WriteReg(UART_XOFF1(UART_BASE),UART_Config->xoffChar);
+   DRV_UART_WriteReg(UART_XON2(UART_BASE),UART_Config->xonChar);
+   DRV_UART_WriteReg(UART_XOFF2(UART_BASE),UART_Config->xoffChar);
+   DRV_UART_WriteReg(UART_LCR(UART_BASE),byte);         /* DLAB End */
+   
+   kal_mem_cpy( &UARTPort[port].DCB, UART_Config, sizeof(UARTDCBStruct) );
+   
+   savedMask = SaveAndSetIRQMask();
+   DRV_UART_WriteReg(UART_IER(UART_BASE),IER);
+   RestoreIRQMask(savedMask);
+}
+
+void U_ReadDCBConfig (UART_PORT port, UARTDCBStruct *DCB)
+{
+	kal_mem_cpy( DCB, &UARTPort[port].DCB, sizeof(UARTDCBStruct) );
+}
+
+void UART_loopback(UART_PORT port)
+{
+   kal_uint16 tmp;
+   kal_uint32 UART_BASE;
+   /* Enable Loop Back test!! */
+   if(port >= MAX_UART_PORT_NUM)
+      return;
+   UART_BASE = UART_BaseAddr[port];
+   tmp = DRV_UART_Reg(UART_MCR(UART_BASE));
+   tmp |= UART_MCR_LOOPB;
+   DRV_UART_WriteReg(UART_MCR(UART_BASE), tmp);
+}
+
+void UART_PDN_Disable(UART_PORT port)
+{
+	switch(port)
+    {
+    	case uart_port1:
+		PDN_CLR(PDN_UART0);
+	#if defined(__HIF_UART_SUPPORT__) ||(defined(DRV_DEBUG)&&(defined(DRV_DEBUG_DMA_MODE) || defined(DRV_DEBUG_BUFFER_DMA_MODE)))
+		HDMA_PDN_CLR(port+2);
+		HDMA_PDN_CLR(port+3);
+	#endif
+            break;
+        case uart_port2:
+            PDN_CLR(PDN_UART1);
+            break;
+        default:
+            ASSERT(0);
+            break;
+     }
+}
+
+void UART_PDN_Enable(UART_PORT port)
+{
+	switch(port)
+    {
+    	case uart_port1:
+		PDN_SET(PDN_UART0);
+		HDMA_PDN_SET(port+2);
+		HDMA_PDN_SET(port+3);
+            break;
+        case uart_port2:
+            PDN_SET(PDN_UART1);
+            break;
+        default:
+            ASSERT(0);
+            break;
+     }
+}
+
+void UART_HWInit(UART_PORT port)
+{
+	UARTDCBStruct *DCBdefault;
+	UARTDCBStruct  UART_DefaultConfig =
+	{
+		UART_BAUD_1500000,	// baud
+		len_8,			// dataBits
+		sb_1,			// stopBits
+		pa_none,		// parity
+		fc_none,		// no flow control
+		0x11,			// xonChar
+		0x13,			// xoffChar
+		KAL_FALSE
+	};
+	kal_uint32 UART_BASE;
+
+	if(port >= MAX_UART_PORT_NUM)
+		return;
+	UART_BASE = UART_BaseAddr[port];
+	
+	UART_PDN_Disable(port);
+
+	/* Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03 */
+	/* BaudRate and autoflowcontrol */
+	DCBdefault = (UARTDCBStruct *)&UART_DefaultConfig;
+	U_SetDCBConfig(port, DCBdefault, UARTPort[port].ownerid);
+  
+	DRV_UART_Reg(UART_LSR(UART_BASE));
+	DRV_UART_Reg(UART_MSR(UART_BASE));
+
+	/* DTR , RTS is on, data will be coming,Output2 is high */
+	DRV_UART_SetBits(UART_MCR(UART_BASE), UART_MCR_Normal);
+
+	DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+   
+	// Set handle value to 0xFF to indicate this handle is invalid
+	UARTPort[port].handle = 0xFF;
+   
+	UARTPort[port].Rec_state = UART_RecNormal;
+	UARTPort[port].port_no = port;
+   
+	UARTPort[port].sleep_on_tx = uart_sleep_on_tx_allow;
+	UARTPort[port].EnableTX= KAL_TRUE;
+	UARTPort[port].power_on= KAL_TRUE;
+
+	// HDMA related HW init
+	// init FIFO Control Regitser: UART_FCR_RFTL_12 | UART_FCR_TFTL_0 | UART_FCR_CLRT | UART_FCR_CLRR | UART_FCR_FIFOE
+	DRV_UART_WriteReg(UART_FCR(UART_BaseAddr[port]), 0x87);
+#if defined(MTK_SLEEP_ENABLE)
+	DRV_UART_WriteReg(UART_SLEEP_EN(UART_BASE),KAL_TRUE);
+#endif
+	switch(port)
+	{
+		case uart_port1:
+			// init TX HDMA
+			HDMA_MODE_CONFIG(UART1_HDMA_TX_CHANNEL, HDMA_CKSUM_EN_DEFAULT, HDMA_LIST_MODE, HDMA_CKSUM_12B);
+			HDMA_CONFIG(UART1_HDMA_TX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+			HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_TX_CHANNEL, 0);
+
+			// init RX HDMA
+			HDMA_CONFIG_RX_SEL(UART1_HDMA_RX_CHANNEL, 0x3);
+			HDMA_MODE_CONFIG(UART1_HDMA_RX_CHANNEL, HDMA_CKSUM_EN_DEFAULT, HDMA_LIST_MODE, HDMA_CKSUM_12B);
+			HDMA_CONFIG(UART1_HDMA_RX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+			HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_RX_CHANNEL, 0);
+#ifdef DRV_DEBUG
+			DRV_WriteReg32(UART_DMA_EN(UART_BaseAddr[port]), 0x0);
+#else
+			DRV_WriteReg32(UART_DMA_EN(UART_BaseAddr[port]), UART_TXRXDMA_ON|UART_TO_CNT_AUTORST);
+			DRV_WriteReg32(UART_DMA_ACK(UART_BaseAddr[port]),UART_DMA_ACK_DIS);
+#endif
+			break;
+
+		case uart_port2:
+			break;
+		default:
+			ASSERT(0);
+			break;
+	}
+
+	// If needTxDoneCb is 1, the driver must call DclSerialPort_DrvTxDone(handle, source_id, tx_ior) after tx_ior data is sent.
+	// initial value is 0
+	UARTPort[port].need_tx_done_cb = KAL_FALSE;
+}
+
+kal_bool U_Open(UART_PORT port, module_type ownerid)
+{
+	kal_uint32 UART_BASE;
+	kal_uint16  MSR;
+	kal_uint8 byte;
+	kal_uint8  irq_code = 0;
+
+	UART_BASE = UART_BaseAddr[port];
+	if(port == uart_port_null)
+		return KAL_FALSE;
+ 
+	UARTPort[port].initialized = KAL_TRUE;
+	UARTPort[port].ownerid = ownerid;
+         
+	UARTPort[port].RingBuffers.rx_buffer = UART_rings->ring[port].rx_adrs;
+	UARTPort[port].RingBuffers.tx_buffer = UART_rings->ring[port].tx_adrs;
+	Buf_init(&(UARTPort[port].Rx_Buffer),(kal_uint8 *)(UARTPort[port].RingBuffers.rx_buffer),(kal_uint16)UART_rings->ring[port].rx_len);
+	Buf_init(&(UARTPort[port].Tx_Buffer),(kal_uint8 *)(UARTPort[port].RingBuffers.tx_buffer),(kal_uint16)UART_rings->ring[port].tx_len);   
+	if( UART_IsVfifoSetting(port, TX_VFIFO) == KAL_FALSE )
+	{
+		UARTPort[port].RingBuffers.txISR_buffer = UART_rings->ring[port].txisr_adrs;
+		Buf_init(&(UARTPort[port].Tx_Buffer_ISR),(kal_uint8 *)(UARTPort[port].RingBuffers.txISR_buffer),(kal_uint16)UART_rings->ring[port].txisr_len);				
+	}
+
+	MSR = DRV_UART_Reg(UART_MSR(UART_BASE));
+
+	if (MSR & UART_MSR_DSR)
+		UARTPort[port].DSR = io_high;
+	else
+		UARTPort[port].DSR = io_low;
+   
+   /* Rx FIFO trigger = 62, Tx FIFO trigger is 16, and FIFO enable. */
+   DRV_UART_WriteReg(UART_FCR(UART_BASE),UART_FCR_Normal);
+
+   if( UART_IsVfifoSetting(port, TXRX_VFIFO))
+   {
+		ASSERT(0);/*wrong configuration*/
+   }
+   else
+   {	
+		if (UARTPort[port].DCB.flowControl == fc_none)
+		{
+			   DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+		}
+		else if (UARTPort[port].DCB.flowControl == fc_hw)
+		{
+//		   DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+			DRV_UART_WriteReg32(UART_MCR(UART_BASE), (DRV_UART_Reg32(UART_MCR(UART_BASE)) | 0x02));
+			byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+			DRV_UART_WriteReg(UART_LCR(UART_BASE), 0xbf); 
+			DRV_UART_WriteReg(UART_EFR(UART_BASE), DRV_UART_Reg(UART_EFR(UART_BASE)) | UART_EFR_AutoRTSCTS);
+			DRV_UART_WriteReg(UART_LCR(UART_BASE), byte);
+		}
+		else if (UARTPort[port].DCB.flowControl == fc_sw)
+		{
+			// need to set EFR enhance before IRE	
+			byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+			DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf); 
+			DRV_UART_WriteReg(UART_EFR(UART_BASE), DRV_UART_Reg(UART_EFR(UART_BASE)) | UART_EFR_Enchance);	
+			DRV_UART_WriteReg(UART_LCR(UART_BASE),byte);
+
+			DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_SW_NORMALINTS);                        
+			DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0); //reset to disable first
+			if(uart_support_autoescape()==KAL_TRUE)
+			{
+                  	/*For META, Dont use auto escape*/
+#if defined(META_MODE_SW_ESCAPING)
+                 		if(kal_query_boot_mode() != FACTORY_BOOT || UARTPort[port].ownerid != MOD_DHL_READER)
+#endif
+                 		 {
+                    		 /*For AutoEscape*/
+                     		byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+                   		  	// DLAB start */
+                    			DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf);            /* Enchance setting */
+                     		DRV_UART_WriteReg(UART_XON1(UART_BaseAddr[port]),0x11);
+                     		DRV_UART_WriteReg(UART_XON2(UART_BaseAddr[port]),0x11);
+                    			 DRV_UART_WriteReg(UART_XOFF1(UART_BaseAddr[port]),0x13);
+                     		DRV_UART_WriteReg(UART_XOFF2(UART_BaseAddr[port]),0x13);
+				//autoescape
+                    			 DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
+                     		DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
+                     		DRV_UART_WriteReg(UART_LCR(UART_BASE),byte);            /* Enchance setting */            
+                  		}
+               	}   
+		}
+   }      
+   
+   /*For excetpion, we dont need to do the following */
+#ifdef __MTK_TARGET__
+   if(INT_QueryExceptionStatus())
+      return KAL_TRUE; 
+#endif   
+	switch(port)
+	{
+		case uart_port1:	
+			irq_code = UART_GetIRQCode(uart_port1);
+			IRQMask(irq_code);
+			//IRQ_Register_LISR(irq_code, UART1_LISR, "UART1");
+			//IRQSensitivity(irq_code, LEVEL_SENSITIVE);
+			IRQClearInt(irq_code);
+			DRV_WriteReg32(UART_IER(UART_BASE), 0x4);
+			IRQUnmask(irq_code);
+			break;
+			
+		case uart_port2:
+			irq_code = UART_GetIRQCode(uart_port2);
+			IRQMask(irq_code);
+			//IRQ_Register_LISR(irq_code, UART2_LISR, "UART2");
+			//IRQSensitivity(irq_code, LEVEL_SENSITIVE);
+			IRQClearInt(irq_code);
+			DRV_WriteReg32(UART_IER(UART_BASE), 0x4);
+			IRQUnmask(irq_code);
+			break;
+		default:
+			ASSERT(0);
+			break;
+	}
+
+	IRQMask(UART_HDMA_INTR_ID);
+	//IRQ_Register_LISR(UART_HDMA_INTR_ID, uart_hdma_lisr, "UART_HDMA");
+	//IRQSensitivity(UART_HDMA_INTR_ID, LEVEL_SENSITIVE);
+
+	HDMA_LENERR_INTR_UNMASK(2);
+	HDMA_BD_CSERR_INTR_UNMASK(2);
+	HDMA_GPD_CSERR_INTR_UNMASK(2);
+	HDMA_LENERR_INTR_UNMASK(3);
+	HDMA_BD_CSERR_INTR_UNMASK(3);
+	HDMA_GPD_CSERR_INTR_UNMASK(3);
+	HDMA_QE_INTR_UNMASK(3);	// RX done
+	HDMA_INT_CLEAR_ALL();
+	IRQUnmask(UART_HDMA_INTR_ID);
+
+	return KAL_TRUE;
+}
+
+void U_Purge(UART_PORT port, UART_buffer dir, module_type ownerid)
+{
+	kal_uint32 UART_BASE = UART_BaseAddr[port];
+
+	/* Rx FIFO trigger = 62, Tx FIFO trigger is 16, and FIFO enable. */
+	// for MT6290, Rx FIFO trigger = 12. Tx FIFO trigger is 0
+	if (dir == RX_BUF)
+		DRV_UART_WriteReg(UART_FCR(UART_BASE),(UART_FCR_Normal & ~UART_FCR_CLRT));
+	else
+		DRV_UART_WriteReg(UART_FCR(UART_BASE),(UART_FCR_Normal & ~UART_FCR_CLRR));
+}
+
+void U_Close(UART_PORT port, module_type ownerid)
+{
+	kal_uint32 UART_BASE = UART_BaseAddr[port];
+	kal_uint8 irq_code;
+
+	UARTPort[port].initialized = KAL_FALSE;
+	UARTPort[port].ownerid = (module_type) ((kal_uint16) MOD_UART1_HISR + (kal_uint8) port); 
+   
+	switch(port)
+	{
+		case uart_port1:
+			irq_code = UART_GetIRQCode(uart_port1);
+			IRQMask(irq_code);
+			break;
+		case uart_port2:
+			irq_code = UART_GetIRQCode(uart_port2);
+			IRQMask(irq_code);
+			break;
+		default:
+			ASSERT(0);
+			break;
+	}
+
+	DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+
+	U_ConfigEscape(port, 0xff, 0, UARTPort[port].ownerid);
+
+	U_ClrRxBuffer(port, UARTPort[port].ownerid);		// clear sw RX buffer
+	U_ClrTxBuffer(port, UARTPort[port].ownerid);		// clear sw TX buffer
+	U_Purge(port, RX_BUF, UARTPort[port].ownerid);		// clear hw RX FIFO
+	U_Purge(port, TX_BUF, UARTPort[port].ownerid);		// clear hw TX FIFO
+ 
+	DRV_UART_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
+   
+	UART_PDN_Enable(port);
+
+   
+	if(UARTPort[port].handle != 0xFF)
+	{
+		UARTPort[port].handle = 0xFF;
+	}
+}
+
+void U_SetOwner (UART_PORT port, module_type ownerid)
+{
+	U_ClrTxBuffer(port, UARTPort[port].ownerid);		// clear sw TX buffer
+	U_ClrRxBuffer(port, UARTPort[port].ownerid);		// clear sw RX buffer
+
+	UARTPort[port].ownerid = ownerid;
+	UARTPort[port].need_tx_done_cb = KAL_FALSE;
+}
+
+module_type U_GetOwnerID(UART_PORT port)
+{
+	return UARTPort[port].ownerid;
+}
+
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid)
+{
+
+   UARTPort[port].ESCDet.EscChar = EscChar;
+   UARTPort[port].ESCDet.GuardTime = ESCGuardtime;
+	// Escape character register is WO
+	DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]), EscChar);	// added by ansel
+	DRV_UART_WriteReg(UART_GUARD(UART_BaseAddr[port]), ESCGuardtime);	// added by ansel
+   if (UARTPort[port].ESCDet.GuardTime)
+   {
+      UARTPort[port].Rec_state = UART_RecNormal;
+   }
+}
+
+void U_SetFlowCtrl(UART_PORT port, kal_bool XON, module_type ownerid)    {}   /*NULL for all*/
+
+kal_uint32 U_GetFlowCtrl(UART_PORT port, module_type ownerid)
+{
+	kal_uint16 IER, LCR;
+	kal_uint32 savedMask;
+	kal_uint32 UART_BASE;
+	kal_uint32 EFR;
+
+	UART_BASE = UART_BaseAddr[port];
+
+	savedMask = SaveAndSetIRQMask();
+	IER = DRV_UART_Reg(UART_IER(UART_BASE));
+	DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+	RestoreIRQMask(savedMask);
+
+	LCR = DRV_UART_Reg(UART_LCR(UART_BASE));
+	DRV_UART_WriteReg(UART_LCR(UART_BASE), 0xBF);
+	EFR = DRV_UART_Reg(UART_EFR(UART_BASE));
+	DRV_UART_WriteReg(UART_LCR(UART_BASE), LCR);
+
+	savedMask = SaveAndSetIRQMask();
+	DRV_UART_WriteReg(UART_IER(UART_BASE), IER);
+	RestoreIRQMask(savedMask);
+
+	return EFR;
+}
+
+void U_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid) {}   /*NULL for DCE*/
+void U_CtrlRI (UART_PORT port, IO_level SRI, module_type ownerid) {}   /*NULL for DCE*/
+void U_CtrlDTR (UART_PORT port, IO_level SDTR, module_type ownerid) {}
+void U_ReadHWStatus(UART_PORT port, IO_level *SDSR, IO_level *SCTS)
+{
+   kal_uint16 MSR;
+   kal_uint32 UART_BASE;
+
+   UART_BASE = UART_BaseAddr[port];
+   MSR = DRV_UART_Reg(UART_MSR(UART_BASE));
+   *SDSR = (IO_level)(( MSR & UART_MSR_DSR) >> 5);
+   *SCTS = (IO_level)(( MSR & UART_MSR_CTS) >> 4);
+}
+
+void U_CtrlBreak(UART_PORT port, IO_level SBREAK, module_type ownerid)
+{
+	kal_uint32 UART_BASE = UART_BaseAddr[port];
+	if(SBREAK == io_high)
+	{
+		if(HDMA_BUF0_IS_ACTIVE((port + 2)))
+			HDMA_BUF0_STOP((port + 2));
+		DRV_UART_SetBits(UART_LCR(UART_BASE), UART_LCR_BREAK);
+	} else
+	{
+		DRV_UART_ClearBits(UART_LCR(UART_BASE), UART_LCR_BREAK);
+		if(uart_wait_tgpd_head[port] != NULL || uart_tgpd_head[port] != NULL)
+			HDMA_BUF0_RESUME((port + 2));
+	}
+}
+
+kal_uint16 U_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid)
+{
+	kal_uint16 real_count, index;
+	kal_uint16 data_count = 0;
+
+	if(status != NULL)
+		*status = 0;
+   
+	DisableRxIntr(UART_BaseAddr[port]);
+	if (status != NULL)
+	{
+		if (UARTPort[port].EscFound)
+		{
+			*status |= UART_STAT_EscDet;
+			UARTPort[port].EscFound = KAL_FALSE;
+		}
+		if(UARTPort[port].breakDet)
+		{
+			*status |= UART_STAT_Break;
+			UARTPort[port].breakDet = KAL_FALSE;
+		}
+	}
+   
+	EnableRxIntr(UART_BaseAddr[port]);
+
+	do {
+		Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+
+		if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+			|| (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+		{  
+         
+			for(index = 0; (index < real_count) && (data_count < Length); index++)
+			{
+				Buf_Pop(&(UARTPort[port].Rx_Buffer), *(Buffaddr + data_count));           
+            
+				// The following are for software flow control
+				if(uart_escape_state==0)
+				{
+					if(*(Buffaddr + data_count) == 0x77)
+					{
+						uart_escape_state=0x77;
+					} else
+					{
+						data_count++;
+					}
+            
+				} else if(uart_escape_state == 0x77)
+				{
+					switch(*(Buffaddr + data_count))
+					{
+						case 0x01:
+							*(Buffaddr+data_count) = UARTPort[port].DCB.xonChar;
+							data_count++;
+							break;
+						case 0x02:                  
+							*(Buffaddr+data_count)=UARTPort[port].DCB.xoffChar; 
+							data_count++;
+							break;               
+						case 0x03:                  
+							*(Buffaddr + data_count) = 0x77;
+							data_count++;
+							break;      
+						default:
+							break;
+               
+					}
+					uart_escape_state=0x0;        
+            
+				}
+			}   
+      
+		} else // HW flow control
+		{
+			for(index = 0; (index < real_count) && (data_count < Length); index++)
+			{
+				Buf_Pop(&(UARTPort[port].Rx_Buffer),*(Buffaddr + data_count));
+				data_count++;
+			}
+      		}   
+
+      		// satisfy uart owner request, so break
+	 	if (data_count == Length) break;            
+
+		// disable interrupt
+		DisableRxIntr(UART_BaseAddr[port]);
+
+		Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+      		// there is no data in ringbuffer, so break
+		if(real_count == 0)
+		{
+			send_Rxilm[port] = KAL_TRUE;  
+			// enable interrupt
+			EnableRxIntr(UART_BaseAddr[port]); 
+			break;
+		}
+
+		/* enable interrupt*/
+		EnableRxIntr(UART_BaseAddr[port]);
+	} while(KAL_TRUE);        
+   
+	return data_count;
+}
+
+#ifdef DRV_DEBUG
+
+void UART_DMA_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length)
+{
+	if(port>=uart_port3){
+		return;
+	}
+	clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)Buffaddr), CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)Buffaddr, (kal_uint32)Length));
+
+	HDMA_BUF0_PROG_ADDR_CONFIG(port+2, (kal_uint32)Buffaddr);
+	HDMA_BUF0_XFER_SIZE_CONFIG(port+2, (kal_uint32)Length);
+
+	Data_Sync_Barrier();
+
+	HDMA_BUF0_START(port+2);
+}
+
+kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length)
+{
+	kal_uint16 real_count, index;
+    #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+	kal_uint16 is_empty;
+	#endif
+	if(port >= MAX_UART_PORT_NUM)
+		return 0;
+
+	Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer), real_count);
+	if(real_count > Length)
+	{
+		real_count = Length;
+	}
+
+    /* 
+     * The spin lock is used for the con-currency case of HDMA HISR
+     * and dbg_print. The write/read pointer of buffer is the basis
+     * whether to start the next DMA or NOT, so use the spin lock
+     * to protect the pointer updatding actions
+     */
+    #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+    #ifndef KTEST_UART_TRACES
+    kal_take_spinlock(print_buf_lock, KAL_INFINITE_WAIT);
+    #else
+    kal_hrt_take_itc_lock(KAL_ITC_PRINT, KAL_INFINITE_WAIT);
+    #endif
+
+    /* To check if DMA should be start in this API */
+	Buf_IsEmpty(&(UARTPort[port].Tx_Buffer), is_empty);
+    #endif
+	
+	for(index = 0; index < real_count; index++)
+	{
+		Buf_Push(&(UARTPort[port].Tx_Buffer), *(Buffaddr + index));
+	}
+
+    #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+    #ifndef KTEST_UART_TRACES
+	kal_give_spinlock(print_buf_lock);
+    #else
+    kal_hrt_give_itc_lock(KAL_ITC_PRINT);
+    #endif
+	#endif
+	
+	switch(port)
+	{
+		case uart_port1:
+        #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+            if (is_empty == Buff_isEmpty)
+                UART_TxDMAHandler(&UARTPort[uart_port1], 0);
+        #else
+            EnableTxIntr(UART_BaseAddr[port]);	
+        #endif
+			break;
+		case uart_port2:
+			EnableTxIntr(UART_BaseAddr[port]);
+			break;
+		default:
+			ASSERT(0);
+			break;
+	}
+
+
+	return real_count;
+}
+#endif   /*DRV_DEBUG*/
+
+/*************************************************************************
+   * FUNCTION                                                            
+   *	UART_GetTxWorkingMode
+   *
+   * DESCRIPTION                                                           
+   *	
+   *	This function is to get the uart TX working mode.
+   *
+   * PARAMETERS
+   *  port        - the uart port
+   *
+   *  RETURNS
+   *  UART_ON_VFIFO: the uart port Tx working on VFIFO mode
+   *  UART_ON_DMA: the uart port Tx working on normal DMA mode
+   *  UART_ON_MCU: the uart port Tx working on sw mode 
+   *
+   * Global AFFECTED
+   *
+   *************************************************************************/
+UART_WORKING_MODE UART_GetTxWorkingMode(UART_PORT port)
+{
+	if(UART_IsVfifoSetting(port, TX_VFIFO))
+		return UART_ON_VFIFO;
+
+	return UART_ON_MCU;
+}
+
+kal_uint16 U_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid )
+{
+	kal_uint16 real_count, index;
+	if(port >= MAX_UART_PORT_NUM)
+		return 0;
+	
+	Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer), real_count);
+	if(real_count > Length)
+	{
+		real_count = Length;
+	}
+	
+	for(index = 0; index < real_count; index++)
+	{
+		Buf_Push(&(UARTPort[port].Tx_Buffer), *(Buffaddr + index));
+	}
+	   
+	switch(port)
+	{
+		case uart_port1:
+			EnableTxIntr(UART_BaseAddr[port]);	  
+			break;
+		case uart_port2:
+			EnableTxIntr(UART_BaseAddr[port]);
+			break;
+		default:
+			ASSERT(0);
+			break;
+	}
+	return real_count;
+}
+
+#ifndef __ROMSA_SUPPORT__ /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE 
+#else
+kal_uint16 
+#endif
+U_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid)
+{
+	return 0;
+}
+#endif /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE 
+#else
+kal_uint16 
+#endif
+U_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid)
+{
+	return 0;
+}
+
+kal_uint16 U_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid)
+{ 
+	return 0;
+}
+
+//============================== ISR level ====================
+/*============================ UART1 ========================*/
+void UART_RLSHandler(void *parameter)
+{
+	kal_uint16 LSR;
+	UARTStruct *UARTData = (UARTStruct *) parameter;
+	kal_uint32 UART_BASE;
+
+	if(UARTData->port_no >= MAX_UART_PORT_NUM)
+		return;
+   
+	UART_BASE = UART_BaseAddr[UARTData->port_no];
+	LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+/*
+	if(LSR & UART_LSR_OE) dbg_print("Overrun Error\n\r");
+	if(LSR & UART_LSR_PE) dbg_print("Parity Error\n\r");
+	if(LSR & UART_LSR_FE) dbg_print("Framing Error\n\r");
+*/
+	if(LSR & UART_LSR_BI)
+	{
+		UARTData->breakDet = KAL_TRUE;
+		U_Purge(UARTData->port_no, RX_BUF, UARTPort[UARTData->port_no].ownerid);
+	}
+   
+	if((LSR & UART_LSR_OE) || (LSR & UART_LSR_FIFOERR))
+	{
+		//for check BT overwrite UART FIFO, because BT do not use flow control, lost data will cause BT fail
+//		if((UARTPort[UARTData->port_no].ownerid == MOD_BT))
+//		{
+//			UART_DBG(__LINE__, UART_GetTimeStamp(), ust_get_current_time(), LSR);
+//			ASSERT(!(LSR & UART_LSR_OE)); // BT send too fast, VFIFO can not get bus, overwrite UART FIFO
+//		}   	   
+		DisableRLSIntr(UART_BASE);
+	}
+}
+
+void UART_Calback(void *parameter) {}
+
+void UART_SetRateFix(UART_PORT  port) {}
+
+int uart_pio_get_data_like_dma(UART_PORT port, kal_uint8 *ptr_dat, kal_uint32 allow_len)
+{
+	int real_len = 0;
+	kal_uint32 base = UART_BaseAddr[port];
+	if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR) == 0) {
+			/* RX no data */
+			return 0;
+	}
+	for(;;) {
+		while ((real_len < allow_len) && (DRV_Reg8(UART_LSR(base))&UART_LSR_DR)) {
+			*ptr_dat++ = DRV_Reg8(UART_RBR(base));
+			real_len ++;
+		}
+
+		if (real_len == allow_len) {
+			/* Got Enough data */
+			break;
+		}
+
+		/* 32k timer, 30us */
+		kal_uint32 delayTime1;
+		delayTime1 = drv_get_current_time()+3;	/* delay 60~90us*/
+		while(delayTime1 != drv_get_current_time()) {
+			if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR))
+				break;
+				
+		}
+
+		if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR) == 0) {
+			/* RX Timeout */
+			break;
+		}
+	}
+
+	return real_len;
+}
+void UART_RecHandler(void *parameter) {
+	   UARTStruct *UARTData=(UARTStruct *)parameter;
+	   kal_uint32 UART_BASE;
+	   kal_uint16 RoomLeft;
+	   kal_uint16 LSR;
+	   kal_uint8  cRXChar;
+	   if(UARTData->port_no >= MAX_UART_PORT_NUM)
+		  return;
+		  
+	   UART_BASE = UART_BaseAddr[UARTData->port_no];   
+	   Buf_GetRoomLeft(&(UARTData->Rx_Buffer),RoomLeft);
+	  		
+	   while (RoomLeft)
+	   {
+		  LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+		  if (LSR & UART_LSR_BI)
+		  {
+			 UARTData->breakDet = KAL_TRUE;
+			 U_Purge(UARTData->port_no,RX_BUF,UARTPort[UARTData->port_no].ownerid);
+			 LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+		  }
+		  
+		  if (LSR & UART_LSR_DR)
+		  {
+  	    
+			 cRXChar = (kal_uint8)DRV_UART_Reg(UART_RBR(UART_BASE));
+	
+			 Buf_Push(&(UARTData->Rx_Buffer),cRXChar);
+			 RoomLeft--;		 
+		  }
+		  else
+		  {
+			 break;
+		  }
+	   }	   
+	   if (!RoomLeft)	/*buffer is full*/
+		  DisableRxIntr(UART_BASE);
+
+
+}
+
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+/* This function might be called by HISR and dbg_print */
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done)
+{
+    UARTStruct *UARTData = (UARTStruct *) parameter;
+    kal_uint16 real_count_TASK, done_count;
+    BUFFER_INFO *TxBuf = (BUFFER_INFO *)(&(UARTData->Tx_Buffer));
+
+    if(UARTData->port_no >= MAX_UART_PORT_NUM)
+        return;
+
+    /* 
+     * The spin lock is used for the con-currency case of HDMA HISR
+     * and dbg_print. The write/read pointer of buffer is the basis
+     * whether to start the next DMA or NOT, so use the spin lock
+     * to protect the pointer updatding actions
+     */
+    #ifndef KTEST_UART_TRACES
+    kal_take_spinlock(print_buf_lock, KAL_INFINITE_WAIT);
+    #else
+    kal_hrt_take_itc_lock(KAL_ITC_PRINT, KAL_INFINITE_WAIT);
+    #endif
+    
+    if (chk_done) {
+        done_count = DRV_Reg32(GDMA_HCCR(UARTData->port_no+2)) & 0xFFFF;
+
+        if (done_count) {
+            BRead(TxBuf) += done_count;
+            if (BRead(TxBuf) >= BLength(TxBuf))
+                BRead(TxBuf) -= BLength(TxBuf);
+        }
+    }
+
+    Buf_GetBytesAvail_DMA(&(UARTData->Tx_Buffer), real_count_TASK);
+
+    #ifndef KTEST_UART_TRACES
+    kal_give_spinlock(print_buf_lock);
+    #else
+    kal_hrt_give_itc_lock(KAL_ITC_PRINT);
+    #endif
+
+    if (real_count_TASK) {
+        clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)BuffRead(TxBuf)), 
+            CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)BuffRead(TxBuf), (kal_uint32)real_count_TASK));
+        
+    	HDMA_BUF0_PROG_ADDR_CONFIG(UARTData->port_no+2, (kal_uint32)BuffRead(TxBuf));
+    	HDMA_BUF0_XFER_SIZE_CONFIG(UARTData->port_no+2, (kal_uint32)real_count_TASK);
+    	HDMA_BUF0_START(UARTData->port_no+2);
+
+    	return;
+	}
+}
+#endif
+
+void UART_TrxHandler(void *parameter)
+{
+	UARTStruct *UARTData = (UARTStruct *) parameter;
+	kal_uint32 UART_BASE;
+	kal_uint16 byteCount, index;
+	kal_uint16 real_count_TASK, real_count = 0;
+	kal_uint16 offset;
+	kal_uint8 TX_DATA;
+
+	if(UARTData->port_no >= MAX_UART_PORT_NUM)
+		return;
+
+	UART_BASE = UART_BaseAddr[UARTData->port_no];
+
+	byteCount = UART1_TxFIFO_DEPTH;
+
+	if(real_count != byteCount)
+	{
+		Buf_GetBytesAvail(&(UARTData->Tx_Buffer), real_count_TASK);
+		offset = byteCount - real_count;
+		real_count = real_count_TASK;
+		if(real_count_TASK > offset)
+		{
+			real_count = offset;
+		}
+      
+		for(index = 0; index < real_count; index++)
+		{
+			Buf_Pop(&(UARTData->Tx_Buffer),TX_DATA);
+			DRV_UART_WriteReg(UART_THR(UART_BASE), (kal_uint16) TX_DATA);
+		}
+	}
+
+	Buf_GetBytesAvail(&(UARTData->Tx_Buffer), real_count_TASK);
+	if(real_count_TASK == 0)
+		DisableTxIntr(UART_BASE);
+}
+
+void UART_MsHandler(void *parameter) {}
+
+//Bei add for get irq code
+kal_uint8 UART_GetIRQCode(UART_PORT port)
+{
+	kal_uint8 IRQ_code = 0;
+	switch(port)
+	{
+		case uart_port1:
+    		 IRQ_code = IRQ_UART_MD0_CODE;
+			 break;
+		case uart_port2:
+    		 IRQ_code = IRQ_UART_MD1_CODE;
+			 break;
+		default:
+			 break;
+	}
+	return IRQ_code;
+}
+
+void UART1_LISR(kal_uint32 vector)
+{
+	IRQMask(IRQ_UART_MD0_CODE);
+	kal_activate_hisr_index(UART_1_HISR);
+}
+
+void UART1_HISR(void)
+{
+	kal_uint16 IIR;
+   
+	IIR = DRV_UART_Reg(UART_IIR(UART_BaseAddr[uart_port1]));
+	if (IIR & UART_IIR_INT_INVALID)
+	{
+		IRQClearInt(IRQ_UART_MD0_CODE);
+		IRQUnmask(IRQ_UART_MD0_CODE);
+      
+		return;
+	}
+
+	switch(IIR & UART_IIR_INT_MASK)
+	{
+	
+		case UART_IIR_RLS:
+			UART_RLSHandler(&UARTPort[uart_port1]);
+			break;
+		case UART_IIR_CTI:
+		case UART_IIR_RDA:
+#ifdef __SLT_TOOL_SUPPORT__
+			UART_RecHandler(&UARTPort[uart_port1]) ;
+#endif
+			break;
+		case UART_IIR_THRE:
+			UART_TrxHandler(&UARTPort[uart_port1]);
+			break;
+		case UART_IIR_MS :
+		case UART_IIR_SWFlowCtrl:
+		case UART_IIR_HWFlowCtrl:
+		default:
+			break;
+	}
+	IRQClearInt(IRQ_UART_MD0_CODE);
+	IRQUnmask(IRQ_UART_MD0_CODE);
+}
+
+/*============================ UART2 ========================*/
+void UART2_LISR(kal_uint32 vector)
+{
+	IRQMask(IRQ_UART_MD1_CODE);
+	kal_activate_hisr_index(UART_2_HISR);
+}
+
+void UART2_HISR(void)
+{
+	kal_uint16 IIR;
+
+	IIR = DRV_UART_Reg(UART_IIR(UART_BaseAddr[uart_port2]));
+	if (IIR & UART_IIR_INT_INVALID)
+	{
+		IRQClearInt(IRQ_UART_MD1_CODE);
+		IRQUnmask(IRQ_UART_MD1_CODE);
+      
+		return;
+	}
+
+	switch(IIR & UART_IIR_INT_MASK)
+	{
+	
+		case UART_IIR_RLS:
+			UART_RLSHandler(&UARTPort[uart_port2]);
+			break;
+		case UART_IIR_CTI:
+		case UART_IIR_RDA:
+			break;
+		case UART_IIR_THRE:
+			UART_TrxHandler(&UARTPort[uart_port2]);
+			break;
+		case UART_IIR_MS :
+		case UART_IIR_SWFlowCtrl:
+		case UART_IIR_HWFlowCtrl:
+		default:
+			break;
+	}
+	IRQClearInt(IRQ_UART_MD1_CODE);
+	IRQUnmask(IRQ_UART_MD1_CODE);
+}
+
+
+typedef struct _ut_hdma_intr_s{
+	kal_uint32 hdma_done_int;
+	kal_uint32 hdma_qe_int;
+	kal_uint32 hdma_len_err_int;
+	kal_uint32 hdma_bd_cserr_int;
+	kal_uint32 hdma_gpd_cserr_int;
+}ut_hdma_intr_t;
+
+volatile static ut_hdma_intr_t ut_hdma_intr_record[2];
+
+
+void uart_hdma_lisr(kal_uint32 vector)
+{
+	IRQMask(UART_HDMA_INTR_ID);
+	kal_activate_hisr_index(GDMA2_HISR);
+}
+
+void uart_hdma_hisr(void)
+{
+	//kal_uint32 mask;
+	kal_uint32 val, chl;
+	kal_uint32 i;
+
+	//mask = SaveAndSetIRQMask();
+
+	val = DRV_Reg32(GDMA_GISAR_UART);
+
+	//Set the interrupt record table
+	for(i = 0; i < sizeof(ut_hdma_intr_record) / sizeof(ut_hdma_intr_t); i++ ){
+		chl = i + 2;
+
+		if(IS_HDMA_DONE_INTR(val, chl)){
+			ut_hdma_intr_record[i].hdma_done_int++;
+
+            #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+    		if (chl == UART1_HDMA_TX_CHANNEL) {
+    		    UART_TxDMAHandler(&UARTPort[uart_port1], 1);
+    		}
+    		#endif
+		}
+
+		if(IS_HDMA_QE_INTR(val, chl)){
+			ut_hdma_intr_record[i].hdma_qe_int++;
+			
+            #if defined(__HMU_ENABLE__)
+	            if (chl == UART1_HDMA_RX_CHANNEL) {
+	                // trigger UARTCORE task to polling RX
+	                hmu_hifeg_set(HIF_DRV_EG_HIF_TICK_EVENT_UART);
+	            }
+            #endif
+		}
+
+		if(IS_HDMA_GPD_CSERR_INTR(val, chl)){
+			ut_hdma_intr_record[i].hdma_gpd_cserr_int++;
+			ASSERT(0);
+		}
+
+		if(IS_HDMA_BD_CSERR_INTR(val, chl)){
+			ut_hdma_intr_record[i].hdma_bd_cserr_int++;
+			ASSERT(0);
+		}
+
+		if(IS_HDMA_LENERR_INTR(val, chl)){
+			ut_hdma_intr_record[i].hdma_len_err_int++;
+			ASSERT(0);
+		}
+	}
+
+	//Clear the interrupt status
+	HDMA_INT_CLEAR_ALL();
+
+	//RestoreIRQMask(mask);
+	IRQUnmask(UART_HDMA_INTR_ID);
+}
+
+#ifdef __USB_COM_PORT_ENABLE__
+extern UARTStruct USB2UARTPort[MAX_USB_PORT_NUM];
+#endif   /*__USB_COM_PORT_ENABLE__*/
+
+void UART_SetSleepEnable(UART_PORT port, kal_bool enable)
+{
+	DRV_UART_WriteReg(UART_SLEEP_EN(UART_BaseAddr[port]), enable);
+}
+
+//This API only for test purpose, can only be called by MEUT DVT test.
+//***********  do not call this API directly   ************
+//***********  do not call this API directly   ************
+//***********  do not call this API directly   ************
+void UART_set_FIFO_trigger(UART_PORT port, kal_uint16 tx_level, kal_uint16 rx_level)
+{
+	if(port >= MAX_UART_PORT_NUM)
+		return;
+	DRV_UART_WriteReg(UART_FCR(UART_BaseAddr[port]), ((tx_level<<4) | (rx_level<<6) | 0x7));
+}
+
+void U_Register_TX_cb(UART_PORT port, module_type ownerid, UART_TX_FUNC func) {}
+void U_Register_RX_cb(UART_PORT port, module_type ownerid, UART_RX_FUNC func) {}
+void UART_TurnOnPower(UART_PORT port, kal_bool enable) {}
+
+/* This is to check that all the data in UART TX ring buffer is empty. */
+kal_bool UART_CheckTxBufferEmpty(UART_PORT port)
+{
+	kal_uint8 result;
+	void *p_cur_gpd;
+	if(port >= MAX_UART_PORT_NUM)
+		return KAL_FALSE;
+
+// HDMA
+	if(uart_wait_tgpd_head[port] != NULL || uart_wait_tgpd_tail[port] != NULL) return KAL_FALSE;
+	p_cur_gpd = uart_tgpd_head[port];	
+	while(1)
+	{
+		if(p_cur_gpd == NULL) break;
+		if(p_cur_gpd == uart_tgpd_tail[port]) break;
+		if(QBM_DES_GET_HWO(p_cur_gpd + 0x40000000)) return KAL_FALSE;
+		p_cur_gpd = QBM_DES_GET_NEXT(p_cur_gpd);
+	}
+
+	Buf_IsEmpty(&(UARTPort[port].Tx_Buffer), result);
+	return ((Buff_isEmpty == result) ? KAL_TRUE : KAL_FALSE);
+}
+
+/* This is to check that all TX data have been sent out 
+including UART TX ring buffer and UART FIFO. */
+kal_bool UART_CheckTxAllSentOut(UART_PORT port)
+{
+   if(port >= MAX_UART_PORT_NUM)
+      return KAL_FALSE;
+
+   if (UART_CheckTxBufferEmpty(port) == KAL_FALSE)
+      return KAL_FALSE;
+   if (UART_LSR_TEMT & DRV_UART_Reg(UART_LSR(UART_BaseAddr[port])))
+      return KAL_TRUE;
+   else
+      return KAL_FALSE;
+}
+
+
+// this function has a problem
+void UART_GetTxBufferSize(UART_PORT port, kal_uint32 *total_size, kal_uint32 *rest_size)
+{
+	if(port >= MAX_UART_PORT_NUM)
+		return;
+	*total_size = UARTPort[port].Tx_Buffer.Length;
+	if(uart_tgpd_head[port] != NULL || uart_wait_tgpd_head[port] != NULL)
+	{
+		*rest_size = uart_cal_tgpd_buf_length((void *) GDMA_HDCPRN((port + 2)), (void *) uart_tgpd_tail[port]);
+		*rest_size += uart_cal_tgpd_buf_length((void *) uart_wait_tgpd_head[port], (void *) uart_wait_tgpd_tail[port]);
+
+	} else
+		Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer), *rest_size);
+}
+
+
+/*
+* FUNCTION                                                            
+*	UART_VFIFO_TX_DMA_Enable
+*
+* DESCRIPTION                                                           
+*   	for
+*
+* CALLS  
+*	This function is called to enable or disable VFIFO DMA TX
+*     it is for logacc only , logacc will take UART TX , it might cause UART & VFIFO DMA sync problem
+*     so we must disable VFIFO DMA when logacc on
+*     enable and reset VFIFO DMA when logacc off
+*
+* PARAMETERS
+*	port: uart port
+*	enable: disable or enable VFIFO DMA TX
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void UART_VFIFO_TX_DMA_Enable(UART_PORT port,kal_bool enable) {}
+
+
+
+
+// Used under ASSERT condition
+// This has effect only when the port does NOT support VFIFO and used as Catcher port
+// After ASSERT, DHL will wait UART to send out all the data before ASSERT.
+// But now, all the interrupts are disabled, DHL may wait forever when the UART port is configured with DMA
+// To solve this problem, we provide this function for DHL to call 
+// in order to send out all the data in ring buffer before ASSERT
+// DHL will open UART port again after previous data is sent out
+void UART_AssertWaitPrevDataSentOut(UART_PORT port){
+	kal_uint16 LSR;
+	kal_uint16 TX_DATA;
+
+	if(port >= MAX_UART_PORT_NUM)
+		return;
+   
+	// Manually send out data by MCU polling
+	while(!UART_CheckTxBufferEmpty(port))
+	{
+		LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+		if(LSR & UART_LSR_THRE)
+		{
+			Buf_Pop(&(UARTPort[port].Tx_Buffer), TX_DATA);
+			DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]), (kal_uint16) TX_DATA);
+		}
+	}
+
+	// Wait UART controller to sent out the data in FIFO
+	while(!UART_CheckTxAllSentOut(port));
+}
+
+kal_uint32 UART_Get_Maxbaudrate(UART_PORT port)
+{
+	return 6000000;
+}
+
+kal_uint32 UART_PutBytesIor(UART_PORT port, void *putIor)
+{
+	void *p_ior;
+	if(port >= MAX_UART_PORT_NUM)
+		return 0;
+
+	p_ior = putIor;
+	while(1)
+	{
+		// if there is no tgpd, atach a bypass tgpd
+		uart_en_q_de_q_with_mutex(port, UART_TX, UART_EN_Q, ((tty_io_request_t *) putIor)->first_gpd, ((tty_io_request_t *) putIor)->last_gpd);
+		if(((tty_io_request_t *) p_ior)->next_request == NULL)
+		{
+			break;
+		} else
+		{
+			p_ior = ((tty_io_request_t *) p_ior)->next_request;
+		}
+	}
+
+	return 0;
+}
+
+kal_uint32 UART_PutBytesIor_LIGHT(UART_PORT port, void *putIor)
+{
+	void *p_ior;
+	if(port >= MAX_UART_PORT_NUM)
+		return 0;
+
+	p_ior = putIor;
+	while(1)
+	{
+		// if there is no tgpd, atach a bypass tgpd
+		uart_en_q_de_q_with_mutex(port, UART_TX, UART_EN_Q_LIGHT, ((tty_io_request_t *) putIor)->first_gpd, ((tty_io_request_t *) putIor)->last_gpd);
+		if(((tty_io_request_t *) p_ior)->next_request == NULL)
+		{
+			break;
+		} else
+		{
+			p_ior = ((tty_io_request_t *) p_ior)->next_request;
+		}
+	}
+
+	return 0;
+}
+
+kal_uint32 UART_GetBytesIor(UART_PORT port, void *ior)
+{
+	void *p_ior;
+
+	if(port >= MAX_UART_PORT_NUM)
+		return 0;
+
+	p_ior = ior;
+	while(1)
+	{
+		uart_en_q_de_q_with_mutex(port, UART_RX, UART_EN_Q, ((tty_io_request_t *) p_ior)->first_gpd, ((tty_io_request_t *) p_ior)->last_gpd);
+		if(((tty_io_request_t *) p_ior)->next_request == NULL)
+		{
+			break;
+		} else
+		{
+			p_ior = ((tty_io_request_t *) p_ior)->next_request;
+		}
+	}
+
+	return 0;
+}
+
+
+void UART_DriverInit(UART_PORT port)
+{
+	module_type ownerid;
+	static kal_bool b_uart_custom_init = KAL_FALSE;
+	kal_bool Is_OpenUart = KAL_TRUE;
+
+	ownerid = (MOD_UART1_HISR + port);
+		
+	// Customization 
+	if(b_uart_custom_init == KAL_FALSE)
+	{
+		uart_customize_init();
+		b_uart_custom_init = KAL_TRUE;
+	}
+
+	if(Is_OpenUart == KAL_TRUE)
+	{
+		UART_HWInit(port);
+
+		pUart_CMD_FUNC[port]= &UartDriver;
+
+		U_Open(port, ownerid);
+	}
+
+	// create mutex
+	if(mutex_status == KAL_FALSE && !INT_QueryExceptionStatus())
+	{
+		mutexid = kal_create_mutex("DRV_UART");
+		mutex_status = KAL_TRUE;
+	}
+}
+
+void UART_SetNeedTxDoneCb(UART_PORT port, kal_bool needTxDoneCb, module_type ownerid)
+{
+	UARTPort[port].need_tx_done_cb = needTxDoneCb;
+}
+
+kal_uint32 uart_cal_tgpd_buf_length(void *head, void *tail)
+{
+	void *gpd_cur, *bd_cur;
+	kal_uint32 sum = 0;
+
+	if(head == NULL || tail == NULL)
+		return 0;
+
+	gpd_cur = head;
+	while(1)
+	{
+		if(QBM_DES_GET_BPS(gpd_cur) == 0)
+		{
+			if(QBM_DES_GET_BDP(gpd_cur))
+			{
+				bd_cur = QBM_DES_GET_DATAPTR(gpd_cur);
+				while(1)
+				{
+					sum += QBM_DES_GET_DATALEN(bd_cur);
+
+					if(QBM_DES_GET_EOL(bd_cur)) {break;}
+					else {bd_cur = QBM_DES_GET_NEXT(bd_cur);}
+				}
+			} else
+			{
+				sum += QBM_DES_GET_DATALEN(gpd_cur);
+			}
+		}
+
+		if(gpd_cur == tail) {return sum;}
+		else {gpd_cur = QBM_DES_GET_NEXT(gpd_cur);}
+	}
+}
+
+void uart_en_q_de_q_with_mutex(UART_PORT port, kal_bool tx_or_rx, kal_uint8 en_q_or_de_q, void *p_ior_head, void *p_ior_tail)
+{
+	void *p_gpd_head = NULL;
+	void *p_gpd_tail = NULL;
+	void *p_gpd_cur = NULL;
+	kal_uint32 queue_len = 0;
+	tty_io_request_t *ior = NULL;
+if(!kal_if_hisr()){
+	// lock mutex
+	kal_take_mutex(mutexid);
+}
+	DCL_HANDLE handle = DclSerialPort_Open(port, 0);
+
+	if(tx_or_rx == (kal_bool) UART_TX)
+	{
+		if(en_q_or_de_q == UART_EN_Q)
+		{
+
+			uart_cal_chksum_and_flush_gpd_list(p_ior_head, p_ior_tail);
+
+			if(uart_wait_tgpd_head[port] == NULL && uart_wait_tgpd_tail[port] == NULL)
+			{
+				uart_wait_tgpd_head[port] = p_ior_head;
+				uart_wait_tgpd_tail[port] = p_ior_tail;
+			} else
+			{
+				qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_wait_tgpd_head[port], (void **) &uart_wait_tgpd_tail[port]);
+			}
+		} else if(en_q_or_de_q == UART_EN_Q_LIGHT)
+		{
+			if(uart_wait_tgpd_head[port] == NULL && uart_wait_tgpd_tail[port] == NULL)
+			{
+				uart_wait_tgpd_head[port] = p_ior_head;
+				uart_wait_tgpd_tail[port] = p_ior_tail;
+			} else
+			{
+				qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_wait_tgpd_head[port], (void **) &uart_wait_tgpd_tail[port]);
+			}
+		} else
+		{
+			if(uart_tgpd_head[port] != NULL)
+			{
+				if(en_q_or_de_q == UART_DE_Q)
+				{
+					queue_len = qbmt_de_q((void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+				} else if(en_q_or_de_q == UART_DE_Q_ALL)
+				{
+#if defined(META_MODE_SW_ESCAPING)
+                    if(kal_query_boot_mode() != FACTORY_BOOT)
+#endif
+                    {
+					HDMA_BUF0_STOP((2 + port));
+					}
+					uart_clear_hwo_of_gpd_list(uart_tgpd_head[port], uart_tgpd_tail[port]);
+					queue_len = qbmt_de_q((void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);				
+					QBM_FREE_ONE(uart_tgpd_head[port]);
+					
+					if(uart_wait_tgpd_head[port] != NULL)
+					{
+						if(queue_len > 0)
+						{
+							qbmt_common_en_q_rx(uart_wait_tgpd_head[port], uart_wait_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+						} else
+						{
+							p_gpd_head = uart_wait_tgpd_head[port];
+							p_gpd_tail = uart_wait_tgpd_tail[port];
+							queue_len = 1;
+						}
+						uart_clear_hwo_of_gpd_list(p_gpd_head, p_gpd_tail);
+					}				
+
+					uart_tgpd_head[port] = NULL;
+					uart_tgpd_tail[port] = NULL;
+					uart_wait_tgpd_head[port] = NULL;
+					uart_wait_tgpd_tail[port] = NULL;
+				} else ASSERT(0);
+
+				if(queue_len > 0)
+				{
+					if(UARTPort[port].need_tx_done_cb)
+					{
+						ior = (tty_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(p_gpd_head);
+						ior->first_gpd = p_gpd_head;
+						ior->last_gpd = p_gpd_tail;
+						ior->next_request = NULL;
+						DclSerialPort_DrvTxDone(handle, kal_get_active_module_id(), ior);
+					} else
+					{
+						qbmt_dest_q((void *) p_gpd_head, (void *) p_gpd_tail);
+					}
+				}
+			}
+		}
+	} else
+	{
+		if(en_q_or_de_q == (kal_bool) UART_EN_Q)
+		{
+			if(uart_rgpd_head[port] == NULL && uart_rgpd_tail[port] == NULL)
+			{
+				uart_cal_chksum_and_flush_gpd_list(p_ior_head, p_ior_tail);
+
+				QBM_DES_CLR_HWO(p_ior_tail);
+				QBM_CACHE_FLUSH((void *) p_ior_tail, QBM_SIZE_GPD_BD_TST);
+				HDMA_BUF0_PROG_ADDR_CONFIG((3 + port), p_ior_head);
+				uart_rgpd_head[port] = p_ior_head;
+				uart_rgpd_tail[port] = p_ior_tail;
+				HDMA_BUF0_START((3 + port));
+            	}else{
+				qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_rgpd_head[port], (void **) &uart_rgpd_tail[port]);
+				uart_cal_chksum_and_flush_gpd_list(uart_rgpd_head[port], uart_rgpd_tail[port]);
+				QBM_DES_CLR_HWO(uart_rgpd_tail[port]);
+				QBM_CACHE_FLUSH((void *) uart_rgpd_tail[port], QBM_SIZE_GPD_BD_TST);
+				
+				HDMA_BUF0_RESUME((3 + port));
+			}
+		} else
+		{
+			if(uart_rgpd_head[port] == NULL)
+			{
+				if(!kal_if_hisr()){
+				kal_give_mutex(mutexid);
+				}
+				return;
+			} else
+			{
+				if(en_q_or_de_q == UART_DE_Q)
+				{
+					queue_len = qbmt_de_q((void **) &uart_rgpd_head[port], (void **) &uart_rgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+				} else if(en_q_or_de_q == UART_DE_Q_ALL)
+				{
+					// stop q
+					HDMA_BUF0_STOP((port + 3));
+					// de-Q all GPDs
+					p_gpd_head = uart_rgpd_head[port];
+					p_gpd_tail = uart_rgpd_tail[port];
+					uart_rgpd_head[port] = NULL;
+					uart_rgpd_tail[port] = NULL;
+					queue_len = 1; // not real queue length
+				}
+
+				if(p_gpd_head != NULL && p_gpd_tail != NULL && queue_len > 0)
+				{
+#if defined(META_MODE_SW_ESCAPING) && !defined(UART_SIM_QMU)
+                    if(kal_query_boot_mode() == FACTORY_BOOT){
+				   		UART_META_ExBytes(port, p_gpd_head, p_gpd_tail);
+					}
+#endif
+					ior = (tty_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(p_gpd_head);
+					ior->first_gpd = p_gpd_head;
+					ior->last_gpd = p_gpd_tail;
+					ior->next_request = NULL;
+ 					DclSerialPort_DrvRx(handle, kal_get_active_module_id(), ior); // need to modify
+				}
+			}
+		}
+	}
+
+	if(uart_wait_tgpd_head[port] != NULL && uart_wait_tgpd_tail[port] != NULL && !(DRV_Reg32(UART_LCR(UART_BaseAddr[port])) & UART_LCR_BREAK))
+	{
+		if(uart_tgpd_head[port] == NULL && uart_tgpd_tail[port] == NULL)
+		{
+			uart_tgpd_head[port] = uart_wait_tgpd_head[port];
+			uart_tgpd_tail[port] = uart_wait_tgpd_tail[port];
+
+			// connect a BPS GPD to the tail
+			qbmt_alloc_q(QBM_TYPE_TGPD_BPS, 1, (void **) &p_gpd_cur, (void **) &p_gpd_cur);
+			ASSERT(p_gpd_cur!= NULL);
+
+			qbmt_common_en_q_rx(p_gpd_cur, p_gpd_cur, (void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port]);
+#if defined(META_MODE_SW_ESCAPING)
+			if(kal_query_boot_mode() == FACTORY_BOOT){
+				UART_META_PutBytes(port,uart_tgpd_head[port], uart_tgpd_tail[port]);
+			}else
+#endif
+			{
+			HDMA_BUF0_PROG_ADDR_CONFIG((2 + port), uart_tgpd_head[port]);
+			HDMA_BUF0_START((2 + port));
+			}
+			uart_wait_tgpd_head[port] = NULL;
+			uart_wait_tgpd_tail[port] = NULL;
+		} else if(QBM_DES_GET_BPS(uart_tgpd_head[port]) && QBM_DES_GET_BPS(uart_tgpd_tail[port]))
+		{
+			QBM_FREE_ONE(uart_tgpd_head[port]);
+
+			uart_tgpd_head[port] = uart_wait_tgpd_head[port];
+			uart_tgpd_tail[port] = uart_wait_tgpd_tail[port];
+
+			// connect a BPS GPD to the tail
+			qbmt_alloc_q(QBM_TYPE_TGPD_BPS, 1, (void **) &p_gpd_cur, (void **) &p_gpd_cur);
+			ASSERT(p_gpd_cur!= NULL);
+			qbmt_common_en_q_rx(p_gpd_cur, p_gpd_cur, (void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port]);
+#if defined(META_MODE_SW_ESCAPING)
+            if(kal_query_boot_mode() == FACTORY_BOOT){
+				UART_META_PutBytes(port,uart_wait_tgpd_head[port], uart_wait_tgpd_tail[port]);
+			}else
+#endif
+			{
+			HDMA_BUF0_PROG_ADDR_CONFIG((2 + port), uart_wait_tgpd_head[port]);
+			HDMA_BUF0_START((2 + port));
+			}
+			uart_wait_tgpd_head[port] = NULL;
+			uart_wait_tgpd_tail[port] = NULL;
+		}
+	}
+	if(!kal_if_hisr()){
+	// unlock mutex
+	kal_give_mutex(mutexid);
+	}
+	return;
+}
+
+
+void uart_qbm_virt_to_phy(void** pp_gpd_head, void** pp_gpd_tail)
+{
+	void *gpd_ptr = NULL, *gpd_ptr_tmp = NULL;
+	void *bd_ptr = NULL, *bd_ptr_tmp = NULL;;
+	void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+
+	*pp_gpd_head = (void*)virt_to_phys(*pp_gpd_head);
+	gpd_ptr = *pp_gpd_head;
+	while(1)
+	{
+		if(QBM_DES_GET_BDP(gpd_ptr))
+		{
+			bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			bd_ptr = (void*)virt_to_phys(bd_ptr);
+			QBM_DES_SET_DATAPTR(gpd_ptr,bd_ptr);
+			qbm_cal_set_checksum_by_len((const kal_uint8 *)gpd_ptr, 12);
+			while(1)
+			{
+				bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+				bd_data_ptr = (void*)virt_to_phys(bd_data_ptr);
+				QBM_DES_SET_DATAPTR(bd_ptr,bd_data_ptr);
+				if(QBM_DES_GET_EOL(bd_ptr))
+				{
+					break;
+				} else
+				{
+					bd_ptr_tmp = (void*)QBM_DES_GET_NEXT(bd_ptr);
+					bd_ptr_tmp = (void*)virt_to_phys(bd_ptr_tmp);
+					QBM_DES_SET_NEXT(bd_ptr,bd_ptr_tmp);
+					qbm_cal_set_checksum_by_len((const kal_uint8 *)bd_ptr, 12);
+					bd_ptr = QBM_DES_GET_NEXT(bd_ptr);
+				}
+			}
+		} else
+		{
+			pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			pgd_data_ptr = (void*)virt_to_phys(pgd_data_ptr);
+			QBM_DES_SET_DATAPTR(gpd_ptr,pgd_data_ptr);
+		}
+
+		if(gpd_ptr == *pp_gpd_tail)
+		{
+			break;
+		} else
+		{
+			gpd_ptr_tmp = (void*)QBM_DES_GET_NEXT(gpd_ptr);
+			gpd_ptr_tmp = (void*)virt_to_phys(gpd_ptr_tmp);
+			QBM_DES_SET_NEXT(gpd_ptr,gpd_ptr_tmp);
+			qbm_cal_set_checksum_by_len((const kal_uint8 *) gpd_ptr, 12);
+			gpd_ptr =  QBM_DES_GET_NEXT(gpd_ptr);
+		}
+
+	}
+
+}
+
+void uart_qbm_phy_to_virt(void**pp_gpd_head, void**pp_gpd_tail)
+{
+	void *gpd_ptr = NULL, *gpd_ptr_tmp = NULL;
+	void *bd_ptr = NULL, *bd_ptr_tmp = NULL;;
+	void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+
+	
+	*pp_gpd_head = (void*)phys_to_virt(*pp_gpd_head);
+	QBM_CACHE_INVALID(*pp_gpd_head, QBM_SIZE_TGPD);
+	gpd_ptr = *pp_gpd_head;
+    	*pp_gpd_tail = (void*)phys_to_virt(*pp_gpd_tail);
+	QBM_CACHE_INVALID(*pp_gpd_tail, QBM_SIZE_TGPD);
+	while(1)
+	{
+		if(QBM_DES_GET_BDP(gpd_ptr))
+		{
+			bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			bd_ptr = (void*)phys_to_virt(bd_ptr);
+			QBM_CACHE_INVALID(bd_ptr, QBM_SIZE_TBD);
+			QBM_DES_SET_DATAPTR(gpd_ptr,bd_ptr);
+			
+			while(1)
+			{
+				bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+				bd_data_ptr = (void*)phys_to_virt(bd_data_ptr);
+				QBM_CACHE_INVALID(bd_data_ptr, QBM_SIZE_CACHE_ALIGN(QBM_DES_GET_DATALEN(bd_data_ptr)));
+				QBM_DES_SET_DATAPTR(bd_ptr,bd_data_ptr);
+
+				if(QBM_DES_GET_EOL(bd_ptr))
+				{
+					break;
+				} else
+				{
+					bd_ptr_tmp = (void*)QBM_DES_GET_NEXT(bd_ptr);
+					bd_ptr_tmp = (void*)phys_to_virt(bd_ptr_tmp);
+					QBM_CACHE_INVALID(bd_ptr_tmp, QBM_SIZE_TBD);
+					QBM_DES_SET_NEXT(bd_ptr,bd_ptr_tmp);
+					bd_ptr = QBM_DES_GET_NEXT(bd_ptr);
+				}
+			}
+		} else
+		{
+			pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			pgd_data_ptr = (void*)phys_to_virt(pgd_data_ptr);
+			QBM_CACHE_INVALID(pgd_data_ptr, QBM_SIZE_CACHE_ALIGN(QBM_DES_GET_DATALEN(pgd_data_ptr)));
+			QBM_DES_SET_DATAPTR(gpd_ptr,pgd_data_ptr);
+		}
+
+		if(gpd_ptr == *pp_gpd_tail)
+		{
+			break;
+		} else
+		{
+			gpd_ptr_tmp = (void*)QBM_DES_GET_NEXT(gpd_ptr);
+			gpd_ptr_tmp = (void*)phys_to_virt(gpd_ptr_tmp);
+			QBM_CACHE_INVALID(gpd_ptr_tmp, QBM_SIZE_TGPD);
+			QBM_DES_SET_NEXT(gpd_ptr,gpd_ptr_tmp);			
+			gpd_ptr =  QBM_DES_GET_NEXT(gpd_ptr);
+		}
+
+	}
+
+}
+
+void UART_META_PutBytes(UART_PORT port, void * gpd_head, void * gpd_tail){
+	hdma_tbd_t *bd_ptr = NULL, *p_bd_cur =NULL;
+	hdma_tgpd_t *gpd_ptr = NULL;
+	kal_uint8 gpd_ext_len=0, bd_ext_len=0;
+	kal_uint32	gpd_data_len=0, bd_data_len=0;
+	kal_uint8 *gpd_ext_ptr=NULL, *gpd_data_ptr=NULL, *bd_ext_ptr=NULL, *bd_data_ptr=NULL;
+	
+	gpd_ptr = (hdma_tgpd_t*)gpd_head;
+	while(1){
+		if(QBM_DES_GET_HWO(gpd_ptr)==0){
+			break;
+		}
+		if(QBM_DES_GET_BPS(gpd_ptr)){
+		    QBM_DES_CLR_HWO(gpd_ptr);
+		    QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+			goto next;
+		}
+		if (QBM_DES_GET_EXTLEN(gpd_ptr)) {
+			gpd_ext_len = QBM_DES_GET_EXTLEN(gpd_ptr);	
+			gpd_ext_ptr = QBM_DES_GET_EXT(gpd_ptr);
+			PutUARTDatas(port, UART_ESCAPE_CHAR, gpd_ext_ptr,gpd_ext_len);
+			//U_SendData(port, gpd_ext_ptr, gpd_ext_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+		}
+		if (QBM_DES_GET_BDP(gpd_ptr)) {
+			bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			p_bd_cur = bd_ptr;
+			while (1) {
+				if (QBM_DES_GET_EXTLEN(p_bd_cur)) {
+					bd_ext_len = QBM_DES_GET_EXTLEN(p_bd_cur);
+					bd_ext_ptr = QBM_DES_GET_EXT(p_bd_cur);
+					PutUARTDatas(port, UART_ESCAPE_CHAR, bd_ext_ptr,bd_ext_len);
+					//U_SendData(port, bd_ext_ptr, bd_ext_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+
+				}
+				if (QBM_DES_GET_DATALEN(p_bd_cur)) {
+					bd_data_len = QBM_DES_GET_DATALEN(p_bd_cur);
+					bd_data_ptr = QBM_DES_GET_DATAPTR(p_bd_cur);
+					PutUARTDatas(port, UART_ESCAPE_CHAR, bd_data_ptr,bd_data_len);
+					//U_SendData(port, bd_data_ptr, bd_data_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+				}
+				if (QBM_DES_GET_EOL(p_bd_cur)) {
+					break;
+				}
+				p_bd_cur = (void *)QBM_DES_GET_NEXT(p_bd_cur);
+			}
+		} else{
+		
+			gpd_data_len = QBM_DES_GET_DATALEN(gpd_ptr);
+			gpd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			PutUARTDatas(port, UART_ESCAPE_CHAR, gpd_data_ptr,gpd_data_len);
+			//U_SendData(port, gpd_data_ptr, gpd_data_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+		}
+		
+		QBM_DES_CLR_HWO(gpd_ptr);
+		QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+		if(gpd_ptr == gpd_tail)
+		{	
+			break;
+		} else
+		{
+next:
+			gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+		}
+	}
+
+    /* Cooperate with Non-Blocking CACHE API */
+	MM_Sync();
+}
+
+
+void uart_cal_chksum_and_flush_gpd_list(void * gpd_head, void * gpd_tail)
+{
+	hdma_tbd_t *gpd_ptr = NULL, *bd_ptr = NULL;
+	void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+	
+	gpd_ptr = (hdma_tbd_t*)gpd_head;
+	while(1)
+	{
+		QBM_DES_SET_HWO(gpd_ptr);
+#if !defined(__DRVTEST_SW_DOMAIN__)
+		qbm_cal_set_checksum_by_len((const kal_uint8 *) gpd_ptr, 12);
+#endif
+		QBM_CACHE_FLUSH((void *) gpd_ptr, QBM_SIZE_TGPD);
+
+		if(QBM_DES_GET_BDP(gpd_ptr))
+		{
+			bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			while(1)
+			{
+#if !defined(__DRVTEST_SW_DOMAIN__)
+				qbm_cal_set_checksum_by_len((const kal_uint8 *) bd_ptr, 12);
+#endif
+				QBM_CACHE_FLUSH((void *) bd_ptr, QBM_SIZE_TBD);
+				bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+				QBM_CACHE_FLUSH((void *) bd_data_ptr, QBM_DES_GET_DATALEN(bd_ptr));
+
+				if(QBM_DES_GET_EOL(bd_ptr))
+				{
+					break;
+				} else
+				{
+					bd_ptr = (void *) QBM_DES_GET_NEXT(bd_ptr);
+				}
+			}
+		} else
+		{
+			pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+			QBM_CACHE_FLUSH((void *) pgd_data_ptr, QBM_DES_GET_DATALEN(gpd_ptr));		
+		}
+
+		if(gpd_ptr == gpd_tail)
+		{
+			break;
+		} else
+		{
+			gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+		}
+
+	}
+
+    /* Cooperate with Non-Blocking CACHE API */
+    MM_Sync();
+}
+
+void uart_clear_hwo_of_gpd_list(void *gpd_head, void *gpd_tail)
+{
+	hdma_tbd_t *gpd_ptr = NULL;//, *bd_ptr = NULL;
+
+	gpd_ptr = gpd_head;
+	while(1)
+	{
+		QBM_DES_CLR_HWO(gpd_ptr);
+		QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_GPD_BD_TST);
+
+		if(gpd_ptr == gpd_tail)
+		{
+			break;
+		} else
+		{
+			gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+		}
+	}
+
+    /* Cooperate with Non-Blocking CACHE API */
+    MM_Sync();
+}
+
+typedef struct _uart_bps_gpd_pool {
+    void *gpd_head;
+    void *gpd_tail;
+    kal_uint32 free_num;
+    kal_uint32 alloc_ok_cnt;
+    kal_uint32 alloc_fail_cnt;
+    kal_uint32 free_ok_cnt;
+    void *buffer_start;
+    void *buffer_end;
+    kal_uint32 total_num;
+} uart_bps_gpd_pool;
+
+static void *uart_discard_tgpd_head = NULL;
+static void *uart_discard_tgpd_tail = NULL;
+static void *uart_discard_rgpd_head = NULL;
+static void *uart_discard_rgpd_tail = NULL;
+static kal_uint32 uart_excpt_tx_bytes[MAX_UART_PORT_NUM];
+static kal_uint32 uart_excpt_rx_bytes[MAX_UART_PORT_NUM];
+static uart_bps_gpd_pool uart_bps_gpd_pool_info;
+
+extern void uart_cal_chksum_and_flush_gpd_list(void *gpd_head, void *gpd_tail);
+
+
+kal_bool uart_except_init_qbm()
+{
+    uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+    bm_queue_config conf;
+    kal_uint32 ret;
+
+    qbm_init_q_config(&conf);
+	
+	conf.buff_num = UART_ECPT_QBM_BPS_NUM;
+	conf.p_mem_pool_str = uart_ecpt_bps_buf;
+	conf.p_mem_pool_end = conf.p_mem_pool_str  + UART_ECPT_QBM_BPS_BUF_SZ;
+	ret = qbm_init_queue_non_free(QBM_TYPE_TGPD_BPS, &conf, 
+	                              &gpd_pool->gpd_head,
+	                              &gpd_pool->gpd_tail);
+    if(QBM_ERROR_OK != ret)
+        return KAL_FALSE;
+
+    gpd_pool->buffer_start = conf.p_mem_pool_str;
+    gpd_pool->buffer_end   = conf.p_mem_pool_end;
+    gpd_pool->total_num    = conf.buff_num;
+    gpd_pool->free_num     = conf.buff_num;
+    
+    return KAL_TRUE;
+}
+
+kal_bool uart_except_check_bps_gpd(void *p_gpd)
+{
+	kal_uint8* uart_bps_buf;
+
+	uart_bps_buf = uart_ecpt_bps_buf;
+	
+    if (((kal_uint8 *)p_gpd >= uart_bps_buf) && ((kal_uint8 *)p_gpd < uart_bps_buf + UART_ECPT_QBM_BPS_BUF_SZ)){
+        return KAL_TRUE;
+    }
+    return KAL_FALSE;
+}
+
+void uart_except_free_bps_gpd(void *p_gpd)
+{
+    uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+    
+    ASSERT(uart_except_check_bps_gpd(p_gpd));
+
+    if (gpd_pool->gpd_head == NULL) {
+        gpd_pool->gpd_head = gpd_pool->gpd_tail = p_gpd;
+    } else {
+        QBM_DES_SET_NEXT(gpd_pool->gpd_tail, p_gpd);
+        gpd_pool->gpd_tail = p_gpd;
+    }
+
+    gpd_pool->free_num ++;
+    gpd_pool->free_ok_cnt ++;
+}
+
+void *uart_except_alloc_bps_gpd(kal_bool tx_or_rx)
+{
+    void *p_ret_gpd;
+    uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+    
+    if (gpd_pool->gpd_head == NULL) {
+        gpd_pool->alloc_fail_cnt ++;
+        return NULL;
+    }
+
+    p_ret_gpd = gpd_pool->gpd_head;
+    if (gpd_pool->gpd_head == gpd_pool->gpd_tail) {
+        gpd_pool->gpd_head = gpd_pool->gpd_tail = NULL;
+    } else {
+        gpd_pool->gpd_head = QBM_DES_GET_NEXT(gpd_pool->gpd_head);
+    }
+
+    gpd_pool->free_num --;
+    gpd_pool->alloc_ok_cnt ++;
+
+    QBM_DES_SET_NEXT(p_ret_gpd, NULL);
+
+    //QBM_DES_SET_BPS(p_ret_gpd);
+    
+    return p_ret_gpd;
+}
+
+kal_uint32 uart_except_free_bps_gpd_in_list(void **pp_head, void **pp_tail)
+{
+    void *p_gpd_cur, *p_gpd_pre, *p_gpd_nex; 
+    int free_num = 0;
+
+    p_gpd_cur = *pp_head;
+    p_gpd_pre = NULL;
+
+    if (*pp_head == NULL || *pp_tail == NULL)
+        return 0;
+        
+    while (1) {
+        p_gpd_nex = QBM_DES_GET_NEXT(p_gpd_cur);
+        if (uart_except_check_bps_gpd(p_gpd_cur)) {            
+            /* free this gpd from list */
+            if (p_gpd_pre == NULL)
+                *pp_head = p_gpd_nex;
+            else
+                QBM_DES_SET_NEXT(p_gpd_pre, p_gpd_nex);
+
+            uart_except_free_bps_gpd(p_gpd_cur);
+            free_num ++;
+        } else {
+            p_gpd_pre = p_gpd_cur;
+        }
+
+        if(p_gpd_cur == *pp_tail)
+            break;
+            
+        p_gpd_cur = p_gpd_nex;
+    }
+
+    return free_num;
+}
+
+void uart_except_en_q_rx(
+		void *p_new_head, 
+		void *p_new_tail, 
+		void **pp_orig_head, 
+		void **pp_orig_tail
+		)
+{
+    void *p_orig_tail = NULL;
+    
+    ASSERT(pp_orig_head!=NULL);
+    ASSERT(pp_orig_tail!=NULL);
+    if (*pp_orig_head != NULL) {
+        p_orig_tail = *pp_orig_tail;
+
+        /* set new tail's HWO=0 */
+        QBM_DES_CLR_HWO(p_new_tail);
+        QBM_CACHE_FLUSH(p_new_tail, QBM_SIZE_TGPD);
+
+        /* link new list to tail of orig list */
+        QBM_DES_SET_NEXT(p_orig_tail, p_new_head);
+
+        /* re-calc the orig tail's checksum */
+#if !defined(__DRVTEST_SW_DOMAIN__)
+        qbm_cal_set_checksum_wth_hwo(p_orig_tail);
+#endif
+        
+        /* set the orig tail's HWO=1 */
+        QBM_DES_SET_HWO(p_orig_tail);
+        QBM_CACHE_FLUSH(p_orig_tail, QBM_SIZE_TGPD);  
+
+        /* update the orig tail */
+        *pp_orig_tail = p_new_tail;
+    } else {
+        *pp_orig_head = p_new_head;
+        *pp_orig_tail = p_new_tail;
+    }
+}
+/* the last gpd will not be de-queued */
+kal_uint32 uart_except_de_q(
+		void **pp_src_head, 
+		void **pp_src_tail, 
+		void **pp_new_head, 
+		void **pp_new_tail
+		)
+{
+    kal_uint32 deqno = 0;
+    void *p_this_gpd = NULL;
+    *pp_new_head = NULL;
+    *pp_new_tail = NULL;
+
+    if (pp_src_head != NULL && *pp_src_head != NULL && *pp_src_head != *pp_src_tail) {
+        p_this_gpd = *pp_src_head;
+        QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+        if (!QBM_DES_GET_HWO(p_this_gpd)){
+            *pp_new_head = p_this_gpd;
+
+            while(!QBM_DES_GET_HWO(p_this_gpd) && p_this_gpd != *pp_src_tail) {
+                *pp_new_tail = p_this_gpd;
+                deqno ++;
+                
+                p_this_gpd = QBM_DES_GET_NEXT(p_this_gpd);
+                QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+            }
+
+            *pp_src_head = p_this_gpd;
+        } 
+    }
+
+    return deqno;
+}
+
+kal_uint32 uart_except_de_q_with_timeout(
+		UART_PORT port, 
+		void **pp_src_head, 
+		void **pp_src_tail, 
+		void **pp_new_head, 
+		void **pp_new_tail
+		)
+{
+    kal_uint32 deqno = 0;
+    void *p_this_gpd = NULL;
+    *pp_new_head = NULL;
+    *pp_new_tail = NULL;
+
+    if (pp_src_head != NULL && *pp_src_head != NULL && *pp_src_head != *pp_src_tail) {
+        p_this_gpd = *pp_src_head;
+        QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+        if (!QBM_DES_GET_HWO(p_this_gpd)){
+            *pp_new_head = p_this_gpd;
+
+            while(!QBM_DES_GET_HWO(p_this_gpd) && p_this_gpd != *pp_src_tail) {
+                *pp_new_tail = p_this_gpd;
+                deqno ++;
+                
+                p_this_gpd = QBM_DES_GET_NEXT(p_this_gpd);
+                QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+            }
+
+            *pp_src_head = p_this_gpd;
+		uart_ecpt_timer_reset(port);
+        }else{
+		uart_ecpt_timer_start(port);
+	}
+    }
+
+    return deqno;
+}
+
+DCL_STATUS uart_except_check_dma_status(kal_uint32 hdma_channel)
+{
+    kal_uint32 int_sts;
+    DCL_STATUS ret_sts = STATUS_OK;
+    
+    int_sts = DRV_Reg32(GDMA_GISAR_UART);
+    
+	if(IS_HDMA_LENERR_INTR(int_sts, hdma_channel)) {
+	    DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 16));
+	    ret_sts = STATUS_FAIL;
+	}
+
+	if(IS_HDMA_BD_CSERR_INTR(int_sts, hdma_channel)) {  
+	    DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 24));
+	    ret_sts = STATUS_ERROR_CRCERROR;
+	}
+	
+	if(IS_HDMA_GPD_CSERR_INTR(int_sts, hdma_channel)) {   
+	    DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 28));
+	    ret_sts = STATUS_ERROR_CRCERROR;
+	}
+
+	return ret_sts;
+}
+
+DCL_STATUS
+uart_en_q_de_q_for_ecpt(
+    UART_PORT port, 
+    kal_bool tx_or_rx, 
+    kal_uint8 en_q_or_de_q, 
+    void **pp_gpd_head, 
+    void **pp_gpd_tail, 
+    kal_uint32 *p_num
+)
+{
+    void *p_gpd_head, *p_gpd_tail;  /* work queue */
+    void *p_bps_gpd;
+    kal_uint32 deq_num;
+    DCL_STATUS ret = STATUS_OK;
+    kal_uint32 hdma_ch;
+    kal_uint32 xfer_bytes;
+
+    ASSERT(pp_gpd_head != NULL);
+    ASSERT(pp_gpd_tail != NULL);
+    
+    /* get global variable to local variable */
+    if (tx_or_rx == (kal_bool)UART_TX) {
+        p_gpd_head = uart_tgpd_head[port];
+        p_gpd_tail = uart_tgpd_tail[port];
+    } else {
+        p_gpd_head = uart_rgpd_head[port];
+        p_gpd_tail = uart_rgpd_tail[port];
+    }
+
+    hdma_ch = (tx_or_rx == (kal_bool)UART_TX)?port+2:port+3;
+
+    if (en_q_or_de_q == UART_EN_Q) {
+        if (*pp_gpd_head == NULL || *pp_gpd_tail == NULL) {
+            goto  end;
+        }
+
+        /* alloc a bypass gpd */
+        if (tx_or_rx == (kal_bool)UART_TX) {
+            p_bps_gpd = uart_except_alloc_bps_gpd(tx_or_rx);
+            if (p_bps_gpd == NULL) {
+                ret = STATUS_FAIL;
+                goto end;
+            }
+
+            /* append the bypass gpd to the gpd list */
+            QBM_DES_SET_NEXT(*pp_gpd_tail, p_bps_gpd);
+            *pp_gpd_tail = p_bps_gpd;
+        } else {
+            QBM_DES_CLR_HWO(*pp_gpd_tail);
+        }
+
+        /* re-calc checksum and flush cache */
+        uart_cal_chksum_and_flush_gpd_list(*pp_gpd_head, *pp_gpd_tail);
+
+        /* now, start en-q operation */
+        if (p_gpd_head == NULL) {
+            /* clear tail's HWO bit manually */
+            QBM_DES_CLR_HWO(*pp_gpd_tail);
+            QBM_CACHE_FLUSH(*pp_gpd_tail, QBM_SIZE_TGPD_BPS);
+
+            p_gpd_head = *pp_gpd_head;
+            p_gpd_tail = *pp_gpd_tail;
+#if defined(META_MODE_SW_ESCAPING)
+          if((kal_query_boot_mode() == FACTORY_BOOT) && (tx_or_rx ==(kal_bool)UART_TX)){
+		   UART_META_PutBytes(port, p_gpd_head, p_gpd_tail);
+	     }else
+#endif
+	     {
+            /* newly configure and start DMA */
+            HDMA_BUF0_PROG_ADDR_CONFIG(hdma_ch, p_gpd_head);
+            HDMA_BUF0_START(hdma_ch);
+	     }
+        } else {
+            /* Because META mode Tx should be done before new en_q,  p_gpd_head must be NULL. so Tx would not be affected by new Start putbytes. 
+            	  The following step just for backup, but should not be running. If it run, will may send more data or lose data*/
+#if defined(META_MODE_SW_ESCAPING)
+        if((kal_query_boot_mode() == FACTORY_BOOT) && (tx_or_rx ==(kal_bool)UART_TX)){
+		   UART_META_PutBytes(port, p_gpd_head, p_gpd_tail);
+	     }else
+#endif
+	     {
+            /* tail's HWO bit will be cleared automatically */
+            /* en-q and resume DMA */
+            uart_except_en_q_rx(*pp_gpd_head, *pp_gpd_tail, (void **)&p_gpd_head, (void **)&p_gpd_tail);
+            HDMA_BUF0_RESUME(hdma_ch);
+	     }           
+        }
+    } else if (en_q_or_de_q == UART_DE_Q) {
+        if (p_gpd_head == NULL) {
+            *pp_gpd_head = NULL;
+            *pp_gpd_tail = NULL;
+            if (NULL != p_num)
+                *p_num = 0;
+            goto end;
+        }
+        
+        if(tx_or_rx == (kal_bool)UART_TX){
+        	deq_num = uart_except_de_q_with_timeout(port,(void **)&p_gpd_head, (void **) &p_gpd_tail, (void **)pp_gpd_head, (void **)pp_gpd_tail);
+	}else{
+		deq_num = uart_except_de_q((void **)&p_gpd_head, (void **) &p_gpd_tail, (void **)pp_gpd_head, (void **)pp_gpd_tail);
+	}
+		
+        if (deq_num == 0) {
+            *pp_gpd_head = NULL;
+            *pp_gpd_tail = NULL;
+            if (NULL != p_num)
+                *p_num = deq_num;
+            goto end;
+        }
+
+        /* check if all is done */
+        if (p_gpd_head == p_gpd_tail && QBM_DES_GET_HWO(p_gpd_head)==0) {
+            if (uart_except_check_bps_gpd(p_gpd_head)) {
+                uart_except_free_bps_gpd(p_gpd_head);
+                QBM_DES_SET_NEXT(*pp_gpd_tail, NULL);
+            } else {
+                QBM_DES_SET_NEXT(*pp_gpd_tail, p_gpd_head);
+                *pp_gpd_tail = p_gpd_head;
+            }
+                
+            p_gpd_head = p_gpd_tail = NULL;
+        }
+
+        /* check and free bypass GPD allocated by us in list */
+        deq_num -= uart_except_free_bps_gpd_in_list(pp_gpd_head, pp_gpd_tail);
+
+        if (NULL != p_num && deq_num > 0) {
+            *p_num = deq_num;
+#if defined(META_MODE_SW_ESCAPING)
+		if(kal_query_boot_mode() == FACTORY_BOOT && tx_or_rx == (kal_bool)UART_RX){
+			UART_META_ExBytes(port, *pp_gpd_head, *pp_gpd_tail);
+		}
+#endif
+            xfer_bytes = uart_cal_tgpd_buf_length(*pp_gpd_head, *pp_gpd_tail);
+            if (tx_or_rx == (kal_bool)UART_TX)
+                uart_excpt_tx_bytes[port] += xfer_bytes;
+            else
+                uart_excpt_rx_bytes[port] += xfer_bytes;
+        }
+		
+    } else {  
+        ASSERT(en_q_or_de_q != UART_EN_Q && en_q_or_de_q != UART_DE_Q);
+    }
+
+    /* updated global variable from local variable */
+    if (tx_or_rx == (kal_bool)UART_TX) {
+        uart_tgpd_head[port] = p_gpd_head;
+        uart_tgpd_tail[port] = p_gpd_tail;
+    } else {
+        uart_rgpd_head[port] = p_gpd_head;
+        uart_rgpd_tail[port] = p_gpd_tail;
+    }
+                
+end:
+    return ret;
+}
+
+DCL_STATUS uart_ecpt_tx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+	return uart_en_q_de_q_for_ecpt(port, UART_TX, UART_EN_Q, &p_first_gpd, &p_last_gpd, NULL);
+}
+
+DCL_STATUS uart_ecpt_tx_done_info(UART_PORT port, void **pp_first_gpd, void **pp_last_gpd, kal_uint32 *gpd_num)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+	return uart_en_q_de_q_for_ecpt(port, UART_TX, UART_DE_Q, pp_first_gpd, pp_last_gpd, gpd_num);
+}
+
+DCL_STATUS uart_ecpt_assign_rx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+	return uart_en_q_de_q_for_ecpt(port, UART_RX, UART_EN_Q, &p_first_gpd, &p_last_gpd, NULL);
+}
+
+DCL_STATUS uart_ecpt_get_rx_gpd(UART_PORT port, void **pp_first_gpd, void **pp_last_gpd, kal_uint32 *gpd_num)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+	return uart_en_q_de_q_for_ecpt(port, UART_RX, UART_DE_Q, pp_first_gpd, pp_last_gpd, gpd_num);
+}
+
+void uart_ecpt_clear_sw_queue(UART_PORT port)
+{
+    static kal_bool first_time_clear = KAL_TRUE;
+
+    if (first_time_clear) {
+        first_time_clear = KAL_FALSE;
+
+        if (uart_wait_tgpd_head[port] != NULL) {
+            if (uart_discard_tgpd_head != NULL) {
+                QBM_DES_SET_NEXT(uart_discard_tgpd_tail, uart_wait_tgpd_head[port]);
+                uart_discard_tgpd_tail = uart_wait_tgpd_tail[port];
+            } else {
+                uart_discard_tgpd_head = uart_wait_tgpd_head[port];
+                uart_discard_tgpd_tail = uart_wait_tgpd_tail[port];
+            }
+    	}
+
+    	if (uart_tgpd_head[port] != NULL) {
+    	    if (uart_discard_tgpd_head != NULL) {
+                QBM_DES_SET_NEXT(uart_discard_tgpd_tail, uart_tgpd_head[port]);
+                uart_discard_tgpd_tail = uart_tgpd_tail[port];
+            } else {
+                uart_discard_tgpd_head = uart_tgpd_head[port];
+                uart_discard_tgpd_tail = uart_tgpd_tail[port];
+            }
+        }
+
+        if (uart_rgpd_head[port] != NULL) {
+            if (uart_discard_rgpd_head != NULL) {
+                QBM_DES_SET_NEXT(uart_discard_rgpd_tail, uart_rgpd_head[port]);
+                uart_discard_rgpd_tail = uart_rgpd_tail[port];
+            } else {
+                uart_discard_rgpd_head = uart_rgpd_head[port];
+                uart_discard_rgpd_tail = uart_rgpd_tail[port];
+            }
+        }
+
+	} else {
+        ;
+	}
+	
+    uart_wait_tgpd_head[port] = NULL;
+    uart_wait_tgpd_tail[port] = NULL;
+    
+	uart_tgpd_head[port] = NULL;
+    uart_tgpd_tail[port] = NULL;
+    
+	uart_rgpd_head[port] = NULL;
+    uart_rgpd_tail[port] = NULL;
+}
+
+DCL_STATUS uart_ecpt_clear_ch(UART_PORT port)
+{
+	kal_uint32 val = 0;
+
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+#if defined(META_MODE_SW_ESCAPING)
+	if(kal_query_boot_mode() != FACTORY_BOOT)
+#endif
+    {
+    /* Wait Tx HDMA Channel to be inactive */
+	while(HDMA_BUF0_IS_ACTIVE((port + 2)))
+	{
+		val = DRV_Reg32(GDMA_GISAR_UART);
+		if(IS_HDMA_LENERR_INTR(val, (2 + port))) break;
+		if(IS_HDMA_GPD_CSERR_INTR(val, (2 + port))) break;
+		if(IS_HDMA_BD_CSERR_INTR(val, (2 + port))) break;
+	}
+
+    /* Stop Tx HDMA Channel */
+	HDMA_BUF0_STOP((2 + port));
+	while (HDMA_BUF0_IS_ACTIVE((port + 2)));
+}
+	/* Stop Rx HDMA Channel */
+	HDMA_BUF0_STOP((3 + port));
+	while (HDMA_BUF0_IS_ACTIVE((port + 3)));
+
+	/* Clear SW Queue */
+	uart_ecpt_clear_sw_queue(port);
+
+	return STATUS_OK;
+}
+
+void uart_ecpt_timer_reset(UART_PORT port){
+	ASSERT(port < MAX_UART_PORT_NUM);
+	uart_ecpt_timer[port].timer_during = 0;
+	uart_ecpt_timer[port].timer_old = 0;
+	uart_ecpt_timer[port].timer_now = 0;
+	uart_ecpt_timer[port].timer_start = 0;
+}
+
+void uart_ecpt_timer_start(UART_PORT port)
+{	
+	ASSERT(port < MAX_UART_PORT_NUM);
+	if(uart_ecpt_timer[port].timer_start == 0){
+		uart_ecpt_timer[port].timer_now = ust_get_current_time();
+		uart_ecpt_timer[port].timer_old = uart_ecpt_timer[port].timer_now; 
+		uart_ecpt_timer[port].timer_during = 0;
+		uart_ecpt_timer[port].timer_start = 1;
+	}else{
+		uart_ecpt_timer[port].timer_now = ust_get_current_time();
+	}
+}
+
+kal_uint32 uart_ecpt_get_timer_during(UART_PORT port)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+	uart_ecpt_timer[port].timer_during =ust_us_duration(uart_ecpt_timer[port].timer_old,uart_ecpt_timer[port].timer_now)/1000 ;
+	return uart_ecpt_timer[port].timer_during;
+}
+
+DCL_STATUS uart_ecpt_init_hif(UART_PORT port)
+{
+	ASSERT(port < MAX_UART_PORT_NUM);
+
+	/* need re-init hardware ??? */
+
+	/* initial exception mode qbm */
+	if (uart_except_init_qbm() != KAL_TRUE) {
+        return STATUS_FAIL;
+	}
+	return STATUS_OK;
+}
+
+DCL_STATUS uart_except_reset(UART_PORT port)
+{
+    	ASSERT(port < MAX_UART_PORT_NUM);
+	uart_ecpt_tx_state[port] = HIF_STATE_NORMAL;
+	uart_ecpt_timer_reset(port);
+    
+    return STATUS_OK;
+}
+kal_uint32 uart_ecpt_get_tx_state(UART_PORT port){
+	ASSERT(port < MAX_UART_PORT_NUM);
+	kal_uint32 timer_dur = 0;
+	timer_dur = uart_ecpt_get_timer_during(port);
+	if(timer_dur>=UART_ECPT_MAX_TIMEOUT){
+		uart_ecpt_tx_state[port] = HIF_STATE_TXERROR;
+		uart_ecpt_timer_reset( port);
+	}else{
+		uart_ecpt_tx_state[port] = HIF_STATE_NORMAL;
+	}
+	
+    return uart_ecpt_tx_state[port];
+}
+
+
+#else //#if !defined(DRV_UART_OFF)
+
+UARTStruct UARTPort[MAX_UART_PORT_NUM];
+
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{
+	KAL_FALSE,
+	KAL_FALSE,
+};
+
+void UART_Boot_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len){}
+void U_Register(UART_PORT port, UartType_enum type, UartDriver_strcut* drv){}
+kal_bool U_Open(UART_PORT port, module_type ownerid){}
+void U_Close(UART_PORT port, module_type ownerid){}
+kal_uint16 U_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid){}
+kal_uint16 U_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid){}
+kal_uint16 U_GetBytesAvail(UART_PORT port){}
+kal_uint16 U_GetTxRoomLeft(UART_PORT port){}
+kal_uint16 U_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid){}
+kal_uint16 U_GetTxISRRoomLeft(UART_PORT port){}
+kal_uint16 U_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid){}
+kal_uint16 U_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid ){}
+void U_Purge(UART_PORT port, UART_buffer dir, module_type ownerid){}
+void U_SetOwner (UART_PORT port, module_type ownerid){}
+void U_SetFlowCtrl(UART_PORT port, kal_bool XON, module_type ownerid){}
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid){}
+void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid){}
+void U_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid){}
+void U_CtrlBreak(UART_PORT port, IO_level SBREAK, module_type ownerid){}
+void U_ClrRxBuffer(UART_PORT port, module_type ownerid){}
+void U_ClrTxBuffer(UART_PORT port, module_type ownerid){}
+void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate, module_type ownerid){}
+module_type U_GetOwnerID(UART_PORT port){}
+void U_SetAutoBaud_Div(UART_PORT port, module_type ownerid){}
+void U_Register_TX_cb(UART_PORT port, module_type ownerid, UART_TX_FUNC func){}
+void U_Register_RX_cb(UART_PORT port, module_type ownerid, UART_RX_FUNC func){}
+kal_uint8 U_GetUARTByte(UART_PORT port){}
+kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value){return 0;}
+void U_PutUARTByte(UART_PORT port, kal_uint8 data){}
+void U_PutUARTBytes(UART_PORT port, kal_uint8 *data, kal_uint16 len){}
+void U_ReadDCBConfig(UART_PORT port, UARTDCBStruct *DCB){}
+void U_CtrlRI (UART_PORT port, IO_level SRI, module_type ownerid){}
+void U_CtrlDTR (UART_PORT port, IO_level SDTR, module_type ownerid){}
+void U_ReadHWStatus(UART_PORT port, IO_level *SDSR, IO_level *SCTS){}
+void UART_AssertWaitPrevDataSentOut(UART_PORT port){}
+void UART_Calback(void *parameter){}
+void UART_CheckAT_Callback(void *parameter){}
+kal_bool UART_CheckTxAllSentOut(UART_PORT port){}
+kal_bool UART_CheckTxBufferEmpty(UART_PORT port){}
+void UART_CompensateAT(UART_PORT  port){}
+void uart_customize_init(void){}
+void UART_dafault_rx_cb(UART_PORT port){}
+void UART_dafault_tx_cb(UART_PORT port){}
+void UART_DriverInit(UART_PORT port){}
+void UART_EnableTX(UART_PORT port, kal_bool enable){}
+void UART_GetTxBufferSize(UART_PORT port, kal_uint32 *total_size, kal_uint32 *rest_size){}
+void UART_HWInit(UART_PORT port){}
+kal_bool UART_IsVfifoSetting(UART_PORT port, UART_TxRx_VFIFO_support vs){}
+void UART_RecHandler(void *parameter){}
+void UART_MsHandler(void *parameter){}
+void UART_RLSHandler(void *parameter){}
+void UART_sendilm(UART_PORT port, msg_type msgid){}
+void UART_set_FIFO_trigger(UART_PORT port, kal_uint16 tx_level, kal_uint16 rx_level){}
+void UART_SetRateFix(UART_PORT  port){}
+void UART_SetSleepEnable(UART_PORT port, kal_bool enable){}
+void UART_SleepOnTx_Enable(UART_PORT port, UART_SLEEP_ON_TX enable_flag){}
+kal_bool uart_support_autoescape(void){}
+void UART_SwitchPort(UART_PORT *APP_port, UART_PORT new_uart_port){}
+void UART_TrxHandler(void *parameter){}
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done){}
+void UART_TurnOnPower(UART_PORT port, kal_bool enable){}
+void UART1_HISR(void){}
+void UART2_HISR(void){}
+void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len){}
+kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length){}
+void PutUARTRingBufferData(UART_PORT port){}
+void UART_loopback(UART_PORT port){}
+void UART_dsp_dafault_tx_cb(UART_PORT port){}
+void UART_dsp_dafault_rx_cb(UART_PORT port){}
+#endif //if !defined(DRV_UART_OFF)
+
+
+// uart dispatch funtion table
+UartDriver_strcut UartDriver=
+{
+   	U_Open,
+	U_Close,
+	U_GetBytes,			// SIO_CMD_GET_BYTES is not supported
+	U_PutBytes,			// SIO_CMD_PUT_BYTES is not supported
+	U_GetBytesAvail,		// SIO_CMD_GET_RX_AVAIL is not supported
+	U_GetTxRoomLeft,		// SIO_CMD_GET_TX_AVAIL is not supported
+	U_PutISRBytes,			// SIO_CMD_PUT_ISR_BYTES is not supported
+	U_GetTxISRRoomLeft,		// SIO_CMD_GET_ISR_TX_AVAIL is not supported
+	U_Purge,
+	U_SetOwner,
+	U_SetFlowCtrl,
+	U_ConfigEscape,
+	U_SetDCBConfig,
+	U_CtrlDCD,			// SIO_CMD_CTRL_DCD is not supported
+	U_CtrlBreak,
+	U_ClrRxBuffer,
+	U_ClrTxBuffer,
+	U_SetBaudRate,
+	U_SendISRData,			// SIO_CMD_SEND_ISR_DATA is not supported
+	U_SendData,			// SIO_CMD_SEND_DATA is not supported
+	U_GetOwnerID,
+	U_SetAutoBaud_Div,		// SIO_CMD_SET_AUTOBAUD_DIV is not supported
+	/*TY adds these to expand flexibility 2004/10/15*/
+	U_Register_TX_cb,        	// SIO_CMD_REG_TX_CB is not supported 
+	U_Register_RX_cb,		// SIO_CMD_REG_RX_CB is not supported
+	/*TY adds these to let virtual COM port can retrive exception log 2005/3/8*/
+	U_GetUARTByte,			// SIO_CMD_GET_UART_BYTE is not supported
+	U_PutUARTByte,			// SIO_CMD_PUT_UART_BYTE is not supported
+	U_PutUARTBytes,			// SIO_CMD_PUT_UART_BYTES is not supported
+	/*for virtual com port to return DCB configuration*/
+	U_ReadDCBConfig,
+	U_CtrlRI,			// SIO_CMD_CTRL_RI is not supported
+	U_CtrlDTR,			// SIO_CMD_CTRL_DTR is not supported
+	U_ReadHWStatus,
+	U_GetUARTByteWithTimeOut
+};
+
+
+typedef struct hdma_tgpd_ss {
+	kal_uint8 hwo:1;
+	kal_uint8 bdp:1;
+	kal_uint8 bps:1;
+	kal_uint8 resv1:4;
+	kal_uint8 ioc:1;
+	kal_uint8 cksum;
+	kal_uint16 resv2;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint8 resv3;
+} hdma_tgpd_tt;
+
+typedef struct hdma_rgpd_ss {
+	kal_uint8 hwo:1;
+	kal_uint8 bdp:1;
+	kal_uint8 bps:1;
+	kal_uint8 resv1:4;
+	kal_uint8 ioc:1;
+	kal_uint8 cksum;
+	kal_uint16 allowBufLen;
+	kal_uint32 nextPtr;
+	kal_uint32 bufPtr;
+	kal_uint16 bufLen;
+	kal_uint16 resv2;
+} hdma_rgpd_tt;
+
+
+// dummy_fdma() just for mt6595 workaround patch. removed on LR12.
+/*  
+void dummy_fdma(kal_uint32 gdma_start)
+{
+
+	FDMA_PDN_CLR(3);
+	if(gdma_start == 0){
+		DRV_WriteReg32(0xff2c0080, 0x4); // stop (GDMA_FDCR0)
+		FDMA_PDN_SET(3);
+	}
+	else{
+		DRV_WriteReg32(0xff2c0080, 0x4); // stop (GDMA_FDCR0)
+		while(DRV_Reg32(0xff2c0014) & (1<<16)); // check done state (GDMA_FDCSR0)
+		
+		DRV_WriteReg32(0xff2c0014, 0x02000000); // GDMA_FDCSR
+		DRV_WriteReg32(0xff2c0084, 0xbf830C20); // GDMA_FDSAR3
+		DRV_WriteReg32(0xff2c0088, 0xbf830C24); // GDMA_FDDAR3
+		DRV_WriteReg32(0xff2c0080, 0xffff43a1); // start (GDMA_FDCR3)
+	}
+	return;
+}
+
+}
+*/
+
+extern UARTStruct UARTPort[];
+extern Seriport_HANDLER_T  Uart_Drv_Handler;
+
+enum {
+   INIT_NOTINIT,
+   INIT_REG_CB,
+   INIT_DRV_ATTACH,
+   INIT_DRV_INIT,
+   INIT_UPMOD_INIT,
+   INIT_SET_BAUDRATE,
+   INIT_DONE,
+} uart_excpt_drv_init_stage = INIT_NOTINIT;
+kal_bool uart_excpt_drv_init_done_g = KAL_FALSE;
+kal_bool uart_st_in_except_mode_g = KAL_FALSE;
+
+#if defined __UART_UT__
+kal_int32 uart_hmu_pre_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return 0;
+}
+
+kal_int32 uart_hmu_post_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_pre_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_except_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+#else
+
+kal_int32 uart_hmu_pre_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+
+    return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_pre_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+
+	return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+	return KAL_TRUE;
+}
+
+UARTStruct* uart_core_get_instance(kal_uint32 uart_port)
+{
+    return &UARTPort[uart_port];
+}
+
+DCL_STATUS uart_ttyhdr_reg_ttycore(UARTStruct*p_dev_inst, kal_uint32 port)
+{
+	DCL_STATUS status;
+	DCL_HANDLE handle;
+
+	handle =  DclSerialPort_Open(port, 0);
+	
+	uart_excpt_drv_init_stage = INIT_REG_CB;
+	status = DclSerialPort_DrvRegisterCb(handle, &Uart_Drv_Handler);
+
+	if (KAL_TRUE == uart_st_in_except_mode_g && STATUS_ALREADY_OPENED == status) {
+        return STATUS_OK;
+    }
+	return status;
+}
+
+DCL_STATUS uart_ttyhdr_cmd_init(UART_PORT port)
+{
+    DCL_STATUS status;
+    DCL_HANDLE handle;
+	DCL_CTRL_DATA_T data;
+
+	handle = DclSerialPort_Open(port, 0);
+	
+    uart_excpt_drv_init_stage = INIT_DRV_ATTACH;
+   	status = DclSerialPort_DrvAttach(handle);
+	if(status != STATUS_OK)
+	{	
+		return STATUS_FAIL;
+	}
+
+   uart_excpt_drv_init_stage = INIT_DRV_INIT;
+   status = DclSerialPort_Control(handle, SIO_CMD_INIT, &data);
+
+   return status;
+   
+}
+
+DCL_STATUS uart_ttyhdr_upmodule_init(UART_PORT port)
+{
+    DCL_STATUS status;
+    DCL_HANDLE handle;
+    UART_CTRL_DCB_T data;
+
+    handle = DclSerialPort_Open(port, 0);
+    
+    uart_excpt_drv_init_stage = INIT_UPMOD_INIT;
+    status = DclSerialPort_UpModuleInit(handle, MOD_DRV_DBG, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+    if (status != STATUS_OK && status != STATUS_ALREADY_OPENED) {
+        return status;
+    }
+    
+    //DclSerialPort_UpModuleRegisterCb(handle, dbg_print_tty_rx_cb, NULL, dbg_print_tty_state_cb);
+
+    data.u4OwenrId = MOD_DRV_DBG;
+    data.rUARTConfig.u4Baud = UART_BAUD_1500000;
+    data.rUARTConfig.u1DataBits = len_8;
+    data.rUARTConfig.u1StopBits = sb_1;
+    data.rUARTConfig.u1Parity = pa_none;
+    data.rUARTConfig.u1FlowControl = fc_sw;
+    data.rUARTConfig.ucXonChar = 0x11;
+    data.rUARTConfig.ucXoffChar = 0x13;
+    data.rUARTConfig.fgDSRCheck = KAL_FALSE;
+
+    // Set baudrate
+    uart_excpt_drv_init_stage = INIT_SET_BAUDRATE;
+    status = DclSerialPort_Control(handle, SIO_CMD_SET_DCB_CONFIG, (DCL_CTRL_DATA_T*)&data);
+
+    return status;
+}
+
+kal_int32 uart_hmu_except_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+    DCL_STATUS ret;
+    UARTStruct* p_dev_inst;
+    kal_uint32 uart_port;
+    kal_uint32 init_ports[] = {uart_port1, uart_port2};
+    kal_uint32 ret_val = 0;
+    int i;
+
+    uart_st_in_except_mode_g = KAL_TRUE;
+    if (uart_excpt_drv_init_done_g == KAL_TRUE) {
+        return 0;
+    }
+
+    for (i = 0; i < sizeof(init_ports)/sizeof(init_ports[0]); i++) {
+        uart_port = init_ports[i];
+
+        p_dev_inst = uart_core_get_instance(uart_port);
+
+        if(p_dev_inst->initialized == KAL_TRUE){
+            continue;
+        }
+
+        ret = uart_ttyhdr_reg_ttycore(p_dev_inst, uart_port);
+        if (STATUS_OK != ret) {
+            ret_val = -1;
+            continue;
+        }
+
+        ret = uart_ttyhdr_cmd_init(uart_port);
+        if (STATUS_OK != ret) {
+            ret_val = -1;
+            continue;
+        }
+    }
+
+    uart_excpt_drv_init_stage = INIT_DONE;
+    uart_excpt_drv_init_done_g = KAL_TRUE;
+
+    return ret_val;
+}
+
+#endif 
+
+
diff --git a/mcu/driver/devdrv/uart/src/uart_handler.c b/mcu/driver/devdrv/uart/src/uart_handler.c
new file mode 100644
index 0000000..7614234
--- /dev/null
+++ b/mcu/driver/devdrv/uart/src/uart_handler.c
@@ -0,0 +1,610 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2012
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ *   uart_handler.c
+ *
+ * Project:
+ * --------
+ *   TATAKA
+ *
+ * Description:
+ * ------------
+ *   Handler for UART
+ *
+ * Author:
+ * -------
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 07 29 2019 yao.xue
+ * [MOLY00425268] [SMO][VMOLY]Remove unnecessary Assert in user load
+ * Modify Assert to DEBUG ASSERT in UART driver
+ *
+ * 02 15 2019 panu.peisa
+ * [MOLY00384803] [Gen97][SystemService][Change Request] KAL Refactoring Phase-in
+ * 	
+ * Added changes to swrd part.
+ *
+ * 04 10 2018 yuke.ren
+ * [MOLY00318981] Merge SLT Code
+ * .
+ *
+ * 03 13 2018 shenghui.shi
+ * [MOLY00309657] UMOLYE driver warning fix
+ * update UART driver
+ *
+ * 09 07 2017 yao.xue
+ * [MOLY00275927] update uart dbg_print init
+ * update dbgprint init
+ *
+ * 04 24 2017 shenghui.shi
+ * [MOLY00243727] update UART PDN feature
+ * update UART pdn feature,to void system could not entry DCM issue.
+ *
+ * 03 15 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * update dbgprint driver for SMP
+ *
+ * 02 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * 1. add sw escape feature to UMOLY
+ * 2. phase out VFIFO hw code in devdrv_common.c
+ *
+ * 12 18 2014 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * .
+ *
+ * 11 14 2014 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * add UART eception check timeout status feature
+ *
+ * 12 30 2013 shenghui.shi
+ * [MOLY00051976] Update UART driver to separate UARTcore and DRV_DEBUG
+ * update uart driver to sperate uartcore and DRV_DEBUG
+ *
+ * 12 25 2013 shenghui.shi
+ * [MOLY00051587] [MT6290 MOLY] uart driver update for TTY_CMD_EXCEPTION_HIF_POLL
+ * uart driver update for TTY_CMD_EXCEPTION_HIF_POL
+ *
+ * 12 04 2013 shenghui.shi
+ * [MOLY00048917] [MT6290E2] uart driver update
+ * .
+ *
+ * 11 07 2013 shenghui.shi
+ * [MOLY00045403] update UARTcore task
+ * .
+ *
+ * 08 27 2013 shenghui.shi
+ * [MOLY00035212] fix uart build modis error
+ * update UART exception driver for following the HMU standard mode.
+ *
+ * 02 04 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * rename: 7208 -> 6290
+ *
+ * 12 12 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 11 23 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Add UART/HDMA driver
+ ****************************************************************************/
+#include "dcl.h"
+#include "uart_internal.h"
+#include "uart_sw.h"
+#include "kal_general_types.h"
+#include "drv_comm.h"
+#include "kal_public_api.h"
+#include "kal_ex_api.h"
+
+
+#if defined(__HMU_ENABLE__)
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#endif
+
+#define UART_CHUNK_SIZE	512
+
+UartDriver_strcut* pUart_CMD_FUNC[MAX_UART_PORT_NUM];
+kal_uint32 uart_open_event = 0;
+extern UARTStruct UARTPort[];
+extern kal_uint32 uart_ecpt_get_tx_state(UART_PORT port);
+extern void UART_PDN_Disable(UART_PORT port);
+extern void UART_PDN_Enable(UART_PORT port);
+extern void dbg_uart_init(void);
+#ifndef KTEST_UART_TRACES
+extern void dbg_uart_create_spinlock(void);
+#endif
+static DCL_STATUS UART_Handler(DCL_DEV dev,DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data);
+
+Seriport_HANDLER_T  Uart_Drv_Handler = {DCL_UART_TYPE, UART_Handler};
+//extern UART_flowCtrlMode  UART_GetFlowCtrl(UART_PORT uart_port);
+
+DCL_STATUS UART_Handler(DCL_DEV dev,DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	kal_bool return_flag = KAL_FALSE;
+	DCL_STATUS return_status = STATUS_OK;
+	if(dev >= MAX_UART_PORT_NUM)
+		return STATUS_INVALID_DEVICE;
+	
+	switch (cmd)
+	{
+		// Class Driver must implement
+		case SIO_CMD_INIT:
+		{
+		#if defined(DRV_DEBUG)||defined(__IC_SLT__)
+            UART_DriverInit(dev);
+            #ifndef KTEST_UART_TRACES
+                dbg_uart_create_spinlock();
+            #endif
+		 	//dbg_uart_init();
+		#elif defined(__HIF_UART_SUPPORT__)
+			UART_DriverInit(dev);
+		#else	
+		/* disable uart clock in drv_init_phase1() if not used */
+			UART_PDN_Enable(dev);
+		#endif
+		}
+			break;
+			
+		case SIO_CMD_OPEN:
+		{
+			UART_CTRL_OPEN_T* prCtrlOpen;
+#if defined(__UARTCORE_SUPPORT__) && !defined(UARTCORE_NOT_PRESENT) && !defined(__UARTCORE_TASK_DISABLE__)&&!defined(DRV_DEBUG)
+			uart_open_event ++;
+			hmu_hifeg_set(HIF_DRV_EG_UART_IND_EVENT);	
+#endif
+			prCtrlOpen = &(data->rUARTCtrlOPEN);
+			return_flag = pUart_CMD_FUNC[dev]->Open(dev,(module_type)(prCtrlOpen->u4OwenrId));
+			if(return_flag == KAL_FALSE){
+				UART_DriverInit(dev);
+				return_status = STATUS_FAIL;
+			}
+		}
+			break;
+			
+		case SIO_CMD_CLOSE:
+		{
+			UART_CTRL_CLOSE_T* prCtrlClose;
+			prCtrlClose = &(data->rUARTCtrlCLOSE);
+			pUart_CMD_FUNC[dev]->Close(dev,(module_type)(prCtrlClose->u4OwenrId));
+#if defined(__UARTCORE_SUPPORT__) && !defined(UARTCORE_NOT_PRESENT) && !defined(__UARTCORE_TASK_DISABLE__)&&!defined(DRV_DEBUG)
+			if(uart_open_event>0){
+				uart_open_event--;
+			}
+#endif	
+		}
+			break;
+			
+		case SIO_CMD_PURGE:
+		{
+			UART_CTRL_PURGE_T* prCtrlPurge;
+			prCtrlPurge = &(data->rUARTCtrlPURGE);
+			pUart_CMD_FUNC[dev]->Purge(dev,(UART_buffer)(prCtrlPurge->dir),(module_type)(prCtrlPurge->u4OwenrId) );
+		}
+			break;
+
+		case SIO_CMD_SET_OWNER:
+		{
+			UART_CTRL_OWNER_T* prCtrlOwner;
+			prCtrlOwner = &(data->rUARTCtrlOWNER);
+			pUart_CMD_FUNC[dev]->SetOwner(dev, (module_type) (prCtrlOwner->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_CLR_RX_BUF:
+		{
+			UART_CTRL_CLR_BUFFER_T* prCtrlClrBuffer;
+			prCtrlClrBuffer = &(data->rUARTCtrlCLRBUFFER);
+			pUart_CMD_FUNC[dev]->ClrRxBuffer(dev, (module_type) (prCtrlClrBuffer->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_CLR_TX_BUF:
+		{
+			UART_CTRL_CLR_BUFFER_T* prCtrlClrBuffer;
+			prCtrlClrBuffer = &(data->rUARTCtrlCLRBUFFER);
+			pUart_CMD_FUNC[dev]->ClrTxBuffer(dev, (module_type) (prCtrlClrBuffer->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_GET_OWNER_ID:
+		{
+			UART_CTRL_OWNER_T* prCtrlOwner;
+			prCtrlOwner = &(data->rUARTCtrlOWNER);
+			prCtrlOwner->u4OwenrId = pUart_CMD_FUNC[dev]->GetOwnerID(dev);
+		}
+			break;
+
+		// Other SIO configuration related commands
+		case SIO_CMD_SET_FLOW_CTRL:
+		{
+			UART_CTRL_FLOW_CTRL_T* prCtrlFlowCtrl;
+			prCtrlFlowCtrl = &(data->rUARTCtrlFLOWCTRL);
+			pUart_CMD_FUNC[dev]->SetFlowCtrl(dev,(kal_bool)(prCtrlFlowCtrl->bXON),(module_type)(prCtrlFlowCtrl->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_CONFIG_ESCAPE:
+		{
+			UART_CTRL_CONFIG_ESP_T* prCtrlConfigEsp;
+			prCtrlConfigEsp = &(data->rUARTCtrlCONFIGESP);
+			pUart_CMD_FUNC[dev]->ConfigEscape(dev, prCtrlConfigEsp->uEscChar, prCtrlConfigEsp->u2ESCGuardtime, (module_type) (prCtrlConfigEsp->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_SET_DCB_CONFIG:		
+		{
+			UARTDCBStruct *prDCB;
+			UART_CTRL_DCB_T* prCtrlDCB;
+			prCtrlDCB = &(data->rUARTCtrlDCB);
+			prDCB = (UARTDCBStruct*)(&(prCtrlDCB->rUARTConfig));
+			pUart_CMD_FUNC[dev]->SetDCBConfig(dev,prDCB,(module_type)(prCtrlDCB->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_CTRL_DCD:		// Not used in MT6290 UART
+			DEBUG_ASSERT(0);
+			break;
+
+		case SIO_CMD_CTRL_BREAK:
+		{
+			UART_CTRL_BREAK_T* prCtrlBreak;
+			prCtrlBreak = &(data->rUARTCtrlBREAK);
+			pUart_CMD_FUNC[dev]->CtrlBreak(dev, (IO_level) (prCtrlBreak->rIOLevelBRK), (module_type) (prCtrlBreak->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_SET_BAUDRATE:
+		{
+			UART_CTRL_BAUDRATE_T* prCtrlBaudrate;
+			prCtrlBaudrate = &(data->rUARTCtrlBAUDRATE);
+			pUart_CMD_FUNC[dev]->SetBaudRate(dev, prCtrlBaudrate->baudrate, (module_type)(prCtrlBaudrate->u4OwenrId));
+		}
+			break;
+
+		case SIO_CMD_SET_AUTOBAUD_DIV:	// LTE TBC
+			DEBUG_ASSERT(0);
+			break;
+
+		case SIO_CMD_READ_DCB_CONFIG:	
+		{
+			UARTDCBStruct *prDCB;
+			UART_CTRL_DCB_T* prCtrlDCB;
+			prCtrlDCB = &(data->rUARTCtrlDCB);
+			prDCB = (UARTDCBStruct*) &(prCtrlDCB->rUARTConfig);
+			pUart_CMD_FUNC[dev]->ReadDCBConfig(dev, prDCB); 
+		}
+			break;
+
+		case SIO_CMD_CTRL_RI:		// Not used in MT6290 UART
+			DEBUG_ASSERT(0);
+			break;
+
+		case SIO_CMD_GET_ESCAPE_INFO:		
+		{
+			UART_CTRL_CONFIG_ESP_T* prCtrlConfigEsp;
+			prCtrlConfigEsp = &(data->rUARTCtrlCONFIGESP);
+			prCtrlConfigEsp->u2ESCGuardtime = UARTPort[dev].ESCDet.GuardTime;
+			prCtrlConfigEsp->uEscChar = UARTPort[dev].ESCDet.EscChar;
+		}
+			break;
+
+		case SIO_CMD_CTRL_DTR:		// Not used in MT6290 UART
+		case SIO_CMD_READ_HW_STATUS:	// Not used in MT6290 UART (assert temporary)
+
+		// Not used commands in driver level (TTY would handle/wrap these commands from conventional upper layer module)
+		case SIO_CMD_GET_BYTES:
+		case SIO_CMD_PUT_BYTES:
+		case SIO_CMD_GET_RX_AVAIL:
+		case SIO_CMD_GET_TX_AVAIL:
+		case SIO_CMD_PUT_ISR_BYTES:
+		case SIO_CMD_GET_ISR_TX_AVAIL:
+		case SIO_CMD_SEND_ISR_DATA:
+		case SIO_CMD_SEND_DATA:
+		case SIO_CMD_REG_TX_CB:
+		case SIO_CMD_REG_RX_CB:
+		case SIO_CMD_PUT_UART_BYTE:
+		case SIO_CMD_GET_UART_BYTE:
+		case SIO_CMD_PUT_UART_BYTES:
+			DEBUG_ASSERT(0);
+			break;
+
+		// ???
+		case SIO_CMD_GET_UART_BYTE_WITH_TIMEOUT:
+			// temporary
+			DEBUG_ASSERT(0);
+		{
+			 UART_CTRL_GET_UART_BYTE_WITH_TIMEOUT_T* prCtrlGetUartByte;
+			 prCtrlGetUartByte = &(data->rUARTCtrlGETUARTBYTEWithTimeOut);
+			 prCtrlGetUartByte->u1retByte = pUart_CMD_FUNC[dev]->GetUARTByte_WithTimeOut(dev, &(prCtrlGetUartByte->uByte), prCtrlGetUartByte->u4timeout_value); 
+		}
+			break;
+
+		// Only UART driver need to take care
+		case UART_CMD_SET_FIFO_TRIGGER:
+		{
+			 UART_CTRL_SFT_T* prCtrlSFT;
+			 prCtrlSFT = &(data->rUARTCtrlSFT); 
+			 UART_set_FIFO_trigger(dev, prCtrlSFT->tx_level, prCtrlSFT->rx_level);
+		}
+			break;
+		
+		case UART_CMD_POWER_ON:
+			break;
+
+		case UART_CMD_CHECK_TX_BUF_EMPTY:
+		{
+			UART_CTRL_CHECK_TBE_T* prCtrlTBE;
+			prCtrlTBE = &(data->rUARTCtrlCheckBUFEMP);
+			prCtrlTBE->bFlag = UART_CheckTxBufferEmpty(dev);
+		}
+			break;
+				
+	 	case UART_CMD_CHECK_TX_SEND_OUT:
+ 		{
+			UART_CTRL_CHECK_TSO_T* prCtrlTSO;
+			prCtrlTSO = &(data->rUARTCtrlCheckTXSendOut);
+			prCtrlTSO->bFlag = UART_CheckTxAllSentOut(dev);
+		}
+	 		break;
+		
+		case UART_CMD_GET_TX_BUF_SIZE:
+			DEBUG_ASSERT(0);
+		{
+			UART_CTRL_GET_TBS_T* prCtrlGetTBS;
+			prCtrlGetTBS = &(data->rUARTCtrlGetTxBufSize);
+			UART_GetTxBufferSize(dev, (kal_uint32 *)(prCtrlGetTBS->ptotal_size), (kal_uint32 *)(prCtrlGetTBS->preturn_size));
+		}
+			break;
+		
+		case UART_CMD_SLEEP_TX_ENABLE:
+			return STATUS_UNSUPPORTED;
+		
+		case UART_CMD_CTRL_SLEEP_MODE:
+		{
+			UART_CTRL_SLEEP_ENABLE_T* prCtrlSleepEnable;
+			prCtrlSleepEnable = &(data->rUARTCtrlSleepEnable);
+			UART_SetSleepEnable(dev, (kal_bool) prCtrlSleepEnable->bFlag);
+		}
+			break;
+		case UART_CMD_SWITCH_PORT:
+			return STATUS_UNSUPPORTED;
+		
+		case UART_CMD_BOOTUP_INIT:
+		{
+			UART_Bootup_Init();
+		}
+			break;
+		
+		case UART_CMD_BOOT_PUTBYTES:
+		{
+			UART_CTRL_BOOT_PUTBYTES_T* prCtrlPutBytes;
+			prCtrlPutBytes = &(data->rUARTCtrlBootPutBytes);
+			UART_Boot_PutUARTBytes(dev,prCtrlPutBytes->puBuffaddr, prCtrlPutBytes->u2Length);
+		}
+			break;
+		
+		case UART_CMD_LOOPBACK:
+		{
+			UART_loopback(dev);
+		}
+			break;
+			
+		case UART_CMD_ASSERT_WAIT_SEND_OUT:
+		{
+			UART_AssertWaitPrevDataSentOut(dev);
+		}
+			break;
+			
+		case UART_CMD_CTRL_USE_VFIFO:
+			return STATUS_UNSUPPORTED;
+			DEBUG_ASSERT(0);
+		{
+//			UART_CTRL_USE_VFIFO_T* prCtrlUseVfifo;
+//			prCtrlUseVfifo = &(data->rUARTCtrlUseVFifo);
+//			UART_UseVFIFO(dev,prCtrlUseVfifo->bUseVFifo);
+		}
+			break;
+
+		case UART_CMD_GET_FLOW_CONTROL:
+		{
+			UART_CTRL_GET_FC_T* prCtrlFlowControl;
+			prCtrlFlowControl = &(data->rUARTCtrlGetFC);
+			prCtrlFlowControl->FlowCtrlMode = (UART_FLOW_CTRL_MODE_T) U_GetFlowCtrl(dev, prCtrlFlowControl->u4OwenrId);
+		}
+			break;
+			
+	 	case UART_CMD_REG_DEF_CB:
+			DEBUG_ASSERT(0);
+			break;
+				
+		case UART_CMD_BMT_PUT_BYTES:
+		{
+			#ifdef DRV_DEBUG
+			UART_CTRL_PUT_BYTES_T* prCtrlBMTPutBytes;
+			prCtrlBMTPutBytes = &(data->rUARTCtrlPUTBYTES);
+		 	BMT_PutBytes(dev, prCtrlBMTPutBytes->puBuffaddr, prCtrlBMTPutBytes->u2Length);
+		 	#endif
+		}
+			break;
+			
+		case UART_CMD_GET_MAX_BAUDRATE:
+		{
+			UART_CTRL_GET_MAXBAUDRATE_T* prCtrlGetMaxBaudrate;
+			prCtrlGetMaxBaudrate = &(data->rUARTCtrlGetMaxBaudrate);
+			prCtrlGetMaxBaudrate->max_baudrate = UART_Get_Maxbaudrate(dev);
+		}
+			break;
+
+		case UART_CMD_RECHANDLER_VFIFO:
+		case UART_CMD_TRXHANDLER_VFIFO:
+		case UART_CMD_RECTIMEOUTHANDLE:
+		case UART_CMD_CTRL_TX_DMA:
+			DEBUG_ASSERT(0);
+		{
+			UART_CTRL_USE_VFIFO_T* prCtrlTxDMA;
+			prCtrlTxDMA = &(data->rUARTCtrlUseVFifo);
+			UART_VFIFO_TX_DMA_Enable(dev,(kal_bool)(prCtrlTxDMA->bUseVFifo));
+		}
+			break;
+
+		// TTY commands
+		case TTY_CMD_GET_CHUNK_SIZE:
+		{
+			UART_CTRL_GET_CHUNK_SIZE_T *prCtrlGetChunkSize;
+			prCtrlGetChunkSize = &(data->rUARTCtrlGETCHUNKSIZE);
+			prCtrlGetChunkSize->chunkSize = UART_CHUNK_SIZE;
+		}
+			break;
+
+		case TTY_CMD_ASSIGN_RX_IOR:
+		{
+			UART_CTRL_ASSIGN_RX_IOR_T *prCtrlAssignRxIor;
+			prCtrlAssignRxIor = &(data->rUARTCtrlAssignRxIor);
+			UART_GetBytesIor(dev, prCtrlAssignRxIor->ior);
+		}
+			break;
+
+		case TTY_CMD_NEED_TX_DONE_CB:
+		{
+			UART_CTRL_NEED_TX_DONE_CB_T *prNeedTxDoneCb;
+			prNeedTxDoneCb = &(data->rUARTCtrlNeedTxDoneCb);
+			UART_SetNeedTxDoneCb(dev, prNeedTxDoneCb->needTxDoneCb, prNeedTxDoneCb->u4OwnerId);
+		}
+			break;
+
+		case TTY_CMD_GET_DRV_STATE:
+		{
+			UART_CTRL_GET_DRV_STATE_T *prGetDrvState;
+			prGetDrvState = &(data->rUARTCtrlGetDrvState);
+			prGetDrvState->drv_state = DRV_ST_ATTACHED;
+		}
+			break;
+
+		case TTY_CMD_PUT_BYTES_IOR:
+		{
+			UART_CTRL_PUT_BYTES_IOR_T *prCtrlPutBytesIor;
+			prCtrlPutBytesIor = &(data->rUARTCtrlPUTBYTESIOR);
+			UART_PutBytesIor(dev, prCtrlPutBytesIor->putIor);
+		}
+			break;
+
+		case TTY_CMD_PUT_BYTES_IOR_LIGHT:
+		{
+			UART_CTRL_PUT_BYTES_IOR_T *prCtrlPutBytesIor;
+			prCtrlPutBytesIor = &(data->rUARTCtrlPUTBYTESIOR);
+			UART_PutBytesIor_LIGHT(dev, prCtrlPutBytesIor->putIor);
+		}
+			break;
+
+		// TTY commands for exception
+		case TTY_CMD_EXCEPTION_RESET:
+			break;	
+
+		case TTY_CMD_EXCEPTION_HIF_INIT:
+		{
+			return_status = uart_ecpt_init_hif(dev);
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_CLEAR_CHANNEL:
+		{
+			return_status = uart_ecpt_clear_ch(dev);
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_TX_GPD:
+		{
+			TTY_CTRL_EXCP_TX_GPD_T* prCtrlExptTxGpd;
+			prCtrlExptTxGpd = &(data->rTTYCtrlExcpTxGPD);
+			return_status = uart_ecpt_tx_gpd(dev, prCtrlExptTxGpd->first_gpd, prCtrlExptTxGpd->last_gpd);
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_TX_DONE_INFO:
+		{
+			TTY_CTRL_EXCP_TX_DONE_INFO_T* prCtrlExptTxDoneInfo; 
+			prCtrlExptTxDoneInfo = &(data->rTTYCtrlExcpTxDoneInfo);
+			return_status = uart_ecpt_tx_done_info(dev, &(prCtrlExptTxDoneInfo->first_gpd), &(prCtrlExptTxDoneInfo->last_gpd), (kal_uint32 *) &(prCtrlExptTxDoneInfo->num));
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_HIF_STATE:
+		{   
+			TTY_CTRL_EXCP_HIF_STATE_T* prCtrlExptHifState;
+			prCtrlExptHifState = &(data->rTTYCtrlExcpHifState);
+			prCtrlExptHifState->hif_state = uart_ecpt_get_tx_state(dev); //HIF_STATE_NORMAL
+
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_ASSIGN_RX_GPD:
+		{
+			TTY_CTRL_EXCP_ASSIGN_RX_GPD_T* prCtrlExptAssignRxGpd;
+			prCtrlExptAssignRxGpd = &(data->rTTYCtrlExcpAssignRxGPD);
+			return_status = uart_ecpt_assign_rx_gpd(dev, prCtrlExptAssignRxGpd->first_gpd, prCtrlExptAssignRxGpd->last_gpd);
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_GET_RX_GPD:
+		{
+			TTY_CTRL_EXCP_GET_RX_GPD_T* prCtrlExptGetRxGpd;
+			prCtrlExptGetRxGpd = &(data->rTTYCtrlExcpGetRxGPD);
+			return_status = uart_ecpt_get_rx_gpd(dev, &(prCtrlExptGetRxGpd->first_gpd), &(prCtrlExptGetRxGpd->last_gpd), (kal_uint32 *) &(prCtrlExptGetRxGpd->num));
+		}
+			break;
+
+		case TTY_CMD_EXCEPTION_HIF_POLL:
+        {
+            TTY_CTRL_EXCP_HIF_POLL_T* pCtrlHifPoll;
+            pCtrlHifPoll = &(data->rTTYCtrlExcpHifPoll);
+            pCtrlHifPoll->reset_event = DCL_FALSE;
+        }
+			break;
+
+		default:
+			return STATUS_INVALID_CMD;
+	}
+
+	return return_status;
+}