From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web09.3650.1668159304389869692 for ; Fri, 11 Nov 2022 01:35:07 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: loongson.cn, ip: 114.242.206.163, mailfrom: lichao@loongson.cn) Received: from loongson.cn (unknown [10.40.24.149]) by gateway (Coremail) with SMTP id _____8CxLLdFF25jdxUGAA--.7393S3; Fri, 11 Nov 2022 17:35:01 +0800 (CST) Received: from lichao-PC (unknown [10.40.24.149]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxoOJCF25jdNEQAA--.45613S2; Fri, 11 Nov 2022 17:34:58 +0800 (CST) Date: Fri, 11 Nov 2022 17:34:58 +0800 From: "Chao Li" To: xianglai li Cc: "=?utf-8?Q?devel=40edk2.groups.io?=" , Bibo Mao , Leif Lindholm , Liming Gao , Michael D Kinney Message-ID: In-Reply-To: <077592953cccfdc8880525348dfc38a1ebe65661.1668157715.git.lixianglai@loongson.cn> References: <077592953cccfdc8880525348dfc38a1ebe65661.1668157715.git.lixianglai@loongson.cn> Subject: Re: [edk2-platforms][PATCH V5 01/15] Platform/Loongson: Add Serial Port library X-Mailer: Mailspring MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxoOJCF25jdNEQAA--.45613S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQAHCGNs6eQZ0AAPsK X-Coremail-Antispam: 1Uk129KBjvAXoWfWFWxtF47XrWxZFWkXrW7CFg_yoW5Xw4rAo WUZa1fAw1UJr1xuw4kGw17W3y8Aw4xZwn8Ja10qa48W3Z3Zwn8uwn8Z395WwnxXryYgr15 Gr1xtF97Aa9Iy34rn29KB7ZKAUJUUUUk529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ec02F40Eb7x2x7xS6r1j6r4UMc02F40EFcxC0VAKzVAqx4xG6I80ewAqx4xG64kEw2xG 04xIwI0_Xr0_WrUv73VFW2AGmfu7bjvjm3AaLaJ3UjIYCTnIWjp_UUUOT7kC6x804xWl14 x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wAFIxvE14AKwVWU XVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14 v26r1I6r4UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r1j6r4UM28EF7xvwVC2z280aVAF wI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVWxJr0_GcWln4kS14v26r1q6r43M2 AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I8CrVAYj202 j2C_Jr0_Gr1l5I8CrVACY4xI64kE6c02F40Ex7xfMc02F40Ew4AK048IF2xKxVW5JVWrJw Av7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY 6r1j6r4UM4x0Y48IcxkI7VAKI48JMx8GjcxK6IxK0xIIj40E5I8CrwCY1x0262kKe7AKxV WUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E 14v26r106r1rMI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIx kGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAF wI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r 4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7IU0njjPUU UUU== Content-Type: multipart/alternative; boundary="636e1742_3f57d6fd_1e57b" --636e1742_3f57d6fd_1e57b Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Reviewed-by: Chao Li Thanks, Chao -------- On 11=E6=9C=88 11 2022, at 5:12 =E4=B8=8B=E5=8D=88, xianglai li wrote: > Serial Port library for LoongarchQemuPkg > > > > RE=46: https://bugzilla.tianocore.org/show=5Fbug.cgi=3Fid=3D4054 > > > Cc: Bibo Mao > Cc: Chao Li > Cc: Leif Lindholm > Cc: Liming Gao > Cc: Michael D Kinney > Signed-off-by: xianglai li > --- > .../LoongArchQemuPkg/Include/Library/Cpu.h =7C 237 +++++++ > .../Include/LoongArchQemuPlatform.h =7C 95 +++ > .../Library/SerialPortLib/SerialPortLib.c =7C 593 ++++++++++++++++++ > .../Library/SerialPortLib/SerialPortLib.inf =7C 39 ++ > 4 files changed, 964 insertions(+) > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/C= pu.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/LoongArch= QemuPlatform.h > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/SerialPor= tLib/SerialPortLib.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/SerialPor= tLib/SerialPortLib.inf > > > diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h b= /Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h > new file mode 100644 > index 0000000000..c6599c6ed7 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h > =40=40 -0,0 +1,237 =40=40 > +/** =40file > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - EXC - Exception > + - INT - Interrupt > + - =46PU - =46loating Point Unit > + - CSR - CPU Status Register > + - READQ - Read Quad Word > +**/ > +=23ifndef LOONGARCH=5FCPU=5FH=5F > +=23define LOONGARCH=5FCPU=5FH=5F > + > +/* Exception types decoded by machdep exception decoder */ > +=23define EXC=5FINT 0 /* HW interrupt */ > +=23define EXC=5FTLBL 1 /* TLB miss on a load */ > +=23define EXC=5FTLBS 2 /* TLB miss on a store */ > +=23define EXC=5FTLBI 3 /* TLB miss on a ifetch */ > +=23define EXC=5FTLBM 4 /* TLB modified fault */ > +=23define EXC=5FTLBRI 5 /* TLB Read-Inhibit exception */ > +=23define EXC=5FTLBXI 6 /* TLB Execution-Inhibit exception */ > +=23define EXC=5FTLBPE 7 /* TLB Privilege Error */ > +=23define EXC=5FADE 8 /* Address Error */ > +=23define EXC=5FALE 9 /* Unalign Access */ > +=23define EXC=5FOOB 10 /* Out of bounds */ > +=23define EXC=5FSYS 11 /* System call */ > +=23define EXC=5FBP 12 /* Breakpoint */ > +=23define EXC=5FINE 13 /* Inst. Not Exist */ > +=23define EXC=5FIPE 14 /* Inst. Privileged Error */ > +=23define EXC=5F=46PDIS 15 /* =46PU Disabled */ > +=23define EXC=5FLSXDIS 16 /* LSX Disabled */ > +=23define EXC=5FLASXDIS 17 /* LASX Disabled */ > +=23define EXC=5F=46PE 18 /* =46loating Point Exception */ > +=23define EXC=5FWATCH 19 /* Watch address reference */ > +=23define EXC=5FBAD 255 /* Undecodeable */ > + > +=23define COPY=5FSIGCODE // copy sigcode above user stack in exec > +=23define ZERO =24r0 /* wired zero */ > +=23define RA =24r1 /* return address */ > +=23define GP =24r2 /* global pointer - caller saved for PIC */ > +=23define SP =24r3 /* stack pointer */ > +=23define V0 =24r4 /* return value - caller saved */ > +=23define V1 =24r5 > +=23define A0 =24r4 /* argument registers */ > +=23define A1 =24r5 > +=23define A2 =24r6 > +=23define A3 =24r7 > +=23define A4 =24r8 /* arg reg 64 bit; caller saved in 32 bit */ > +=23define A5 =24r9 > +=23define A6 =24r10 > +=23define A7 =24r11 > +=23define T0 =24r12 /* caller saved */ > +=23define T1 =24r13 > +=23define T2 =24r14 > +=23define T3 =24r15 > +=23define T4 =24r16 /* callee saved */ > +=23define T5 =24r17 > +=23define T6 =24r18 > +=23define T7 =24r19 > +=23define T8 =24r20 /* caller saved */ > +=23define TP =24r21 /* TLS */ > +=23define =46P =24r22 /* frame pointer */ > +=23define S0 =24r23 /* callee saved */ > +=23define S1 =24r24 > +=23define S2 =24r25 > +=23define S3 =24r26 > +=23define S4 =24r27 > +=23define S5 =24r28 > +=23define S6 =24r29 > +=23define S7 =24r30 > +=23define S8 =24r31 /* callee saved */ > + > +=23define =46CSR0 =24r0 > + > +// > +// Location of the saved registers relative to ZERO. > +// Usage is p->p=5Fregs=5BXX=5D. > +// > +=23define RA=5FNUM 1 > +=23define GP=5FNUM 2 > +=23define SP=5FNUM 3 > +=23define A0=5FNUM 4 > +=23define A1=5FNUM 5 > +=23define A2=5FNUM 6 > +=23define A3=5FNUM 7 > +=23define A4=5FNUM 8 > +=23define A5=5FNUM 9 > +=23define A6=5FNUM 10 > +=23define A7=5FNUM 11 > +=23define T0=5FNUM 12 > +=23define T1=5FNUM 13 > +=23define T2=5FNUM 14 > +=23define T3=5FNUM 15 > +=23define T4=5FNUM 16 > +=23define T5=5FNUM 17 > +=23define T6=5FNUM 18 > +=23define T7=5FNUM 19 > +=23define T8=5FNUM 20 > +=23define TP=5FNUM 21 > +=23define =46P=5FNUM 22 > +=23define S0=5FNUM 23 > +=23define S1=5FNUM 24 > +=23define S2=5FNUM 25 > +=23define S3=5FNUM 26 > +=23define S4=5FNUM 27 > +=23define S5=5FNUM 28 > +=23define S6=5FNUM 29 > +=23define S7=5FNUM 30 > +=23define S8=5FNUM 31 > + > +=23define =46P0=5FNUM 0 > +=23define =46P1=5FNUM 1 > +=23define =46P2=5FNUM 2 > +=23define =46P3=5FNUM 3 > +=23define =46P4=5FNUM 4 > +=23define =46P5=5FNUM 5 > +=23define =46P6=5FNUM 6 > +=23define =46P7=5FNUM 7 > +=23define =46P8=5FNUM 8 > +=23define =46P9=5FNUM 9 > +=23define =46P10=5FNUM 10 > +=23define =46P11=5FNUM 11 > +=23define =46P12=5FNUM 12 > +=23define =46P13=5FNUM 13 > +=23define =46P14=5FNUM 14 > +=23define =46P15=5FNUM 15 > +=23define =46P16=5FNUM 16 > +=23define =46P17=5FNUM 17 > +=23define =46P18=5FNUM 18 > +=23define =46P19=5FNUM 19 > +=23define =46P20=5FNUM 20 > +=23define =46P21=5FNUM 21 > +=23define =46P22=5FNUM 22 > +=23define =46P23=5FNUM 23 > +=23define =46P24=5FNUM 24 > +=23define =46P25=5FNUM 25 > +=23define =46P26=5FNUM 26 > +=23define =46P27=5FNUM 27 > +=23define =46P28=5FNUM 28 > +=23define =46P29=5FNUM 29 > +=23define =46P30=5FNUM 30 > +=23define =46P31=5FNUM 31 > +=23define =46CSR=5FNUM 32 > +=23define =46CC=5FNUM 33 > + > +=23ifdef =5F=5FASSEMBLY=5F=5F > +=23define =5FULCAST=5F > +=23define =5FU64CAST=5F > +=23else > +=23define =5FULCAST=5F (unsigned long) > +=23define =5FU64CAST=5F (u64) > +=23endif > + > +=23define LOONGARCH=5FCSR=5FCRMD 0 > +=23define LOONGARCH=5FCSR=5FPRMD 1 > +=23define LOONGARCH=5FCSR=5FEUEN 2 > +=23define CSR=5FEUEN=5FLBTEN=5FSHI=46T 3 > +=23define CSR=5FEUEN=5FLBTEN (=5FULCAST=5F(0x1) << CSR=5FEUEN=5FLBTEN=5F= SHI=46T) > +=23define CSR=5FEUEN=5FLASXEN=5FSHI=46T 2 > +=23define CSR=5FEUEN=5FLASXEN (=5FULCAST=5F(0x1) << CSR=5FEUEN=5FLASXE= N=5FSHI=46T) > +=23define CSR=5FEUEN=5FLSXEN=5FSHI=46T 1 > +=23define CSR=5FEUEN=5FLSXEN (=5FULCAST=5F(0x1) << CSR=5FEUEN=5FLSXEN=5F= SHI=46T) > +=23define CSR=5FEUEN=5F=46PEN=5FSHI=46T 0 > +=23define CSR=5FEUEN=5F=46PEN (=5FULCAST=5F(0x1) << CSR=5FEUEN=5F=46PE= N=5FSHI=46T) > +=23define LOONGARCH=5FCSR=5FEC=46G 4 > + > +/* Exception status */ > +=23define LOONGARCH=5FCSR=5FESTAT 5 > +=23define CSR=5FESTAT=5FESUBCODE=5FSHI=46T 22 > +=23define CSR=5FESTAT=5FESUBCODE=5FWIDTH 9 > +=23define CSR=5FESTAT=5FESUBCODE (=5FULCAST=5F(0x1ff) << CSR=5FESTAT=5F= ESUBCODE=5FSHI=46T) > +=23define CSR=5FESTAT=5FEXC=5FSHI=46T 16 > +=23define CSR=5FESTAT=5FEXC=5FWIDTH 6 > +=23define CSR=5FESTAT=5FEXC (=5FULCAST=5F(0x3f) << CSR=5FESTAT=5FEXC=5F= SHI=46T) > +=23define CSR=5FESTAT=5FIS=5FSHI=46T 0 > +=23define CSR=5FESTAT=5FIS=5FWIDTH 15 > +=23define CSR=5FESTAT=5FIS (=5FULCAST=5F(0x7fff) << CSR=5FESTAT=5FIS=5F= SHI=46T) > + > +=23define LOONGARCH=5FCSR=5FEPC 6 > +=23define LOONGARCH=5FCSR=5FBADV 7 > +=23define LOONGARCH=5FCSR=5FBADINST 8 > +=23define LOONGARCH=5FCSR=5FBADI 8 > +=23define LOONGARCH=5FCSR=5FEBASE 0xc /* Exception entry base address = */ > +=23define LOONGARCH=5FCSR=5FCPUNUM 0x20 /* CPU core number */ > + > +/* register number save in stack on exception */ > +=23define =46P=5FBASE=5FNUM 34 > +=23define BASE=5FNUM 32 > +=23define CSR=5FNUM 10 > +=23define =46P=5FBASE=5FINDEX (CSR=5FNUM + BASE=5FNUM) > +=23define BOOTCORE=5FID 0 > + > +=23define LOONGSON=5FIOCSR=5FIPI=5FSTATUS 0x1000 > +=23define LOONGSON=5FIOCSR=5FIPI=5FEN 0x1004 > +=23define LOONGSON=5FIOCSR=5FIPI=5FSET 0x1008 > +=23define LOONGSON=5FIOCSR=5FIPI=5FCLEAR 0x100c > +=23define LOONGSON=5FCSR=5FMAIL=5FBU=460 0x1020 > +=23define LOONGSON=5FCSR=5FMAIL=5FBU=461 0x1028 > +=23define LOONGSON=5FCSR=5FMAIL=5FBU=462 0x1030 > +=23define LOONGSON=5FCSR=5FMAIL=5FBU=463 0x1038 > + > +/* Bit Domains for C=46G registers */ > +=23define LOONGARCH=5FCPUC=46G4 0x4 > +=23define LOONGARCH=5FCPUC=46G5 0x5 > + > +/* Kscratch registers */ > +=23define LOONGARCH=5FCSR=5FKS0 0x30 > +=23define LOONGARCH=5FCSR=5FKS1 0x31 > + > +/* Stable timer registers */ > +=23define LOONGARCH=5FCSR=5FTMC=46G 0x41 > +=23define LOONGARCH=5FCSR=5FTMC=46G=5FEN (1ULL << 0) > +=23define LOONGARCH=5FCSR=5FTMC=46G=5FPERIOD (1ULL << 1) > +=23define LOONGARCH=5FCSR=5FTMC=46G=5FTIMEVAL (0x3fffffffffffULL << 2)= > +=23define LOONGARCH=5FCSR=5FTVAL 0x42 /* Timer value */ > +=23define LOONGARCH=5FCSR=5FCNTC 0x43 /* Timer offset */ > +=23define LOONGARCH=5FCSR=5FTINTCLR 0x44 /* Timer interrupt clear */ > + > +/* TLB refill exception base address */ > +=23define LOONGARCH=5FCSR=5FTLBREBASE 0x88 > +=23define LOONGARCH=5FCSR=5FTLBRSAVE 0x8b /* KScratch for TLB refill e= xception */ > +=23define LOONGARCH=5FCSR=5FPGD 0x1b /* Page table base */ > + > +/* Invalid addr with global=3D1 or matched asid in current tlb */ > +=23define INVTLB=5FADDR=5FGTRUE=5FOR=5FASID 0x6 > + > +/* Bits 8 and 9 of =46PU Status Register specify the rounding mode */ > +=23define =46PU=5FCSR=5FRM 0x300 > +=23define =46PU=5FCSR=5FRN 0x000 /* nearest */ > +=23define =46PU=5FCSR=5FRZ 0x100 /* towards zero */ > +=23define =46PU=5FCSR=5FRU 0x200 /* towards +Infinity */ > +=23define =46PU=5FCSR=5FRD 0x300 /* towards -Infinity */ > + > +=23endif > diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPl= atform.h b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatfo= rm.h > new file mode 100644 > index 0000000000..e942e6a994 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.= h > =40=40 -0,0 +1,95 =40=40 > +/** =40file > + LoongArch Qemu Platform macro definition. > + > + Copyright (c) 2022, Loongson Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + **/ > + > +=23ifndef LOONGARCH=5FQEMU=5FPLAT=46ORM=5FH=5F > +=23define LOONGARCH=5FQEMU=5FPLAT=46ORM=5FH=5F > + > +/* Acpi pm device */ > +=23define LS7A=5FPCH=5FREG=5FBASE 0x10000000UL > +=23define LS7A=5FACPI=5FREG=5FBASE (LS7A=5FPCH=5FREG=5FBASE + 0x000D00= 00) > +=23define LS7A=5FPM=5FCNT=5FBLK (0x14) /* 2 bytes */ > +=23define LS7A=5FGPE0=5FRESET=5FREG (0x30) /* 4 bytes */ > + > +=23define ACPI=5FBITMASK=5FSLEEP=5FTYPE 0x1C00 > +=23define ACPI=5FBITMASK=5FSLEEP=5FENABLE 0x2000 > + > +//--------------------------------------------- > +// UART Register Offsets > +//--------------------------------------------- > +=23define BAUD=5FLOW=5FO=46=46SET 0x00 > +=23define BAUD=5FHIGH=5FO=46=46SET 0x01 > +=23define IER=5FO=46=46SET 0x01 > +=23define LCR=5FSHADOW=5FO=46=46SET 0x01 > +=23define =46CR=5FSHADOW=5FO=46=46SET 0x02 > +=23define IR=5FCONTROL=5FO=46=46SET 0x02 > +=23define =46CR=5FO=46=46SET 0x02 > +=23define EIR=5FO=46=46SET 0x02 > +=23define BSR=5FO=46=46SET 0x03 > +=23define LCR=5FO=46=46SET 0x03 > +=23define MCR=5FO=46=46SET 0x04 > +=23define LSR=5FO=46=46SET 0x05 > +=23define MSR=5FO=46=46SET 0x06 > + > +/* character format control register */ > +=23define C=46CR=5FDLAB 0x80 /* divisor latch */ > +=23define C=46CR=5FSBREAK 0x40 /* send break */ > +=23define C=46CR=5FPZERO 0x30 /* zero parity */ > +=23define C=46CR=5FPONE 0x20 /* one parity */ > +=23define C=46CR=5FPEVEN 0x10 /* even parity */ > +=23define C=46CR=5FPODD 0x00 /* odd parity */ > +=23define C=46CR=5FPENAB 0x08 /* parity enable */ > +=23define C=46CR=5FSTOPB 0x04 /* 2 stop bits */ > +=23define C=46CR=5F8BITS 0x03 /* 8 data bits */ > +=23define C=46CR=5F7BITS 0x02 /* 7 data bits */ > +=23define C=46CR=5F6BITS 0x01 /* 6 data bits */ > +=23define C=46CR=5F5BITS 0x00 /* 5 data bits */ > +/* modem control register */ > +=23define MCR=5FLOOPBACK 0x10 /* loopback */ > +=23define MCR=5FIENABLE 0x08 /* output 2 =3D int enable */ > +=23define MCR=5FDRS 0x04 /* output 1 =3D xxx */ > +=23define MCR=5FRTS 0x02 /* enable RTS */ > +=23define MCR=5FDTR 0x01 /* enable DTR */ > + > +/* line status register */ > +=23define LSR=5FRCV=5F=46I=46O 0x80 /* error in receive fifo */ > +=23define LSR=5FTSRE 0x40 /* transmitter empty */ > +=23define LSR=5FTXRDY 0x20 /* transmitter ready */ > +=23define LSR=5FBI 0x10 /* break detected */ > +=23define LSR=5F=46E 0x08 /* framing error */ > +=23define LSR=5FPE 0x04 /* parity error */ > +=23define LSR=5FOE 0x02 /* overrun error */ > +=23define LSR=5FRXRDY 0x01 /* receiver ready */ > +=23define LSR=5FRCV=5FMASK 0x1f > + > +/* 16550 UART register offsets and bitfields */ > +=23define R=5FUART=5FRXBU=46 0 > +=23define R=5FUART=5FTXBU=46 0 > +=23define R=5FUART=5FBAUD=5FLOW 0 > +=23define R=5FUART=5FBAUD=5FHIGH 1 > +=23define R=5FUART=5F=46CR 2 > +=23define B=5FUART=5F=46CR=5F=46I=46OE BIT0 > +=23define B=5FUART=5F=46CR=5F=46I=46O64 BIT5 > +=23define R=5FUART=5FLCR 3 > +=23define B=5FUART=5FLCR=5FDLAB BIT7 > +=23define R=5FUART=5FMCR 4 > +=23define B=5FUART=5FMCR=5FDTRC BIT0 > +=23define B=5FUART=5FMCR=5FRTS BIT1 > +=23define R=5FUART=5FLSR 5 > +=23define B=5FUART=5FLSR=5FRXRDY BIT0 > +=23define B=5FUART=5FLSR=5FTXRDY BIT5 > +=23define B=5FUART=5FLSR=5FTEMT BIT6 > +=23define R=5FUART=5FMSR 6 > +=23define B=5FUART=5FMSR=5FCTS BIT4 > +=23define B=5FUART=5FMSR=5FDSR BIT5 > +=23define B=5FUART=5FMSR=5FRI BIT6 > +=23define B=5FUART=5FMSR=5FDCD BIT7 > +=23define UART=5FBASE=5FADDRESS (0x1fe001e0) > +=23define UART=5FBPS (115200) > +=23define UART=5FWAIT=5FTIMOUT (1000000) > +=23endif > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/S= erialPortLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib= /SerialPortLib.c > new file mode 100644 > index 0000000000..7044db81ee > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPo= rtLib.c > =40=40 -0,0 +1,593 =40=40 > +/** =40file > + UART Serial Port library functions > + > + Copyright (c) 2022 Loongson Technology Corporation Limited. All right= s reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + =40par Glossary: > + - Bps - Bit Per Second > + - CTL - Control > + - Config - Configure > +**/ > + > +=23include > +=23include > +=23include > +=23include > +=23include > + > +UINTN gUartBase =3D UART=5FBASE=5FADDRESS; > +UINTN gBps =3D UART=5FBPS; > + > +/** > + Initialize the serial device hardware. > + > + If no initialization is required, then return RETURN=5FSUCCESS. > + If the serial device was successfuly initialized, then return RETURN=5F= SUCCESS. > + If the serial device could not be initialized, then return RETURN=5FD= EVICE=5FERROR. > + > + =40retval RETURN=5FSUCCESS The serial device was initialized. > + =40retval RETURN=5FDEVICE=5FERROR The serail device could not be init= ialized. > +**/ > +RETURN=5FSTATUS > +E=46IAPI > +SerialPortInitialize ( > + VOID > + ) > +=7B > + UINTN TimeOut; > + // > + // wait for Tx fifo to completely drain */ > + // > + TimeOut =3D UART=5FWAIT=5FTIMOUT; > + while (=21(MmioRead8 ((UINTN) gUartBase + LSR=5FO=46=46SET) & LSR=5FT= SRE)) =7B > + if (--TimeOut =3D=3D 0) =7B > + break; > + =7D > + =7D > + // > + // Set communications format > + // > + MmioWrite8 ((UINTN) (gUartBase + LCR=5FO=46=46SET), C=46CR=5FDLAB); > + > + // > + // Configure baud rate > + // > + > + MmioWrite8 ((UINTN) (gUartBase + LCR=5FO=46=46SET), C=46CR=5F8BITS); > + MmioWrite8 ((UINTN) (gUartBase + MCR=5FO=46=46SET), MCR=5FIENABLE =7C= MCR=5FDTR =7C MCR=5FRTS); > + > + return RETURN=5FSUCCESS; > +=7D > + > +/** > + 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 operat= ion failed. > + > + If Buffer is NULL, then ASSERT (). > + > + If NumberOfBytes is zero, then return 0. > + > + =40param Buffer Pointer to the data buffer to be written. > + =40param NumberOfBytes Number of bytes to written to the serial devic= e. > + > + =40retval 0 NumberOfBytes is 0. > + =40retval >0 The number of bytes written to the serial device. > + If this value is less than NumberOfBytes, then the read operation fai= led. > +**/ > +UINTN > +E=46IAPI > +UartCtlWrite ( > + IN UINT8 *Buffer, > + IN UINTN NumberOfBytes, > + IN UINTN CtlAddr > +) > +=7B > + UINTN Result; > + UINT8 Data; > + > + if (Buffer =3D=3D NULL) =7B > + return 0; > + =7D > + > + Result =3D NumberOfBytes; > + > + while (NumberOfBytes--) =7B > + // > + // Wait for the serail port to be ready. > + // > + do =7B > + Data =3D MmioRead8 (CtlAddr + LSR=5FO=46=46SET); > + =7D while ((Data & LSR=5FTXRDY) =3D=3D 0); > + MmioWrite8 (CtlAddr, *Buffer++); > + =7D > + return Result; > +=7D > +/** > + Writes data to serial port. > + > + =40param Buffer Pointer to the data buffer to store the data writed t= o serial port. > + =40param NumberOfBytes Number of bytes to write to the serial port. > + > + =40retval 0 NumberOfBytes is 0. > + =40retval >0 The number of bytes write the serial port. > + If this value is less than NumberOfBytes, then the write operation fa= iled. > +**/ > +UINTN > +E=46IAPI > +SerialPortWrite ( > + IN UINT8 *Buffer, > + IN UINTN NumberOfBytes > +) > +=7B > + return UartCtlWrite (Buffer, NumberOfBytes, gUartBase); > +=7D > +/** > + Reads data from a serial device into a buffer. > + > + =40param Buffer Pointer to the data buffer to store the data read fro= m the serial device. > + =40param NumberOfBytes Number of bytes to read from the serial device= . > + > + =40retval 0 NumberOfBytes is 0. > + =40retval >0 The number of bytes read from the serial device. > + If this value is less than NumberOfBytes, then the read operation fai= led. > +**/ > +UINTN > +E=46IAPI > +UartCtlRead ( > + OUT UINT8 *Buffer, > + IN UINTN NumberOfBytes, > + IN UINTN CtlAddr > +) > +=7B > + UINTN Result; > + UINT8 Data; > + > + if (NULL =3D=3D Buffer) =7B > + return 0; > + =7D > + > + Result =3D NumberOfBytes; > + > + while (NumberOfBytes--) =7B > + // > + // Wait for the serail port to be ready. > + // > + do =7B > + Data =3D MmioRead8 (CtlAddr + LSR=5FO=46=46SET); > + =7D while ((Data & LSR=5FRXRDY) =3D=3D 0); > + > + *Buffer++ =3D MmioRead8 (CtlAddr); > + =7D > + return Result; > +=7D > +/** > + Read data from serial port. > + > + =40param Buffer Pointer to the data buffer to store the data read fro= m serial port. > + =40param NumberOfBytes Number of bytes to read from the serial port. > + > + =40retval 0 NumberOfBytes is 0. > + =40retval >0 The number of bytes read from the serial port. > + If this value is less than NumberOfBytes, then the read operation fai= led. > +**/ > +UINTN > +E=46IAPI > +SerialPortRead ( > + OUT UINT8 *Buffer, > + IN UINTN NumberOfBytes > +) > +=7B > + return UartCtlRead (Buffer, NumberOfBytes, gUartBase); > +=7D > +/** > + 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 =46= ALSE is returned. > + > + =40retval TRUE Data is waiting to be read from the serial device. > + =40retval =46ALSE There is no data waiting to be read from the serial= device. > +**/ > +BOOLEAN > +E=46IAPI > +SerialPortPoll ( > + VOID > + ) > +=7B > + UINT8 Data; > + > + // > + // Read the serial port status. > + // > + Data =3D MmioRead8 ((UINTN) gUartBase + LSR=5FO=46=46SET); > + > + return (BOOLEAN) ((Data & LSR=5FRXRDY) =21=3D 0); > +=7D > +/** > + To get serial register base address. > + > + =40param VOID > + > + =40return serial register base address. > +**/ > +UINTN > +GetSerialRegisterBase ( > + VOID > + ) > +=7B > + return gUartBase; > +=7D > +/** > + Read an 8-bit register. > + =40param Base The base address register of UART device. > + =40param Offset The offset of the register to read. > + > + =40return The value read from the 16550 register. > +**/ > +UINT8 > +SerialPortReadRegister ( > + UINTN Base, > + UINTN Offset > + ) > +=7B > + return MmioRead8 (Base + Offset); > +=7D > + > +/** > + Write an 8-bit register. > + =40param Base The base address register of UART device. > + =40param Offset The offset of the register to write. > + =40param Value The value to write to the register specified by Offset= . > + > + =40return The value written to the 16550 register. > +**/ > +UINT8 > +SerialPortWriteRegister ( > + UINTN Base, > + UINTN Offset, > + UINT8 Value > + ) > +=7B > + return MmioWrite8 (Base + Offset, Value); > +=7D > + > +/** > + Sets the control bits on a serial device. > + > + =40param Control Sets the bits of Control that are settable. > + > + =40retval RETURN=5FSUCCESS The new control bits were set on the seria= l device. > + =40retval RETURN=5FUNSUPPORTED The serial device does not support thi= s operation. > + =40retval RETURN=5FDEVICE=5FERROR The serial device is not functionin= g correctly. > +**/ > +RETURN=5FSTATUS > +E=46IAPI > +SerialPortSetControl ( > + IN UINT32 Control > + ) > +=7B > + UINTN SerialRegisterBase; > + UINT8 Mcr; > + > + // > + // =46irst determine the parameter is invalid. > + // > + if ((Control & (=7E(E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND =7C E=46I=5F= SERIAL=5FDATA=5FTERMINAL=5FREADY =7C > + E=46I=5FSERIAL=5FHARDWARE=5F=46LOW=5FCONTROL=5FENABLE))) =21=3D 0) > + =7B > + return RETURN=5FUNSUPPORTED; > + =7D > + > + SerialRegisterBase =3D GetSerialRegisterBase (); > + if (SerialRegisterBase =3D=3D0) =7B > + return RETURN=5FUNSUPPORTED; > + =7D > + > + // > + // Read the Modem Control Register. > + // > + Mcr =3D SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FMCR); > + Mcr &=3D (=7E(B=5FUART=5FMCR=5FDTRC =7C B=5FUART=5FMCR=5FRTS)); > + > + if ((Control & E=46I=5FSERIAL=5FDATA=5FTERMINAL=5FREADY) =3D=3D E=46I= =5FSERIAL=5FDATA=5FTERMINAL=5FREADY) =7B > + Mcr =7C=3D B=5FUART=5FMCR=5FDTRC; > + =7D > + > + if ((Control & E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND) =3D=3D E=46I=5FS= ERIAL=5FREQUEST=5FTO=5FSEND) =7B > + Mcr =7C=3D B=5FUART=5FMCR=5FRTS; > + =7D > + > + // > + // Write the Modem Control Register. > + // > + SerialPortWriteRegister (SerialRegisterBase, R=5FUART=5FMCR, Mcr); > + > + return RETURN=5FSUCCESS; > +=7D > + > +/** > + Retrieve the status of the control bits on a serial device. > + > + =40param Control A pointer to return the current control signals from= the serial device. > + > + =40retval RETURN=5FSUCCESS The control bits were read from the serial= device. > + =40retval RETURN=5FUNSUPPORTED The serial device does not support thi= s operation. > + =40retval RETURN=5FDEVICE=5FERROR The serial device is not functionin= g correctly. > +**/ > +RETURN=5FSTATUS > +E=46IAPI > +SerialPortGetControl ( > + OUT UINT32 *Control > + ) > +=7B > + UINTN SerialRegisterBase; > + UINT8 Msr; > + UINT8 Mcr; > + UINT8 Lsr; > + > + SerialRegisterBase =3D GetSerialRegisterBase (); > + if (SerialRegisterBase =3D=3D0) =7B > + return RETURN=5FUNSUPPORTED; > + =7D > + > + *Control =3D 0; > + > + // > + // Read the Modem Status Register. > + // > + Msr =3D SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FMSR); > + > + if ((Msr & B=5FUART=5FMSR=5FCTS) =3D=3D B=5FUART=5FMSR=5FCTS) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FCLEAR=5FTO=5FSEND; > + =7D > + > + if ((Msr & B=5FUART=5FMSR=5FDSR) =3D=3D B=5FUART=5FMSR=5FDSR) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FDATA=5FSET=5FREADY; > + =7D > + > + if ((Msr & B=5FUART=5FMSR=5FRI) =3D=3D B=5FUART=5FMSR=5FRI) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FRING=5FINDICATE; > + =7D > + > + if ((Msr & B=5FUART=5FMSR=5FDCD) =3D=3D B=5FUART=5FMSR=5FDCD) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FCARRIER=5FDETECT; > + =7D > + > + // > + // Read the Modem Control Register. > + // > + Mcr =3D SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FMCR); > + > + if ((Mcr & B=5FUART=5FMCR=5FDTRC) =3D=3D B=5FUART=5FMCR=5FDTRC) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FDATA=5FTERMINAL=5FREADY; > + =7D > + > + if ((Mcr & B=5FUART=5FMCR=5FRTS) =3D=3D B=5FUART=5FMCR=5FRTS) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND; > + =7D > + > + if (PcdGetBool (PcdSerialUseHardware=46lowControl)) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FHARDWARE=5F=46LOW=5FCONTROL=5FENABLE= ; > + =7D > + > + // > + // Read the Line Status Register. > + // > + Lsr =3D SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FLSR); > + > + if ((Lsr & (B=5FUART=5FLSR=5FTEMT =7C B=5FUART=5FLSR=5FTXRDY)) =3D=3D= (B=5FUART=5FLSR=5FTEMT =7C B=5FUART=5FLSR=5FTXRDY)) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FOUTPUT=5FBU=46=46ER=5FEMPTY; > + =7D > + > + if ((Lsr & B=5FUART=5FLSR=5FRXRDY) =3D=3D 0) =7B > + *Control =7C=3D E=46I=5FSERIAL=5FINPUT=5FBU=46=46ER=5FEMPTY; > + =7D > + > + return RETURN=5FSUCCESS; > +=7D > + > +/** > + Sets the baud rate, receive =46I=46O depth, transmit/receice time out= , parity, > + data bits, and stop bits on a serial device. > + > + =40param BaudRate The requested baud rate. A BaudRate value of 0 will= use the > + device's default interface speed. > + On output, the value actually set. > + =40param Reveive=46ifoDepth The requested depth of the =46I=46O on th= e receive side of the > + serial interface. A Receive=46ifoDepth value of 0 will use > + the device's default =46I=46O depth. > + On output, the value actually set. > + =40param Timeout The requested time out for a single character in mic= roseconds. > + 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. > + =40param Parity The type of parity to use on this serial device. A Pa= rity value of > + DefaultParity will use the device's default parity value. > + On output, the value actually set. > + =40param 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. > + =40param StopBits The number of stop bits to use on this serial devic= e. A StopBits > + value of DefaultStopBits will use the device's default number of > + stop bits. > + On output, the value actually set. > + > + =40retval RETURN=5FSUCCESS The new attributes were set on the serial = device. > + =40retval RETURN=5FUNSUPPORTED The serial device does not support thi= s operation. > + =40retval RETURN=5FINVALID=5FPARAMETER One or more of the attributes = has an unsupported value. > + =40retval RETURN=5FDEVICE=5FERROR The serial device is not functionin= g correctly. > +**/ > +RETURN=5FSTATUS > +E=46IAPI > +UartCtlConfig ( > + IN OUT UINT64 *BaudRate, > + IN OUT UINT32 *Receive=46ifoDepth, > + IN OUT UINT32 *Timeout, > + IN OUT E=46I=5FPARITY=5FTYPE *Parity, > + IN OUT UINT8 *DataBits, > + IN OUT E=46I=5FSTOP=5FBITS=5FTYPE *StopBits, > + IN UINTN CtlAddr > + ) > +=7B > + UINTN SerialRegisterBase; > + UINT8 Lcr; > + UINT8 LcrData; > + UINT8 LcrParity; > + UINT8 LcrStop; > + > + SerialRegisterBase =3D CtlAddr; > + if (SerialRegisterBase =3D=3D0) =7B > + return RETURN=5FUNSUPPORTED; > + =7D > + > + // > + // Check for default settings and fill in actual values. > + // > + if (*BaudRate =3D=3D 0) =7B > + *BaudRate =3D PcdGet32 (PcdSerialBaudRate); > + =7D > + > + if (*DataBits =3D=3D 0) =7B > + LcrData =3D (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3); > + *DataBits =3D LcrData + 5; > + =7D else =7B > + if ((*DataBits < 5) > + =7C=7C (*DataBits > 8)) > + =7B > + return RETURN=5FINVALID=5FPARAMETER; > + =7D > + // > + // Map 5..8 to 0..3 > + // > + LcrData =3D (UINT8) (*DataBits - (UINT8) 5); > + =7D > + > + if (*Parity =3D=3D DefaultParity) =7B > + LcrParity =3D (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); > + switch (LcrParity) =7B > + case 0: > + *Parity =3D NoParity; > + break; > + > + case 3: > + *Parity =3D EvenParity; > + break; > + > + case 1: > + *Parity =3D OddParity; > + break; > + > + case 7: > + *Parity =3D SpaceParity; > + break; > + > + case 5: > + *Parity =3D MarkParity; > + break; > + > + default: > + break; > + =7D > + =7D else =7B > + switch (*Parity) =7B > + case NoParity: > + LcrParity =3D 0; > + break; > + > + case EvenParity: > + LcrParity =3D 3; > + break; > + > + case OddParity: > + LcrParity =3D 1; > + break; > + > + case SpaceParity: > + LcrParity =3D 7; > + break; > + > + case MarkParity: > + LcrParity =3D 5; > + break; > + > + default: > + return RETURN=5FINVALID=5FPARAMETER; > + =7D > + =7D > + > + if (*StopBits =3D=3D DefaultStopBits) =7B > + LcrStop =3D (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); > + switch (LcrStop) =7B > + case 0: > + *StopBits =3D OneStopBit; > + break; > + > + case 1: > + if (*DataBits =3D=3D 5) =7B > + *StopBits =3D One=46iveStopBits; > + =7D else =7B > + *StopBits =3D TwoStopBits; > + =7D > + break; > + > + default: > + break; > + =7D > + =7D else =7B > + switch (*StopBits) =7B > + case OneStopBit: > + LcrStop =3D 0; > + break; > + > + case One=46iveStopBits: > + case TwoStopBits: > + LcrStop =3D 1; > + break; > + > + default: > + return RETURN=5FINVALID=5FPARAMETER; > + =7D > + =7D > + SerialPortWriteRegister (SerialRegisterBase, R=5FUART=5FLCR, B=5FUART= =5FLCR=5FDLAB); > + > + // > + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. > + // Strip reserved bits from line control value > + // > + Lcr =3D (UINT8) ((LcrParity << 3) =7C (LcrStop << 2) =7C LcrData); > + SerialPortWriteRegister (SerialRegisterBase, R=5FUART=5FLCR, (UINT8) = (Lcr & 0x3=46)); > + > + return RETURN=5FSUCCESS; > +=7D > +/** > + Set the serial port Attributes. > + > + =40param VOID > + > + =40return serial register base address. > +**/ > +RETURN=5FSTATUS > +E=46IAPI > +SerialPortSetAttributes ( > + IN OUT UINT64 *BaudRate, > + IN OUT UINT32 *Receive=46ifoDepth, > + IN OUT UINT32 *Timeout, > + IN OUT E=46I=5FPARITY=5FTYPE *Parity, > + IN OUT UINT8 *DataBits, > + IN OUT E=46I=5FSTOP=5FBITS=5FTYPE *StopBits > + ) > +=7B > + UINTN SerialRegisterBase; > + > + SerialRegisterBase =3D GetSerialRegisterBase (); > + > + return UartCtlConfig (&gBps, Receive=46ifoDepth, Timeout, Parity, Dat= aBits, StopBits, > + SerialRegisterBase); > +=7D > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/S= erialPortLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortL= ib/SerialPortLib.inf > new file mode 100644 > index 0000000000..22cf82cf79 > --- /dev/null > +++ b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPo= rtLib.inf > =40=40 -0,0 +1,39 =40=40 > +=23=23 =40file > +=23 UART Serial Port library functions > +=23 > +=23 Copyright (c) 2022 Loongson Technology Corporation Limited. All ri= ghts reserved.
> +=23 > +=23 SPDX-License-Identifier: BSD-2-Clause-Patent > +=23 > +=23=23 > + > +=5BDefines=5D > + IN=46=5FVERSION =3D 0x00010005 > + BASE=5FNAME =3D PcAtSerialPortLib > + =46ILE=5FGUID =3D f4fb883d-8138-4f29-bb0c-c574e9312c74 > + MODULE=5FTYPE =3D BASE > + VERSION=5FSTRING =3D 1.0 > + LIBRARY=5FCLASS =3D SerialPortLib > + > +=23 > +=23 VALID=5FARCHITECTURES =3D LOONGARCH64 > +=23 > + > +=5BSources=5D > + SerialPortLib.c > + > +=5BPackages=5D > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + Platform/Loongson/LoongArchQemuPkg/Loongson.dec > + > +=5BLibraryClasses=5D > + BaseLib > + IoLib > + PcdLib > + > +=5BPcd=5D > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardware=46lowControl =23=23= CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate =23=23 CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl =23=23 CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate =23=23 CONSUMES > -- > 2.31.1 --636e1742_3f57d6fd_1e57b Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline
Reviewed-by: Chao Li  <lichao=40loongson.cn>


Thanks,
Chao
--------

On 11=E6=9C=88 11 2022, = at 5:12 =E4=B8=8B=E5=8D=88, xianglai li <lixianglai=40loongson.cn> = wrote:
Serial Port library for LoongarchQemuPk= g



RE=46: https://bugzilla.tianocore.org/show=5Fbug.= cgi=3Fid=3D4054



Cc: Bibo Mao <maobibo=40loongson= .cn>

Cc: Chao Li <lichao=40loongson.cn>

<= div>Cc: Leif Lindholm <quic=5Fllindhol=40quicinc.com>

Cc: Liming Gao <gaoliming=40byosoft.com.cn>
Cc: Mich= ael D Kinney <michael.d.kinney=40intel.com>

Signed-of= f-by: xianglai li <lixianglai=40loongson.cn>

---
.../LoongArchQemuPkg/Include/Library/Cpu.h =7C 237 +++++++
.../Include/LoongArchQemuPlatform.h =7C 95 +++

..= ./Library/SerialPortLib/SerialPortLib.c =7C 593 ++++++++++++++++++
<= br>
.../Library/SerialPortLib/SerialPortLib.inf =7C 39 ++

4 files changed, 964 insertions(+)

create mode 100644 Pl= atform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h

crea= te mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPl= atform.h

create mode 100644 Platform/Loongson/LoongArchQemu= Pkg/Library/SerialPortLib/SerialPortLib.c

create mode 10064= 4 Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/SerialPortLib.= inf



diff --git a/Platform/Loongson/LoongArchQemuPkg= /Include/Library/Cpu.h b/Platform/Loongson/LoongArchQemuPkg/Include/Libra= ry/Cpu.h

new file mode 100644

index 000000000= 0..c6599c6ed7

--- /dev/null

+++ b/Platform/Lo= ongson/LoongArchQemuPkg/Include/Library/Cpu.h

=40=40 -0,0 += 1,237 =40=40

+/** =40file

+

+ C= opyright (c) 2022 Loongson Technology Corporation Limited. All rights res= erved.<BR>

+

+ SPDX-License-Identifier:= BSD-2-Clause-Patent

+

+ =40par Glossary:
+ - EXC - Exception

+ - INT - Interrupt
+ - =46PU - =46loating Point Unit

+ - CSR - CPU Statu= s Register

+ - READQ - Read Quad Word

+**/
+=23ifndef LOONGARCH=5FCPU=5FH=5F

+=23define LO= ONGARCH=5FCPU=5FH=5F

+

+/* Exception types de= coded by machdep exception decoder */

+=23define EXC=5FINT = 0 /* HW interrupt */

+=23define EXC=5FTLBL 1 /* TLB miss on= a load */

+=23define EXC=5FTLBS 2 /* TLB miss on a store *= /

+=23define EXC=5FTLBI 3 /* TLB miss on a ifetch */
<= br>
+=23define EXC=5FTLBM 4 /* TLB modified fault */

+=23= define EXC=5FTLBRI 5 /* TLB Read-Inhibit exception */

+=23d= efine EXC=5FTLBXI 6 /* TLB Execution-Inhibit exception */

+= =23define EXC=5FTLBPE 7 /* TLB Privilege Error */

+=23defin= e EXC=5FADE 8 /* Address Error */

+=23define EXC=5FALE 9 /*= Unalign Access */

+=23define EXC=5FOOB 10 /* Out of bounds= */

+=23define EXC=5FSYS 11 /* System call */

+=23define EXC=5FBP 12 /* Breakpoint */

+=23define EXC=5FI= NE 13 /* Inst. Not Exist */

+=23define EXC=5FIPE 14 /* Inst= . Privileged Error */

+=23define EXC=5F=46PDIS 15 /* =46PU = Disabled */

+=23define EXC=5FLSXDIS 16 /* LSX Disabled */
+=23define EXC=5FLASXDIS 17 /* LASX Disabled */

+=23define EXC=5F=46PE 18 /* =46loating Point Exception */

+=23define EXC=5FWATCH 19 /* Watch address reference */

+= =23define EXC=5FBAD 255 /* Undecodeable */

+

= +=23define COPY=5FSIGCODE // copy sigcode above user stack in exec
<= br>
+=23define ZERO =24r0 /* wired zero */

+=23define R= A =24r1 /* return address */

+=23define GP =24r2 /* global = pointer - caller saved for PIC */

+=23define SP =24r3 /* st= ack pointer */

+=23define V0 =24r4 /* return value - caller= saved */

+=23define V1 =24r5

+=23define A0 =24= r4 /* argument registers */

+=23define A1 =24r5

+=23define A2 =24r6

+=23define A3 =24r7

+=23= define A4 =24r8 /* arg reg 64 bit; caller saved in 32 bit */

+=23define A5 =24r9
+=23define A6 =24r10

+=23= define A7 =24r11

+=23define T0 =24r12 /* caller saved */
+=23define T1 =24r13

+=23define T2 =24r14
=
+=23define T3 =24r15

+=23define T4 =24r16 /* calle= e saved */

+=23define T5 =24r17

+=23define T6= =24r18

+=23define T7 =24r19

+=23define T8 =24= r20 /* caller saved */

+=23define TP =24r21 /* TLS */
=
+=23define =46P =24r22 /* frame pointer */

+=23def= ine S0 =24r23 /* callee saved */

+=23define S1 =24r24
=
+=23define S2 =24r25

+=23define S3 =24r26
+=23define S4 =24r27

+=23define S5 =24r28

+=23define S6 =24r29

+=23define S7 =24r30

= +=23define S8 =24r31 /* callee saved */

+

+=23= define =46CSR0 =24r0

+

+//

+// = Location of the saved registers relative to ZERO.

+// Usage= is p->p=5Fregs=5BXX=5D.

+//

+=23define RA= =5FNUM 1

+=23define GP=5FNUM 2

+=23define SP=5F= NUM 3

+=23define A0=5FNUM 4

+=23define A1=5FN= UM 5

+=23define A2=5FNUM 6

+=23define A3=5FNU= M 7

+=23define A4=5FNUM 8

+=23define A5=5FNUM= 9

+=23define A6=5FNUM 10

+=23define A7=5FNUM= 11

+=23define T0=5FNUM 12

+=23define T1=5FNU= M 13

+=23define T2=5FNUM 14

+=23define T3=5FN= UM 15

+=23define T4=5FNUM 16

+=23define T5=5F= NUM 17

+=23define T6=5FNUM 18

+=23define T7=5F= NUM 19

+=23define T8=5FNUM 20

+=23define TP=5F= NUM 21

+=23define =46P=5FNUM 22

+=23define S0= =5FNUM 23

+=23define S1=5FNUM 24

+=23define S= 2=5FNUM 25

+=23define S3=5FNUM 26

+=23define = S4=5FNUM 27

+=23define S5=5FNUM 28

+=23define= S6=5FNUM 29

+=23define S7=5FNUM 30

+=23defin= e S8=5FNUM 31

+

+=23define =46P0=5FNUM 0
+=23define =46P1=5FNUM 1

+=23define =46P2=5FNUM 2=

+=23define =46P3=5FNUM 3

+=23define =46P4=5F= NUM 4

+=23define =46P5=5FNUM 5

+=23define =46= P6=5FNUM 6

+=23define =46P7=5FNUM 7

+=23defin= e =46P8=5FNUM 8

+=23define =46P9=5FNUM 9

+=23= define =46P10=5FNUM 10

+=23define =46P11=5FNUM 11

=
+=23define =46P12=5FNUM 12

+=23define =46P13=5FNUM 13<= /div>
+=23define =46P14=5FNUM 14

+=23define =46P15=5F= NUM 15

+=23define =46P16=5FNUM 16

+=23define = =46P17=5FNUM 17

+=23define =46P18=5FNUM 18

+=23= define =46P19=5FNUM 19

+=23define =46P20=5FNUM 20

=
+=23define =46P21=5FNUM 21

+=23define =46P22=5FNUM 22<= /div>
+=23define =46P23=5FNUM 23

+=23define =46P24=5F= NUM 24

+=23define =46P25=5FNUM 25

+=23define = =46P26=5FNUM 26

+=23define =46P27=5FNUM 27

+=23= define =46P28=5FNUM 28

+=23define =46P29=5FNUM 29

=
+=23define =46P30=5FNUM 30

+=23define =46P31=5FNUM 31<= /div>
+=23define =46CSR=5FNUM 32

+=23define =46CC=5F= NUM 33

+

+=23ifdef =5F=5FASSEMBLY=5F=5F
=
+=23define =5FULCAST=5F

+=23define =5FU64CAST=5F
+=23else

+=23define =5FULCAST=5F (unsigned lon= g)

+=23define =5FU64CAST=5F (u64)

+=23endif
+

+=23define LOONGARCH=5FCSR=5FCRMD 0
+=23define LOONGARCH=5FCSR=5FPRMD 1

+=23define LOONGA= RCH=5FCSR=5FEUEN 2

+=23define CSR=5FEUEN=5FLBTEN=5FSHI=46T = 3

+=23define CSR=5FEUEN=5FLBTEN (=5FULCAST=5F(0x1) <<= CSR=5FEUEN=5FLBTEN=5FSHI=46T)

+=23define CSR=5FEUEN=5FLASX= EN=5FSHI=46T 2

+=23define CSR=5FEUEN=5FLASXEN (=5FULCAST=5F= (0x1) << CSR=5FEUEN=5FLASXEN=5FSHI=46T)

+=23define CS= R=5FEUEN=5FLSXEN=5FSHI=46T 1

+=23define CSR=5FEUEN=5FLSXEN = (=5FULCAST=5F(0x1) << CSR=5FEUEN=5FLSXEN=5FSHI=46T)

+= =23define CSR=5FEUEN=5F=46PEN=5FSHI=46T 0

+=23define CSR=5F= EUEN=5F=46PEN (=5FULCAST=5F(0x1) << CSR=5FEUEN=5F=46PEN=5FSHI=46T)<= /div>
+=23define LOONGARCH=5FCSR=5FEC=46G 4

+
=
+/* Exception status */

+=23define LOONGARCH=5FCSR= =5FESTAT 5

+=23define CSR=5FESTAT=5FESUBCODE=5FSHI=46T 22
+=23define CSR=5FESTAT=5FESUBCODE=5FWIDTH 9

+=23= define CSR=5FESTAT=5FESUBCODE (=5FULCAST=5F(0x1ff) << CSR=5FESTAT=5F= ESUBCODE=5FSHI=46T)

+=23define CSR=5FESTAT=5FEXC=5FSHI=46T = 16

+=23define CSR=5FESTAT=5FEXC=5FWIDTH 6

+=23= define CSR=5FESTAT=5FEXC (=5FULCAST=5F(0x3f) << CSR=5FESTAT=5FEXC=5F= SHI=46T)

+=23define CSR=5FESTAT=5FIS=5FSHI=46T 0

<= div>+=23define CSR=5FESTAT=5FIS=5FWIDTH 15

+=23define CSR=5F= ESTAT=5FIS (=5FULCAST=5F(0x7fff) << CSR=5FESTAT=5FIS=5FSHI=46T)
+

+=23define LOONGARCH=5FCSR=5FEPC 6

+=23define LOONGARCH=5FCSR=5FBADV 7

+=23define LOONGARCH= =5FCSR=5FBADINST 8

+=23define LOONGARCH=5FCSR=5FBADI 8
+=23define LOONGARCH=5FCSR=5FEBASE 0xc /* Exception entry base = address */

+=23define LOONGARCH=5FCSR=5FCPUNUM 0x20 /* CPU = core number */

+

+/* register number save in = stack on exception */

+=23define =46P=5FBASE=5FNUM 34
=
+=23define BASE=5FNUM 32

+=23define CSR=5FNUM 10
+=23define =46P=5FBASE=5FINDEX (CSR=5FNUM + BASE=5FNUM)
+=23define BOOTCORE=5FID 0

+

+=23de= fine LOONGSON=5FIOCSR=5FIPI=5FSTATUS 0x1000

+=23define LOON= GSON=5FIOCSR=5FIPI=5FEN 0x1004

+=23define LOONGSON=5FIOCSR=5F= IPI=5FSET 0x1008

+=23define LOONGSON=5FIOCSR=5FIPI=5FCLEAR = 0x100c

+=23define LOONGSON=5FCSR=5FMAIL=5FBU=460 0x1020
+=23define LOONGSON=5FCSR=5FMAIL=5FBU=461 0x1028

+=23define LOONGSON=5FCSR=5FMAIL=5FBU=462 0x1030

+=23defin= e LOONGSON=5FCSR=5FMAIL=5FBU=463 0x1038

+

+/*= Bit Domains for C=46G registers */

+=23define LOONGARCH=5F= CPUC=46G4 0x4

+=23define LOONGARCH=5FCPUC=46G5 0x5
+

+/* Kscratch registers */

+=23define = LOONGARCH=5FCSR=5FKS0 0x30

+=23define LOONGARCH=5FCSR=5FKS1= 0x31

+

+/* Stable timer registers */
+=23define LOONGARCH=5FCSR=5FTMC=46G 0x41

+=23define= LOONGARCH=5FCSR=5FTMC=46G=5FEN (1ULL << 0)

+=23defin= e LOONGARCH=5FCSR=5FTMC=46G=5FPERIOD (1ULL << 1)

+=23= define LOONGARCH=5FCSR=5FTMC=46G=5FTIMEVAL (0x3fffffffffffULL << 2)=

+=23define LOONGARCH=5FCSR=5FTVAL 0x42 /* Timer value */
+=23define LOONGARCH=5FCSR=5FCNTC 0x43 /* Timer offset */
+=23define LOONGARCH=5FCSR=5FTINTCLR 0x44 /* Timer interrupt = clear */

+

+/* TLB refill exception base addr= ess */

+=23define LOONGARCH=5FCSR=5FTLBREBASE 0x88
+=23define LOONGARCH=5FCSR=5FTLBRSAVE 0x8b /* KScratch for TLB refi= ll exception */

+=23define LOONGARCH=5FCSR=5FPGD 0x1b /* Pa= ge table base */

+

+/* Invalid addr with glob= al=3D1 or matched asid in current tlb */

+=23define INVTLB=5F= ADDR=5FGTRUE=5FOR=5FASID 0x6

+

+/* Bits 8 and= 9 of =46PU Status Register specify the rounding mode */

+=23= define =46PU=5FCSR=5FRM 0x300

+=23define =46PU=5FCSR=5FRN 0= x000 /* nearest */

+=23define =46PU=5FCSR=5FRZ 0x100 /* tow= ards zero */

+=23define =46PU=5FCSR=5FRU 0x200 /* towards += Infinity */

+=23define =46PU=5FCSR=5FRD 0x300 /* towards -I= nfinity */

+

+=23endif

diff --g= it a/Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h b= /Platform/Loongson/LoongArchQemuPkg/Include/LoongArchQemuPlatform.h
=
new file mode 100644

index 0000000000..e942e6a994<= /div>
--- /dev/null

+++ b/Platform/Loongson/LoongAr= chQemuPkg/Include/LoongArchQemuPlatform.h

=40=40 -0,0 +1,95= =40=40

+/** =40file

+ LoongArch Qemu Platfor= m macro definition.

+

+ Copyright (c) 2022, L= oongson Limited. All rights reserved.

+

+ SPD= X-License-Identifier: BSD-2-Clause-Patent

+

+= **/

+

+=23ifndef LOONGARCH=5FQEMU=5FPLAT=46O= RM=5FH=5F

+=23define LOONGARCH=5FQEMU=5FPLAT=46ORM=5FH=5F
+

+/* Acpi pm device */

+=23defi= ne LS7A=5FPCH=5FREG=5FBASE 0x10000000UL

+=23define LS7A=5FA= CPI=5FREG=5FBASE (LS7A=5FPCH=5FREG=5FBASE + 0x000D0000)

+=23= define LS7A=5FPM=5FCNT=5FBLK (0x14) /* 2 bytes */

+=23defin= e LS7A=5FGPE0=5FRESET=5FREG (0x30) /* 4 bytes */

+
+=23define ACPI=5FBITMASK=5FSLEEP=5FTYPE 0x1C00

+=23d= efine ACPI=5FBITMASK=5FSLEEP=5FENABLE 0x2000

+

+//---------------------------------------------

+// UART= Register Offsets

+//--------------------------------------= -------

+=23define BAUD=5FLOW=5FO=46=46SET 0x00

+=23define BAUD=5FHIGH=5FO=46=46SET 0x01

+=23define IER=5F= O=46=46SET 0x01

+=23define LCR=5FSHADOW=5FO=46=46SET 0x01
+=23define =46CR=5FSHADOW=5FO=46=46SET 0x02

+=23= define IR=5FCONTROL=5FO=46=46SET 0x02

+=23define =46CR=5FO=46= =46SET 0x02

+=23define EIR=5FO=46=46SET 0x02

= +=23define BSR=5FO=46=46SET 0x03

+=23define LCR=5FO=46=46SE= T 0x03

+=23define MCR=5FO=46=46SET 0x04

+=23d= efine LSR=5FO=46=46SET 0x05

+=23define MSR=5FO=46=46SET 0x0= 6

+

+/* character format control register */<= /div>
+=23define C=46CR=5FDLAB 0x80 /* divisor latch */

=
+=23define C=46CR=5FSBREAK 0x40 /* send break */

+=23d= efine C=46CR=5FPZERO 0x30 /* zero parity */

+=23define C=46= CR=5FPONE 0x20 /* one parity */

+=23define C=46CR=5FPEVEN 0= x10 /* even parity */

+=23define C=46CR=5FPODD 0x00 /* odd = parity */

+=23define C=46CR=5FPENAB 0x08 /* parity enable *= /

+=23define C=46CR=5FSTOPB 0x04 /* 2 stop bits */
+=23define C=46CR=5F8BITS 0x03 /* 8 data bits */

+=23= define C=46CR=5F7BITS 0x02 /* 7 data bits */

+=23define C=46= CR=5F6BITS 0x01 /* 6 data bits */

+=23define C=46CR=5F5BITS= 0x00 /* 5 data bits */

+/* modem control register */
=
+=23define MCR=5FLOOPBACK 0x10 /* loopback */

+=23= define MCR=5FIENABLE 0x08 /* output 2 =3D int enable */

+=23= define MCR=5FDRS 0x04 /* output 1 =3D xxx */

+=23define MCR= =5FRTS 0x02 /* enable RTS */

+=23define MCR=5FDTR 0x01 /* e= nable DTR */

+

+/* line status register */
+=23define LSR=5FRCV=5F=46I=46O 0x80 /* error in receive fifo= */

+=23define LSR=5FTSRE 0x40 /* transmitter empty */
+=23define LSR=5FTXRDY 0x20 /* transmitter ready */

+=23define LSR=5FBI 0x10 /* break detected */

+=23define= LSR=5F=46E 0x08 /* framing error */

+=23define LSR=5FPE 0x= 04 /* parity error */

+=23define LSR=5FOE 0x02 /* overrun e= rror */

+=23define LSR=5FRXRDY 0x01 /* receiver ready */
+=23define LSR=5FRCV=5FMASK 0x1f

+

+/* 16550 UART register offsets and bitfields */

+=23defi= ne R=5FUART=5FRXBU=46 0

+=23define R=5FUART=5FTXBU=46 0
+=23define R=5FUART=5FBAUD=5FLOW 0

+=23define R=5F= UART=5FBAUD=5FHIGH 1

+=23define R=5FUART=5F=46CR 2
+=23define B=5FUART=5F=46CR=5F=46I=46OE BIT0

+=23defi= ne B=5FUART=5F=46CR=5F=46I=46O64 BIT5

+=23define R=5FUART=5F= LCR 3

+=23define B=5FUART=5FLCR=5FDLAB BIT7

+= =23define R=5FUART=5FMCR 4

+=23define B=5FUART=5FMCR=5FDTRC= BIT0

+=23define B=5FUART=5FMCR=5FRTS BIT1

+=23= define R=5FUART=5FLSR 5

+=23define B=5FUART=5FLSR=5FRXRDY B= IT0

+=23define B=5FUART=5FLSR=5FTXRDY BIT5

+=23= define B=5FUART=5FLSR=5FTEMT BIT6

+=23define R=5FUART=5FMSR= 6

+=23define B=5FUART=5FMSR=5FCTS BIT4

+=23d= efine B=5FUART=5FMSR=5FDSR BIT5

+=23define B=5FUART=5FMSR=5F= RI BIT6

+=23define B=5FUART=5FMSR=5FDCD BIT7

= +=23define UART=5FBASE=5FADDRESS (0x1fe001e0)

+=23define UA= RT=5FBPS (115200)

+=23define UART=5FWAIT=5FTIMOUT (1000000)=

+=23endif

diff --git a/Platform/Loongson/Loo= ngArchQemuPkg/Library/SerialPortLib/SerialPortLib.c b/Platform/Loongson/L= oongArchQemuPkg/Library/SerialPortLib/SerialPortLib.c

new f= ile mode 100644

index 0000000000..7044db81ee

= --- /dev/null

+++ b/Platform/Loongson/LoongArchQemuPkg/Libr= ary/SerialPortLib/SerialPortLib.c

=40=40 -0,0 +1,593 =40=40=

+/** =40file

+ UART Serial Port library func= tions

+

+ Copyright (c) 2022 Loongson Technol= ogy Corporation Limited. All rights reserved.<BR>

+
+ SPDX-License-Identifier: BSD-2-Clause-Patent

+

+ =40par Glossary:

+ - Bps - Bit Per Secon= d

+ - CTL - Control

+ - Config - Configure
+**/

+

+=23include <Base.h>=

+=23include <Library/Cpu.h>

+=23includ= e <Library/IoLib.h>

+=23include <Library/SerialPor= tLib.h>

+=23include <LoongArchQemuPlatform.h>
+

+UINTN gUartBase =3D UART=5FBASE=5FADDRESS;
+UINTN gBps =3D UART=5FBPS;

+

+/**=

+ Initialize the serial device hardware.

+
+ If no initialization is required, then return RETURN=5FSUC= CESS.

+ If the serial device was successfuly initialized, t= hen return RETURN=5FSUCCESS.

+ If the serial device could n= ot be initialized, then return RETURN=5FDEVICE=5FERROR.

+
+ =40retval RETURN=5FSUCCESS The serial device was initializ= ed.

+ =40retval RETURN=5FDEVICE=5FERROR The serail device c= ould not be initialized.

+**/

+RETURN=5FSTATU= S

+E=46IAPI

+SerialPortInitialize (

=
+ VOID

+ )

+=7B

+ UINTN Ti= meOut;

+ //

+ // wait for Tx fifo to complete= ly drain */

+ //

+ TimeOut =3D UART=5FWAIT=5F= TIMOUT;

+ while (=21(MmioRead8 ((UINTN) gUartBase + LSR=5FO= =46=46SET) & LSR=5FTSRE)) =7B

+ if (--TimeOut =3D=3D 0)= =7B

+ break;

+ =7D

+ =7D
=
+ //

+ // Set communications format

= + //

+ MmioWrite8 ((UINTN) (gUartBase + LCR=5FO=46=46SET), = C=46CR=5FDLAB);

+

+ //

+ // Con= figure baud rate

+ //

+

+ MmioW= rite8 ((UINTN) (gUartBase + LCR=5FO=46=46SET), C=46CR=5F8BITS);

=
+ MmioWrite8 ((UINTN) (gUartBase + MCR=5FO=46=46SET), MCR=5FIENABLE = =7C MCR=5FDTR =7C MCR=5FRTS);

+

+ return RETU= RN=5FSUCCESS;

+=7D

+

+/**
=
+ Write data from buffer to serial device.

+
=
+ Writes NumberOfBytes data bytes from Buffer to the serial devi= ce.

+ The number of bytes actually written to the serial de= vice is returned.

+ If the return value is less than Number= OfBytes, then the write operation failed.

+

+= If Buffer is NULL, then ASSERT ().

+

+ If Nu= mberOfBytes is zero, then return 0.

+

+ =40pa= ram Buffer Pointer to the data buffer to be written.

+ =40p= aram NumberOfBytes Number of bytes to written to the serial device.
=
+

+ =40retval 0 NumberOfBytes is 0.

= + =40retval >0 The number of bytes written to the serial device.
=
+ If this value is less than NumberOfBytes, then the read operat= ion failed.

+**/

+UINTN

+E=46IA= PI

+UartCtlWrite (

+ IN UINT8 *Buffer,
<= br>
+ IN UINTN NumberOfBytes,

+ IN UINTN CtlAddr
<= br>
+)

+=7B

+ UINTN Result;

+ UINT8 Data;

+

+ if (Buffer =3D=3D NULL) =7B=

+ return 0;

+ =7D

+

<= div>+ Result =3D NumberOfBytes;

+

+ while (Nu= mberOfBytes--) =7B

+ //

+ // Wait for the ser= ail port to be ready.

+ //

+ do =7B

=
+ Data =3D MmioRead8 (CtlAddr + LSR=5FO=46=46SET);

+ =7D= while ((Data & LSR=5FTXRDY) =3D=3D 0);

+ MmioWrite8 (C= tlAddr, *Buffer++);

+ =7D

+ return Result;
+=7D

+/**

+ Writes data to serial= port.

+

+ =40param Buffer Pointer to the dat= a buffer to store the data writed to serial port.

+ =40para= m NumberOfBytes Number of bytes to write to the serial port.

+

+ =40retval 0 NumberOfBytes is 0.

+ =40re= tval >0 The number of bytes write the serial port.

+ If = this value is less than NumberOfBytes, then the write operation failed.
+**/

+UINTN

+E=46IAPI

<= div>+SerialPortWrite (

+ IN UINT8 *Buffer,

+ = IN UINTN NumberOfBytes

+)

+=7B

= + return UartCtlWrite (Buffer, NumberOfBytes, gUartBase);

+= =7D

+/**

+ Reads data from a serial device in= to a buffer.

+

+ =40param Buffer Pointer to t= he data buffer to store the data read from the serial device.

+ =40param NumberOfBytes Number of bytes to read from the serial devic= e.

+

+ =40retval 0 NumberOfBytes is 0.
<= br>
+ =40retval >0 The number of bytes read from the serial device= .

+ If this value is less than NumberOfBytes, then the read= operation failed.

+**/

+UINTN

= +E=46IAPI

+UartCtlRead (

+ OUT UINT8 *Buffer,=

+ IN UINTN NumberOfBytes,

+ IN UINTN CtlAddr=

+)

+=7B

+ UINTN Result;
<= br>
+ UINT8 Data;

+

+ if (NULL =3D=3D Buf= fer) =7B

+ return 0;

+ =7D

+
+ Result =3D NumberOfBytes;

+

+ w= hile (NumberOfBytes--) =7B

+ //

+ // Wait for= the serail port to be ready.

+ //

+ do =7B
+ Data =3D MmioRead8 (CtlAddr + LSR=5FO=46=46SET);

=
+ =7D while ((Data & LSR=5FRXRDY) =3D=3D 0);

+
+ *Buffer++ =3D MmioRead8 (CtlAddr);

+ =7D
=
+ return Result;

+=7D

+/**

=
+ Read data from serial port.

+

+ =40par= am Buffer Pointer to the data buffer to store the data read from serial p= ort.

+ =40param NumberOfBytes Number of bytes to read from = the serial port.

+

+ =40retval 0 NumberOfByte= s is 0.

+ =40retval >0 The number of bytes read from the= serial port.

+ If this value is less than NumberOfBytes, t= hen the read operation failed.

+**/

+UINTN
+E=46IAPI

+SerialPortRead (

+ OUT= UINT8 *Buffer,

+ IN UINTN NumberOfBytes

+)
+=7B

+ return UartCtlRead (Buffer, NumberOfByt= es, gUartBase);

+=7D

+/**

+ Pol= ls a serial device to see if there is any data waiting to be read.
<= br>
+

+ Polls aserial device to see if there is any dat= a 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 =46ALSE is ret= urned.

+

+ =40retval TRUE Data is waiting to = be read from the serial device.

+ =40retval =46ALSE There i= s no data waiting to be read from the serial device.

+**/
+BOOLEAN

+E=46IAPI

+SerialPortPo= ll (

+ VOID

+ )

+=7B

<= div>+ UINT8 Data;

+

+ //

+ // R= ead the serial port status.

+ //

+ Data =3D M= mioRead8 ((UINTN) gUartBase + LSR=5FO=46=46SET);

+
+ return (BOOLEAN) ((Data & LSR=5FRXRDY) =21=3D 0);

+=7D

+/**

+ To get serial register base ad= dress.

+

+ =40param VOID

+
+ =40return serial register base address.

+**/
+UINTN

+GetSerialRegisterBase (

+= VOID

+ )

+=7B

+ return gUartBa= se;

+=7D

+/**

+ Read an 8-bit r= egister.

+ =40param Base The base address register of UART = device.

+ =40param Offset The offset of the register to rea= d.

+

+ =40return The value read from the 1655= 0 register.

+**/

+UINT8

+Serial= PortReadRegister (

+ UINTN Base,

+ UINTN Offs= et

+ )

+=7B

+ return MmioRead8 = (Base + Offset);

+=7D

+

+/**
+ Write an 8-bit register.

+ =40param Base The = base address register of UART device.

+ =40param Offset The= offset of the register to write.

+ =40param Value The valu= e to write to the register specified by Offset.

+

=
+ =40return The value written to the 16550 register.

+= **/

+UINT8

+SerialPortWriteRegister (
+ UINTN Base,

+ UINTN Offset,

+ UINT8 = Value

+ )

+=7B

+ return MmioWri= te8 (Base + Offset, Value);

+=7D

+

<= div>+/**

+ Sets the control bits on a serial device.
<= br>
+

+ =40param Control Sets the bits of Control that = are settable.

+

+ =40retval RETURN=5FSUCCESS = The new control bits were set on the serial device.

+ =40re= tval RETURN=5FUNSUPPORTED The serial device does not support this operati= on.

+ =40retval RETURN=5FDEVICE=5FERROR The serial device i= s not functioning correctly.

+**/

+RETURN=5FS= TATUS

+E=46IAPI

+SerialPortSetControl (
=
+ IN UINT32 Control

+ )

+=7B
+ UINTN SerialRegisterBase;

+ UINT8 Mcr;

+

+ //

+ // =46irst determine the paramete= r is invalid.

+ //

+ if ((Control & (=7E(= E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND =7C E=46I=5FSERIAL=5FDATA=5FTERMINAL= =5FREADY =7C

+ E=46I=5FSERIAL=5FHARDWARE=5F=46LOW=5FCONTROL= =5FENABLE))) =21=3D 0)

+ =7B

+ return RETURN=5F= UNSUPPORTED;

+ =7D

+

+ SerialRe= gisterBase =3D GetSerialRegisterBase ();

+ if (SerialRegist= erBase =3D=3D0) =7B

+ return RETURN=5FUNSUPPORTED;
+ =7D

+

+ //

+ // Read th= e Modem Control Register.

+ //

+ Mcr =3D Seri= alPortReadRegister (SerialRegisterBase, R=5FUART=5FMCR);

+ = Mcr &=3D (=7E(B=5FUART=5FMCR=5FDTRC =7C B=5FUART=5FMCR=5FRTS));
=
+

+ if ((Control & E=46I=5FSERIAL=5FDATA=5FTER= MINAL=5FREADY) =3D=3D E=46I=5FSERIAL=5FDATA=5FTERMINAL=5FREADY) =7B
=
+ Mcr =7C=3D B=5FUART=5FMCR=5FDTRC;

+ =7D
+

+ if ((Control & E=46I=5FSERIAL=5FREQUEST=5FTO=5F= SEND) =3D=3D E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND) =7B

+ Mc= r =7C=3D B=5FUART=5FMCR=5FRTS;

+ =7D

+
<= br>
+ //

+ // Write the Modem Control Register.
+ //

+ SerialPortWriteRegister (SerialRegisterBase, = R=5FUART=5FMCR, Mcr);

+

+ return RETURN=5FSUC= CESS;

+=7D

+

+/**

+ Retrieve the status of the control bits on a serial device.

<= div>+

+ =40param Control A pointer to return the current co= ntrol signals from the serial device.

+

+ =40= retval RETURN=5FSUCCESS The control bits were read from the serial device= .

+ =40retval RETURN=5FUNSUPPORTED The serial device does n= ot support this operation.

+ =40retval RETURN=5FDEVICE=5FER= ROR The serial device is not functioning correctly.

+**/
+RETURN=5FSTATUS

+E=46IAPI

+Seria= lPortGetControl (

+ OUT UINT32 *Control

+ )
+=7B

+ UINTN SerialRegisterBase;

+ UINT8 Msr;

+ UINT8 Mcr;

+ UINT8 Lsr;
=
+

+ SerialRegisterBase =3D GetSerialRegisterBase (= );

+ if (SerialRegisterBase =3D=3D0) =7B

+ re= turn RETURN=5FUNSUPPORTED;

+ =7D

+

<= div>+ *Control =3D 0;

+

+ //

+ = // Read the Modem Status Register.

+ //

+ Msr= =3D SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FMSR);
+

+ if ((Msr & B=5FUART=5FMSR=5FCTS) =3D=3D B=5F= UART=5FMSR=5FCTS) =7B

+ *Control =7C=3D E=46I=5FSERIAL=5FCL= EAR=5FTO=5FSEND;

+ =7D

+

+ if (= (Msr & B=5FUART=5FMSR=5FDSR) =3D=3D B=5FUART=5FMSR=5FDSR) =7B
+ *Control =7C=3D E=46I=5FSERIAL=5FDATA=5FSET=5FREADY;

+ =7D

+

+ if ((Msr & B=5FUART=5FMSR=5F= RI) =3D=3D B=5FUART=5FMSR=5FRI) =7B

+ *Control =7C=3D E=46I= =5FSERIAL=5FRING=5FINDICATE;

+ =7D

+
+ if ((Msr & B=5FUART=5FMSR=5FDCD) =3D=3D B=5FUART=5FMSR=5FDCD)= =7B

+ *Control =7C=3D E=46I=5FSERIAL=5FCARRIER=5FDETECT;
+ =7D

+

+ //

+ // = Read the Modem Control Register.

+ //

+ Mcr =3D= SerialPortReadRegister (SerialRegisterBase, R=5FUART=5FMCR);

+

+ if ((Mcr & B=5FUART=5FMCR=5FDTRC) =3D=3D B=5FUAR= T=5FMCR=5FDTRC) =7B

+ *Control =7C=3D E=46I=5FSERIAL=5FDATA= =5FTERMINAL=5FREADY;

+ =7D

+

+ = if ((Mcr & B=5FUART=5FMCR=5FRTS) =3D=3D B=5FUART=5FMCR=5FRTS) =7B
+ *Control =7C=3D E=46I=5FSERIAL=5FREQUEST=5FTO=5FSEND;
<= br>
+ =7D

+

+ if (PcdGetBool (PcdSerialUs= eHardware=46lowControl)) =7B

+ *Control =7C=3D E=46I=5FSERI= AL=5FHARDWARE=5F=46LOW=5FCONTROL=5FENABLE;

+ =7D

<= div>+

+ //

+ // Read the Line Status Register= .

+ //

+ Lsr =3D SerialPortReadRegister (Seri= alRegisterBase, R=5FUART=5FLSR);

+

+ if ((Lsr= & (B=5FUART=5FLSR=5FTEMT =7C B=5FUART=5FLSR=5FTXRDY)) =3D=3D (B=5FUA= RT=5FLSR=5FTEMT =7C B=5FUART=5FLSR=5FTXRDY)) =7B

+ *Control= =7C=3D E=46I=5FSERIAL=5FOUTPUT=5FBU=46=46ER=5FEMPTY;

+ =7D=

+

+ if ((Lsr & B=5FUART=5FLSR=5FRXRDY) =3D= =3D 0) =7B

+ *Control =7C=3D E=46I=5FSERIAL=5FINPUT=5FBU=46= =46ER=5FEMPTY;

+ =7D

+

+ return= RETURN=5FSUCCESS;

+=7D

+

+/**<= /div>
+ Sets the baud rate, receive =46I=46O depth, transmit/rece= ice time out, parity,

+ data bits, and stop bits on a seria= l device.

+

+ =40param BaudRate The requested= baud rate. A BaudRate value of 0 will use the

+ device's d= efault interface speed.

+ On output, the value actually set= .

+ =40param Reveive=46ifoDepth The requested depth of the = =46I=46O on the receive side of the

+ serial interface. A R= eceive=46ifoDepth value of 0 will use

+ the device's defaul= t =46I=46O depth.

+ On output, the value actually set.
+ =40param Timeout The requested time out for a single characte= r in microseconds.

+ This timeout applies to both the trans= mit 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.

+ =40param Parit= y 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.

+ =40param = DataBits The number of data bits to use on the serial device. A DataBits<= /div>
+ vaule of 0 will use the device's default data bit setting= .

+ On output, the value actually set.

+ =40p= aram StopBits The number of stop bits to use on this serial device. A Sto= pBits

+ value of DefaultStopBits will use the device's defa= ult number of

+ stop bits.

+ On output, the v= alue actually set.

+

+ =40retval RETURN=5FSUC= CESS The new attributes were set on the serial device.

+ =40= retval RETURN=5FUNSUPPORTED The serial device does not support this opera= tion.

+ =40retval RETURN=5FINVALID=5FPARAMETER One or more = of the attributes has an unsupported value.

+ =40retval RET= URN=5FDEVICE=5FERROR The serial device is not functioning correctly.
+**/

+RETURN=5FSTATUS

+E=46IAPI
+UartCtlConfig (

+ IN OUT UINT64 *BaudRate,
+ IN OUT UINT32 *Receive=46ifoDepth,

+ IN OUT UIN= T32 *Timeout,

+ IN OUT E=46I=5FPARITY=5FTYPE *Parity,
=
+ IN OUT UINT8 *DataBits,

+ IN OUT E=46I=5FSTOP=5F= BITS=5FTYPE *StopBits,

+ IN UINTN CtlAddr

+ )=

+=7B

+ UINTN SerialRegisterBase;

+ UINT8 Lcr;

+ UINT8 LcrData;

+ UINT8 LcrP= arity;

+ UINT8 LcrStop;

+

+ Ser= ialRegisterBase =3D CtlAddr;

+ if (SerialRegisterBase =3D=3D= 0) =7B

+ return RETURN=5FUNSUPPORTED;

+ =7D
+

+ //

+ // Check for default se= ttings and fill in actual values.

+ //

+ if (= *BaudRate =3D=3D 0) =7B

+ *BaudRate =3D PcdGet32 (PcdSerial= BaudRate);

+ =7D

+

+ if (*DataB= its =3D=3D 0) =7B

+ LcrData =3D (UINT8) (PcdGet8 (PcdSerial= LineControl) & 0x3);

+ *DataBits =3D LcrData + 5;
=
+ =7D else =7B

+ if ((*DataBits < 5)

<= div>+ =7C=7C (*DataBits > 8))

+ =7B

+ retu= rn RETURN=5FINVALID=5FPARAMETER;

+ =7D

+ //
+ // Map 5..8 to 0..3

+ //

+ Lcr= Data =3D (UINT8) (*DataBits - (UINT8) 5);

+ =7D

+

+ if (*Parity =3D=3D DefaultParity) =7B

= + LcrParity =3D (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) &= ; 0x7);

+ switch (LcrParity) =7B

+ case 0:
+ *Parity =3D NoParity;

+ break;

= +

+ case 3:

+ *Parity =3D EvenParity;
+ break;

+

+ case 1:

+ *= Parity =3D OddParity;

+ break;

+

+ case 7:

+ *Parity =3D SpaceParity;

+ brea= k;

+

+ case 5:

+ *Parity =3D Ma= rkParity;

+ break;

+

+ default:=

+ break;

+ =7D

+ =7D else =7B<= /div>
+ switch (*Parity) =7B

+ case NoParity:
=
+ LcrParity =3D 0;

+ break;

+
<= br>
+ case EvenParity:

+ LcrParity =3D 3;

+ break;

+

+ case OddParity:

+= LcrParity =3D 1;

+ break;

+

+ = case SpaceParity:

+ LcrParity =3D 7;

+ break;=

+

+ case MarkParity:

+ LcrPari= ty =3D 5;

+ break;

+

+ default:=

+ return RETURN=5FINVALID=5FPARAMETER;

+ =7D=

+ =7D

+

+ if (*StopBits =3D=3D= DefaultStopBits) =7B

+ LcrStop =3D (UINT8) ((PcdGet8 (PcdS= erialLineControl) >> 2) & 0x1);

+ switch (LcrStop= ) =7B

+ case 0:

+ *StopBits =3D OneStopBit;
+ break;

+

+ case 1:

+ if (*DataBits =3D=3D 5) =7B

+ *StopBits =3D One=46iveS= topBits;

+ =7D else =7B

+ *StopBits =3D TwoSt= opBits;

+ =7D

+ break;

+
<= br>
+ default:

+ break;

+ =7D

+ =7D else =7B

+ switch (*StopBits) =7B

+ = case OneStopBit:

+ LcrStop =3D 0;

+ break;
+

+ case One=46iveStopBits:

+ cas= e TwoStopBits:

+ LcrStop =3D 1;

+ break;
+

+ default:

+ return RETURN=5FINVA= LID=5FPARAMETER;

+ =7D

+ =7D

+ = SerialPortWriteRegister (SerialRegisterBase, R=5FUART=5FLCR, B=5FUART=5FL= CR=5FDLAB);

+

+ //

+ // Clear D= LAB and configure Data Bits, Parity, and Stop Bits.

+ // St= rip reserved bits from line control value

+ //

+ Lcr =3D (UINT8) ((LcrParity << 3) =7C (LcrStop << 2) =7C = LcrData);

+ SerialPortWriteRegister (SerialRegisterBase, R=5F= UART=5FLCR, (UINT8) (Lcr & 0x3=46));

+

+ = return RETURN=5FSUCCESS;

+=7D

+/**

<= div>+ Set the serial port Attributes.

+

+ =40= param VOID

+

+ =40return serial register base= address.

+**/

+RETURN=5FSTATUS

+E=46IAPI

+SerialPortSetAttributes (

+ IN OU= T UINT64 *BaudRate,

+ IN OUT UINT32 *Receive=46ifoDepth,
+ IN OUT UINT32 *Timeout,

+ IN OUT E=46I=5FPARI= TY=5FTYPE *Parity,

+ IN OUT UINT8 *DataBits,

= + IN OUT E=46I=5FSTOP=5FBITS=5FTYPE *StopBits

+ )

=
+=7B

+ UINTN SerialRegisterBase;

+
=
+ SerialRegisterBase =3D GetSerialRegisterBase ();

+

+ return UartCtlConfig (&gBps, Receive=46ifoDepth, T= imeout, Parity, DataBits, StopBits,

+ SerialRegisterBase);<= /div>
+=7D

diff --git a/Platform/Loongson/LoongArch= QemuPkg/Library/SerialPortLib/SerialPortLib.inf b/Platform/Loongson/Loong= ArchQemuPkg/Library/SerialPortLib/SerialPortLib.inf

new fil= e mode 100644

index 0000000000..22cf82cf79

--= - /dev/null

+++ b/Platform/Loongson/LoongArchQemuPkg/Librar= y/SerialPortLib/SerialPortLib.inf

=40=40 -0,0 +1,39 =40=40<= /div>
+=23=23 =40file

+=23 UART Serial Port library= functions

+=23

+=23 Copyright (c) 2022 Loong= son Technology Corporation Limited. All rights reserved.<BR>
<= br>
+=23

+=23 SPDX-License-Identifier: BSD-2-Clause-Pat= ent

+=23

+=23=23

+

+=5BDefines=5D

+ IN=46=5FVERSION =3D 0x00010005

=
+ BASE=5FNAME =3D PcAtSerialPortLib

+ =46ILE=5FGUID =3D= f4fb883d-8138-4f29-bb0c-c574e9312c74

+ MODULE=5FTYPE =3D B= ASE

+ VERSION=5FSTRING =3D 1.0

+ LIBRARY=5FCL= ASS =3D SerialPortLib

+

+=23

+=23= VALID=5FARCHITECTURES =3D LOONGARCH64

+=23

+=

+=5BSources=5D

+ SerialPortLib.c

+

+=5BPackages=5D

+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec

+ Platform/Loongs= on/LoongArchQemuPkg/Loongson.dec

+

+=5BLibrar= yClasses=5D

+ BaseLib

+ IoLib

+= PcdLib

+

+=5BPcd=5D

+ gEfiMdeM= odulePkgTokenSpaceGuid.PcdSerialUseHardware=46lowControl =23=23 CONSUMES<= /div>
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate =23=23 C= ONSUMES

+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineContr= ol =23=23 CONSUMES

+ gEfiMdeModulePkgTokenSpaceGuid.PcdSeri= alClockRate =23=23 CONSUMES

--

2.31.1
--636e1742_3f57d6fd_1e57b--