From: "Chao Li" <lichao@loongson.cn>
To: devel@edk2.groups.io, lixianglai@loongson.cn
Cc: gaoliming <gaoliming@byosoft.com.cn>, maobibo@loongson.cn
Subject: Re: 回复: [edk2-devel] [edk2-platforms][PATCH V1 01/16] Platform/Loongson: Add Serial Port library
Date: Fri, 9 Sep 2022 18:40:57 +0800 (GMT+08:00) [thread overview]
Message-ID: <4ffeda56.79a5.18321d6a07c.Coremail.lichao@loongson.cn> (raw)
In-Reply-To: <958f0bd.78c2.18321824253.Coremail.lixianglai@loongson.cn>
Hi Liming and Xianhlai,
The new feature request of LoongArch VM has been created in the
BZ, REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054 . Please check.
Thanks,
Chao
> -----原始邮件-----
> 发件人: xianglai <lixianglai@loongson.cn>
> 发送时间:2022-09-09 17:08:48 (星期五)
> 收件人: gaoliming <gaoliming@byosoft.com.cn>
> 抄送: devel@edk2.groups.io, maobibo@loongson.cn
> 主题: Re: 回复: [edk2-devel] [edk2-platforms][PATCH V1 01/16] Platform/Loongson: Add Serial Port library
>
>
> Hi Liming:
> Thanks for writing back and for the tips. You can get all the patches at:
> https://github.com/loongson/edk2-platforms/tree/devel-LoongArch-patch
>
> Thanks
> xianglai
>
> > -----原始邮件-----
> > 发件人: gaoliming <gaoliming@byosoft.com.cn>
> > 发送时间:2022-09-09 16:44:42 (星期五)
> > 收件人: devel@edk2.groups.io, lixianglai@loongson.cn
> > 抄送: maobibo@loongson.cn
> > 主题: 回复: [edk2-devel] [edk2-platforms][PATCH V1 01/16] Platform/Loongson: Add Serial Port library
> >
> > Xianglai:
> > Please share the github link to get all patches.
> >
> > Thanks
> > Liming
> > > -----邮件原件-----
> > > 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 xianglai
> > > 发送时间: 2022年9月9日 11:12
> > > 收件人: devel@edk2.groups.io
> > > 抄送: maobibo@loongson.cn
> > > 主题: [edk2-devel] [edk2-platforms][PATCH V1 01/16] Platform/Loongson:
> > > Add Serial Port library
> > >
> > > Serial Port library for LoongarchQemuPkg
> > >
> > > Signed-off-by: xianglai li <lixianglai@loongson.cn>
> > > ---
> > > .../LoongArchQemuPkg/Include/Library/Cpu.h | 344 ++++++++++
> > > .../Include/LoongArchQemuPlatform.h | 103 +++
> > > .../Library/SerialPortLib/SerialPortLib.c | 612 ++++++++++++++++++
> > > .../Library/SerialPortLib/SerialPortLib.inf | 36 ++
> > > 4 files changed, 1095 insertions(+)
> > > create mode 100644
> > > Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h
> > > create mode 100644
> > > Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h
> > > create mode 100644
> > > Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib.c
> > > create mode 100644
> > > Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib.in
> > > f
> > >
> > > diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h
> > > b/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h
> > > new file mode 100644
> > > index 0000000000..de466b7c6f
> > > --- /dev/null
> > > +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h
> > > @@ -0,0 +1,344 @@
> > > +/** @file
> > >
> > > +
> > >
> > > + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights
> > > reserved.<BR>
> > >
> > > +
> > >
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > + @par Glossary:
> > >
> > > + - EXC - Exception
> > >
> > > + - INT - Interrupt
> > >
> > > + - FPU - Floating Point Unit
> > >
> > > + - CSR - CPU Status Register
> > >
> > > + - READQ - Read Quad Word
> > >
> > > +**/
> > >
> > > +#ifndef LOONGARCH_CPU_H_
> > >
> > > +#define LOONGARCH_CPU_H_
> > >
> > > +
> > >
> > > +/* Exception types decoded by machdep exception decoder */
> > >
> > > +#define EXC_INT 0 /* HW interrupt */
> > >
> > > +#define EXC_TLBL 1 /* TLB miss on a load */
> > >
> > > +#define EXC_TLBS 2 /* TLB miss on a store */
> > >
> > > +#define EXC_TLBI 3 /* TLB miss on a ifetch */
> > >
> > > +#define EXC_TLBM 4 /* TLB modified fault */
> > >
> > > +#define EXC_TLBRI 5 /* TLB Read-Inhibit exception */
> > >
> > > +#define EXC_TLBXI 6 /* TLB Execution-Inhibit exception */
> > >
> > > +#define EXC_TLBPE 7 /* TLB Privilege Error */
> > >
> > > +#define EXC_ADE 8 /* Address Error */
> > >
> > > +#define EXC_ALE 9 /* Unalign Access */
> > >
> > > +#define EXC_OOB 10 /* Out of bounds */
> > >
> > > +#define EXC_SYS 11 /* System call */
> > >
> > > +#define EXC_BP 12 /* Breakpoint */
> > >
> > > +#define EXC_INE 13 /* Inst. Not Exist */
> > >
> > > +#define EXC_IPE 14 /* Inst. Privileged Error */
> > >
> > > +#define EXC_FPDIS 15 /* FPU Disabled */
> > >
> > > +#define EXC_LSXDIS 16 /* LSX Disabled */
> > >
> > > +#define EXC_LASXDIS 17 /* LASX Disabled */
> > >
> > > +#define EXC_FPE 18 /* Floating Point Exception */
> > >
> > > +#define EXC_WATCH 19 /* Watch address reference */
> > >
> > > +#define EXC_BAD 255 /* Undecodeable */
> > >
> > > +
> > >
> > > +#define COPY_SIGCODE // copy sigcode above user stack in exec
> > >
> > > +#define ZERO $r0 /* wired zero */
> > >
> > > +#define RA $r1 /* return address */
> > >
> > > +#define GP $r2 /* global pointer - caller saved for PIC */
> > >
> > > +#define SP $r3 /* stack pointer */
> > >
> > > +#define V0 $r4 /* return value - caller saved */
> > >
> > > +#define V1 $r5
> > >
> > > +#define A0 $r4 /* argument registers */
> > >
> > > +#define A1 $r5
> > >
> > > +#define A2 $r6
> > >
> > > +#define A3 $r7
> > >
> > > +#define A4 $r8 /* arg reg 64 bit; caller saved in 32 bit */
> > >
> > > +#define A5 $r9
> > >
> > > +#define A6 $r10
> > >
> > > +#define A7 $r11
> > >
> > > +#define T0 $r12 /* caller saved */
> > >
> > > +#define T1 $r13
> > >
> > > +#define T2 $r14
> > >
> > > +#define T3 $r15
> > >
> > > +#define T4 $r16 /* callee saved */
> > >
> > > +#define T5 $r17
> > >
> > > +#define T6 $r18
> > >
> > > +#define T7 $r19
> > >
> > > +#define T8 $r20 /* caller saved */
> > >
> > > +#define TP $r21 /* TLS */
> > >
> > > +#define FP $r22 /* frame pointer */
> > >
> > > +#define S0 $r23 /* callee saved */
> > >
> > > +#define S1 $r24
> > >
> > > +#define S2 $r25
> > >
> > > +#define S3 $r26
> > >
> > > +#define S4 $r27
> > >
> > > +#define S5 $r28
> > >
> > > +#define S6 $r29
> > >
> > > +#define S7 $r30
> > >
> > > +#define S8 $r31 /* callee saved */
> > >
> > > +
> > >
> > > +#define FCSR0 $r0
> > >
> > > +
> > >
> > > +//
> > >
> > > +// Location of the saved registers relative to ZERO.
> > >
> > > +// Usage is p->p_regs[XX].
> > >
> > > +//
> > >
> > > +#define RA_NUM 1
> > >
> > > +#define GP_NUM 2
> > >
> > > +#define SP_NUM 3
> > >
> > > +#define A0_NUM 4
> > >
> > > +#define A1_NUM 5
> > >
> > > +#define A2_NUM 6
> > >
> > > +#define A3_NUM 7
> > >
> > > +#define A4_NUM 8
> > >
> > > +#define A5_NUM 9
> > >
> > > +#define A6_NUM 10
> > >
> > > +#define A7_NUM 11
> > >
> > > +#define T0_NUM 12
> > >
> > > +#define T1_NUM 13
> > >
> > > +#define T2_NUM 14
> > >
> > > +#define T3_NUM 15
> > >
> > > +#define T4_NUM 16
> > >
> > > +#define T5_NUM 17
> > >
> > > +#define T6_NUM 18
> > >
> > > +#define T7_NUM 19
> > >
> > > +#define T8_NUM 20
> > >
> > > +#define TP_NUM 21
> > >
> > > +#define FP_NUM 22
> > >
> > > +#define S0_NUM 23
> > >
> > > +#define S1_NUM 24
> > >
> > > +#define S2_NUM 25
> > >
> > > +#define S3_NUM 26
> > >
> > > +#define S4_NUM 27
> > >
> > > +#define S5_NUM 28
> > >
> > > +#define S6_NUM 29
> > >
> > > +#define S7_NUM 30
> > >
> > > +#define S8_NUM 31
> > >
> > > +
> > >
> > > +#define FP0_NUM 0
> > >
> > > +#define FP1_NUM 1
> > >
> > > +#define FP2_NUM 2
> > >
> > > +#define FP3_NUM 3
> > >
> > > +#define FP4_NUM 4
> > >
> > > +#define FP5_NUM 5
> > >
> > > +#define FP6_NUM 6
> > >
> > > +#define FP7_NUM 7
> > >
> > > +#define FP8_NUM 8
> > >
> > > +#define FP9_NUM 9
> > >
> > > +#define FP10_NUM 10
> > >
> > > +#define FP11_NUM 11
> > >
> > > +#define FP12_NUM 12
> > >
> > > +#define FP13_NUM 13
> > >
> > > +#define FP14_NUM 14
> > >
> > > +#define FP15_NUM 15
> > >
> > > +#define FP16_NUM 16
> > >
> > > +#define FP17_NUM 17
> > >
> > > +#define FP18_NUM 18
> > >
> > > +#define FP19_NUM 19
> > >
> > > +#define FP20_NUM 20
> > >
> > > +#define FP21_NUM 21
> > >
> > > +#define FP22_NUM 22
> > >
> > > +#define FP23_NUM 23
> > >
> > > +#define FP24_NUM 24
> > >
> > > +#define FP25_NUM 25
> > >
> > > +#define FP26_NUM 26
> > >
> > > +#define FP27_NUM 27
> > >
> > > +#define FP28_NUM 28
> > >
> > > +#define FP29_NUM 29
> > >
> > > +#define FP30_NUM 30
> > >
> > > +#define FP31_NUM 31
> > >
> > > +#define FCSR_NUM 32
> > >
> > > +#define FCC_NUM 33
> > >
> > > +
> > >
> > > +#ifdef __ASSEMBLY__
> > >
> > > +#define _ULCAST_
> > >
> > > +#define _U64CAST_
> > >
> > > +#else
> > >
> > > +#define _ULCAST_ (unsigned long)
> > >
> > > +#define _U64CAST_ (u64)
> > >
> > > +#endif
> > >
> > > +
> > >
> > > +#define LOONGARCH_CSR_CRMD 0
> > >
> > > +#define LOONGARCH_CSR_PRMD 1
> > >
> > > +#define LOONGARCH_CSR_EUEN 2
> > >
> > > +#define CSR_EUEN_LBTEN_SHIFT 3
> > >
> > > +#define CSR_EUEN_LBTEN (_ULCAST_(0x1) <<
> > > CSR_EUEN_LBTEN_SHIFT)
> > >
> > > +#define CSR_EUEN_LASXEN_SHIFT 2
> > >
> > > +#define CSR_EUEN_LASXEN (_ULCAST_(0x1) <<
> > > CSR_EUEN_LASXEN_SHIFT)
> > >
> > > +#define CSR_EUEN_LSXEN_SHIFT 1
> > >
> > > +#define CSR_EUEN_LSXEN (_ULCAST_(0x1) <<
> > > CSR_EUEN_LSXEN_SHIFT)
> > >
> > > +#define CSR_EUEN_FPEN_SHIFT 0
> > >
> > > +#define CSR_EUEN_FPEN (_ULCAST_(0x1) <<
> > > CSR_EUEN_FPEN_SHIFT)
> > >
> > > +#define LOONGARCH_CSR_ECFG 4
> > >
> > > +
> > >
> > > +/* Exception status */
> > >
> > > +#define LOONGARCH_CSR_ESTAT 5
> > >
> > > +#define CSR_ESTAT_ESUBCODE_SHIFT 22
> > >
> > > +#define CSR_ESTAT_ESUBCODE_WIDTH 9
> > >
> > > +#define CSR_ESTAT_ESUBCODE (_ULCAST_(0x1ff) <<
> > > CSR_ESTAT_ESUBCODE_SHIFT)
> > >
> > > +#define CSR_ESTAT_EXC_SHIFT 16
> > >
> > > +#define CSR_ESTAT_EXC_WIDTH 6
> > >
> > > +#define CSR_ESTAT_EXC (_ULCAST_(0x3f) <<
> > > CSR_ESTAT_EXC_SHIFT)
> > >
> > > +#define CSR_ESTAT_IS_SHIFT 0
> > >
> > > +#define CSR_ESTAT_IS_WIDTH 15
> > >
> > > +#define CSR_ESTAT_IS (_ULCAST_(0x7fff) <<
> > > CSR_ESTAT_IS_SHIFT)
> > >
> > > +#define LOONGARCH_CSR_EPC 6
> > >
> > > +#define LOONGARCH_CSR_BADV 7
> > >
> > > +#define LOONGARCH_CSR_BADINST 8
> > >
> > > +#define LOONGARCH_CSR_BADI 8
> > >
> > > +#define LOONGARCH_CSR_EBASE 0xc /* Exception entry base
> > > address */
> > >
> > > +#define LOONGARCH_CSR_CPUNUM 0x20 /* CPU core number */
> > >
> > > +
> > >
> > > +/* register number save in stack on exception */
> > >
> > > +#define FP_BASE_NUM 34
> > >
> > > +#define BASE_NUM 32
> > >
> > > +#define CSR_NUM 10
> > >
> > > +#define FP_BASE_INDEX (CSR_NUM + BASE_NUM)
> > >
> > > +#define BOOTCORE_ID 0
> > >
> > > +
> > >
> > > +#define LOONGSON_IOCSR_IPI_STATUS 0x1000
> > >
> > > +#define LOONGSON_IOCSR_IPI_EN 0x1004
> > >
> > > +#define LOONGSON_IOCSR_IPI_SET 0x1008
> > >
> > > +#define LOONGSON_IOCSR_IPI_CLEAR 0x100c
> > >
> > > +#define LOONGSON_CSR_MAIL_BUF0 0x1020
> > >
> > > +#define LOONGSON_CSR_MAIL_BUF1 0x1028
> > >
> > > +#define LOONGSON_CSR_MAIL_BUF2 0x1030
> > >
> > > +#define LOONGSON_CSR_MAIL_BUF3 0x1038
> > >
> > > +
> > >
> > > +/* Bit Domains for CFG registers */
> > >
> > > +#define LOONGARCH_CPUCFG4 0x4
> > >
> > > +#define LOONGARCH_CPUCFG5 0x5
> > >
> > > +
> > >
> > > +/* Kscratch registers */
> > >
> > > +#define LOONGARCH_CSR_KS0 0x30
> > >
> > > +#define LOONGARCH_CSR_KS1 0x31
> > >
> > > +
> > >
> > > +/* Stable timer registers */
> > >
> > > +#define LOONGARCH_CSR_TMCFG 0x41
> > >
> > > +#define LOONGARCH_CSR_TMCFG_EN (1ULL << 0)
> > >
> > > +#define LOONGARCH_CSR_TMCFG_PERIOD (1ULL << 1)
> > >
> > > +#define LOONGARCH_CSR_TMCFG_TIMEVAL (0x3fffffffffffULL << 2)
> > >
> > > +#define LOONGARCH_CSR_TVAL 0x42 /* Timer value */
> > >
> > > +#define LOONGARCH_CSR_CNTC 0x43 /* Timer offset */
> > >
> > > +#define LOONGARCH_CSR_TINTCLR 0x44 /* Timer interrupt
> > > clear */
> > >
> > > +
> > >
> > > +/* TLB refill exception base address */
> > >
> > > +#define LOONGARCH_CSR_TLBREBASE 0x88
> > >
> > > +#define LOONGARCH_CSR_TLBRSAVE 0x8b /* KScratch for TLB
> > > refill exception */
> > >
> > > +#define LOONGARCH_CSR_PGD 0x1b /* Page table base */
> > >
> > > +
> > >
> > > +/* Bits 8 and 9 of FPU Status Register specify the rounding mode */
> > >
> > > +#define FPU_CSR_RM 0x300
> > >
> > > +#define FPU_CSR_RN 0x000 /* nearest */
> > >
> > > +#define FPU_CSR_RZ 0x100 /* towards zero */
> > >
> > > +#define FPU_CSR_RU 0x200 /* towards +Infinity */
> > >
> > > +#define FPU_CSR_RD 0x300 /* towards -Infinity */
> > >
> > > +
> > >
> > > +/*
> > >
> > > + Reads data from the specified CSR register.
> > >
> > > +
> > >
> > > + @param[OUT] val The value is read from the CSR specified register.
> > >
> > > + @param[IN] reg Specifies the register number of the CSR to read
> > > the data.
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_CSR_READQ(val, reg) \
> > >
> > > +do { \
> > >
> > > + UINT64 __res; \
> > >
> > > + /* csrrd rd, csr_num */ \
> > >
> > > + __asm__ __volatile__( \
> > >
> > > + "csrrd %0, %1 \n\t" \
> > >
> > > + :"=r"(__res) \
> > >
> > > + :"i"(reg) \
> > >
> > > + : \
> > >
> > > + ); \
> > >
> > > + (val) = __res; \
> > >
> > > +} while(0)
> > >
> > > +
> > >
> > > +/*
> > >
> > > + Write data to the specified CSR register.
> > >
> > > +
> > >
> > > + @param[OUT] val The value is write to the CSR specified register.
> > >
> > > + @param[IN] reg Specifies the register number of the CSR to write
> > > the data.
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_CSR_WRITEQ(val, reg) \
> > >
> > > +do { \
> > >
> > > + UINT64 __val = val; \
> > >
> > > + /* csrwr rd, csr_num */ \
> > >
> > > + __asm__ __volatile__( \
> > >
> > > + "csrwr %0, %1 \n\t" \
> > >
> > > + : "+r"(__val) \
> > >
> > > + : "i"(reg), "r"(__val) \
> > >
> > > + : "memory" \
> > >
> > > + ); \
> > >
> > > +} while(0)
> > >
> > > +
> > >
> > > +/*
> > >
> > > + Exchange specified bit data with the specified CSR registers
> > >
> > > +
> > >
> > > + @param[IN] val The value Exchanged with the CSR specified
> > > register.
> > >
> > > + @param[IN] mask Specifies the mask for swapping bits
> > >
> > > + @param[IN] reg Specifies the register number of the CSR to
> > > Exchange the data.
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_CSR_XCHGQ(val, mask, reg) \
> > >
> > > +do { \
> > >
> > > + UINT64 __val = val; \
> > >
> > > + UINT64 __mask = mask; \
> > >
> > > + /* csrwr rd, csr_num */ \
> > >
> > > + __asm__ __volatile__( \
> > >
> > > + "csrxchg %0, %1, %2 \n\t" \
> > >
> > > + : "+r"(__val) \
> > >
> > > + : "r"(__mask), "i"(reg), "r"(__val) \
> > >
> > > + : "memory" \
> > >
> > > + ); \
> > >
> > > +} while(0)
> > >
> > > +/*
> > >
> > > + Reads data from the specified CPUCFG register.
> > >
> > > +
> > >
> > > + @param[OUT] val The value is read from the CPUCFG specified
> > > register.
> > >
> > > + @param[IN] reg Specifies the register number of the CPUCFG to
> > > read the data.
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_GET_CPUCFG(val, reg) \
> > >
> > > +do { \
> > >
> > > + UINT64 __res; \
> > >
> > > + /* cpucfg rd, rj */ \
> > >
> > > + __asm__ __volatile__( \
> > >
> > > + "cpucfg %0, %1 \n\t" \
> > >
> > > + :"=r"(__res) \
> > >
> > > + :"r"(reg) \
> > >
> > > + : \
> > >
> > > + ); \
> > >
> > > + val = (UINT32)__res; \
> > >
> > > +} while(0)
> > >
> > > +
> > >
> > > +/*
> > >
> > > + Enables floating-point unit
> > >
> > > +
> > >
> > > + @param VOID
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_ENABLR_FPU() \
> > >
> > > +do { \
> > >
> > > + LOONGARCH_CSR_XCHGQ(CSR_EUEN_FPEN, \
> > >
> > > + CSR_EUEN_FPEN, \
> > >
> > > + LOONGARCH_CSR_EUEN); \
> > >
> > > +} while (0)
> > >
> > > +
> > >
> > > +/*
> > >
> > > + Disable floating-point unit
> > >
> > > +
> > >
> > > + @param VOID
> > >
> > > +
> > >
> > > + @retval VOID
> > >
> > > + */
> > >
> > > +#define LOONGARCH_DISABLE_FPU() \
> > >
> > > +do { \
> > >
> > > + LOONGARCH_CSR_XCHGQ(0, \
> > >
> > > + CSR_EUEN_FPEN, \
> > >
> > > + LOONGARCH_CSR_EUEN); \
> > >
> > > +} while (0)
> > >
> > > +
> > >
> > > +#endif
> > >
> > > diff --git
> > > a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.
> > > h
> > > b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.
> > > h
> > > new file mode 100644
> > > index 0000000000..62b81d88c3
> > > --- /dev/null
> > > +++
> > > b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.
> > > h
> > > @@ -0,0 +1,103 @@
> > > +/** @file
> > >
> > > + LoongArch Qemu Platform macro definition.
> > >
> > > +
> > >
> > > + Copyright (c) 2021, Loongson Limited. All rights reserved.
> > >
> > > +
> > >
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > + **/
> > >
> > > +
> > >
> > > +#ifndef LOONGARCH_QEMU_PLATFORM_H_
> > >
> > > +#define LOONGARCH_QEMU_PLATFORM_H_
> > >
> > > +
> > >
> > > +
> > >
> > > +/* Acpi pm device */
> > >
> > > +#define LS7A_PCH_REG_BASE 0x10000000UL
> > >
> > > +#define LS7A_ACPI_REG_BASE (LS7A_PCH_REG_BASE +
> > > 0x000D0000)
> > >
> > > +#define LS7A_PM_CNT_BLK (0x14) /* 2 bytes */
> > >
> > > +#define LS7A_GPE0_RESET_REG (0x30) /* 4 bytes */
> > >
> > > +
> > >
> > > +#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
> > >
> > > +#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
> > >
> > > +
> > >
> > > +
> > >
> > > +//---------------------------------------------
> > >
> > > +// UART Register Offsets
> > >
> > > +//---------------------------------------------
> > >
> > > +#define BAUD_LOW_OFFSET 0x00
> > >
> > > +#define BAUD_HIGH_OFFSET 0x01
> > >
> > > +#define IER_OFFSET 0x01
> > >
> > > +#define LCR_SHADOW_OFFSET 0x01
> > >
> > > +#define FCR_SHADOW_OFFSET 0x02
> > >
> > > +#define IR_CONTROL_OFFSET 0x02
> > >
> > > +#define FCR_OFFSET 0x02
> > >
> > > +#define EIR_OFFSET 0x02
> > >
> > > +#define BSR_OFFSET 0x03
> > >
> > > +#define LCR_OFFSET 0x03
> > >
> > > +#define MCR_OFFSET 0x04
> > >
> > > +#define LSR_OFFSET 0x05
> > >
> > > +#define MSR_OFFSET 0x06
> > >
> > > +
> > >
> > > +/* character format control register */
> > >
> > > +#define CFCR_DLAB 0x80 /* divisor latch */
> > >
> > > +#define CFCR_SBREAK 0x40 /* send break */
> > >
> > > +#define CFCR_PZERO 0x30 /* zero parity */
> > >
> > > +#define CFCR_PONE 0x20 /* one parity */
> > >
> > > +#define CFCR_PEVEN 0x10 /* even parity */
> > >
> > > +#define CFCR_PODD 0x00 /* odd parity */
> > >
> > > +#define CFCR_PENAB 0x08 /* parity enable */
> > >
> > > +#define CFCR_STOPB 0x04 /* 2 stop bits */
> > >
> > > +#define CFCR_8BITS 0x03 /* 8 data bits */
> > >
> > > +#define CFCR_7BITS 0x02 /* 7 data bits */
> > >
> > > +#define CFCR_6BITS 0x01 /* 6 data bits */
> > >
> > > +#define CFCR_5BITS 0x00 /* 5 data bits */
> > >
> > > +/* modem control register */
> > >
> > > +#define MCR_LOOPBACK 0x10 /* loopback */
> > >
> > > +#define MCR_IENABLE 0x08 /* output 2 = int enable */
> > >
> > > +#define MCR_DRS 0x04 /* output 1 = xxx */
> > >
> > > +#define MCR_RTS 0x02 /* enable RTS */
> > >
> > > +#define MCR_DTR 0x01 /* enable DTR */
> > >
> > > +
> > >
> > > +/* line status register */
> > >
> > > +#define LSR_RCV_FIFO 0x80 /* error in receive fifo */
> > >
> > > +#define LSR_TSRE 0x40 /* transmitter empty */
> > >
> > > +#define LSR_TXRDY 0x20 /* transmitter ready */
> > >
> > > +#define LSR_BI 0x10 /* break detected */
> > >
> > > +#define LSR_FE 0x08 /* framing error */
> > >
> > > +#define LSR_PE 0x04 /* parity error */
> > >
> > > +#define LSR_OE 0x02 /* overrun error */
> > >
> > > +#define LSR_RXRDY 0x01 /* receiver ready */
> > >
> > > +#define LSR_RCV_MASK 0x1f
> > >
> > > +
> > >
> > > +/* 16550 UART register offsets and bitfields */
> > >
> > > +#define R_UART_RXBUF 0
> > >
> > > +#define R_UART_TXBUF 0
> > >
> > > +#define R_UART_BAUD_LOW 0
> > >
> > > +#define R_UART_BAUD_HIGH 1
> > >
> > > +#define R_UART_FCR 2
> > >
> > > +#define B_UART_FCR_FIFOE BIT0
> > >
> > > +#define B_UART_FCR_FIFO64 BIT5
> > >
> > > +#define R_UART_LCR 3
> > >
> > > +#define B_UART_LCR_DLAB BIT7
> > >
> > > +#define R_UART_MCR 4
> > >
> > > +#define B_UART_MCR_DTRC BIT0
> > >
> > > +#define B_UART_MCR_RTS BIT1
> > >
> > > +#define R_UART_LSR 5
> > >
> > > +#define B_UART_LSR_RXRDY BIT0
> > >
> > > +#define B_UART_LSR_TXRDY BIT5
> > >
> > > +#define B_UART_LSR_TEMT BIT6
> > >
> > > +#define R_UART_MSR 6
> > >
> > > +#define B_UART_MSR_CTS BIT4
> > >
> > > +#define B_UART_MSR_DSR BIT5
> > >
> > > +#define B_UART_MSR_RI BIT6
> > >
> > > +#define B_UART_MSR_DCD BIT7
> > >
> > > +#define UART_BASE_ADDRESS (0x1fe001e0)
> > >
> > > +#define UART_BPS (115200)
> > >
> > > +#define UART_WAIT_TIMOUT (1000000)
> > >
> > > +//---------------------------------------------
> > >
> > > +// UART Settings
> > >
> > > +//---------------------------------------------
> > >
> > > +#define PHYS_TO_CACHED(x) ((x))
> > >
> > > +#define PHYS_TO_UNCACHED(x) ((x))
> > >
> > > +
> > >
> > > +#endif
> > >
> > > diff --git
> > > a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .c
> > > b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .c
> > > new file mode 100644
> > > index 0000000000..5b2f3a8194
> > > --- /dev/null
> > > +++
> > > b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .c
> > > @@ -0,0 +1,612 @@
> > > +/** @file
> > >
> > > + UART Serial Port library functions
> > >
> > > +
> > >
> > > + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights
> > > reserved.<BR>
> > >
> > > +
> > >
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > + @par Glossary:
> > >
> > > + - Bps - Bit Per Second
> > >
> > > + - CTL - Control
> > >
> > > + - Config - Configure
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include <Base.h>
> > >
> > > +#include <Library/Cpu.h>
> > >
> > > +#include <Library/IoLib.h>
> > >
> > > +#include <Library/SerialPortLib.h>
> > >
> > > +#include <LoongArchQemuPlatform.h>
> > >
> > > +
> > >
> > > +UINTN gUartBase = PHYS_TO_UNCACHED(UART_BASE_ADDRESS);
> > >
> > > +UINTN gBps = UART_BPS;
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Initialize the serial device hardware.
> > >
> > > +
> > >
> > > + If no initialization is required, then return RETURN_SUCCESS.
> > >
> > > + If the serial device was successfuly initialized, then return
> > > RETURN_SUCCESS.
> > >
> > > + If the serial device could not be initialized, then return
> > > RETURN_DEVICE_ERROR.
> > >
> > > +
> > >
> > > + @retval RETURN_SUCCESS The serial device was initialized.
> > >
> > > + @retval RETURN_DEVICE_ERROR The serail device could not be
> > > initialized.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +RETURN_STATUS
> > >
> > > +EFIAPI
> > >
> > > +SerialPortInitialize (
> > >
> > > + VOID
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN TimeOut;
> > >
> > > + //
> > >
> > > + // wait for Tx fifo to completely drain */
> > >
> > > + //
> > >
> > > + TimeOut = UART_WAIT_TIMOUT;
> > >
> > > + while (!(MmioRead8 ((UINTN) gUartBase + LSR_OFFSET) & LSR_TSRE)) {
> > >
> > > + if (--TimeOut == 0) {
> > >
> > > + break;
> > >
> > > + }
> > >
> > > + }
> > >
> > > + //
> > >
> > > + // Set communications format
> > >
> > > + //
> > >
> > > + MmioWrite8 ((UINTN) (gUartBase + LCR_OFFSET), CFCR_DLAB);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Configure baud rate
> > >
> > > + //
> > >
> > > +
> > >
> > > +
> > >
> > > + MmioWrite8 ((UINTN) (gUartBase + LCR_OFFSET), CFCR_8BITS);
> > >
> > > + MmioWrite8 ((UINTN) (gUartBase + MCR_OFFSET), MCR_IENABLE |
> > > MCR_DTR | MCR_RTS);
> > >
> > > + //
> > >
> > > + // if enable interrupt the kernel of lemote will error in STR mode
> > during
> > > wake up phase.
> > >
> > > + //
> > >
> > > + //MmioWrite8 ((UINTN) (gUartBase + IER_OFFSET), CFCR_8BITS);
> > >
> > > +
> > >
> > > + return RETURN_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Write data from buffer to serial device.
> > >
> > > +
> > >
> > > + Writes NumberOfBytes data bytes from Buffer to the serial device.
> > >
> > > + The number of bytes actually written to the serial device is returned.
> > >
> > > + If the return value is less than NumberOfBytes, then the write
> > operation
> > > failed.
> > >
> > > +
> > >
> > > + If Buffer is NULL, then ASSERT ().
> > >
> > > +
> > >
> > > + If NumberOfBytes is zero, then return 0.
> > >
> > > +
> > >
> > > + @param Buffer Pointer to the data buffer to be written.
> > >
> > > + @param NumberOfBytes Number of bytes to written to the serial
> > > device.
> > >
> > > +
> > >
> > > + @retval 0 NumberOfBytes is 0.
> > >
> > > + @retval >0 The number of bytes written to the serial
> > > device.
> > >
> > > + If this value is less than NumberOfBytes,
> > > then the read operation failed.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +UartCtlWrite (
> > >
> > > + IN UINT8 *Buffer,
> > >
> > > + IN UINTN NumberOfBytes,
> > >
> > > + IN UINTN CtlAddr
> > >
> > > +)
> > >
> > > +{
> > >
> > > + UINTN Result;
> > >
> > > + UINT8 Data;
> > >
> > > +
> > >
> > > + if (Buffer == NULL) {
> > >
> > > + return 0;
> > >
> > > + }
> > >
> > > +
> > >
> > > + Result = NumberOfBytes;
> > >
> > > +
> > >
> > > + while (NumberOfBytes--) {
> > >
> > > + //
> > >
> > > + // Wait for the serail port to be ready.
> > >
> > > + //
> > >
> > > + do {
> > >
> > > + Data = MmioRead8 (CtlAddr + LSR_OFFSET);
> > >
> > > + } while ((Data & LSR_TXRDY) == 0);
> > >
> > > + MmioWrite8 (CtlAddr, *Buffer++);
> > >
> > > + }
> > >
> > > +
> > >
> > > + return Result;
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Writes data to serial port.
> > >
> > > +
> > >
> > > + @param Buffer Pointer to the data buffer to store the data
> > > writed to serial port.
> > >
> > > + @param NumberOfBytes Number of bytes to write to the serial
> > > port.
> > >
> > > +
> > >
> > > + @retval 0 NumberOfBytes is 0.
> > >
> > > + @retval >0 The number of bytes write the serial port.
> > >
> > > + If this value is less than NumberOfBytes,
> > > then the write operation failed.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +SerialPortWrite (
> > >
> > > + IN UINT8 *Buffer,
> > >
> > > + IN UINTN NumberOfBytes
> > >
> > > +)
> > >
> > > +{
> > >
> > > + return UartCtlWrite (Buffer, NumberOfBytes, gUartBase);
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Reads data from a serial device into a buffer.
> > >
> > > +
> > >
> > > + @param Buffer Pointer to the data buffer to store the data
> > > read from the serial device.
> > >
> > > + @param NumberOfBytes Number of bytes to read from the serial
> > > device.
> > >
> > > +
> > >
> > > + @retval 0 NumberOfBytes is 0.
> > >
> > > + @retval >0 The number of bytes read from the serial
> > > device.
> > >
> > > + If this value is less than NumberOfBytes,
> > > then the read operation failed.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +UartCtlRead (
> > >
> > > + OUT UINT8 *Buffer,
> > >
> > > + IN UINTN NumberOfBytes,
> > >
> > > + IN UINTN CtlAddr
> > >
> > > +)
> > >
> > > +{
> > >
> > > + UINTN Result;
> > >
> > > + UINT8 Data;
> > >
> > > +
> > >
> > > + if (NULL == Buffer) {
> > >
> > > + return 0;
> > >
> > > + }
> > >
> > > +
> > >
> > > + Result = NumberOfBytes;
> > >
> > > +
> > >
> > > + while (NumberOfBytes--) {
> > >
> > > + //
> > >
> > > + // Wait for the serail port to be ready.
> > >
> > > + //
> > >
> > > + do {
> > >
> > > + Data = MmioRead8 (CtlAddr + LSR_OFFSET);
> > >
> > > + } while ((Data & LSR_RXRDY) == 0);
> > >
> > > +
> > >
> > > + *Buffer++ = MmioRead8 (CtlAddr);
> > >
> > > + }
> > >
> > > +
> > >
> > > + return Result;
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Read data from serial port.
> > >
> > > +
> > >
> > > + @param Buffer Pointer to the data buffer to store the data
> > > read from serial port.
> > >
> > > + @param NumberOfBytes Number of bytes to read from the serial
> > > port.
> > >
> > > +
> > >
> > > + @retval 0 NumberOfBytes is 0.
> > >
> > > + @retval >0 The number of bytes read from the serial
> > > port.
> > >
> > > + If this value is less than NumberOfBytes,
> > > then the read operation failed.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +SerialPortRead (
> > >
> > > + OUT UINT8 *Buffer,
> > >
> > > + IN UINTN NumberOfBytes
> > >
> > > +)
> > >
> > > +{
> > >
> > > + return UartCtlRead (Buffer, NumberOfBytes, gUartBase);
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Polls a serial device to see if there is any data waiting to be read.
> > >
> > > +
> > >
> > > + Polls aserial device to see if there is any data waiting to be read.
> > >
> > > + If there is data waiting to be read from the serial device, then TRUE
> > is
> > > returned.
> > >
> > > + If there is no data waiting to be read from the serial device, then
> > FALSE is
> > > returned.
> > >
> > > +
> > >
> > > + @retval TRUE Data is waiting to be read from the serial
> > > device.
> > >
> > > + @retval FALSE There is no data waiting to be read from the
> > > serial device.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +SerialPortPoll (
> > >
> > > + VOID
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINT8 Data;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Read the serial port status.
> > >
> > > + //
> > >
> > > + Data = MmioRead8 ((UINTN) gUartBase + LSR_OFFSET);
> > >
> > > +
> > >
> > > + return (BOOLEAN) ((Data & LSR_RXRDY) != 0);
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + To get serial register base address.
> > >
> > > +
> > >
> > > + @param VOID
> > >
> > > +
> > >
> > > + @return serial register base address.
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +GetSerialRegisterBase (
> > >
> > > + VOID
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return gUartBase;
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Read an 8-bit register.
> > >
> > > + @param Base The base address register of UART device.
> > >
> > > + @param Offset The offset of the register to read.
> > >
> > > +
> > >
> > > + @return The value read from the 16550 register.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINT8
> > >
> > > +SerialPortReadRegister (
> > >
> > > + UINTN Base,
> > >
> > > + UINTN Offset
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return MmioRead8 (Base + Offset);
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Write an 8-bit register.
> > >
> > > + @param Base The base address register of UART device.
> > >
> > > + @param Offset The offset of the register to write.
> > >
> > > + @param Value The value to write to the register specified by Offset.
> > >
> > > +
> > >
> > > + @return The value written to the 16550 register.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINT8
> > >
> > > +SerialPortWriteRegister (
> > >
> > > + UINTN Base,
> > >
> > > + UINTN Offset,
> > >
> > > + UINT8 Value
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return MmioWrite8 (Base + Offset, Value);
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Sets the control bits on a serial device.
> > >
> > > +
> > >
> > > + @param Control Sets the bits of Control that are
> > > settable.
> > >
> > > +
> > >
> > > + @retval RETURN_SUCCESS The new control bits were set on the
> > > serial device.
> > >
> > > + @retval RETURN_UNSUPPORTED The serial device does not support
> > > this operation.
> > >
> > > + @retval RETURN_DEVICE_ERROR The serial device is not functioning
> > > correctly.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +RETURN_STATUS
> > >
> > > +EFIAPI
> > >
> > > +SerialPortSetControl (
> > >
> > > + IN UINT32 Control
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN SerialRegisterBase;
> > >
> > > + UINT8 Mcr;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // First determine the parameter is invalid.
> > >
> > > + //
> > >
> > > + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND |
> > > EFI_SERIAL_DATA_TERMINAL_READY |
> > >
> > > +
> > > EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0)
> > >
> > > + {
> > >
> > > + return RETURN_UNSUPPORTED;
> > >
> > > + }
> > >
> > > +
> > >
> > > + SerialRegisterBase = GetSerialRegisterBase ();
> > >
> > > + if (SerialRegisterBase ==0) {
> > >
> > > + return RETURN_UNSUPPORTED;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Read the Modem Control Register.
> > >
> > > + //
> > >
> > > + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> > >
> > > + Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
> > >
> > > +
> > >
> > > + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) ==
> > > EFI_SERIAL_DATA_TERMINAL_READY) {
> > >
> > > + Mcr |= B_UART_MCR_DTRC;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) ==
> > > EFI_SERIAL_REQUEST_TO_SEND) {
> > >
> > > + Mcr |= B_UART_MCR_RTS;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Write the Modem Control Register.
> > >
> > > + //
> > >
> > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
> > >
> > > +
> > >
> > > + return RETURN_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Retrieve the status of the control bits on a serial device.
> > >
> > > +
> > >
> > > + @param Control A pointer to return the current
> > > control signals from the serial device.
> > >
> > > +
> > >
> > > + @retval RETURN_SUCCESS The control bits were read from the
> > > serial device.
> > >
> > > + @retval RETURN_UNSUPPORTED The serial device does not support
> > > this operation.
> > >
> > > + @retval RETURN_DEVICE_ERROR The serial device is not functioning
> > > correctly.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +RETURN_STATUS
> > >
> > > +EFIAPI
> > >
> > > +SerialPortGetControl (
> > >
> > > + OUT UINT32 *Control
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN SerialRegisterBase;
> > >
> > > + UINT8 Msr;
> > >
> > > + UINT8 Mcr;
> > >
> > > + UINT8 Lsr;
> > >
> > > +
> > >
> > > + SerialRegisterBase = GetSerialRegisterBase ();
> > >
> > > + if (SerialRegisterBase ==0) {
> > >
> > > + return RETURN_UNSUPPORTED;
> > >
> > > + }
> > >
> > > +
> > >
> > > + *Control = 0;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Read the Modem Status Register.
> > >
> > > + //
> > >
> > > + Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR);
> > >
> > > +
> > >
> > > + if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
> > >
> > > + *Control |= EFI_SERIAL_CLEAR_TO_SEND;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
> > >
> > > + *Control |= EFI_SERIAL_DATA_SET_READY;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
> > >
> > > + *Control |= EFI_SERIAL_RING_INDICATE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
> > >
> > > + *Control |= EFI_SERIAL_CARRIER_DETECT;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Read the Modem Control Register.
> > >
> > > + //
> > >
> > > + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> > >
> > > +
> > >
> > > + if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
> > >
> > > + *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
> > >
> > > + *Control |= EFI_SERIAL_REQUEST_TO_SEND;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> > >
> > > + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Read the Line Status Register.
> > >
> > > + //
> > >
> > > + Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR);
> > >
> > > +
> > >
> > > + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) ==
> > > (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
> > >
> > > + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if ((Lsr & B_UART_LSR_RXRDY) == 0) {
> > >
> > > + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return RETURN_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Sets the baud rate, receive FIFO depth, transmit/receice time out,
> > parity,
> > >
> > > + data bits, and stop bits on a serial device.
> > >
> > > +
> > >
> > > + @param BaudRate The requested baud rate. A BaudRate
> > > value of 0 will use the
> > >
> > > + device's default interface speed.
> > >
> > > + On output, the value actually set.
> > >
> > > + @param ReveiveFifoDepth The requested depth of the FIFO on the
> > > receive side of the
> > >
> > > + serial interface. A ReceiveFifoDepth value
> > > of 0 will use
> > >
> > > + the device's default FIFO depth.
> > >
> > > + On output, the value actually set.
> > >
> > > + @param Timeout The requested time out for a single
> > > character in microseconds.
> > >
> > > + This timeout applies to both the transmit
> > > and receive side of the
> > >
> > > + interface. A Timeout value of 0 will use
> > > the device's default time
> > >
> > > + out value.
> > >
> > > + On output, the value actually set.
> > >
> > > + @param Parity The type of parity to use on this serial
> > > device. A Parity value of
> > >
> > > + DefaultParity will use the device's default
> > > parity value.
> > >
> > > + On output, the value actually set.
> > >
> > > + @param DataBits The number of data bits to use on the
> > > serial device. A DataBits
> > >
> > > + vaule of 0 will use the device's default
> > > data bit setting.
> > >
> > > + On output, the value actually set.
> > >
> > > + @param StopBits The number of stop bits to use on this
> > > serial device. A StopBits
> > >
> > > + value of DefaultStopBits will use the
> > > device's default number of
> > >
> > > + stop bits.
> > >
> > > + On output, the value actually set.
> > >
> > > +
> > >
> > > + @retval RETURN_SUCCESS The new attributes were set on
> > > the serial device.
> > >
> > > + @retval RETURN_UNSUPPORTED The serial device does not
> > > support this operation.
> > >
> > > + @retval RETURN_INVALID_PARAMETER One or more of the attributes
> > > has an unsupported value.
> > >
> > > + @retval RETURN_DEVICE_ERROR The serial device is not
> > > functioning correctly.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +RETURN_STATUS
> > >
> > > +EFIAPI
> > >
> > > +UartCtlConfig (
> > >
> > > + IN OUT UINT64 *BaudRate,
> > >
> > > + IN OUT UINT32 *ReceiveFifoDepth,
> > >
> > > + IN OUT UINT32 *Timeout,
> > >
> > > + IN OUT EFI_PARITY_TYPE *Parity,
> > >
> > > + IN OUT UINT8 *DataBits,
> > >
> > > + IN OUT EFI_STOP_BITS_TYPE *StopBits,
> > >
> > > + IN UINTN CtlAddr
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN SerialRegisterBase;
> > >
> > > + UINT8 Lcr;
> > >
> > > + UINT8 LcrData;
> > >
> > > + UINT8 LcrParity;
> > >
> > > + UINT8 LcrStop;
> > >
> > > +
> > >
> > > +
> > >
> > > + SerialRegisterBase = CtlAddr;
> > >
> > > + if (SerialRegisterBase ==0) {
> > >
> > > + return RETURN_UNSUPPORTED;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Check for default settings and fill in actual values.
> > >
> > > + //
> > >
> > > + if (*BaudRate == 0) {
> > >
> > > + *BaudRate = PcdGet32 (PcdSerialBaudRate);
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (*DataBits == 0) {
> > >
> > > + LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3);
> > >
> > > + *DataBits = LcrData + 5;
> > >
> > > + } else {
> > >
> > > + if ((*DataBits < 5)
> > >
> > > + || (*DataBits > 8))
> > >
> > > + {
> > >
> > > + return RETURN_INVALID_PARAMETER;
> > >
> > > + }
> > >
> > > + //
> > >
> > > + // Map 5..8 to 0..3
> > >
> > > + //
> > >
> > > + LcrData = (UINT8) (*DataBits - (UINT8) 5);
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (*Parity == DefaultParity) {
> > >
> > > + LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
> > >
> > > + switch (LcrParity) {
> > >
> > > + case 0:
> > >
> > > + *Parity = NoParity;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case 3:
> > >
> > > + *Parity = EvenParity;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case 1:
> > >
> > > + *Parity = OddParity;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case 7:
> > >
> > > + *Parity = SpaceParity;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case 5:
> > >
> > > + *Parity = MarkParity;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + default:
> > >
> > > + break;
> > >
> > > + }
> > >
> > > + } else {
> > >
> > > + switch (*Parity) {
> > >
> > > + case NoParity:
> > >
> > > + LcrParity = 0;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case EvenParity:
> > >
> > > + LcrParity = 3;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case OddParity:
> > >
> > > + LcrParity = 1;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case SpaceParity:
> > >
> > > + LcrParity = 7;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case MarkParity:
> > >
> > > + LcrParity = 5;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + default:
> > >
> > > + return RETURN_INVALID_PARAMETER;
> > >
> > > + }
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (*StopBits == DefaultStopBits) {
> > >
> > > + LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
> > >
> > > + switch (LcrStop) {
> > >
> > > + case 0:
> > >
> > > + *StopBits = OneStopBit;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case 1:
> > >
> > > + if (*DataBits == 5) {
> > >
> > > + *StopBits = OneFiveStopBits;
> > >
> > > + } else {
> > >
> > > + *StopBits = TwoStopBits;
> > >
> > > + }
> > >
> > > + break;
> > >
> > > +
> > >
> > > + default:
> > >
> > > + break;
> > >
> > > + }
> > >
> > > + } else {
> > >
> > > + switch (*StopBits) {
> > >
> > > + case OneStopBit:
> > >
> > > + LcrStop = 0;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + case OneFiveStopBits:
> > >
> > > + case TwoStopBits:
> > >
> > > + LcrStop = 1;
> > >
> > > + break;
> > >
> > > +
> > >
> > > + default:
> > >
> > > + return RETURN_INVALID_PARAMETER;
> > >
> > > + }
> > >
> > > + }
> > >
> > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> > > B_UART_LCR_DLAB);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
> > >
> > > + // Strip reserved bits from line control value
> > >
> > > + //
> > >
> > > + Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData);
> > >
> > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr &
> > > 0x3F));
> > >
> > > +
> > >
> > > + return RETURN_SUCCESS;
> > >
> > > +}
> > >
> > > +/**
> > >
> > > + Set the serial port Attributes.
> > >
> > > +
> > >
> > > + @param VOID
> > >
> > > +
> > >
> > > + @return serial register base address.
> > >
> > > +**/
> > >
> > > +RETURN_STATUS
> > >
> > > +EFIAPI
> > >
> > > +SerialPortSetAttributes (
> > >
> > > + IN OUT UINT64 *BaudRate,
> > >
> > > + IN OUT UINT32 *ReceiveFifoDepth,
> > >
> > > + IN OUT UINT32 *Timeout,
> > >
> > > + IN OUT EFI_PARITY_TYPE *Parity,
> > >
> > > + IN OUT UINT8 *DataBits,
> > >
> > > + IN OUT EFI_STOP_BITS_TYPE *StopBits
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN SerialRegisterBase;
> > >
> > > +
> > >
> > > + SerialRegisterBase = GetSerialRegisterBase ();
> > >
> > > +
> > >
> > > + return UartCtlConfig (&gBps, ReceiveFifoDepth, Timeout, Parity,
> > > DataBits, StopBits,
> > >
> > > + SerialRegisterBase);
> > >
> > > +}
> > >
> > > diff --git
> > > a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .inf
> > > b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .inf
> > > new file mode 100644
> > > index 0000000000..6c4674151b
> > > --- /dev/null
> > > +++
> > > b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib
> > > .inf
> > > @@ -0,0 +1,36 @@
> > > +## @file
> > >
> > > +# UART Serial Port library functions
> > >
> > > +#
> > >
> > > +# Copyright (c) 2021 Loongson Technology Corporation Limited. All rights
> > > reserved.<BR>
> > >
> > > +#
> > >
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +#
> > >
> > > +##
> > >
> > > +
> > >
> > > +
> > >
> > > +[Defines]
> > >
> > > + INF_VERSION = 0x00010005
> > >
> > > + BASE_NAME = PcAtSerialPortLib
> > >
> > > + FILE_GUID =
> > > f4fb883d-8138-4f29-bb0c-c574e9312c74
> > >
> > > + MODULE_TYPE = BASE
> > >
> > > + VERSION_STRING = 1.0
> > >
> > > + LIBRARY_CLASS = SerialPortLib
> > >
> > > +
> > >
> > > +[Packages]
> > >
> > > + MdePkg/MdePkg.dec
> > >
> > > + MdeModulePkg/MdeModulePkg.dec
> > >
> > > + Platform/Loongson/LoongArchQemuPkg/Loongson.dec
> > >
> > > +
> > >
> > > +[LibraryClasses]
> > >
> > > + BaseLib
> > >
> > > + IoLib
> > >
> > > + PcdLib
> > >
> > > +
> > >
> > > +[Sources]
> > >
> > > + SerialPortLib.c
> > >
> > > +
> > >
> > > +[Pcd]
> > >
> > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl
> > > ## CONSUMES
> > >
> > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
> > > ## CONSUMES
> > >
> > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl
> > > ## CONSUMES
> > >
> > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate
> > > ## CONSUMES
> > >
> > > --
> > > 2.31.1
> > >
> > >
> > >
> > > -=-=-=-=-=-=
> > > Groups.io Links: You receive all messages sent to this group.
> > > View/Reply Online (#93568): https://edk2.groups.io/g/devel/message/93568
> > > Mute This Topic: https://groups.io/mt/93565591/4905953
> > > Group Owner: devel+owner@edk2.groups.io
> > > Unsubscribe: https://edk2.groups.io/g/devel/unsub
> > > [gaoliming@byosoft.com.cn]
> > > -=-=-=-=-=-=
> > >
> > >
> > >
> >
> >
> >
> >
>
>
> 本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。
> This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it.
>
>
>
>
本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。
This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it.
next prev parent reply other threads:[~2022-09-09 10:41 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-09 3:11 [edk2-platforms][PATCH V1 00/16] Platform: Add Loongson support xianglai
2022-09-09 3:11 ` [edk2-platforms][PATCH V1 01/16] Platform/Loongson: Add Serial Port library xianglai
2022-09-09 8:44 ` 回复: [edk2-devel] " gaoliming
2022-09-09 9:08 ` xianglai
2022-09-09 10:40 ` Chao Li [this message]
2022-09-09 3:11 ` [edk2-platforms][PATCH V1 02/16] Platform/Loongson: Support SEC And Add Readme.md xianglai
2022-09-09 3:11 ` [edk2-platforms][PATCH V1 03/16] Platform/Loongson: Add PeiServicesTablePointerLib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 04/16] Platform/Loongson: Add QemuFwCfgLib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 05/16] Platform/Loongson: Add MmuLib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 06/16] Platform/Loongson: Add StableTimerLib xianglai
2022-09-09 16:49 ` [edk2-devel] " Michael D Kinney
2022-09-13 2:35 ` xianglai
[not found] ` <17144AF1748B76B9.3485@groups.io>
2022-09-13 9:46 ` xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 07/16] Platform/Loongson: Support PEI phase xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 08/16] Platform/Loongson: Add CPU DXE driver xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 09/16] Platform/Loongson: Add PciCpuIoDxe driver xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 10/16] Platform/Loongson: Add timer Dxe driver xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 11/16] Platform/Loongson: Add RealTime Clock lib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 12/16] Platform/Loongson: Add Platform Boot Manager Lib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 13/16] Platform/Loongson: Add Reset System Lib xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 14/16] Platform/Loongson: Support Dxe xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 15/16] Platform/Loongson: Add QemuFlashFvbServicesRuntimeDxe driver xianglai
2022-09-09 3:12 ` [edk2-platforms][PATCH V1 16/16] Platform/Loongson: Support for saving variables to flash xianglai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4ffeda56.79a5.18321d6a07c.Coremail.lichao@loongson.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox