From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96449+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96449+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652804; cv=none; d=zohomail.com; s=zohoarc; b=N0kBLMMyqxr3/PSI0AxIajatJz5Bs26TU6pikzEmOZJ2b9XhZ2zKUryV+1uHp6EADbDZZTMhcdsoH0C/KJmdYkMzLiVffp6Tuox4PCm+8J68xV8umOl16iTTCOhUxauSG75dePKpD0zR75LzEGt3IatyPk7GadHeMQtNsa5qVng= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652804; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=OSFgTkYwZTlj2NLIibbJZedJ37vP0CpOL5khEz32Cwo=; b=c7OBnBWjZ0dHGx8GRURq47+jK392S+y3yJGS9gK5iQWF6+c282rO2I6qVyslX4Ow81Vouv0injg6mpM3mpnvera1H5Q6vasu9l4IOzxYQw4tqFDT8uLArUiygjVQAVNWjHSdTdmQxczKRyHSxeVMzBTS2qzJcDBOVclAuLyuPhg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96449+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652803937216.412222201227; Wed, 16 Nov 2022 18:40:03 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id hQneYY1788612xI4IN7dESro; Wed, 16 Nov 2022 18:40:03 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6321.1668652800888360549 for ; Wed, 16 Nov 2022 18:40:02 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Cxjdr8nnVj8CMIAA--.23102S3; Thu, 17 Nov 2022 10:39:56 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S3; Thu, 17 Nov 2022 10:39:56 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 01/16] Platform/Loongson: Add Serial Port library Date: Thu, 17 Nov 2022 10:39:27 +0800 Message-Id: <5a0ce4e0c0ef2adde6017074c59813d34f5cdf34.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S3 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWDWw4DGrWDGFy8Cw18tFWxXrb_yoWrWF13Xo W8Ja1fCw15Jw1xuws5Kw17Wr18Xw4I9rn5JF4YgFWUX3Z7Xws8uw1DX3sYgwn3Gryjqr15 Gr1xtas7JFZay34rn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqq1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6x kF7I0E14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020E x4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E74AGY7Cv6cx26rWlOx8S6xCaFV Cjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7VAKI48JMxAIw28IcVCjz48v 1sIEY20_WwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcV CF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7xRE6wZ7UUUUU== Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: G44Hm9Y0h43NExN6b7NfWxBAx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652803; bh=CgH0rWuJ/SDaWlMSjgKaNU8zotOGcYIsOw7FhhGQM7I=; h=Cc:Date:From:Reply-To:Subject:To; b=uYhlJYESJBtCCMQCpxGStRLdJChGT/KnJlintfPrJFIMVmE5f1r0ut+H+T3i2SasnMj 22nb7+KZ/q5gkUWEO+l4lillxJywA1rgt9Zbaq73nNrXwVoe12N5CuEOjQbYLB/knbDv2 UPOgEuqSeF3wbPVSbLL1BNKzW+qp+0F7OMs= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652805848100017 Content-Type: text/plain; charset="utf-8" Serial Port library for LoongarchQemuPkg REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Include/Guid/Early16550UartBaseAddress.h | 22 + .../LoongArchQemuPkg/Include/Library/Cpu.h | 237 +++++ .../Fdt16550SerialPortHookLib.c | 57 ++ .../Fdt16550SerialPortHookLib.inf | 38 + .../SerialPortLib/EarlySerialPortLib16550.c | 900 ++++++++++++++++++ .../SerialPortLib/EarlySerialPortLib16550.inf | 46 + 6 files changed, 1300 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Guid/Early16= 550UartBaseAddress.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550Seri= alPortHookLib/Fdt16550SerialPortHookLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550Seri= alPortHookLib/Fdt16550SerialPortHookLib.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLi= b/EarlySerialPortLib16550.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLi= b/EarlySerialPortLib16550.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Guid/Early16550Uart= BaseAddress.h b/Platform/Loongson/LoongArchQemuPkg/Include/Guid/Early16550U= artBaseAddress.h new file mode 100644 index 0000000000..95aa8f4bc0 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Guid/Early16550UartBaseAdd= ress.h @@ -0,0 +1,22 @@ +/** @file + GUID for the HOB that caches the base address of the 16550 serial port, = for + when PCD access is not available. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EARLY_16550_UART_BASE_ADDRESS_H__ +#define EARLY_16550_UART_BASE_ADDRESS_H__ + +#define EARLY_16550_UART_BASE_ADDRESS_GUID { \ + 0xea67ca3e, 0x1f54, 0x436b, { \ + 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 \ + } \ + } + +extern EFI_GUID gEarly16550UartBaseAddressGuid; + +#endif // EARLY_16550_UART_BASE_ADDRESS_H__ diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h b/Pla= tform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h new file mode 100644 index 0000000000..c6599c6ed7 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/Cpu.h @@ -0,0 +1,237 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + 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 excep= tion */ +#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 f= or 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_SHIF= T) +#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_SHIF= T) + +#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 addres= s */ +#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 exc= eption */ +#define LOONGARCH_CSR_PGD 0x1b /* Page table base */ + +/* Invalid addr with global=3D1 or matched asid in current tlb */ +#define INVTLB_ADDR_GTRUE_OR_ASID 0x6 + +/* 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 */ + +#endif diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550SerialPortH= ookLib/Fdt16550SerialPortHookLib.c b/Platform/Loongson/LoongArchQemuPkg/Lib= rary/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c new file mode 100644 index 0000000000..2b766e10dc --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550SerialPortHookLib/= Fdt16550SerialPortHookLib.c @@ -0,0 +1,57 @@ +/** @file + Platform Hook Library instance for 16550 Uart. + + Copyright (c) 2022, Loongson Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/** Platform hook to retrieve the 16550 UART base address from the GUID Hob + that caches the UART base address from early boot stage and store it in + PcdSerialRegisterBase. + + @retval RETURN_SUCCESS Success. + @retval RETURN_NOT_FOUND Serial Port information not found. + +**/ +RETURN_STATUS +EFIAPI +PlatformHookSerialPortInitialize ( + VOID + ) +{ + VOID *Hob; + UINT64 *UartBase; + + if (PcdGet64 (PcdSerialRegisterBase) !=3D 0) { + return RETURN_SUCCESS; + } + + Hob =3D GetFirstGuidHob (&gEarly16550UartBaseAddressGuid); + if ((Hob =3D=3D NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) !=3D sizeof (*Uar= tBase))) { + return RETURN_NOT_FOUND; + } + + UartBase =3D GET_GUID_HOB_DATA (Hob); + if ((UINTN)*UartBase =3D=3D 0) { + return RETURN_NOT_FOUND; + } + + return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase= ); +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550SerialPortH= ookLib/Fdt16550SerialPortHookLib.inf b/Platform/Loongson/LoongArchQemuPkg/L= ibrary/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf new file mode 100644 index 0000000000..cbc99864be --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/Fdt16550SerialPortHookLib/= Fdt16550SerialPortHookLib.inf @@ -0,0 +1,38 @@ +## @file +# Platform Hook Library instance for 16550 Uart. +# +# Copyright (c) 2022, Loongson Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D Fdt16550SerialPortHookLib + MODULE_UNI_FILE =3D Fdt16550SerialPortHookLib.uni + FILE_GUID =3D C6DFD3F0-179D-4376-89A5-F641A2E7EFB5 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformHookLib|DXE_CORE DXE_DRIVER U= EFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION + CONSTRUCTOR =3D PlatformHookSerialPortInitialize + +[Sources] + Fdt16550SerialPortHookLib.c + +[LibraryClasses] + BaseLib + PcdLib + HobLib + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase + +[Guids] + gEarly16550UartBaseAddressGuid diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/Early= SerialPortLib16550.c b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPor= tLib/EarlySerialPortLib16550.c new file mode 100644 index 0000000000..c713c6e9d6 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialP= ortLib16550.c @@ -0,0 +1,900 @@ +/** @file + 16550 UART Serial Port library functions + + Copyright (c) 2022, Loongson Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +// +// PCI Defintions. +// +#define PCI_BRIDGE_32_BIT_IO_SPACE 0x01 + +// +// 16550 UART register offsets and bitfields +// +#define R_UART_RXBUF 0 // LCR_DLAB =3D 0 +#define R_UART_TXBUF 0 // LCR_DLAB =3D 0 +#define R_UART_BAUD_LOW 0 // LCR_DLAB =3D 1 +#define R_UART_BAUD_HIGH 1 // LCR_DLAB =3D 1 +#define R_UART_IER 1 // LCR_DLAB =3D 0 +#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 + +/** + Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the val= ue is read from + MMIO space. If PcdSerialUseMmio is FALSE, then the value is read from I= /O space. The + parameter Offset is added to the base address of the 16550 registers tha= t is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMI= O space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to read. + + @return The value read from the 16550 register. +**/ +UINT8 +SerialPortReadRegister ( + UINTN Base, + UINTN Offset + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + if (PcdGet8 (PcdSerialRegisterAccessWidth) =3D=3D 32) { + return (UINT8)MmioRead32 (Base + Offset * PcdGet32 (PcdSerialRegiste= rStride)); + } + + return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } else { + return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } +} + +/** + Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the va= lue is written to + MMIO space. If PcdSerialUseMmio is FALSE, then the value is written to = I/O space. The + parameter Offset is added to the base address of the 16550 registers tha= t is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMI= O space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to write. + @param Value The value to write to the 16550 register specified by Of= fset. + + @return The value written to the 16550 register. +**/ +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + if (PcdGet8 (PcdSerialRegisterAccessWidth) =3D=3D 32) { + return (UINT8)MmioWrite32 (Base + Offset * PcdGet32 (PcdSerialRegist= erStride), (UINT8)Value); + } + + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride),= Value); + } else { + return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), V= alue); + } +} + +/** Get the UART base address of the console serial-port from the DT. + + This function fetches the node referenced in the "stdout-path" + property of the "chosen" node and returns the base address of + the console UART. + + @param [in] Fdt Pointer to a Flattened Device Tree (= Fdt). + @param [out] SerialConsoleAddress If success, contains the base address + of the console serial-port. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND Console serial-port info not found in DT. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GetSerialConsolePortAddress ( + IN CONST VOID *Fdt, + OUT UINT64 *SerialConsoleAddress + ) +{ + CONST CHAR8 *Prop; + INT32 PropSize; + CONST CHAR8 *Path; + INT32 PathLen; + INT32 ChosenNode; + INT32 SerialConsoleNode; + INT32 Len; + CONST CHAR8 *NodeStatus; + CONST UINT64 *RegProperty; + + if ((Fdt =3D=3D NULL) || (fdt_check_header (Fdt) !=3D 0)) { + return EFI_INVALID_PARAMETER; + } + + // The "chosen" node resides at the root of the DT. Fetch it. + ChosenNode =3D fdt_path_offset (Fdt, "/chosen"); + if (ChosenNode < 0) { + return EFI_NOT_FOUND; + } + + Prop =3D fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize); + if (PropSize < 0) { + return EFI_NOT_FOUND; + } + + // Determine the actual path length, as a colon terminates the path. + Path =3D ScanMem8 (Prop, ':', PropSize); + if (Path =3D=3D NULL) { + PathLen =3D AsciiStrLen (Prop); + } else { + PathLen =3D Path - Prop; + } + + // Aliases cannot start with a '/', so it must be the actual path. + if (Prop[0] =3D=3D '/') { + SerialConsoleNode =3D fdt_path_offset_namelen (Fdt, Prop, PathLen); + } else { + // Lookup the alias, as this contains the actual path. + Path =3D fdt_get_alias_namelen (Fdt, Prop, PathLen); + if (Path =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + SerialConsoleNode =3D fdt_path_offset (Fdt, Path); + } + + NodeStatus =3D fdt_getprop (Fdt, SerialConsoleNode, "status", &Len); + if ((NodeStatus !=3D NULL) && (AsciiStrCmp (NodeStatus, "okay") !=3D 0))= { + return EFI_NOT_FOUND; + } + + RegProperty =3D fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len); + if (Len !=3D 16) { + return EFI_INVALID_PARAMETER; + } + + *SerialConsoleAddress =3D fdt64_to_cpu (ReadUnaligned64 (RegProperty)); + + return EFI_SUCCESS; +} + +/** + Retrieve the I/O or MMIO base address register for the PCI UART device. + + This function assumes Root Bus Numer is Zero, and enables I/O and MMIO i= n PCI UART + Device if they are not already enabled. + + @return The base address register of the UART device. +**/ +UINTN +GetSerialRegisterBase ( + VOID + ) +{ + VOID *Base; + RETURN_STATUS Status; + UINT64 SerialConsoleAddress; + + Base =3D (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeBase); + Status =3D GetSerialConsolePortAddress (Base, &SerialConsoleAddress); + if (RETURN_ERROR (Status)) { + return (UINTN)0; + } + + return SerialConsoleAddress; +} + +/** + Return whether the hardware flow control signal allows writing. + + @param SerialRegisterBase The base address register of UART device. + + @retval TRUE The serial port is writable. + @retval FALSE The serial port is not writable. +**/ +BOOLEAN +SerialPortWritable ( + UINTN SerialRegisterBase + ) +{ + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + if (PcdGetBool (PcdSerialDetectCable)) { + // + // Wait for both DSR and CTS to be set + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // =3D=3D=3D =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D =3D=3D=3D=3D=3D=3D=3D=3D + // 0 0 No cable connected. Wait + // 0 1 No cable connected. Wait + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clear to send. Transmit + // + return (BOOLEAN)((SerialPortReadRegister (SerialRegisterBase, R_UART= _MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) =3D=3D (B_UART_MSR_DSR | B_UART_= MSR_CTS)); + } else { + // + // Wait for both DSR and CTS to be set OR for DSR to be clear. + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // =3D=3D=3D =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D =3D=3D=3D=3D=3D=3D=3D=3D + // 0 0 No cable connected. Transmit + // 0 1 No cable connected. Transmit + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clar to send. Transmit + // + return (BOOLEAN)((SerialPortReadRegister (SerialRegisterBase, R_UART= _MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) !=3D (B_UART_MSR_DSR)); + } + } + + return TRUE; +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SU= CCESS. + 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 serial device could not be initialized. +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + UINTN SerialRegisterBase; + UINT32 Divisor; + UINT32 CurrentDivisor; + BOOLEAN Initialized; + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor =3D PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate= ) * 16); + if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)= ) >=3D PcdGet32 (PcdSerialBaudRate) * 8) { + Divisor++; + } + + // + // Get the base address of the serial port in either I/O or MMIO space + // + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return RETURN_DEVICE_ERROR; + } + + // + // See if the serial port is already initialized + // + Initialized =3D TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != =3D (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized =3D FALSE; + } + + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialP= ortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); + CurrentDivisor =3D SerialPortReadRegister (SerialRegisterBase, R_UART_= BAUD_HIGH) << 8; + CurrentDivisor |=3D (UINT32)SerialPortReadRegister (SerialRegisterBase, = R_UART_BAUD_LOW); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialP= ortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB)); + if (CurrentDivisor !=3D Divisor) { + Initialized =3D FALSE; + } + + if (Initialized) { + return RETURN_SUCCESS; + } + + // + // Wait for the serial port to be ready. + // Verify that both the transmit FIFO and the shift register are empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UAR= T_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB= ); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(D= ivisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Di= visor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8= (PcdSerialLineControl) & 0x3F)); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8= (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); + + // + // Set FIFO Polled Mode by clearing IER after setting FCR + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); + + 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 devic= e. + If this value is less than NumberOfBytes, then = the write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINTN Index; + UINTN FifoSize; + + if (Buffer =3D=3D NULL) { + return 0; + } + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return 0; + } + + if (NumberOfBytes =3D=3D 0) { + // + // Flush the hardware + // + + // + // Wait for both the transmit FIFO and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_U= ART_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)= ) { + } + + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)) { + } + + return 0; + } + + // + // Compute the maximum size of the Tx FIFO + // + FifoSize =3D 1; + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) !=3D 0) { + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) =3D=3D 0) { + FifoSize =3D 16; + } else { + FifoSize =3D PcdGet32 (PcdSerialExtendedTxFifoSize); + } + } + + Result =3D NumberOfBytes; + while (NumberOfBytes !=3D 0) { + // + // Wait for the serial port to be ready, to make sure both the transmi= t FIFO + // and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_U= ART_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)= ) { + } + + // + // Fill then entire Tx FIFO + // + for (Index =3D 0; Index < FifoSize && NumberOfBytes !=3D 0; Index++, N= umberOfBytes--, Buffer++) { + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)) { + } + + // + // Write byte to the transmit buffer. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer); + } + } + + return Result; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data re= ad 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 +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINT8 Mcr; + + if (NULL =3D=3D Buffer) { + return 0; + } + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return 0; + } + + Mcr =3D (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) = & ~B_UART_MCR_RTS); + + for (Result =3D 0; NumberOfBytes-- !=3D 0; Result++, Buffer++) { + // + // Wait for the serial port to have some data. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UA= RT_LSR_RXRDY) =3D=3D 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(M= cr | B_UART_MCR_RTS)); + } + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + } + + // + // Read byte from the receive buffer. + // + *Buffer =3D SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF); + } + + return Result; +} + +/** + 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 FALS= E is returned. + + @retval TRUE Data is waiting to be read from the serial devi= ce. + @retval FALSE There is no data waiting to be read from the se= rial device. +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + UINTN SerialRegisterBase; + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return FALSE; + } + + // + // Read the serial port status + // + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LS= R_RXRDY) !=3D 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Ser= ialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS)); + } + + return TRUE; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Seria= lPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS)); + } + + return FALSE; +} + +/** + 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 seria= l device. + @retval RETURN_UNSUPPORTED The serial device does not support this op= eration. + @retval RETURN_DEVICE_ERROR The serial device is not functioning corre= ctly. +**/ +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))) !=3D 0) + { + return RETURN_UNSUPPORTED; + } + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + // + // Read the Modem Control Register. + // + Mcr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + Mcr &=3D (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); + + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) =3D=3D EFI_SERIAL_DATA_TE= RMINAL_READY) { + Mcr |=3D B_UART_MCR_DTRC; + } + + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) =3D=3D EFI_SERIAL_REQUEST_TO_= SEND) { + Mcr |=3D 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 si= gnals 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 op= eration. + @retval RETURN_DEVICE_ERROR The serial device is not functioning corre= ctly. +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + *Control =3D 0; + + // + // Read the Modem Status Register. + // + Msr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); + + if ((Msr & B_UART_MSR_CTS) =3D=3D B_UART_MSR_CTS) { + *Control |=3D EFI_SERIAL_CLEAR_TO_SEND; + } + + if ((Msr & B_UART_MSR_DSR) =3D=3D B_UART_MSR_DSR) { + *Control |=3D EFI_SERIAL_DATA_SET_READY; + } + + if ((Msr & B_UART_MSR_RI) =3D=3D B_UART_MSR_RI) { + *Control |=3D EFI_SERIAL_RING_INDICATE; + } + + if ((Msr & B_UART_MSR_DCD) =3D=3D B_UART_MSR_DCD) { + *Control |=3D EFI_SERIAL_CARRIER_DETECT; + } + + // + // Read the Modem Control Register. + // + Mcr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + + if ((Mcr & B_UART_MCR_DTRC) =3D=3D B_UART_MCR_DTRC) { + *Control |=3D EFI_SERIAL_DATA_TERMINAL_READY; + } + + if ((Mcr & B_UART_MCR_RTS) =3D=3D B_UART_MCR_RTS) { + *Control |=3D EFI_SERIAL_REQUEST_TO_SEND; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + *Control |=3D EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + + // + // Read the Line Status Register. + // + Lsr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_LSR); + + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) =3D=3D (B_UART_LSR_TEMT= | B_UART_LSR_TXRDY)) { + *Control |=3D EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + + if ((Lsr & B_UART_LSR_RXRDY) =3D=3D 0) { + *Control |=3D EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parit= y, + 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 d= evice's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial devic= e. A Parity value of + DefaultParity will use the device's default pa= rity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial d= evice. 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 ser= ial device. + @retval RETURN_UNSUPPORTED The serial device does not support thi= s operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an u= nsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning c= orrectly. +**/ +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; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + + SerialRegisterBase =3D GetSerialRegisterBase (); + if (SerialRegisterBase =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + // + // Check for default settings and fill in actual values. + // + if (*BaudRate =3D=3D 0) { + *BaudRate =3D PcdGet32 (PcdSerialBaudRate); + } + + SerialBaudRate =3D (UINT32)*BaudRate; + + if (*DataBits =3D=3D 0) { + LcrData =3D (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3); + *DataBits =3D LcrData + 5; + } else { + if ((*DataBits < 5) || (*DataBits > 8)) { + return RETURN_INVALID_PARAMETER; + } + + // + // Map 5..8 to 0..3 + // + LcrData =3D (UINT8)(*DataBits - (UINT8)5); + } + + if (*Parity =3D=3D DefaultParity) { + LcrParity =3D (UINT8)((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); + switch (LcrParity) { + 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; + } + } else { + switch (*Parity) { + 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_INVALID_PARAMETER; + } + } + + if (*StopBits =3D=3D DefaultStopBits) { + LcrStop =3D (UINT8)((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); + switch (LcrStop) { + case 0: + *StopBits =3D OneStopBit; + break; + + case 1: + if (*DataBits =3D=3D 5) { + *StopBits =3D OneFiveStopBits; + } else { + *StopBits =3D TwoStopBits; + } + + break; + + default: + break; + } + } else { + switch (*StopBits) { + case OneStopBit: + LcrStop =3D 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + LcrStop =3D 1; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor =3D PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >=3D SerialB= audRate * 8) { + Divisor++; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB= ); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(D= ivisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Di= visor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from line control value + // + Lcr =3D (UINT8)((LcrParity << 3) | (LcrStop << 2) | LcrData); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Lcr & 0= x3F)); + + return RETURN_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/Early= SerialPortLib16550.inf b/Platform/Loongson/LoongArchQemuPkg/Library/SerialP= ortLib/EarlySerialPortLib16550.inf new file mode 100644 index 0000000000..ee7b5fda18 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/SerialPortLib/EarlySerialP= ortLib16550.inf @@ -0,0 +1,46 @@ +## @file +# SerialPortLib instance for 16550 UART. +# +# Copyright (c) 2022, Loongson Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D EarlySerialPortLib16550 + FILE_GUID =3D f4fb883d-8138-4f29-bb0c-c574e9312c74 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SerialPortLib + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[LibraryClasses] + BaseLib + IoLib + PcdLib + FdtLib + +[Sources] + EarlySerialPortLib16550.c + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterAccessWidth ## SOMET= IMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMET= IMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSU= MES + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase ## CONSU= MES --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96449): https://edk2.groups.io/g/devel/message/96449 Mute This Topic: https://groups.io/mt/95082586/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96451+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96451+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652804; cv=none; d=zohomail.com; s=zohoarc; b=PkZmQcx9nq3FTBjYg3ZFgCMMK8ahSZyvF0QNtuDrnuftfaib7Tx1ol/koo2txUj25SMCA32wbh56+lYmFP5iH+GjIIuQonlorfdyx4RVnPORrcoLn94jLmWOVpaqWFJImrrAdxCFgykSMXghiO1Nqeoc2b+Ngl4wsiXXYktf2dw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652804; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=FoIsgAzqSA1Yn7D03fTR+x/5iPFScKDxWgaa1p9LZJY=; b=M/v4rLxs4HRK3uy6Ts3yB92nODl45L4IcwJwKGmxVnHvmIOcRDVfR2uf98zhTUKElOmvCVKAjOw2mzzrSyu/5ax7SMNRovDk8xTSY8WPCAx74mLQURHMaH7JLSqQ2rE9/+vgfxYIpTLoLkA2lyhg4F88zupz5leUcB9pSDisDto= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96451+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 166865280487949.430243259143026; Wed, 16 Nov 2022 18:40:04 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id NlCYYY1788612x3YAwtyf822; Wed, 16 Nov 2022 18:40:04 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6323.1668652801586328049 for ; Wed, 16 Nov 2022 18:40:02 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8BxHLf9nnVj8yMIAA--.11748S3; Thu, 17 Nov 2022 10:39:57 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S4; Thu, 17 Nov 2022 10:39:56 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 02/16] Platform/Loongson: Support SEC Date: Thu, 17 Nov 2022 10:39:28 +0800 Message-Id: <77cf6ba26c5b537704f13360dada5a6b79af2205.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S4 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWftr45WFWrtryrJFW8GrWktFb_yoW5CrW7Co WxWFWIkw48Gr1rZw1UGrnrJrW8AF1rXa15tr1rX34DGF4jyF1DKa98J3srGw15Jwn8J3Z8 G34rGaykJrW7t3Wkn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqq1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6x kF7I0E14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020E x4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E74AGY7Cv6cx26rWlOx8S6xCaFV Cjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7VAKI48JMxAIw28IcVCjz48v 1sIEY20_WwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcV CF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7xRE6wZ7UUUUU== Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: xhGbQrYKcCYpCLixOie9XAVWx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652804; bh=XsF2CfRvpzknieJrKvP0HB32D2UJUvRfBOAR4f8vUHQ=; h=Cc:Date:From:Reply-To:Subject:To; b=trRWwGIg0CUqhenp3aM50Wjg8IwXfhDreTzc0nUKjsqpJItufm1hl/RNq32cQaZX3wQ ZNVWdwkVJJeeCXa1vRp1Qm6DIrWS4e7FHANJcb5QPnTd5f8tzusTsqQfIceziCE319hgH WPj4OXRHwb3kD/3dfwF6HuKEg1yLIao0/8E= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652805889100021 Content-Type: text/plain; charset="utf-8" Add SEC Code And Readme.md for LoongArchQemu REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li Signed-off-by: xianglai li --- .../Loongson/LoongArchQemuPkg/Loongson.dec | 38 ++ .../Loongson/LoongArchQemuPkg/Loongson.dsc | 132 +++++ .../Loongson/LoongArchQemuPkg/Loongson.fdf | 53 ++ .../LoongArchQemuPkg/Loongson.fdf.inc | 21 + .../LoongArchQemuPkg/Sec/LoongArch64/Start.S | 84 +++ .../Loongson/LoongArchQemuPkg/Sec/SecMain.c | 494 ++++++++++++++++++ .../Loongson/LoongArchQemuPkg/Sec/SecMain.inf | 51 ++ 7 files changed, 873 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.dec create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.dsc create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Star= t.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dec new file mode 100644 index 0000000000..61f600b20d --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec @@ -0,0 +1,38 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010005 + PACKAGE_NAME =3D LoongArchQemuPkg + PACKAGE_GUID =3D b51d765a-41da-45fc-a537-de3ee785c0f6 + PACKAGE_VERSION =3D 0.1 + +##########################################################################= ###### +# +# Include Section - list of Include Paths that are provided by this packag= e. +# Comments are used for Keywords and Module Types. +# +# Supported Module Types: +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_D= RIVER +# DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION +# +##########################################################################= ###### +[Includes.common] + Include # Root include for the package + +[Guids] + gLoongArchQemuPkgTokenSpaceGuid =3D { 0x0e0383ce, 0x0151, 0x4d01, { 0x8= 0, 0x0e, 0x3f, 0xef, 0x8b, 0x27, 0x6d, 0x52 } } + +## In the PcdsFixedAtBuild and PcdsDynamic areas, numbers start at 0x0. +[PcdsFixedAtBuild, PcdsDynamic] + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase|0x0|UINT64|0x00000000 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize|0x0|UINT32|0x00000001 + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase|0|UINT64|0x0000000b + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize|0|UINT32|0x0000000c + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|0x0|UINT64|0x0000000f + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize|0x0|UINT32|0x00000010 diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dsc new file mode 100644 index 0000000000..049be907dd --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc @@ -0,0 +1,132 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ##### +[Defines] + PLATFORM_NAME =3D LoongArchQemu + PLATFORMPKG_NAME =3D LoongArchQemu + PLATFORM_GUID =3D 7926ea52-b0dc-4ee8-ac63-341eebd84ed4 + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES =3D LOONGARCH64 + BUILD_TARGETS =3D DEBUG|RELEASE + SKUID_IDENTIFIER =3D DEFAULT + FLASH_DEFINITION =3D Platform/Loongson/LoongArchQemuPkg/Lo= ongson.fdf + TTY_TERMINAL =3D FALSE + +##########################################################################= ## +# +# Defines for default states. These can be changed on the command line. +# -D FLAG=3DVALUE +##########################################################################= ## +[BuildOptions] + GCC:RELEASE_*_*_CC_FLAGS =3D -DSPEEDUP + + # + # Disable deprecated APIs. + # + GCC:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES + +[BuildOptions.LOONGARCH64.EDKII.SEC] + *_*_*_CC_FLAGS =3D + +[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,B= uildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICA= TION] + GCC:*_*_*_DLINK_FLAGS =3D -z common-page-size=3D0x1000 + +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] + GCC:*_*_LOONGARCH64_DLINK_FLAGS =3D -z common-page-size=3D0x10000 + +##########################################################################= ###### +# +# Library Class section - list of all Library Classes needed by this Platf= orm. +# +##########################################################################= ###### + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses.common] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + PrintLib | MdePkg/Library/BasePrintLib/BasePrint= Lib.inf + BaseMemoryLib | MdePkg/Library/BaseMemoryLib/BaseMemo= ryLib.inf + BaseLib | MdePkg/Library/BaseLib/BaseLib.inf + PeCoffLib | MdePkg/Library/BasePeCoffLib/BasePeCo= ffLib.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf + IoLib | MdePkg/Library/BaseIoLibIntrinsic/Bas= eIoLibIntrinsic.inf + PlatformHookLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf + SerialPortLib | MdeModulePkg/Library/BaseSerialPortLi= b16550/BaseSerialPortLib16550.inf + DebugPrintErrorLevelLib | MdePkg/Library/BaseDebugPrintErrorLev= elLib/BaseDebugPrintErrorLevelLib.inf + PeCoffExtraActionLib | MdePkg/Library/BasePeCoffExtraActionL= ibNull/BasePeCoffExtraActionLibNull.inf + DebugAgentLib | MdeModulePkg/Library/DebugAgentLibNul= l/DebugAgentLibNull.inf + +##########################################################################= ###### +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform. +# +##########################################################################= ###### +[PcdsFixedAtBuild] +## BaseLib ## + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength | 1= 000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength | 1= 000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength | 1= 000000 + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0= x8000004F + + # Use MMIO for accessing Serial port registers. + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio | T= RUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo | {= 0xFF} + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate | 1= 15200 + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) + # DEBUG_INFO 0x00000040 // Informational debug messages + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // Network Io Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // LoadFile + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + # DEBUG_ERROR 0x80000000 // Error + +!if $(TARGET) =3D=3D RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0= x21 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0= x2f +!endif + # DEBUG_ASSERT_ENABLED 0x01 + # DEBUG_PRINT_ENABLED 0x02 + # DEBUG_CODE_ENABLED 0x04 + # CLEAR_MEMORY_ENABLED 0x08 + # ASSERT_BREAKPOINT_ENABLED 0x10 + # ASSERT_DEADLOOP_ENABLED 0x20 + + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase | 0= x10000 + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize | 0= x10000 + +[PcdsPatchableInModule.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0 + +[Components] + + # + # SEC Phase modules + # + Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.fdf new file mode 100644 index 0000000000..9685795cda --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf @@ -0,0 +1,53 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ########################### +[Defines] +!include Loongson.fdf.inc + +##########################################################################= ########################### +[FD.QEMU_EFI] +BaseAddress =3D $(FD_BASE_ADDRESS) +Size =3D $(FD_SIZE) +ErasePolarity =3D 1 +BlockSize =3D $(BLOCK_SIZE) +NumBlocks =3D $(FD_BLOCKS) + +$(SECFV_OFFSET)|$(SECFV_SIZE) +gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|gLoongArchQemuPkgTokenSp= aceGuid.PcdFlashSecFvSize +FV =3D SECFV + +##########################################################################= ########################### +[FV.SECFV] +FvNameGuid =3D 587d4265-5e71-41da-9c35-4258551f1e22 +BlockSize =3D $(BLOCK_SIZE) +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE + +INF Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf + +##########################################################################= ########################### +[Rule.Common.SEC] + FILE SEC =3D $(NAMED_GUID) { + TE TE Align =3D Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING =3D"$(MODULE_NAME)" Optional + } diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc b/Platform= /Loongson/LoongArchQemuPkg/Loongson.fdf.inc new file mode 100644 index 0000000000..6f17909748 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc @@ -0,0 +1,21 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +DEFINE BLOCK_SIZE =3D 0x1000 + +##########################################################################= ## +# fd total +DEFINE FD_BASE_ADDRESS =3D 0x1c000000 +DEFINE FD_BLOCKS =3D 0x400 +DEFINE FD_SIZE =3D 0x400000 + +##########################################################################= ## +#flash code layout +#Set Sec base address and size in flash +DEFINE SECFV_OFFSET =3D 0x00000000 +DEFINE SECFV_SIZE =3D 0x00010000 diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S b/P= latform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S new file mode 100644 index 0000000000..5d7ce313c0 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/LoongArch64/Start.S @@ -0,0 +1,84 @@ +#-------------------------------------------------------------------------= ----- +# +# Start for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - CSR - CPU Status Register +# - EBASE - Exception Base Address +#-------------------------------------------------------------------------= ----- +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include + +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_GLOBAL ASM_PFX(DeadLoop) + +.text +ASM_PFX(_ModuleEntryPoint): + /* configure reset ebase */ + la.pcrel T0, DeadLoop + csrwr T0, LOONGARCH_CSR_EBASE + + /*disable interrupt*/ + li.d T0, (1 << 2) + csrxchg ZERO, T0, LOONGARCH_CSR_CRMD + + /* read physical cpu number id */ + csrrd T0, LOONGARCH_CSR_CPUNUM + andi T0, T0, 0x3ff + li.d A0, BOOTCORE_ID //0 + bne T0, A0, slave_main + +call_centry: + /*call C function make sure parameter true*/ + li.d A1, FixedPcdGet64(PcdSecPeiTempRamBase) + FixedPcdGet32(PcdSec= PeiTempRamSize) # stack base + li.d A0, FixedPcdGet64(PcdFlashPeiFvBase) # PEI Fv base + move SP, A1 + addi.d SP, SP, -0x8 + bl SecCoreStartupWithStack + +slave_main: + # clear mailbox + li.d T1, LOONGSON_CSR_MAIL_BUF0 + iocsrwr.d ZERO, T1 + + # enable IPI interrupt + li.d T0, (1 << 12) + csrxchg T0, T0, LOONGARCH_CSR_ECFG + + addi.d T0, ZERO, -1 + li.d T1, LOONGSON_IOCSR_IPI_EN + iocsrwr.w T0, T1 + +1: + # wait for wakeup + idle 0 + nop + iocsrrd.w T0, T1 + beqz T0, 1b + + # read and clear ipi interrupt + li.d T1, LOONGSON_IOCSR_IPI_STATUS + iocsrrd.w T0, T1 + li.d T1, LOONGSON_IOCSR_IPI_CLEAR + iocsrwr.w T0, T1 + + # disable IPI interrupt + li.d T0, (1 << 12) + csrxchg ZERO, T0, LOONGARCH_CSR_ECFG + + # read mail buf and jump to specified entry + li.d T1, LOONGSON_CSR_MAIL_BUF0 + iocsrrd.d T0, T1 + or RA, T0, ZERO + jirl ZERO, RA, 0x0 + +.align 12 +ASM_PFX(DeadLoop): + b DeadLoop diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c b/Platform/Lo= ongson/LoongArchQemuPkg/Sec/SecMain.c new file mode 100644 index 0000000000..3f1998c48c --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.c @@ -0,0 +1,494 @@ +/** @file + Main SEC phase code. Transitions to PEI. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + temporary memory to permanent memory and do stack switching. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Temporary Memory Base address. + @param[in] PermanentMemoryBase Permanent Memory Base address. + @param[in] CopySize The size of memory that needs to be migrated. + + @retval EFI_SUCCESS Migration successful. +**/ +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =3D { + TemporaryRamMigration +}; + +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamSupportPpiGuid, + &mTemporaryRamSupportPpi + }, +}; + +/** + Locates a section within a series of sections + with the specified section type. + + The Instance parameter indicates which instance of the section + type to return. (0 is first instance, 1 is second...) + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[in] Instance The section instance number + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +FindFfsSectionInstance ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + IN UINTN Instance, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfSections; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + // + // Loop through the FFS file sections within the PEI Core FFS file + // + EndOfSection =3D (EFI_PHYSICAL_ADDRESS) (UINTN) Sections; + EndOfSections =3D EndOfSection + SizeOfSections; + for (;;) { + if (EndOfSection =3D=3D EndOfSections) { + break; + } + CurrentAddress =3D (EndOfSection + 3) & ~(3ULL); + if (CurrentAddress >=3D EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + Section =3D (EFI_COMMON_SECTION_HEADER*) (UINTN) CurrentAddress; + + Size =3D SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the requested section type + // + if (Section->Type =3D=3D SectionType) { + if (Instance =3D=3D 0) { + *FoundSection =3D Section; + return EFI_SUCCESS; + } else { + Instance--; + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Locates a section within a series of sections + with the specified section type. + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +FindFfsSectionInSections ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + return FindFfsSectionInstance ( + Sections, + SizeOfSections, + SectionType, + 0, + FoundSection + ); +} + +/** + Locates a FFS file with the specified file type and a section + within that file with the specified section type. + + @param[in] Fv The firmware volume to search + @param[in] FileType The file type to locate + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +FindFfsFileAndSection ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + IN EFI_FV_FILETYPE FileType, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", F= v)); + return EFI_VOLUME_CORRUPTED; + } + + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS) (UINTN) Fv; + EndOfFirmwareVolume =3D CurrentAddress + Fv->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile =3D CurrentAddress + Fv->HeaderLength; ; ) { + + CurrentAddress =3D (EndOfFile + 7) & ~(7ULL); + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + File =3D (EFI_FFS_FILE_HEADER*) (UINTN) CurrentAddress; + Size =3D *(UINT32*) File->Size & 0xffffff; + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfFile =3D CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the request file type + // + if (File->Type !=3D FileType) { + continue; + } + + Status =3D FindFfsSectionInSections ( + (VOID*) (File + 1), + (UINTN) EndOfFile - (UINTN) (File + 1), + SectionType, + FoundSection + ); + if (!EFI_ERROR (Status) + || (Status =3D=3D EFI_VOLUME_CORRUPTED)) + { + return Status; + } + } +} + +/** + Locates the PEI Core entry point address + + @param[in] Fv The firmware volume to search + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +FindPeiCoreImageBaseInFv ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_STATUS Status; + EFI_COMMON_SECTION_HEADER *Section; + + Status =3D FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_PE32, + &Section + ); + if (EFI_ERROR (Status)) { + Status =3D FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_TE, + &Section + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n")); + return Status; + } + } + + *PeiCoreImageBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1); + return EFI_SUCCESS; +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report the= m if + remote debug is enabled. +**/ +VOID +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase =3D 0; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + Status =3D FindPeiCoreImageBaseInFv (*BootFirmwareVolumePtr, &PeiCoreIma= geBase); + ASSERT (Status =3D=3D EFI_SUCCESS); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageB= ase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) I= mageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status =3D PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,= (VOID**) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint =3D 0; + } + + return; +} + +/** + Find the peicore entry point and jump to the entry point to execute. + + @param[in] Context The first input parameter of InitializeDebugAgent(= ). +**/ +VOID +EFIAPI +SecStartupPhase2 ( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_FIRMWARE_VOLUME_HEADER *BootFv; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData =3D (EFI_SEC_PEI_HAND_OFF *) Context; + + // + // Find PEI Core entry point. It will report SEC and Pei Core debug info= rmation if remote debug + // is enabled. + // + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolume= Base; + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); + SecCoreData->BootFirmwareVolumeBase =3D BootFv; + SecCoreData->BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength; + + DEBUG ((DEBUG_INFO, "Find Pei EntryPoint=3D%p\n", PeiCoreEntryPoint)); + + // + // Transfer the control to the PEI core + // + DEBUG ((DEBUG_INFO, "SecStartupPhase2 %p\n", PeiCoreEntryPoint)); + + (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDi= spatchTable); + + // + // If we get here then the PEI Core returned, which is not recoverable. + // + ASSERT (FALSE); + CpuDeadLoop (); +} +/** + Entry point to the C language phase of SEC. initialize some temporary me= mory and set up the stack, + the control is transferred to this function. + + @param[in] BootFv The pointer to the PEI FV in memory. + @param[in] TopOfCurrentStack Top of Current Stack. +**/ +VOID +EFIAPI +SecCoreStartupWithStack ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, + IN VOID *TopOfCurrentStack + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + EFI_FIRMWARE_VOLUME_HEADER *BootPeiFv =3D (EFI_FIRMWARE_VOLUME_HEA= DER*) BootFv; + + DEBUG ((DEBUG_INFO, "Entering C environment\n")); + + ProcessLibraryConstructorList (NULL, NULL); + + DEBUG ((DEBUG_INFO, + "SecCoreStartupWithStack (0x%lx, 0x%lx)\n", + (UINTN)BootFv, + (UINTN)TopOfCurrentStack + )); + DEBUG ((DEBUG_INFO, + "(0x%lx, 0x%lx)\n", + (UINTN) (PcdGet64 (PcdSecPeiTempRamBase)), + (UINTN) (PcdGet32 (PcdSecPeiTempRamSize)) + )); + + // |-------------| <-- TopOfCurrentStack + // | Stack | 32k + // |-------------| + // | Heap | 32k + // |-------------| <-- SecCoreData.TemporaryRamBase + // + + ASSERT ((UINTN) (PcdGet64 (PcdSecPeiTempRamBase) + + PcdGet32 (PcdSecPeiTempRamSize)) =3D=3D + (UINTN) TopOfCurrentStack); + + // + // Initialize SEC hand-off state + // + SecCoreData.DataSize =3D sizeof (EFI_SEC_PEI_HAND_OFF); + + SecCoreData.TemporaryRamSize =3D (UINTN) PcdGet32 (PcdSecPeiTempRa= mSize); + SecCoreData.TemporaryRamBase =3D (VOID *) PcdGet64 (PcdSecPeiTempR= amBase); + + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRam= Base + SecCoreData.PeiTemporaryRamSize; + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.BootFirmwareVolumeBase =3D BootPeiFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN) BootPeiFv->FvLength; + + DEBUG ((DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeBase=3D%lx SecCoreData.BootFirmwareVol= umeBase=3D%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeBase), + (UINT64) (SecCoreData.BootFirmwareVolumeBase))); + DEBUG ((DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeSize=3D%lx SecCoreData.BootFirmwareVol= umeSize=3D%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeSize), + (UINT64) (SecCoreData.BootFirmwareVolumeSize))); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phase= s before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL); + SecStartupPhase2 (&SecCoreData); +} + +/** + temporary memory to permanent memory and do stack switching. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Temporary Memory Base address. + @param[in] PermanentMemoryBase Permanent Memory Base address. + @param[in] CopySize The size of memory that needs to be migrated. + + @retval EFI_SUCCESS Migration successful. +**/ +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + VOID *OldHeap; + VOID *NewHeap; + VOID *OldStack; + VOID *NewStack; + BASE_LIBRARY_JUMP_BUFFER JumpBuffer; + + DEBUG ((DEBUG_INFO, + "TemporaryRamMigration (0x%Lx, 0x%Lx, 0x%Lx)\n", + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize + )); + + OldHeap =3D (VOID*) (UINTN)TemporaryMemoryBase; + NewHeap =3D (VOID*) ((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack =3D (VOID*) ((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack =3D (VOID*) (UINTN)PermanentMemoryBase; + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize >> 1); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, CopySize >> 1); + + // Use SetJump ()/LongJump () to switch to a new stack. + // + if (SetJump (&JumpBuffer) =3D=3D 0) { + JumpBuffer.SP =3D JumpBuffer.SP - (UINTN)OldStack + (UINTN)NewStack ; + LongJump (&JumpBuffer, (UINTN)-1); + } + + return EFI_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf b/Platform/= Loongson/LoongArchQemuPkg/Sec/SecMain.inf new file mode 100644 index 0000000000..c0d5439d53 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf @@ -0,0 +1,51 @@ +## @file +# SEC Driver +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SecMain + FILE_GUID =3D 57d02d4f-5a5d-4bfa-b7d6-ba0a4d2c72ce + MODULE_TYPE =3D SEC + VERSION_STRING =3D 1.0 + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + LoongArch64/Start.S + SecMain.c + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + PcdLib + DebugAgentLib + IoLib + PeCoffLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + +[Ppis] + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + +[FixedPcd] + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize + + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96451): https://edk2.groups.io/g/devel/message/96451 Mute This Topic: https://groups.io/mt/95082588/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96447+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96447+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652803; cv=none; d=zohomail.com; s=zohoarc; b=fU5BRQQSYvZoyGxmXsGVe4SNKd6Rn31WFarClFFssV7qd8ctxnGLNRTAxM8GVxVCJZ1qtFcl0OamW88/n3BKXLpJpcza+er2lSmf9LZlBn5iEL1viuxrQeu7BordCL2+z6L3M1A4CWz7c3wrN/vrPN+k2UEY0i/FyTrWQlLbvqE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652803; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=kW3Q0a4JIHDKahwCFmzs37yTmfuAIRmJvoZwoEsitZY=; b=FSHj8Ycoqgkp+Zkz6Hv3i1K1FkFJqcmi9RvVVaUIxFGMbk+EA7huG65A3zlx3tcLL/hYlXiFmKHR2fB3JuyZe8PRW17JcGY85yVw7w2aygvQZFvfnbdsBBjWPdV13U1Exv+AUtYPvYhXCkTUJRHrguLUcxKJwb/9ex4mCcmAf3c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96447+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 166865280311567.646764654408; Wed, 16 Nov 2022 18:40:03 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id QGcxYY1788612xjJf24ChZBu; Wed, 16 Nov 2022 18:40:02 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6319.1668652800602856745 for ; Wed, 16 Nov 2022 18:40:01 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Bxnrf+nnVj9yMIAA--.18461S3; Thu, 17 Nov 2022 10:39:58 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S5; Thu, 17 Nov 2022 10:39:57 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 03/16] Platform/Loongson: Add PeiServicesTablePointerLib. Date: Thu, 17 Nov 2022 10:39:29 +0800 Message-Id: <066fe5aa785feb712a3cc00f94328f46bfa8ebe6.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S5 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvJXoW3Gr1ftr17CF47Ar17KryDJrb_yoW3AFyUpr 43WFs7Kr1UJrWIgryYqa15CFW5AFsrCr98Crs7XF1rC34kZry0qryjvFWFkFyrua45Aw1I gryFkw4Uu3WUXF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bnxFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4 AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF 7I0E14v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7 CjxVAFwI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2 zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VCjz48v1sIEY20_WwAm72CE4IkC6x 0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxF aVAv8VWrMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxV Cjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY 6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6x AIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY 1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7xRE6wZ7UUUUU== Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: abnjxHbH0QUozTiOuNpLUQasx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652802; bh=3H1aoVtSQu6F/zGwd5d8jruwtuFiuiKAGQ/WmpYZMhg=; h=Cc:Date:From:Reply-To:Subject:To; b=izY73yJ/mpy9xySTdgfsYxyCOJ5da1oO7KVjMGoJHuOpt9FlzSRrbo3ZXWttItsonDh wezy1bIJFtdZ/HDtKWT9L29UC6nKXEISS9ir1q0DDhdn6nbzRK+rKG1hRn9pwZlIakD8A vmjcl8XTufXRs8c1VJhXZ9IVYXswbIOr82I= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652803866100002 Content-Type: text/plain; charset="utf-8" Use a register to save PeiServicesTable pointer, This lib Provides PeiServicesTable pointer saving and retrieval services. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../PeiServicesTablePointer.c | 79 +++++++++++++++++++ .../PeiServicesTablePointer.h | 39 +++++++++ .../PeiServicesTablePointerLib.S | 40 ++++++++++ .../PeiServicesTablePointerLib.inf | 32 ++++++++ 4 files changed, 190 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesT= ablePointerLib/PeiServicesTablePointer.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesT= ablePointerLib/PeiServicesTablePointer.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesT= ablePointerLib/PeiServicesTablePointerLib.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesT= ablePointerLib/PeiServicesTablePointerLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePoi= nterLib/PeiServicesTablePointer.c b/Platform/Loongson/LoongArchQemuPkg/Libr= ary/PeiServicesTablePointerLib/PeiServicesTablePointer.c new file mode 100644 index 0000000000..204def3bde --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePointerLib= /PeiServicesTablePointer.c @@ -0,0 +1,79 @@ +/** @file + PEI Services Table Pointer Library. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include "Library/Cpu.h" +#include "PeiServicesTablePointer.h" + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTab= lePointer + in a platform specific manner. + + If PeiServicesTablePointer is NULL, then ASSERT (). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + LoongarchWriteqKs0 ((UINTN)PeiServicesTablePointer); +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU spec= ific manner + as specified in the CPU binding section of the Platform Initialization P= re-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT (). + + @return The pointer to PeiServices. +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + UINTN val; + + LoongarchReadqKs0 (&val); + + return (CONST EFI_PEI_SERVICES **)val; +} + +/** +Perform CPU specific actions required to migrate the PEI Services Table +pointer from temporary RAM to permanent RAM. + +For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes +immediately preceding the Interrupt Descriptor Table (IDT) in memory. +For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes +immediately preceding the Interrupt Descriptor Table (IDT) in memory. +For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in +a dedicated CPU register. This means that there is no memory storage +associated with storing the PEI Services Table pointer, so no additional +migration actions are required for Itanium or ARM CPUs. +*/ +VOID +EFIAPI +MigratePeiServicesTablePointer ( +VOID +) +{ + return; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePoi= nterLib/PeiServicesTablePointer.h b/Platform/Loongson/LoongArchQemuPkg/Libr= ary/PeiServicesTablePointerLib/PeiServicesTablePointer.h new file mode 100644 index 0000000000..5bcbc810d0 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePointerLib= /PeiServicesTablePointer.h @@ -0,0 +1,39 @@ +/** @file + PeiServicesTablePointer + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PEISERVICESTABLEPOINTER_H_ +#define PEISERVICESTABLEPOINTER_H_ + +/** + Write Csr KS0 register. + + @param A0 The value used to write to the KS0 register + + @retval none +**/ +extern +VOID +LoongarchWriteqKs0 ( + IN UINT64 Val + ); + +/** + Read Csr KS0 register. + + @param Val Pointer to the variable used to store the KS0 register value + + @retval none +**/ +extern +VOID +LoongarchReadqKs0 ( + IN UINT64 *Val + ); + +#endif // PEISERVICESTABLEPOINTER_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePoi= nterLib/PeiServicesTablePointerLib.S b/Platform/Loongson/LoongArchQemuPkg/L= ibrary/PeiServicesTablePointerLib/PeiServicesTablePointerLib.S new file mode 100644 index 0000000000..7c6170c5d6 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePointerLib= /PeiServicesTablePointerLib.S @@ -0,0 +1,40 @@ +#-------------------------------------------------------------------------= ----- +# +# Timer Cfg for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ----- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" + +ASM_GLOBAL ASM_PFX(LoongarchWriteqKs0) +ASM_GLOBAL ASM_PFX(LoongarchReadqKs0) + +# +# Write Csr KS0 register. +# @param A0 The value used to write to the KS0 register +# @retval none +# + +ASM_PFX(LoongarchWriteqKs0): + csrwr A0, LOONGARCH_CSR_KS0 + jirl ZERO, RA,0 + +# +# Write Csr KS0 register. +# @param A0 Pointer to the variable used to store the KS0 register value +# @retval none +# + +ASM_PFX(LoongarchReadqKs0): + csrrd T0, LOONGARCH_CSR_KS0 + stptr.d T0, A0, 0 + jirl ZERO, RA,0 + jirl ZERO, RA,0 diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePoi= nterLib/PeiServicesTablePointerLib.inf b/Platform/Loongson/LoongArchQemuPkg= /Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf new file mode 100644 index 0000000000..2ab0d53d4c --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PeiServicesTablePointerLib= /PeiServicesTablePointerLib.inf @@ -0,0 +1,32 @@ +## @file +# PEI Services Table Pointer Library. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiServicesTablePointerLib + FILE_GUID =3D C3C9C4ED-EB8A-4548-BE1B-ABB0B6F35B1E + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PeiServicesTablePointerLib|PEIM PEI_C= ORE SEC + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + PeiServicesTablePointer.c + PeiServicesTablePointerLib.S + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + +[Pcd] --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96447): https://edk2.groups.io/g/devel/message/96447 Mute This Topic: https://groups.io/mt/95082584/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96446+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96446+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652802; cv=none; d=zohomail.com; s=zohoarc; b=L092jrMUt9ZDaZVCKOFTz57usYvtqzyr8C84XgrIwd/gfpTsrbhZcno4JIaU2TzzPXyioR5GkBNn/uetUaKNGjX+agpaluViX5eFlijTpugzVgtyhoOO8SP92NoxklwaR0rHfy9qvXpL6cFPqc0HUg4VnqyafttmFdfGdNaii9I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652802; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=U2Zx4/eKJN/+x62cscLCDRKVCLa0YKCB23wU9niK3rQ=; b=lDrGWxTyQ4f14LaZnKH2KP/VtKa50mvfkkRjbjLGUwQHobbK/FgM5D8e69E3Pbq9Wnbt631vW9+kO5T99qRglSYfHLsZMUgRbGmib4BzERf1mYVzSOyJpXj69h/xQfZtOHEqjO+vDejSk9i2/AMxAd2b5kUfHhn7D//9eKhPYWs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96446+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16686528022881001.3895453253672; Wed, 16 Nov 2022 18:40:02 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 24LEYY1788612xOGf5ALijIY; Wed, 16 Nov 2022 18:40:01 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.6218.1668652800726229224 for ; Wed, 16 Nov 2022 18:40:01 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Dxu9j+nnVjAiQIAA--.23193S3; Thu, 17 Nov 2022 10:39:58 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S6; Thu, 17 Nov 2022 10:39:58 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 04/16] Platform/Loongson: Add QemuFwCfgLib. Date: Thu, 17 Nov 2022 10:39:30 +0800 Message-Id: <30ec04cb50d7ad998977f63a80a8450c128eaa77.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S6 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWfXr4UKryDGFWrKw18XF4DXFb_yoW8tFWUto W8XF97Aw15tw4rW34I9Fn3W3y8Jayjgr4rXF4FyF4UtFn8tF4Y9FW3ta4UGFnYyw1Fy34k A395X3yfZFZayrs5n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqv1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6x kF7I0E14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020E x4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E74AGY7Cv6cx26rWlOx8S6xCaFV Cjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7VAKI48JMxAIw28IcVCjz48v 1sIEY20_WwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcV CF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: LGQBCRgsoQv30FgzWpJNQjFgx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652801; bh=Ki+aNVqFze+fdutJ2ZJhmlFBBNpRcgDwz8sA5DE60pg=; h=Cc:Date:From:Reply-To:Subject:To; b=J+7GHiikfgXmioZ3Tnogna+jd02cBm2OOysGgnDSR0KpyoaiZUrodAupl2Ig1Fo/Jxj qAbyTD3lhxeu5HhL9UDILvJgWwceyfsfDAsUA5KpU1/fJjBpFeKeWvAyYS4SoGWaTINuo 0sV92FA3q5ojpov2GYXjEQlncGT6O5oSfbo= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652803852100001 Content-Type: text/plain; charset="utf-8" QemuFwCfgLib for PEI phase. This library obtains the QemuFWCfg base address by directly parsing the fdt, and reads and writes the data in the QemuFWCfg by operating on the QemuFWCfg base address. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Include/Library/QemuFwCfgLib.h | 174 +++++++ .../QemuFwCfgLib/QemuFwCfgLibInternal.h | 63 +++ .../Library/QemuFwCfgLib/QemuFwCfgPei.c | 117 +++++ .../Library/QemuFwCfgLib/QemuFwCfgPeiLib.c | 463 ++++++++++++++++++ .../Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf | 46 ++ 5 files changed, 863 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/Qemu= FwCfgLib.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib= /QemuFwCfgLibInternal.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib= /QemuFwCfgPei.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib= /QemuFwCfgPeiLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib= /QemuFwCfgPeiLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/QemuFwCfgLi= b.h b/Platform/Loongson/LoongArchQemuPkg/Include/Library/QemuFwCfgLib.h new file mode 100644 index 0000000000..11da4d0b8a --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/QemuFwCfgLib.h @@ -0,0 +1,174 @@ +/** @file + QEMU/KVM Firmware Configuration access + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - FW or Fw - Firmware + - Cfg - Configure +**/ + +#ifndef QEMU_FW_CFG_LIB_ +#define QEMU_FW_CFG_LIB_ + +#include + +typedef enum { + EfiAcpiAddressRangeMemory =3D 1, + EfiAcpiAddressRangeReserved =3D 2, + EfiAcpiAddressRangeACPI =3D 3, + EfiAcpiAddressRangeNVS =3D 4 +} EFI_ACPI_MEMORY_TYPE; + +typedef struct { + UINT64 BaseAddr; + UINT64 Length; + UINT32 Type; + UINT32 Reserved; +} LOONGARCH_MEMMAP_ENTRY; + +/** + Returns a boolean indicating if the firmware configuration interface + is available or not. + + This function may change fw_cfg state. + + @retval TRUE The interface is available + @retval FALSE The interface is not available +**/ +BOOLEAN +EFIAPI +QemuFwCfgIsAvailable ( + VOID + ); + +/** + Selects a firmware configuration item for reading. + + Following this call, any data read from this item will start from + the beginning of the configuration item's data. + + @param[in] QemuFwCfgItem - Firmware Configuration item to read +**/ +VOID +EFIAPI +QemuFwCfgSelectItem ( + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem + ); + +/** + Reads firmware configuration bytes into a buffer + + If called multiple times, then the data read will + continue at the offset of the firmware configuration + item where the previous read ended. + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into +**/ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + +/** + Writes firmware configuration bytes from a buffer + + If called multiple times, then the data written will + continue at the offset of the firmware configuration + item where the previous write ended. + + @param[in] Size - Size in bytes to write + @param[in] Buffer - Buffer to read data from +**/ +VOID +EFIAPI +QemuFwCfgWriteBytes ( + IN UINTN Size, + IN VOID *Buffer + ); + +/** + Skip bytes in the firmware configuration item. + + Increase the offset of the firmware configuration item without transferr= ing + bytes between the item and a caller-provided buffer. Subsequent read, wr= ite + or skip operations will commence at the increased offset. + + @param[in] Size Number of bytes to skip. +**/ +VOID +EFIAPI +QemuFwCfgSkipBytes ( + IN UINTN Size + ); + +/** + Reads a UINT8 firmware configuration value + + @retval Value of Firmware Configuration item read +**/ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ); + +/** + Reads a UINT16 firmware configuration value + + @retval Value of Firmware Configuration item read +**/ +UINT16 +EFIAPI +QemuFwCfgRead16 ( + VOID + ); + +/** + Reads a UINT32 firmware configuration value + + @retval Value of Firmware Configuration item read +**/ +UINT32 +EFIAPI +QemuFwCfgRead32 ( + VOID + ); + +/** + Reads a UINT64 firmware configuration value + + @retval Value of Firmware Configuration item read +**/ +UINT64 +EFIAPI +QemuFwCfgRead64 ( + VOID + ); + +/** + Find the configuration item corresponding to the firmware configuration = file. + + @param[in] Name - Name of file to look up. + @param[out] Item - Configuration item corresponding to the file, to be p= assed + to QemuFwCfgSelectItem (). + @param[out] Size - Number of bytes in the file. + + @retval RETURN_SUCCESS If file is found. + RETURN_NOT_FOUND If file is not found. + RETURN_UNSUPPORTED If firmware configuration is unavailable. +**/ +RETURN_STATUS +EFIAPI +QemuFwCfgFindFile ( + IN CONST CHAR8 *Name, + OUT FIRMWARE_CONFIG_ITEM *Item, + OUT UINTN *Size + ); + +#endif // QEMU_FW_CFG_LIB_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFw= CfgLibInternal.h b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/= QemuFwCfgLibInternal.h new file mode 100644 index 0000000000..229c080961 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFwCfgLibI= nternal.h @@ -0,0 +1,63 @@ +/** @file + fw_cfg library implementation. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - FwCfg - firmWare Configure +**/ + +#ifndef QEMU_FW_CFG_LIB_INTERNAL_H_ +#define QEMU_FW_CFG_LIB_INTERNAL_H_ + +/** + Returns a boolean indicating if the firmware configuration interface is + available for library-internal purposes. + + This function never changes fw_cfg state. + + @retval TRUE The interface is available internally. + @retval FALSE The interface is not available internally. +**/ +BOOLEAN +InternalQemuFwCfgIsAvailable ( + VOID + ); + +/** + Returns a boolean indicating whether QEMU provides the DMA-like access m= ethod + for fw_cfg. + + @retval TRUE The DMA-like access method is available. + @retval FALSE The DMA-like access method is unavailable. +**/ +BOOLEAN +InternalQemuFwCfgDmaIsAvailable ( + VOID + ); + +/** + Transfer an array of bytes, or skip a number of bytes, using the DMA + interface. + + @param[in] Size Size in bytes to transfer or skip. + + @param[in,out] Buffer Buffer to read data into or write data from. Ign= ored, + and may be NULL, if Size is zero, or Control is + FW_CFG_DMA_CTL_SKIP. + + @param[in] Control One of the following: + FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buff= er. + FW_CFG_DMA_CTL_READ - read from fw_cfg into Buf= fer. + FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg. +**/ +VOID +InternalQemuFwCfgDmaBytes ( + IN UINT32 Size, + IN OUT VOID *Buffer OPTIONAL, + IN UINT32 Control + ); + +#endif // QEMU_FW_CFG_LIB_INTERNAL_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFw= CfgPei.c b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFwCf= gPei.c new file mode 100644 index 0000000000..b170c953f3 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c @@ -0,0 +1,117 @@ +/** @file + fw_cfg library implementation. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - FwCfg - firmWare Configure +**/ + +#include +#include +#include + +#include "QemuFwCfgLibInternal.h" + +/** + Returns a boolean indicating if the firmware configuration interface + is available or not. + + This function may change fw_cfg state. + + @retval TRUE The interface is available + @retval FALSE The interface is not available +**/ +BOOLEAN +EFIAPI +QemuFwCfgIsAvailable ( + VOID + ) +{ + UINT32 Signature; + UINT32 Revision; + + QemuFwCfgSelectItem (QemuFwCfgItemSignature); + Signature =3D QemuFwCfgRead32 (); + DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature)); + QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); + Revision =3D QemuFwCfgRead32 (); + DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision)); + if ((Signature !=3D SIGNATURE_32 ('Q', 'E', 'M', 'U')) + || (Revision < 1)) + { + DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n")); + return FALSE; + } + + DEBUG ((DEBUG_INFO, "QemuFwCfg interface is supported.\n")); + return TRUE; +} + +/** + Returns a boolean indicating if the firmware configuration interface is + available for library-internal purposes. + + This function never changes fw_cfg state. + + @retval TRUE The interface is available internally. + @retval FALSE The interface is not available internally. +**/ +BOOLEAN +InternalQemuFwCfgIsAvailable ( + VOID + ) +{ + // + // We always return TRUE, because the consumer of this library ought to = have + // called QemuFwCfgIsAvailable before making other calls which would hit= this + // path. + // + return TRUE; +} + +/** + Returns a boolean indicating whether QEMU provides the DMA-like access m= ethod + for fw_cfg. + + @retval TRUE The DMA-like access method is available. + @retval FALSE The DMA-like access method is unavailable. +**/ +BOOLEAN +InternalQemuFwCfgDmaIsAvailable ( + VOID + ) +{ + return FALSE; +} + +/** + Transfer an array of bytes, or skip a number of bytes, using the DMA + interface. + + @param[in] Size Size in bytes to transfer or skip. + + @param[in, out] Buffer Buffer to read data into or write data from. Ig= nored, + and may be NULL, if Size is zero, or Control is + FW_CFG_DMA_CTL_SKIP. + + @param[in] Control One of the following: + FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buff= er. + FW_CFG_DMA_CTL_READ - read from fw_cfg into Buf= fer. + FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg. +**/ +VOID +InternalQemuFwCfgDmaBytes ( + IN UINT32 Size, + IN OUT VOID *Buffer OPTIONAL, + IN UINT32 Control + ) +{ + // + // We should never reach here + // + ASSERT (FALSE); + CpuDeadLoop (); +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFw= CfgPeiLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuF= wCfgPeiLib.c new file mode 100644 index 0000000000..5593856b82 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFwCfgPeiL= ib.c @@ -0,0 +1,463 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - FwCfg - firmWare Configure + - CTL - Control +**/ + +#include "Uefi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "QemuFwCfgLibInternal.h" + +STATIC UINTN mFwCfgSelectorAddress; +STATIC UINTN mFwCfgDataAddress; +/** + To get firmware configure selector address. + + @param VOID + + @retval firmware configure selector address +**/ +UINTN +EFIAPI +QemuGetFwCfgSelectorAddress ( + VOID + ) +{ + UINTN FwCfgSelectorAddress =3D mFwCfgSelectorAddress; + if (FwCfgSelectorAddress =3D=3D 0) { + FwCfgSelectorAddress =3D (UINTN)PcdGet64 (PcdFwCfgSelectorAddress); + } + return FwCfgSelectorAddress; +} +/** + To get firmware configure Data address. + + @param VOID + + @retval firmware configure data address +**/ +UINTN +EFIAPI +QemuGetFwCfgDataAddress ( + VOID + ) +{ + UINTN FwCfgDataAddress =3D mFwCfgDataAddress; + if (FwCfgDataAddress =3D=3D 0) { + FwCfgDataAddress =3D (UINTN)PcdGet64 (PcdFwCfgDataAddress); + } + return FwCfgDataAddress; +} +/** + Selects a firmware configuration item for reading. + + Following this call, any data read from this item will start from + the beginning of the configuration item's data. + + @param[in] QemuFwCfgItem - Firmware Configuration item to read +**/ +VOID +EFIAPI +QemuFwCfgSelectItem ( + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem + ) +{ + UINTN FwCfgSelectorAddress; + FwCfgSelectorAddress =3D QemuGetFwCfgSelectorAddress (); + MmioWrite16 (FwCfgSelectorAddress, SwapBytes16((UINT16) (UINTN)QemuFwCfg= Item)); +} + +/** + Slow READ_BYTES_FUNCTION. + + @param[in] The size of the data to be read. + @param[in] Buffer The buffer that stores the readout data. +**/ +VOID +EFIAPI +MmioReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + UINTN Left; + UINT8 *Ptr; + UINT8 *End; + UINTN FwCfgDataAddress; + Left =3D Size & 7; + + Size -=3D Left; + Ptr =3D Buffer; + End =3D Ptr + Size; + FwCfgDataAddress =3D QemuGetFwCfgDataAddress (); + while (Ptr < End) { + *(UINT64 *)Ptr =3D MmioRead64 (FwCfgDataAddress); + Ptr +=3D 8; + } + if (Left & 4) { + *(UINT32 *)Ptr =3D MmioRead32 (FwCfgDataAddress); + Ptr +=3D 4; + } + if (Left & 2) { + *(UINT16 *)Ptr =3D MmioRead16 (FwCfgDataAddress); + Ptr +=3D 2; + } + if (Left & 1) { + *Ptr =3D MmioRead8 (FwCfgDataAddress); + } +} + +/** + Slow WRITE_BYTES_FUNCTION. + + @param[in] The size of the data to be write. + @param[in] Buffer The buffer that stores the writein data. +**/ +VOID +EFIAPI +MmioWriteBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + UINTN Idx; + UINTN FwCfgDataAddress; + FwCfgDataAddress =3D QemuGetFwCfgDataAddress (); + for (Idx =3D 0; Idx < Size; ++Idx) { + MmioWrite8 (FwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); + } +} + +/** + Reads firmware configuration bytes into a buffer + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0) +**/ +VOID +EFIAPI +InternalQemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + if ((InternalQemuFwCfgDmaIsAvailable ()) + && (Size <=3D MAX_UINT32)) + { + InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ); + return; + } + MmioReadBytes (Size, Buffer); +} + +/** + Reads firmware configuration bytes into a buffer + + If called multiple times, then the data read will + continue at the offset of the firmware configuration + item where the previous read ended. + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into +**/ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer + ) +{ + if (InternalQemuFwCfgIsAvailable ()) { + InternalQemuFwCfgReadBytes (Size, Buffer); + } else { + ZeroMem (Buffer, Size); + } +} + +/** + Write firmware configuration bytes from a buffer + + If called multiple times, then the data written will + continue at the offset of the firmware configuration + item where the previous write ended. + + @param[in] Size - Size in bytes to write + @param[in] Buffer - Buffer to read data from +**/ +VOID +EFIAPI +QemuFwCfgWriteBytes ( + IN UINTN Size, + IN VOID *Buffer + ) +{ + if (InternalQemuFwCfgIsAvailable ()) { + if ((InternalQemuFwCfgDmaIsAvailable ()) + && (Size <=3D MAX_UINT32)) + { + InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRIT= E); + return; + } + MmioWriteBytes (Size, Buffer); + } +} + +/** + Skip bytes in the firmware configuration item. + + Increase the offset of the firmware configuration item without transferr= ing + bytes between the item and a caller-provided buffer. Subsequent read, wr= ite + or skip operations will commence at the increased offset. + + @param[in] Size Number of bytes to skip. +**/ +VOID +EFIAPI +QemuFwCfgSkipBytes ( + IN UINTN Size + ) +{ + UINTN ChunkSize; + UINT8 SkipBuffer[256]; + + if (!InternalQemuFwCfgIsAvailable ()) { + return; + } + + if ((InternalQemuFwCfgDmaIsAvailable ()) + && (Size <=3D MAX_UINT32)) + { + InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP); + return; + } + + // + // Emulate the skip by reading data in chunks, and throwing it away. The + // implementation below is suitable even for phases where RAM or dynamic + // allocation is not available or appropriate. It also doesn't affect the + // static data footprint for client modules. Large skips are not expecte= d, + // therefore this fallback is not performance critical. The size of + // SkipBuffer is thought not to exert a large pressure on the stack in a= ny + // phase. + // + while (Size > 0) { + ChunkSize =3D MIN (Size, sizeof SkipBuffer); + MmioReadBytes (ChunkSize, SkipBuffer); + Size -=3D ChunkSize; + } +} + +/** + Reads a UINT8 firmware configuration value + + @return Value of Firmware Configuration item read +**/ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ) +{ + UINT8 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + +/** + Reads a UINT16 firmware configuration value + + @return Value of Firmware Configuration item read +**/ +UINT16 +EFIAPI +QemuFwCfgRead16 ( + VOID + ) +{ + UINT16 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + +/** + Reads a UINT32 firmware configuration value + + @return Value of Firmware Configuration item read +**/ +UINT32 +EFIAPI +QemuFwCfgRead32 ( + VOID + ) +{ + UINT32 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + +/** + Reads a UINT64 firmware configuration value + + @return Value of Firmware Configuration item read +**/ +UINT64 +EFIAPI +QemuFwCfgRead64 ( + VOID + ) +{ + UINT64 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + +/** + Find the configuration item corresponding to the firmware configuration = file. + + @param[in] Name - Name of file to look up. + @param[out] Item - Configuration item corresponding to the file, to be p= assed + to QemuFwCfgSelectItem (). + @param[out] Size - Number of bytes in the file. + + @return RETURN_SUCCESS If file is found. + RETURN_NOT_FOUND If file is not found. + RETURN_UNSUPPORTED If firmware configuration is unavailable. +**/ +RETURN_STATUS +EFIAPI +QemuFwCfgFindFile ( + IN CONST CHAR8 *Name, + OUT FIRMWARE_CONFIG_ITEM *Item, + OUT UINTN *Size + ) +{ + UINT32 Count; + UINT32 Idx; + + if (!InternalQemuFwCfgIsAvailable ()) { + return RETURN_UNSUPPORTED; + } + + QemuFwCfgSelectItem (QemuFwCfgItemFileDir); + Count =3D SwapBytes32 (QemuFwCfgRead32 ()); + + for (Idx =3D 0; Idx < Count; ++Idx) { + UINT32 FileSize; + UINT16 FileSelect; + CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE]; + + FileSize =3D QemuFwCfgRead32 (); + FileSelect =3D QemuFwCfgRead16 (); + QemuFwCfgRead16 (); // skip the field called "reserved" + InternalQemuFwCfgReadBytes (sizeof (FileName), FileName); + + if (AsciiStrCmp (Name, FileName) =3D=3D 0) { + *Item =3D SwapBytes16 (FileSelect); + *Size =3D SwapBytes32 (FileSize); + return RETURN_SUCCESS; + } + } + + return RETURN_NOT_FOUND; +} + +/** + firmware config initialize. + + @param VOID + + @return RETURN_SUCCESS Initialization succeeded. +**/ +RETURN_STATUS +EFIAPI +QemuFwCfgInitialize ( + VOID + ) +{ + VOID *DeviceTreeBase; + INT32 Node; + INT32 Prev; + CONST CHAR8 *Type; + INT32 Len; + CONST UINT64 *RegProp; + UINT64 FwCfgSelectorAddress; + UINT64 FwCfgDataAddress; + UINT64 FwCfgDataSize; + RETURN_STATUS PcdStatus; + + DeviceTreeBase =3D (VOID *) (UINTN)PcdGet64 (PcdDeviceTreeBase); + ASSERT (DeviceTreeBase !=3D NULL); + // + // Make sure we have a valid device tree blob + // + ASSERT (fdt_check_header (DeviceTreeBase) =3D=3D 0); + + for (Prev =3D 0;; Prev =3D Node) { + Node =3D fdt_next_node (DeviceTreeBase, Prev, NULL); + if (Node < 0) { + break; + } + + // + // Check for memory node + // + Type =3D fdt_getprop (DeviceTreeBase, Node, "compatible", &Len); + if ((Type) + && (AsciiStrnCmp (Type, "qemu,fw-cfg-mmio", Len) =3D=3D 0)) + { + // + // Get the 'reg' property of this node. For now, we will assume + // two 8 byte quantities for base and size, respectively. + // + RegProp =3D fdt_getprop (DeviceTreeBase, Node, "reg", &Len); + if ((RegProp !=3D 0) + && (Len =3D=3D (2 * sizeof (UINT64)))) + { + FwCfgDataAddress =3D SwapBytes64 (RegProp[0]); + FwCfgDataSize =3D 8; + FwCfgSelectorAddress =3D FwCfgDataAddress + FwCfgDataSize; + + mFwCfgSelectorAddress =3D FwCfgSelectorAddress; + mFwCfgDataAddress =3D FwCfgDataAddress; + + PcdStatus =3D PcdSet64S ( + PcdFwCfgSelectorAddress, + FwCfgSelectorAddress + ); + ASSERT_RETURN_ERROR (PcdStatus); + PcdStatus =3D PcdSet64S ( + PcdFwCfgDataAddress, + FwCfgDataAddress + ); + ASSERT_RETURN_ERROR (PcdStatus); + break; + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT QemuCfg node\n", + __FUNCTION__)); + break; + } + } + } + return RETURN_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFw= CfgPeiLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/Qem= uFwCfgPeiLib.inf new file mode 100644 index 0000000000..8609d615e7 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/QemuFwCfgLib/QemuFwCfgPeiL= ib.inf @@ -0,0 +1,46 @@ +## @file +# initialized fw_cfg library. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D QemuFwCfgSecLib + FILE_GUID =3D cdf9a9d5-7422-4dcb-b41d-607151ad320b + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D QemuFwCfgLib|PEIM + CONSTRUCTOR =3D QemuFwCfgInitialize + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + QemuFwCfgLibInternal.h + QemuFwCfgPeiLib.c + QemuFwCfgPei.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + MemoryAllocationLib + FdtLib + PcdLib + +[Pcd] + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase + gLoongArchQemuPkgTokenSpaceGuid.PcdFwCfgSelectorAddress + gLoongArchQemuPkgTokenSpaceGuid.PcdFwCfgDataAddress --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96446): https://edk2.groups.io/g/devel/message/96446 Mute This Topic: https://groups.io/mt/95082583/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96448+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96448+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652803; cv=none; d=zohomail.com; s=zohoarc; b=cu13ZkbD4CQ59W+k92SNV8AiijSjOB96x+W4QeBCRP1//nJOp8W62rc3lZYj85rl869M/0TqFUhA+DZRyqvyw9UNSnYoHiJQmzhzaXyad0e7FVRf7C2XdhcX5fWUgIqEJMk/bt/OoXC1PWbt7vBft3h1ZZkBNwfsp4fubN9IyO8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652803; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=OScIgkKnWdWJuIBH6d2r92Vue8UZAs+h/N8W+ccAm/8=; b=gkC1kLfbp23I+UtkZU65kgNM0kL5OorwwoF0fQGgwGxCf7RzyHibqOaXPgPEWtR9jv5C7vUV2xIeE6YtGUAkRxek3B+V2s3wxMM6VvAksmLgAY3QsC+u6Ao7j6VSPSfczR1FQ7Rxsh9aFNyyCzr1/tcO+yS/oHib0t3kG9iLmjA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96448+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652803534284.50608082344; Wed, 16 Nov 2022 18:40:03 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id itITYY1788612xa261q7XN62; Wed, 16 Nov 2022 18:40:03 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6322.1668652801018980713 for ; Wed, 16 Nov 2022 18:40:01 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Cxrrf_nnVjBiQIAA--.18626S3; Thu, 17 Nov 2022 10:39:59 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S7; Thu, 17 Nov 2022 10:39:58 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 05/16] Platform/Loongson: Add MmuLib. Date: Thu, 17 Nov 2022 10:39:31 +0800 Message-Id: <1bf6dc3a190b5fe2a71466ed0fe77924c02c7c26.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S7 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWDWF1kWw1kZF1fJw15Jr17Awb_yoW7CF17to WY9F4ruw4UJw4rZr4rCwn2gayxtFsYq39xXr1FvF4jqFsYvrs0kFWUtay5J34fZ34Svrnr GrykXaykJFWS9r1rn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqm1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: p8kZVLX9xSVEwNhCyQCRJJaAx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652803; bh=oVAIcMTWGxemLm/GsnFv81M/e3di9PucI6xEKof15MY=; h=Cc:Date:From:Reply-To:Subject:To; b=S+BOmF1tjns6UkB0IPwm4JmuQr2IN5PcubKXJrTUo51HLRhvTPNOzcniwESOgGpC/rR lqJhg17XRUO4BXu4XDOUizsn2SShYSmE2XCEX3PhRfuNcBTL2knRypgBjI2XMphw1fL09 Q4Alm/c1xJwvb5/sO59X59M5ERDI0dhP6BE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652803893100004 Content-Type: text/plain; charset="utf-8" Read the memory map information through the QemuFwCfg interface, then build the page table through the memory map information, and finally enable Mmu. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../LoongArchQemuPkg/Include/Library/MmuLib.h | 85 ++ .../LoongArchQemuPkg/Library/MmuLib/Mmu.S | 155 ++++ .../Library/MmuLib/MmuBaseLib.inf | 40 + .../Library/MmuLib/MmuBaseLibPei.inf | 47 + .../Library/MmuLib/MmuLibCore.c | 831 ++++++++++++++++++ .../Library/MmuLib/MmuLibCore.h | 40 + .../Library/MmuLib/MmuLibCorePei.c | 231 +++++ .../LoongArchQemuPkg/Library/MmuLib/mmu.h | 190 ++++ .../LoongArchQemuPkg/Library/MmuLib/page.h | 280 ++++++ .../LoongArchQemuPkg/Library/MmuLib/pte.h | 57 ++ 10 files changed, 1956 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuL= ib.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBa= seLib.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBa= seLibPei.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLi= bCore.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLi= bCore.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLi= bCorePei.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h b/= Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h new file mode 100644 index 0000000000..9880fc385c --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/MmuLib.h @@ -0,0 +1,85 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - EXC - execute +**/ +#ifndef MMU_LIB_H_ +#define MMU_LIB_H_ +/** + write operation is performed Count times from the first element of Buffe= r. + Convert EFI Attributes to Loongarch Attributes. + @param[in] EfiAttributes Efi Attributes. + + @retval LoongArch Attributes. +**/ +UINTN +EfiAttributeToLoongArchAttribute ( + IN UINTN EfiAttributes + ); + +/** + Finds the length and memory properties of the memory region correspondin= g to the specified base address. + + @param[in] BaseAddress To find the base address of the memory region. + @param[in] EndAddress To find the end address of the memory region. + @param[out] RegionLength The length of the memory region found. + @param[out] RegionAttributes Properties of the memory region found. + + @retval EFI_SUCCESS The corresponding memory area was successfully f= ound + EFI_NOT_FOUND No memory area found +**/ +EFI_STATUS +GetLoongArchMemoryRegion ( + IN UINTN BaseAddress, + IN UINTN EndAddress, + OUT UINTN *RegionLength, + OUT UINTN *RegionAttributes + ); + +/** + Sets the Attributes of the specified memory region + + @param[in] BaseAddress The base address of the memory region to set th= e Attributes. + @param[in] Length The length of the memory region to set the Attr= ibutes. + @param[in] Attributes The Attributes to be set. + + @retval EFI_SUCCESS The Attributes was set successfully +**/ +EFI_STATUS +LoongArchSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ); + +/** + Sets the non-executable Attributes for the specified memory region + + @param[in] BaseAddress The base address of the memory region to set th= e Attributes. + @param[in] Length The length of the memory region to set the Attr= ibutes. + + @retval EFI_SUCCESS The Attributes was set successfully +**/ +EFI_STATUS +LoongArchSetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ); + +/** + Create a page table and initialize the MMU. + + @param[] VOID + + @retval VOID +**/ +VOID +EFIAPI +ConfigureMmu ( + VOID + ); +#endif // MMU_LIB_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S b/Plat= form/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S new file mode 100644 index 0000000000..d5863de072 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/Mmu.S @@ -0,0 +1,155 @@ +#-------------------------------------------------------------------------= ----- +# +# LoongArch for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ---- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" +#include "mmu.h" + +ASM_GLOBAL ASM_PFX(HandleTlbRefill) +ASM_GLOBAL HandleTlbRefillEnd +ASM_GLOBAL ASM_PFX(LoongarchInvalidTlb) +ASM_GLOBAL ASM_PFX(SetTlbRefillFuncBase) +ASM_GLOBAL ASM_PFX(WriteCsrPageSize) +ASM_GLOBAL ASM_PFX(WriteCsrTlbRefillPageSize) +ASM_GLOBAL ASM_PFX(WriteCsrStlbPageSize) +ASM_GLOBAL ASM_PFX(LoongArchWriteqCsrPwctl0) +ASM_GLOBAL ASM_PFX(LoongArchWriteqCsrPwctl1) +ASM_GLOBAL ASM_PFX(LoongArchWriteqCsrPgdl) +ASM_GLOBAL ASM_PFX(LoongArchWriteqCsrPgdh) +ASM_GLOBAL ASM_PFX(LoongArchXchgCsrCrmd) + +# +# Refill the page table. +# @param VOID +# @retval VOID +# + +ASM_PFX(HandleTlbRefill): + csrwr T0, LOONGARCH_CSR_TLBRSAVE + csrrd T0, LOONGARCH_CSR_PGD + lddir T0, T0, 3 #Put pud BaseAddress into T0 + lddir T0, T0, 2 #Put pmd BaseAddress into T0 + lddir T0, T0, 1 #Put pte BaseAddress into T0 + ldpte T0, 0 + ldpte T0, 1 + tlbfill + csrrd T0, LOONGARCH_CSR_TLBRSAVE + ertn +HandleTlbRefillEnd: + +# +# Invalid corresponding TLB entries are based on the address given +# @param A0 The address corresponding to the invalid page table entry +# @retval none +# + +ASM_PFX(LoongarchInvalidTlb): + invtlb INVTLB_ADDR_GTRUE_OR_ASID, ZERO, A0 + jirl ZERO, RA, 0 + +# +# Set Tlb Refill function to hardware +# @param A0 The address of tlb refill function +# @retval none +# + +ASM_PFX(SetTlbRefillFuncBase): + csrwr A0, LOONGARCH_CSR_TLBREBASE + jirl ZERO, RA,0 + +# +# Set Cpu Status Register Page Size. +# @param A0 Page Size. +# @retval none +# + +ASM_PFX(WriteCsrPageSize): + li.d T0, CSR_TLBIDX_SIZE + sll.d A0, A0, T0 + li.d T0, CSR_TLBIDX_SIZE_MASK + csrxchg A0, T0, LOONGARCH_CSR_TLBIDX + jirl ZERO, RA,0 + +# +# Set Cpu Status Register TLBREFILL Page Size. +# @param A0 Page Size. +# @retval none +# + +ASM_PFX(WriteCsrTlbRefillPageSize): + li.d T0, CSR_TLBREHI_PS_SHIFT + sll.d A0, A0, T0 + li.d T0, CSR_TLBREHI_PS + csrxchg A0, T0, LOONGARCH_CSR_TLBREHI + jirl ZERO, RA,0 + +# +# Set Cpu Status Register STLB Page Size. +# @param val Page Size. +# @retval VOID +# + +ASM_PFX(WriteCsrStlbPageSize): + csrwr A0, LOONGARCH_CSR_STLBPGSIZE + jirl ZERO, RA,0 + +# +# Write Csr PWCTL0 register. +# @param A0 The value used to write to the PWCTL0 register +# @retval none +# + +ASM_PFX(LoongArchWriteqCsrPwctl0): + csrwr A0, LOONGARCH_CSR_PWCTL0 + jirl ZERO, RA,0 + +# +# Write Csr PWCTL1 register. +# @param A0 The value used to write to the PWCTL1 register +# @retval none +# + +ASM_PFX(LoongArchWriteqCsrPwctl1): + csrwr A0, LOONGARCH_CSR_PWCTL1 + jirl ZERO, RA,0 + +# +# Write Csr PGDL register. +# @param A0 The value used to write to the PGDL register +# @retval none +# + +ASM_PFX(LoongArchWriteqCsrPgdl): + csrwr A0, LOONGARCH_CSR_PGDL + jirl ZERO, RA,0 + +# +# Write Csr PGDH register. +# @param A0 The value used to write to the PGDH register +# @retval none +# + +ASM_PFX(LoongArchWriteqCsrPgdh): + csrwr A0, LOONGARCH_CSR_PGDH + jirl ZERO, RA,0 + +# +# Exchange specified bit data with the Csr CRMD register. +# @param[IN] A0 The value Exchanged with the CSR CRMD register. +# @param[IN] A1 Specifies the mask for swapping bits +# @retval VOID +# + +ASM_PFX(LoongArchXchgCsrCrmd): + csrxchg A0, A1, LOONGARCH_CSR_CRMD + jirl ZERO, RA,0 diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.i= nf b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.inf new file mode 100644 index 0000000000..abd864a324 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLib.inf @@ -0,0 +1,40 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D MmuBaseLib + FILE_GUID =3D da8f0232-fb14-42f0-922c-63104d2c70be + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D MmuLib + CONSTRUCTOR =3D MmuInitialize + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + MmuLibCore.c + Mmu.S + +[Packages] + MdePkg/MdePkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[PCD] + gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPgd + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPud + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte + +[LibraryClasses] + MemoryAllocationLib + PcdLib + DebugLib diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPe= i.inf b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPei.inf new file mode 100644 index 0000000000..12848eecfe --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuBaseLibPei.inf @@ -0,0 +1,47 @@ +## @file +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D MmuPeiLib + FILE_GUID =3D da8f0232-fb14-42f0-922c-63104d2c70bd + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D MmuLib | SEC PEIM + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + MmuLibCorePei.c + Mmu.S + MmuLibCore.h + MmuLibCore.c + +[Packages] + MdePkg/MdePkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + OvmfPkg/OvmfPkg.dec + +[PCD] + gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPgd + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPud + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase + gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize + +[LibraryClasses] + MemoryAllocationLib + CacheMaintenanceLib + PcdLib + DebugLib + QemuFwCfgLib diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c= b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c new file mode 100644 index 0000000000..b932e3d568 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c @@ -0,0 +1,831 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Pgd or Pgd or PGD - Page Global Directory + - Pud or Pud or PUD - Page Upper Directory + - Pmd or Pmd or PMD - Page Middle Directory + - Pte or pte or PTE - Page Table Entry + - Val or VAL or val - Value + - Dir - Directory +**/ +#include +#include +#include +#include +#include +#include "Library/Cpu.h" +#include "pte.h" +#include "page.h" +#include "mmu.h" + +BOOLEAN mMmuInited =3D FALSE; +/** + Check to see if mmu successfully initializes. + + @param VOID. + + @retval TRUE Initialization has been completed. + FALSE Initialization did not complete. +**/ +BOOLEAN +MmuIsInit (VOID) { + if ((mMmuInited =3D=3D TRUE) || + (PcdGet64 (PcdSwapPageDir) !=3D 0)) { + return TRUE; + } + return FALSE; +} + +/** + Iterates through the page directory to initialize it. + + @param Dst A pointer to the directory of the page to initialize. + @param Num The number of page directories to initialize. + @param Src A pointer to the data used to initialize the page directory. + + @retval VOID. +**/ +VOID +PageDirInit ( + IN VOID *Dst, + IN UINTN Num, + IN VOID *Src + ) +{ + UINTN *Ptr; + UINTN *End; + UINTN Entry; + + Entry =3D (UINTN)Src; + Ptr =3D (UINTN *)Dst; + End =3D Ptr + Num; + + for ( ;Ptr < End; Ptr++) { + *Ptr =3D Entry; + } + + return ; +} + +/** + Gets the virtual address corresponding to the page global directory tabl= e entry. + + @param Address the virtual address for the table entry. + + @retval PGD A pointer to get the table item. +**/ +PGD * +PgdOffset ( + IN UINTN Address + ) +{ + return ((PGD *)PcdGet64 (PcdSwapPageDir)) + PGD_INDEX (Address); +} + +/** + Gets the virtual address corresponding to the page upper directory table= entry. + + @param Pgd A pointer to a page global directory table entry. + @param Address the virtual address for the table entry. + + @retval PUD A pointer to get the table item. +**/ +PUD * +PudOffset ( + IN PGD *Pgd, + IN UINTN Address + ) +{ + UINTN PgdVal =3D (UINTN)PGD_VAL (*Pgd); + return (PUD *)PgdVal + PUD_INDEX (Address); +} + +/** + Gets the virtual address corresponding to the page middle directory tabl= e entry. + + @param Pud A pointer to a page upper directory table entry. + @param Address the virtual address for the table entry. + + @retval PMD A pointer to get the table item. +**/ +PMD * +PmdOffset ( + IN PUD *Pud, + IN UINTN Address + ) +{ + UINTN PudVal =3D PUD_VAL (*Pud); + return (PMD *)PudVal + PMD_INDEX (Address); +} + +/** + Gets the virtual address corresponding to the page table entry. + + @param Pmd A pointer to a page middle directory table entry. + @param Address the virtual address for the table entry. + + @retval PTE A pointer to get the table item. +**/ +PTE * +PteOffset ( + IN PMD *Pmd, + IN UINTN Address + ) +{ + UINTN PmdVal =3D (UINTN)PMD_VAL (*Pmd); + return (PTE *)PmdVal + PTE_INDEX (Address); +} + +/** + Sets the value of the page table entry. + + @param Pte A pointer to a page table entry. + @param PteVal The value of the page table entry to set. + + @retval VOID +**/ +VOID +SetPte ( + IN PTE *Pte, + IN PTE PteVal + ) +{ + *Pte =3D PteVal; +} + +/** + Sets the value of the page global directory. + + @param Pgd A pointer to a page global directory. + @param Pud The value of the page global directory to set. + + @retval VOID +**/ +VOID +SetPgd ( + IN PGD *Pgd, + IN PUD *Pud + ) +{ + *Pgd =3D (PGD) {((UINTN)Pud)}; +} + +/** + Sets the value of the page upper directory. + + @param Pud A pointer to a page upper directory. + @param Pmd The value of the page upper directory to set. + + @retval VOID +**/ +VOID +SetPud ( + IN PUD *Pud, + IN PMD *Pmd + ) +{ + *Pud =3D (PUD) {((UINTN)Pmd)}; +} + +/** + Sets the value of the page middle directory. + + @param Pmd A pointer to a page middle directory. + @param Pte The value of the page middle directory to set. + + @retval VOID +**/ +VOID +SetPmd ( + IN PMD *Pmd, + IN PTE *Pte + ) +{ + *Pmd =3D (PMD) {((UINTN)Pte)}; +} + +/** + Free up memory space occupied by page tables. + + @param Pte A pointer to the page table. + + @retval VOID +**/ +VOID +PteFree ( + IN PTE *Pte + ) +{ + FreePages ((VOID *)Pte, 1); +} + +/** + Free up memory space occupied by page middle directory. + + @param Pmd A pointer to the page middle directory. + + @retval VOID +**/ +VOID +PmdFree ( + IN PMD *Pmd + ) +{ + FreePages ((VOID *)Pmd, 1); +} + +/** + Free up memory space occupied by page upper directory. + + @param Pud A pointer to the page upper directory. + + @retval VOID +**/ +VOID +PudFree ( + IN PUD *Pud + ) +{ + FreePages ((VOID *)Pud, 1); +} + +/** + Requests the memory space required for the page upper directory, + initializes it, and places it in the specified page global directory + + @param Pgd A pointer to the page global directory. + + @retval EFI_SUCCESS Memory request successful. + @retval EFI_OUT_OF_RESOURCES Resource exhaustion cannot be requested t= o memory. +**/ +INTN +PudAlloc ( + IN PGD *Pgd + ) +{ + PUD *Pud =3D (PUD *) AllocatePages (1); + if (!Pud) { + return EFI_OUT_OF_RESOURCES; + } + + PageDirInit ((VOID *)Pud, ENTRYS_PER_PUD, (VOID *)PcdGet64 (PcdInvalidPm= d)); + + if (pgd_none (*Pgd)) { + SetPgd (Pgd, Pud); + } else { /* Another has populated it */ + PudFree (Pud); + } + + return EFI_SUCCESS; +} + +/** + Requests the memory space required for the page middle directory, + initializes it, and places it in the specified page upper directory + + @param Pud A pointer to the page upper directory. + + @retval EFI_SUCCESS Memory request successful. + @retval EFI_OUT_OF_RESOURCES Resource exhaustion cannot be requested t= o memory. +**/ +EFI_STATUS +PmdAlloc ( + IN PUD *Pud + ) +{ + PMD *Pmd; + + Pmd =3D (PMD *) AllocatePages (1); + if (!Pmd) { + return EFI_OUT_OF_RESOURCES; + } + + PageDirInit ((VOID *)Pmd, ENTRYS_PER_PMD, (VOID *)PcdGet64 (PcdInvalidPt= e)); + + if (pud_none (*Pud)) { + SetPud (Pud, Pmd); + } else {/* Another has populated it */ + PmdFree (Pmd); + } + + return EFI_SUCCESS; +} + +/** + Requests the memory space required for the page table, + initializes it, and places it in the specified page middle directory + + @param Pmd A pointer to the page middle directory. + + @retval EFI_SUCCESS Memory request successful. + @retval EFI_OUT_OF_RESOURCES Resource exhaustion cannot be requested t= o memory. +**/ +INTN +PteAlloc ( + IN PMD *Pmd + ) +{ + PTE *Pte; + + Pte =3D (PTE *) AllocatePages (1); + if (!Pte) { + return EFI_OUT_OF_RESOURCES; + } + + Pte =3D ZeroMem (Pte, EFI_PAGE_SIZE); + + if (pmd_none (*Pmd)) { + SetPmd (Pmd, Pte); + } else { /* Another has populated it */ + PteFree (Pte); + } + + return EFI_SUCCESS; +} + +/** + Requests the memory space required for the page upper directory, + initializes it, and places it in the specified page global directory, + and get the page upper directory entry corresponding to the virtual addr= ess + + @param Pgd A pointer to the page global directory. + + @retval Gets the page upper directory entry +**/ +PUD * +PudAllocGet ( + IN PGD *Pgd, + IN UINTN Address + ) +{ + return ((pgd_none (*(Pgd)) && PudAlloc (Pgd)) ? + NULL : PudOffset (Pgd, Address)); +} + +/** + Requests the memory space required for the page middle directory, + initializes it, and places it in the specified page upper directory, + and get the page middle directory entry corresponding to the virtual add= ress + + @param Pud A pointer to the page upper directory. + + @retval Gets the page middle directory entry +**/ +PMD * +PmdAllocGet ( + IN PUD *Pud, + IN UINTN Address + ) +{ + PMD * ret =3D (pud_none (*Pud) && PmdAlloc (Pud))? + NULL: PmdOffset (Pud, Address); + DEBUG ((DEBUG_VERBOSE, "%a %d PudVal %p PmdOffset %p PMD_INDEX %p .\n", = __func__, __LINE__, + Pud->PudVal, PmdOffset (Pud, Address), PMD_INDEX (Address) )); + + return ret; +} + +/** + Requests the memory space required for the page table, + initializes it, and places it in the specified page middle directory, + and get the page table entry corresponding to the virtual address + + @param Pmd A pointer to the page upper directory. + + @retval Gets the page table entry +**/ +PTE * +PteAllocGet ( + IN PMD *Pmd, + IN UINTN Address + ) +{ + return (pmd_none (*Pmd) && PteAlloc (Pmd))? + NULL: PteOffset (Pmd, Address); +} + +/** + Gets the physical address of the page table entry corresponding to the s= pecified virtual address. + + @param Address the corresponding virtual address of the page table ent= ry. + + @retval A pointer to the page table entry. + @retval NULL +**/ +PTE * +GetPteAddress ( + IN UINTN Address + ) +{ + PGD *Pgd; + PUD *Pud; + PMD *Pmd; + + Pgd =3D PgdOffset (Address); + + if (pgd_none (*Pgd)) { + return NULL; + } + + Pud =3D PudOffset (Pgd, Address); + + if (pud_none (*Pud)) { + return NULL; + } + + Pmd =3D PmdOffset (Pud, Address); + if (pmd_none (*Pmd)) { + return NULL; + } + + if (IS_HUGE_PAGE (Pmd->PmdVal)) { + return ((PTE *)Pmd); + } + + return PteOffset (Pmd, Address); +} + +/** + Establishes a page table entry based on the specified memory region. + + @param Pmd A pointer to the page middle directory. + @param Address The memory space start address. + @param End The end address of the memory space. + @param Attributes Memory space Attributes. + + @retval EFI_SUCCESS The page table entry was created successfully. + @retval EFI_OUT_OF_RESOURCES Page table entry establishment failed = due to resource exhaustion. +**/ +EFI_STATUS +MemoryMapPteRange ( + IN PMD *Pmd, + IN UINTN Address, + IN UINTN End, + IN UINTN Attributes + ) +{ + PTE *Pte; + PTE PteVal; + BOOLEAN UpDate; + + Pte =3D PteAllocGet (Pmd, Address); + if (!Pte) { + return EFI_OUT_OF_RESOURCES; + } + + do { + UpDate =3D FALSE; + PteVal =3D MAKE_PTE (Address, Attributes); + DEBUG ((DEBUG_VERBOSE, + "%a %d Address %p PGD_INDEX %p PUD_INDEX %p PMD_INDEX %p PTE_IND= EX %p MAKE_PTE %p\n", + __func__, __LINE__, Address, PGD_INDEX (Address), PUD_INDEX (Addres= s), PMD_INDEX (Address), + PTE_INDEX (Address), PteVal)); + + if ((!pte_none (*Pte)) && + (PTE_VAL(*Pte) !=3D PTE_VAL(PteVal))) + { + UpDate =3D TRUE; + } + + SetPte (Pte, PteVal); + if (UpDate) { + LoongarchInvalidTlb(Address); + } + } while (Pte++, Address +=3D EFI_PAGE_SIZE, Address !=3D End); + + return EFI_SUCCESS; +} + +/** + Establishes a page middle directory based on the specified memory region. + + @param Pud A pointer to the page upper directory. + @param Address The memory space start address. + @param End The end address of the memory space. + @param Attributes Memory space Attributes. + + @retval EFI_SUCCESS The page middle directory was created successf= ully. + @retval EFI_OUT_OF_RESOURCES Page middle directory establishment fa= iled due to resource exhaustion. +**/ +EFI_STATUS +MemoryMapPmdRange ( + IN PUD *Pud, + IN UINTN Address, + IN UINTN End, + IN UINTN Attributes + ) +{ + PMD *Pmd; + PTE *Pte; + UINTN Next; + UINTN AddressStart_HugePage; + UINTN AddressEnd_HugePage; + + Pmd =3D PmdAllocGet (Pud, Address); + if (!Pmd) { + return EFI_OUT_OF_RESOURCES; + } + + do { + Next =3D PMD_ADDRESS_END (Address, End); + if (((Address & (~PMD_MASK)) =3D=3D 0) && + ((Next & (~PMD_MASK)) =3D=3D 0) && + (pmd_none (*Pmd))) + { + DEBUG ((DEBUG_VERBOSE, + "%a %d Address %p PGD_INDEX %p PUD_INDEX %p PMD_INDEX %p MAKE_= HUGE_PTE %p\n", + __func__, __LINE__, Address, PGD_INDEX (Address), PUD_INDEX (Addr= ess), PMD_INDEX (Address), + MAKE_HUGE_PTE (Address, Attributes))); + + SetPmd (Pmd, (PTE *)MAKE_HUGE_PTE (Address, Attributes)); + } else { + if ((pmd_none (*Pmd)) || + ((!pmd_none (*Pmd)) && + (!IS_HUGE_PAGE (Pmd->PmdVal)))) + { + if (MemoryMapPteRange (Pmd, Address, Next, Attributes)) { + return EFI_OUT_OF_RESOURCES; + } + } else { + SetPmd (Pmd, (PTE *)PcdGet64 (PcdInvalidPte)); + AddressStart_HugePage =3D Address & PMD_MASK; + AddressEnd_HugePage =3D AddressStart_HugePage + HUGE_PAGE_SIZE; + if (MemoryMapPteRange (Pmd, AddressStart_HugePage, AddressEnd_Hug= ePage, Attributes)) { + return EFI_OUT_OF_RESOURCES; + } + Pte =3D GetPteAddress (AddressStart_HugePage); + if (Pte =3D=3D NULL) { + continue ; + } + if (AddressEnd_HugePage > End) { + Next =3D End; + } + } + } + } while (Pmd++, Address =3D Next, Address !=3D End); + + return 0; +} + +/** + Establishes a page upper directory based on the specified memory region. + + @param Pgd A pointer to the page global directory. + @param Address The memory space start address. + @param End The end address of the memory space. + @param Attributes Memory space Attributes. + + @retval EFI_SUCCESS The page upper directory was created successfu= lly. + @retval EFI_OUT_OF_RESOURCES Page upper directory establishment fai= led due to resource exhaustion. +**/ +EFI_STATUS +MemoryMapPudRange ( + IN PGD *Pgd, + IN UINTN Address, + IN UINTN End, + IN UINTN Attributes + ) +{ + PUD *Pud; + UINTN Next; + + Pud =3D PudAllocGet (Pgd, Address); + if (!Pud) { + return EFI_OUT_OF_RESOURCES; + } + + do { + Next =3D PUD_ADDRESS_END (Address, End); + if (MemoryMapPmdRange (Pud, Address, Next, Attributes)) { + return EFI_OUT_OF_RESOURCES; + } + } while (Pud++, Address =3D Next, Address !=3D End); + return EFI_SUCCESS; +} + +/** + Establishes a page global directory based on the specified memory region. + + @param Start The memory space start address. + @param End The end address of the memory space. + @param Attributes Memory space Attributes. + + @retval EFI_SUCCESS The page global directory was created successf= ully. + @retval EFI_OUT_OF_RESOURCES Page global directory establishment fa= iled due to resource exhaustion. +**/ +EFI_STATUS +MemoryMapPageRange ( + IN UINTN Start, + IN UINTN End, + IN UINTN Attributes + ) +{ + PGD *Pgd; + UINTN Next; + UINTN Address =3D Start; + EFI_STATUS Err; + + Pgd =3D PgdOffset (Address); + do { + Next =3D PGD_ADDRESS_END (Address, End); + Err =3D MemoryMapPudRange (Pgd, Address, Next, Attributes); + if (Err) { + return Err; + } + } while (Pgd++, Address =3D Next, Address !=3D End); + + return EFI_SUCCESS; +} + +/** + Page tables are established from memory-mapped tables. + + @param MemoryRegion A pointer to a memory-mapped table entry. + + @retval EFI_SUCCESS The page table was created successfully. + @retval EFI_OUT_OF_RESOURCES Page table establishment failed due t= o resource exhaustion. +**/ +EFI_STATUS +FillTranslationTable ( + IN MEMORY_REGION_DESCRIPTOR *MemoryRegion + ) +{ + return MemoryMapPageRange (MemoryRegion->VirtualBase, + (MemoryRegion->Length + MemoryRegion->VirtualBase), + MemoryRegion->Attributes); +} + +/** + write operation is performed Count times from the first element of Buffe= r. + Convert EFI Attributes to Loongarch Attributes. + @param[in] EfiAttributes Efi Attributes. + + @retval LoongArch Attributes. +**/ +UINTN +EfiAttributeToLoongArchAttribute ( + IN UINTN EfiAttributes + ) +{ + UINTN LoongArchAttributes =3D PAGE_VALID | PAGE_DIRTY | CACHE_CC | PAGE= _USER | PAGE_GLOBAL; + switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) { + case EFI_MEMORY_UC: + LoongArchAttributes |=3D CACHE_SUC; + break; + case EFI_MEMORY_WC: + case EFI_MEMORY_WT: + case EFI_MEMORY_WB: + LoongArchAttributes |=3D CACHE_CC; + break; + default : + LoongArchAttributes |=3D CACHE_CC; + break; + } + + // Write protection attributes + if ((EfiAttributes & EFI_MEMORY_RO) !=3D 0) { + LoongArchAttributes &=3D ~PAGE_DIRTY; + } + + //eXecute protection attribute + if ((EfiAttributes & EFI_MEMORY_XP) !=3D 0) { + LoongArchAttributes |=3D PAGE_NO_EXEC; + } + + return LoongArchAttributes; +} + +/** + Finds the length and memory properties of the memory region correspondin= g to the specified base address. + + @param[in] BaseAddress To find the base address of the memory region. + @param[in] EndAddress To find the end address of the memory region. + @param[out] RegionLength The length of the memory region found. + @param[out] RegionAttributes Properties of the memory region found. + + @retval EFI_SUCCESS The corresponding memory area was successfully f= ound + EFI_NOT_FOUND No memory area found +**/ +EFI_STATUS +GetLoongArchMemoryRegion ( + IN UINTN BaseAddress, + IN UINTN EndAddress, + OUT UINTN *RegionLength, + OUT UINTN *RegionAttributes + ) +{ + PTE *Pte; + UINTN Attributes; + UINTN AttributesTmp; + UINTN MaxAddress; + MaxAddress =3D LShiftU64 (1ULL, MAX_VA_BITS) - 1; + Pte =3D GetPteAddress (BaseAddress); + + if (!MmuIsInit ()) { + return EFI_SUCCESS; + } + if (Pte =3D=3D NULL) { + return EFI_NOT_FOUND; + } + Attributes =3D GET_PAGE_ATTRIBUTES (*Pte); + if (IS_HUGE_PAGE (Pte->PteVal)) { + *RegionAttributes =3D Attributes & (~(PAGE_HUGE)); + *RegionLength +=3D HUGE_PAGE_SIZE; + } else { + *RegionLength +=3D EFI_PAGE_SIZE; + *RegionAttributes =3D Attributes; + } + + while (BaseAddress <=3D MaxAddress) { + Pte =3D GetPteAddress (BaseAddress); + if (Pte =3D=3D NULL) { + return EFI_SUCCESS; + } + AttributesTmp =3D GET_PAGE_ATTRIBUTES (*Pte); + if (IS_HUGE_PAGE (Pte->PteVal)) { + if (AttributesTmp =3D=3D Attributes) { + *RegionLength +=3D HUGE_PAGE_SIZE; + } + BaseAddress +=3D HUGE_PAGE_SIZE; + } else { + if (AttributesTmp =3D=3D Attributes) { + *RegionLength +=3D EFI_PAGE_SIZE; + } + BaseAddress +=3D EFI_PAGE_SIZE; + } + + if (BaseAddress > EndAddress) { + break; + } + } + return EFI_SUCCESS; +} + +/** + Sets the Attributes of the specified memory region + + @param[in] BaseAddress The base address of the memory region to set th= e Attributes. + @param[in] Length The length of the memory region to set the Attr= ibutes. + @param[in] Attributes The Attributes to be set. + + @retval EFI_SUCCESS The Attributes was set successfully +**/ +EFI_STATUS +LoongArchSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length, + IN UINTN Attributes + ) +{ + + if (!MmuIsInit ()) { + return EFI_SUCCESS; + } + Attributes =3D EfiAttributeToLoongArchAttribute (Attributes); + DEBUG ((DEBUG_VERBOSE, "%a %d %p %p %p.\n", __func__, __LINE__, BaseAddr= ess , Length, Attributes)); + MemoryMapPageRange (BaseAddress, BaseAddress + Length, Attributes); + + return EFI_SUCCESS; +} + +/** + Sets the non-executable Attributes for the specified memory region + + @param[in] BaseAddress The base address of the memory region to set th= e Attributes. + @param[in] Length The length of the memory region to set the Attr= ibutes. + + @retval EFI_SUCCESS The Attributes was set successfully +**/ +EFI_STATUS +LoongArchSetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + if (MmuIsInit ()) { + Length =3D EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (Length)); + LoongArchSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP); + } + return EFI_SUCCESS; +} + +/** + Check to see if mmu successfully initializes and saves the result. + + @param VOID. + + @retval EFI_SUCCESS Initialization succeeded. +**/ +EFI_STATUS +MmuInitialize (VOID) +{ + if (PcdGet64 (PcdSwapPageDir) !=3D 0) { + mMmuInited =3D TRUE; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h= b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h new file mode 100644 index 0000000000..7a5e8ea0dd --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.h @@ -0,0 +1,40 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Dir - Directory +**/ +#ifndef MMU_LIB_CORE_H_ +#define MMU_LIB_CORE_H_ +/** + Iterates through the page directory to initialize it. + + @param Dst A pointer to the directory of the page to initialize. + @param Num The number of page directories to initialize. + @param Src A pointer to the data used to initialize the page directory. + + @retval VOID. +**/ +VOID +PageDirInit ( + IN VOID *dest, + IN UINTN Count, + IN VOID *src + ); + +/** + Page tables are established from memory-mapped tables. + + @param MemoryRegion A pointer to a memory-mapped table entry. + + @retval EFI_SUCCESS The page table was created successfully. + @retval EFI_OUT_OF_RESOURCES Page table establishment failed due t= o resource exhaustion. +**/ +EFI_STATUS +FillTranslationTable ( + IN MEMORY_REGION_DESCRIPTOR *MemoryRegion + ); +#endif // MMU_LIB_CORE_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePe= i.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c new file mode 100644 index 0000000000..32a7fc0beb --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c @@ -0,0 +1,231 @@ +/** @file + Platform PEI driver + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - FwCfg - Firmeware Config + - Tlb - Translation Lookaside Buffer +**/ +#include +#include +#include +#include +#include +#include "Library/Cpu.h" +#include "pte.h" +#include "page.h" +#include "mmu.h" +#include +#include "MmuLibCore.h" +#include + +/** + Return the Virtual Memory Map of your platform + + This Virtual Memory Map is used by MemoryInitPei Module to initialize th= e MMU + on your platform. + + @param[out] VirtualMemoryMap Array of MEMORY_REGION_DESCRIPTOR + describing a Physical-to-Virtual Memory + mapping. This array must be ended by a + zero-filled entry. The allocated memory + will not be freed. +**/ +VOID +GetMemoryMapFromFwCfg ( + OUT MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap + ) +{ + + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + LOONGARCH_MEMMAP_ENTRY MemoryMapEntry; + LOONGARCH_MEMMAP_ENTRY *StartEntry; + LOONGARCH_MEMMAP_ENTRY *pEntry; + UINTN Processed; + MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + UINTN Index =3D 0; + ASSERT (VirtualMemoryMap !=3D NULL); + + VirtualMemoryTable =3D AllocatePool ( + sizeof (MEMORY_REGION_DESCRIPTOR) * + MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS + ); + VirtualMemoryTable[Index].PhysicalBase =3D 0x10000000; + VirtualMemoryTable[Index].VirtualBase =3D VirtualMemoryTable[Index].Phy= sicalBase; + VirtualMemoryTable[Index].Length =3D 0x10000000; + VirtualMemoryTable[Index].Attributes =3D PAGE_VALID | PLV_KERNEL | CA= CHE_SUC | PAGE_DIRTY | PAGE_GLOBAL; + ++Index; + + Status =3D QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/memmap error Status %d \n", __fun= c__, __LINE__, Status)); + ZeroMem (&VirtualMemoryTable[Index], sizeof (MEMORY_REGION_DESCRIPTOR)= ); + *VirtualMemoryMap =3D VirtualMemoryTable; + return ; + } + if (FwCfgSize % sizeof MemoryMapEntry !=3D 0) { + DEBUG ((DEBUG_ERROR, "no MemoryMapEntry FwCfgSize:%d\n", FwCfgSize)); + } + + QemuFwCfgSelectItem (FwCfgItem); + StartEntry =3D AllocatePages (EFI_SIZE_TO_PAGES (FwCfgSize)); + QemuFwCfgReadBytes (FwCfgSize, StartEntry); + for (Processed =3D 0; Processed < (FwCfgSize / sizeof MemoryMapEntry); P= rocessed++) { + pEntry =3D StartEntry + Processed; + if (pEntry->Length =3D=3D 0) { + continue; + } + + DEBUG ((DEBUG_INFO, "MemmapEntry Base %p length %p type %d\n", pEntry= ->BaseAddr, pEntry->Length, pEntry->Type)); + VirtualMemoryTable[Index].PhysicalBase =3D pEntry->BaseAddr; + VirtualMemoryTable[Index].VirtualBase =3D VirtualMemoryTable[Index].P= hysicalBase; + VirtualMemoryTable[Index].Length =3D pEntry->Length; + VirtualMemoryTable[Index].Attributes =3D PAGE_VALID | PLV_KERNEL | = CACHE_CC | PAGE_DIRTY | PAGE_GLOBAL; + ++Index; + } + + FreePages (StartEntry, EFI_SIZE_TO_PAGES (FwCfgSize)); + // End of Table + ZeroMem (&VirtualMemoryTable[Index], sizeof (MEMORY_REGION_DESCRIPTOR)); + *VirtualMemoryMap =3D VirtualMemoryTable; + return ; +} + +/** + Create a page table and initialize the MMU. + + @param[] VOID + + @retval VOID +**/ +EFIAPI +VOID +ConfigureMmu (VOID) +{ + PGD *SwapperPageDir =3D NULL; + PGD *InvalidPgd =3D NULL; + PUD *InvalidPudTable =3D NULL; + PMD *InvalidPmdTable =3D NULL; + PTE *InvalidPteTable =3D NULL; + MEMORY_REGION_DESCRIPTOR *MemoryTable =3D NULL; + RETURN_STATUS PcdStatus; + UINTN PgdShift =3D PGD_SHIFT; + UINTN PgdWide =3D PGD_WIDE; + UINTN PudShift =3D PUD_SHIFT; + UINTN PudWide =3D PUD_WIDE; + UINTN PmdShift =3D PMD_SHIFT; + UINTN PmdWide =3D PMD_WIDE; + UINTN PteShift =3D PTE_SHIFT; + UINTN PteWide =3D PTE_WIDE; + UINTN PageEnable =3D 1 << 4; + VOID *TlbReEntry; + + SwapperPageDir =3D AllocatePages (EFI_SIZE_TO_PAGES (PGD_TABLE_SIZE)); + InvalidPgd =3D AllocatePages (EFI_SIZE_TO_PAGES (PGD_TABLE_SIZE)); + InvalidPudTable =3D AllocatePages (EFI_SIZE_TO_PAGES (PUD_TABLE_SIZE)); + InvalidPmdTable =3D AllocatePages (EFI_SIZE_TO_PAGES (PMD_TABLE_SIZE)); + InvalidPteTable =3D AllocatePages (EFI_SIZE_TO_PAGES (PTE_TABLE_SIZE)); + ZeroMem (InvalidPteTable, PTE_TABLE_SIZE); + + if ((!InvalidPgd) || + (!InvalidPudTable) || + (!InvalidPmdTable) || + (!InvalidPteTable)) + { + goto FreeTranslationTable; + } + + /*pgd init*/ + PageDirInit (SwapperPageDir , ENTRYS_PER_PGD, InvalidPudTable); + /*pgd init*/ + PageDirInit (InvalidPgd, ENTRYS_PER_PGD, InvalidPudTable); + /*pud init*/ + PageDirInit (InvalidPudTable, ENTRYS_PER_PUD, InvalidPmdTable); + /*pmd init*/ + PageDirInit (InvalidPmdTable, ENTRYS_PER_PMD, InvalidPteTable); + GetMemoryMapFromFwCfg (&MemoryTable); + + PcdStatus |=3D PcdSet64S (PcdSwapPageDir, (UINTN)SwapperPageDir); + PcdStatus |=3D PcdSet64S (PcdInvalidPgd, (UINTN)InvalidPgd); + PcdStatus |=3D PcdSet64S (PcdInvalidPud, (UINTN)InvalidPudTable); + PcdStatus |=3D PcdSet64S (PcdInvalidPmd, (UINTN)InvalidPmdTable); + PcdStatus |=3D PcdSet64S (PcdInvalidPte, (UINTN)InvalidPteTable); + ASSERT_RETURN_ERROR (PcdStatus); + + while (MemoryTable->Length !=3D 0) { + DEBUG ((DEBUG_VERBOSE, "%a %d VirtualBase %p VirtualEnd %p Attributes = %p .\n", __func__, __LINE__, + MemoryTable->VirtualBase, + (MemoryTable->Length + MemoryTable->VirtualBase), + MemoryTable->Attributes)); + + PcdStatus =3D FillTranslationTable (MemoryTable); + if (EFI_ERROR (PcdStatus)) { + goto FreeTranslationTable; + } + MemoryTable++; + } + + TlbReEntry =3D AllocatePages (1); + if (TlbReEntry =3D=3D NULL) { + goto FreeTranslationTable; + } + CopyMem ((char *)TlbReEntry, HandleTlbRefill, (HandleTlbRefillEnd - Hand= leTlbRefill)); + InvalidateInstructionCacheRange ((VOID *)(UINTN)HandleTlbRefill, (UINTN)= (HandleTlbRefillEnd - HandleTlbRefill)); + + DEBUG ((DEBUG_VERBOSE, + "%a %d PteShift %d PteWide %d PmdShift %d PmdWide %d PudShift %d PudW= ide %d PgdShift %d PgdWide %d.\n", + __func__, __LINE__, + PteShift, PteWide, PmdShift, PmdWide,PudShift, PudWide, PgdShift, PgdW= ide)); + + SetTlbRefillFuncBase ((UINTN)TlbReEntry); + /*set page size*/ + WriteCsrPageSize (DEFAULT_PAGE_SIZE); + WriteCsrStlbPageSize (DEFAULT_PAGE_SIZE); + WriteCsrTlbRefillPageSize (DEFAULT_PAGE_SIZE); + + LoongArchWriteqCsrPwctl0 ((PteShift | PteWide << 5 | PmdShift << 10 | Pm= dWide << 15 | PudShift << 20 | PudWide << 25 + )); + LoongArchWriteqCsrPwctl1 (PgdShift | PgdWide << 6); + LoongArchWriteqCsrPgdl ((UINTN)SwapperPageDir); + LoongArchWriteqCsrPgdh ((UINTN)InvalidPgd); + + DEBUG ((DEBUG_INFO, "%a %d Enable Mmu Start PageBassAddress %p.\n", __fu= nc__, __LINE__, SwapperPageDir)); + LoongArchXchgCsrCrmd ( PageEnable, 1 << 4); + DEBUG ((DEBUG_INFO, "%a %d Enable Mmu End.\n", __func__, __LINE__)); + + return ; + +FreeTranslationTable: + if (SwapperPageDir) { + FreePages (SwapperPageDir, EFI_SIZE_TO_PAGES (PGD_TABLE_SIZE)); + } + + if (InvalidPgd) { + FreePages (InvalidPgd, EFI_SIZE_TO_PAGES (PGD_TABLE_SIZE)); + } + + if (InvalidPudTable) { + FreePages (InvalidPudTable, EFI_SIZE_TO_PAGES (PUD_TABLE_SIZE)); + } + + if (InvalidPmdTable) { + FreePages (InvalidPmdTable, EFI_SIZE_TO_PAGES (PMD_TABLE_SIZE)); + } + + if (InvalidPteTable) { + FreePages (InvalidPteTable, EFI_SIZE_TO_PAGES (PTE_TABLE_SIZE)); + } + + PcdSet64S (PcdSwapPageDir, (UINTN)0); + PcdSet64S (PcdInvalidPgd, (UINTN)0); + PcdSet64S (PcdInvalidPud, (UINTN)0); + PcdSet64S (PcdInvalidPmd, (UINTN)0); + PcdSet64S (PcdInvalidPte, (UINTN)0); + + return ; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h b/Plat= form/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h new file mode 100644 index 0000000000..8e284a2ecd --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/mmu.h @@ -0,0 +1,190 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Tlb or TLB - Translation Lookaside Buffer + - CSR - Cpu State Register + - PGDL - Page Global Directory Low + - PGDH - Page Global Directory High + - TLBIDX - TLB Index + - TLBREHI - TLB Refill Entry High + - PWCTL - Page Walk Control + - STLB - Singular Page Size TLB + - PS - Page Size +**/ +#ifndef MMU_H_ +#define MMU_H_ +/*page size 4k*/ +#define DEFAULT_PAGE_SIZE 0x0c +#define LOONGARCH_CSR_PGDL 0x19 /* Page table base address when VA[= 47] =3D 0 */ +#define LOONGARCH_CSR_PGDH 0x1a /* Page table base address when VA[= 47] =3D 1 */ +#define LOONGARCH_CSR_TLBIDX 0x10 /* TLB Index, EHINV, PageSize, NP */ +#define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */ +#define LOONGARCH_CSR_TLBELO0 0x12 /* TLB EntryLo0 */ +#define LOONGARCH_CSR_TLBELO1 0x13 /* TLB EntryLo1 */ +#define LOONGARCH_CSR_TLBREHI 0x8e /* TLB refill entryhi */ +#define LOONGARCH_CSR_PWCTL0 0x1c /* PWCtl0 */ +#define LOONGARCH_CSR_PWCTL1 0x1d /* PWCtl1 */ +#define LOONGARCH_CSR_STLBPGSIZE 0x1e +#define CSR_TLBIDX_SIZE_MASK 0x3f000000 +#define CSR_TLBIDX_PS_SHIFT 24 +#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT + +#define CSR_TLBREHI_PS_SHIFT 0 +#define CSR_TLBREHI_PS 0x3f + +#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \ + EFI_MEMORY_WC | \ + EFI_MEMORY_WT | \ + EFI_MEMORY_WB | \ + EFI_MEMORY_UCE \ + ) + +typedef struct { + EFI_PHYSICAL_ADDRESS PhysicalBase; + EFI_VIRTUAL_ADDRESS VirtualBase; + UINTN Length; + UINTN Attributes; +} MEMORY_REGION_DESCRIPTOR; + +// The total number of descriptors, including the final "end-of-table" des= criptor. +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS (128) + +extern CHAR8 HandleTlbRefill[], HandleTlbRefillEnd[]; + +/* + Invalid corresponding TLB entries are based on the address given + + @param Address The address corresponding to the invalid page table entry + + @retval none +*/ +extern +VOID +LoongarchInvalidTlb ( + UINTN Address + ); + +/* + Set Tlb Refill function to hardware + + @param A0 The address of tlb refill function + + @retval none +*/ +extern +VOID +SetTlbRefillFuncBase ( + UINTN Address + ); + +/* + Set Cpu Status Register Page Size. + + @param PageSize Page Size. + + @retval none +*/ +extern +VOID +WriteCsrPageSize ( + UINTN PageSize + ); + +/* + Set Cpu Status Register TLBREFILL Page Size. + + @param PageSize Page Size. + + @retval none +*/ +extern +VOID +WriteCsrTlbRefillPageSize ( + UINTN PageSize + ); + +/* + Set Cpu Status Register STLB Page Size. + + @param PageSize Page Size. + + @retval VOID +*/ +extern +VOID +WriteCsrStlbPageSize ( + UINTN PageSize +); + +/* + Write Csr PWCTL0 register. + + @param Val The value used to write to the PWCTL0 register + + @retval none +*/ +extern +VOID +LoongArchWriteqCsrPwctl0 ( + UINTN Val + ); + +/* + Write Csr PWCTL1 register. + + @param Val The value used to write to the PWCTL1 register + + @retval none +*/ +extern +VOID +LoongArchWriteqCsrPwctl1 ( + UINTN Val + ); + +/* + Write Csr PGDL register. + + @param Val The value used to write to the PGDL register + + @retval none +*/ +extern +VOID +LoongArchWriteqCsrPgdl ( + UINTN Val + ); + +/* + Write Csr PGDH register. + + @param Val The value used to write to the PGDH register + + @retval none +*/ +extern +VOID +LoongArchWriteqCsrPgdh ( + UINTN Val + ); + +/* + Exchange specified bit data with the Csr CRMD register. + + @param[IN] Val The value Exchanged with the CSR CRMD register. + @param[IN] Mask Specifies the mask for swapping bits + + @retval VOID +*/ +extern +VOID +LoongArchXchgCsrCrmd ( + UINTN Val, + UINTN Mask + ); + +#endif // MMU_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h b/Pla= tform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h new file mode 100644 index 0000000000..6ab07e7900 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h @@ -0,0 +1,280 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Pgd or Pgd or PGD - Page Global Directory + - Pud or Pud or PUD - Page Upper Directory + - Pmd or Pmd or PMD - Page Middle Directory + - Pte or pte or PTE - Page Table Entry + - Val or VAL or val - Value + - Dir - Directory +**/ +#ifndef PAGE_H_ +#define PAGE_H_ + +#define MAX_VA_BITS 47 +#define PGD_WIDE (8) +#define PUD_WIDE (9) +#define PMD_WIDE (9) +#define PTE_WIDE (9) + +#define ENTRYS_PER_PGD (1 << PGD_WIDE) +#define ENTRYS_PER_PUD (1 << PUD_WIDE) +#define ENTRYS_PER_PMD (1 << PMD_WIDE) +#define ENTRYS_PER_PTE (1 << PTE_WIDE) + +#define PGD_SHIFT (PUD_SHIFT + PUD_WIDE) +#define PUD_SHIFT (PMD_SHIFT + PMD_WIDE) +#define PMD_SHIFT (EFI_PAGE_SHIFT + PTE_WIDE) +#define PTE_SHIFT (EFI_PAGE_SHIFT) + +#define PGD_SIZE (1UL << PGD_SHIFT) +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PMD_SIZE (1UL << PMD_SHIFT) + +#define PGD_MASK (~(PGD_SIZE-1)) +#define PUD_MASK (~(PUD_SIZE-1)) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PAGE_MASK (~(EFI_PAGE_SIZE - 1)) +#define PFN_MASK (~(((UINTN)(1) << (EFI_PAGE_SH= IFT)) - 1) & \ + (((UINTN)(1) << (PAGE_PFN_END= _SHIFT)) - 1)) + +typedef struct { UINTN PgdVal; } PGD; +typedef struct { UINTN PudVal; } PUD; +typedef struct { UINTN PmdVal; } PMD; +typedef struct { UINTN PteVal; } PTE; +/** + Gets the value of the page global directory table entry. + + @param x Page global directory struct variables. + + @retval the value of the page global directory table entry. + **/ +#define PGD_VAL(x) ((x).PgdVal) +/** + Gets the value of the page upper directory table entry. + + @param x Page upper directory struct variables. + + @retval the value of the page upper directory table entry. + **/ +#define PUD_VAL(x) ((x).PudVal) +/** + Gets the value of the page middle directory table entry. + + @param x Page middle directory struct variables. + + @retval the value of the page middle directory table entry. + **/ +#define PMD_VAL(x) ((x).PmdVal) +/** + Gets the value of the page table entry. + + @param x Page table entry struct variables. + + @retval the value of the page table entry. + **/ +#define PTE_VAL(x) ((x).PteVal) + +#define PGD_TABLE_SIZE (ENTRYS_PER_PGD * sizeof(PGD)) +#define PUD_TABLE_SIZE (ENTRYS_PER_PUD * sizeof(PUD)) +#define PMD_TABLE_SIZE (ENTRYS_PER_PMD * sizeof(PMD)) +#define PTE_TABLE_SIZE (ENTRYS_PER_PTE * sizeof(PTE)) +/** + Gets the physical address of the record in the page table entry. + + @param x Page table entry struct variables. + + @retval the value of the physical address. + **/ +#define GET_PAGE_ATTRIBUTES(x) (UINTN) {(PTE_VAL(x) & ~PFN_MA= SK)} +/** + Gets the virtual address of the next block of the specified virtual addr= ess + that is aligned with the size of the global page directory mapping. + + @param Address Specifies the virtual address. + @param End The end address of the memory region. + + @retval the specified virtual address of the next block. + **/ +#define PGD_ADDRESS_END(Address, End) \ +({ \ + UINTN Boundary =3D ((Address) + PGD_SIZE) & PGD_MASK; \ + (Boundary - 1 < (End) - 1)? Boundary: (End); \ +}) +/** + Gets the virtual address of the next block of the specified virtual addr= ess + that is aligned with the size of the page upper directory mapping. + + @param Address Specifies the virtual address. + @param End The end address of the memory region. + + @retval the specified virtual address of the next block. + **/ +#define PUD_ADDRESS_END(Address, End) \ +({ \ + UINTN Boundary =3D ((Address) + PUD_SIZE) & PUD_MASK; \ + (Boundary - 1 < (End) - 1)? Boundary: (End); \ +}) +/** + Gets the virtual address of the next block of the specified virtual addr= ess + that is aligned with the size of the page middle directory mapping. + + @param Address Specifies the virtual address. + @param End The end address of the memory region. + + @retval the specified virtual address of the next block. + **/ +#define PMD_ADDRESS_END(Address, End) \ +({ \ + UINTN Boundary =3D ((Address) + PMD_SIZE) & PMD_MASK; \ + (Boundary - 1 < (End) - 1)? Boundary: (End); \ +}) +/** + Get Specifies the virtual address corresponding to the index of the page= global directory table entry. + + @param Address Specifies the virtual address. + + @retval the index of the page global directory table entry. + **/ +#define PGD_INDEX(Address) (((Address) >> PGD_SHIFT) & (E= NTRYS_PER_PGD-1)) +/** + Get Specifies the virtual address corresponding to the index of the page= upper directory table entry. + + @param Address Specifies the virtual address. + @param End The end address of the memory region. + + @retval the index of the page upper directory table entry. + **/ +#define PUD_INDEX(Address) (((Address) >> PUD_SHIFT) & (E= NTRYS_PER_PUD - 1)) +/** + Get Specifies the virtual address corresponding to the index of the page= middle directory table entry. + + @param Address Specifies the virtual address. + + @retval the index of the page middle directory table entry. + **/ +#define PMD_INDEX(Address) (((Address) >> PMD_SHIFT) & (E= NTRYS_PER_PMD - 1)) +/** + Get Specifies the virtual address corresponding to the index of the page= table entry. + + @param Address Specifies the virtual address. + + @retval the index of the page table entry. + **/ +#define PTE_INDEX(Address) (((Address) >> EFI_PAGE_SHIFT)= & (ENTRYS_PER_PTE - 1)) + +/** + Calculates the value of the page table entry based on the specified virt= ual address and properties. + + @param Address Specifies the virtual address. + @param Attributes Specifies the Attributes. + + @retval the value of the page table entry. + **/ +#define MAKE_PTE(Address, Attributes) (PTE){((((Address) >> EFI_PAGE= _SHIFT) << 12) | (Attributes))} +/** + Get Global bit from Attributes + + @param Attributes Specifies the Attributes. + * */ +#define GET_GLOBALBIT(Attributes) ((Attributes & PAGE_GLOBAL) >>= PAGE_GLOBAL_SHIFT) +/** + Calculates the value of the Huge page table entry based on the specified= virtual address and properties. + + @param Address Specifies the virtual address. + @param Attributes Specifies the Attributes. + + @retval the value of the HUGE page table entry. + **/ +#define MAKE_HUGE_PTE(Address, Attributes) (((((Address) >> PMD_SHIFT) <<= PMD_SHIFT) | \ + ((Attributes) | (GET_GLOBALBI= T(Attributes) << PAGE_HGLOBAL_SHIFT) | \ + PAGE_HUGE))) + + /** + Check whether the large page table entry is. + + @param Val The value of the page table entry. + + @retval 1 Is huge page table entry. + @retval 0 Isn't huge page table entry. + **/ +#define IS_HUGE_PAGE(Val) ((((Val) & PAGE_HUGE) =3D=3D P= AGE_HUGE) && \ + (((Val) & PAGE_HGLOBAL) =3D= =3D PAGE_HGLOBAL)) + +#define HUGE_PAGE_SIZE (PMD_SIZE) + + /** + Check that the global page directory table entry is empty. + + @param pgd the global page directory struct variables. + + @retval 1 Is huge page table entry. + @retval 0 Isn't huge page table entry. + **/ +STATIC +inline +UINTN +pgd_none ( + IN PGD pgd + ) +{ + return (PGD_VAL(pgd) =3D=3D (UINTN)PcdGet64(PcdInvalidPud)); +} + + /** + Check that the page upper directory table entry is empty. + + @param pud Page upper directory struct variables. + + @retval 1 Is huge page table entry. + @retval 0 Isn't huge page table entry. + **/ +STATIC +inline +UINTN +pud_none ( + IN PUD pud + ) +{ + return (PUD_VAL(pud) =3D=3D (UINTN)PcdGet64 (PcdInvalidPmd)); +} + + /** + Check that the page middle directory table entry is empty. + + @param pmd Page middle directory struct variables. + + @retval 1 Is huge page table entry. + @retval 0 Isn't huge page table entry. + **/ +STATIC +inline +UINTN +pmd_none ( + IN PMD pmd + ) +{ + return (PMD_VAL(pmd) =3D=3D (UINTN)PcdGet64(PcdInvalidPte)); +} + /** + Check that the page table entry is empty. + + @param pmd Page table entry struct variables. + + @retval 1 Is huge page table entry. + @retval 0 Isn't huge page table entry. + **/ +STATIC +inline +UINTN +pte_none ( + IN PTE pte + ) +{ + return (!(PTE_VAL(pte) & (~PAGE_GLOBAL))); +} +#endif // PAGE_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h b/Plat= form/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h new file mode 100644 index 0000000000..aacbf81744 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/pte.h @@ -0,0 +1,57 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Tlb or TLB - Translation Lookaside Buffer + - HGLOBAL - Huge Global + - PFN - Page Frame number + - EXEC - Execute + - PLV - Privilege Level + - RPLV - Restricted Privilege Level + - SUC - Strong-ordered UnCached + - CC - Coherent Cached + - WUC - Weak-ordered UnCached +**/ +#ifndef PTE_H_ +#define PTE_H_ +/*Page table property definitions */ +#define PAGE_VALID_SHIFT 0 +#define PAGE_DIRTY_SHIFT 1 +#define PAGE_PLV_SHIFT 2 /* 2~3, two bits */ +#define CACHE_SHIFT 4 /* 4~5, two bits */ +#define PAGE_GLOBAL_SHIFT 6 +#define PAGE_HUGE_SHIFT 6 /* HUGE is a PMD bit */ + +#define PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ +#define PAGE_PFN_SHIFT 12 +#define PAGE_PFN_END_SHIFT 48 +#define PAGE_NO_READ_SHIFT 61 +#define PAGE_NO_EXEC_SHIFT 62 +#define PAGE_RPLV_SHIFT 63 + +/* Used by TLB hardware (placed in EntryLo*) */ +#define PAGE_VALID ((UINTN)(1) << PAGE_VALID_SHIFT) +#define PAGE_DIRTY ((UINTN)(1) << PAGE_DIRTY_SHIFT) +#define PAGE_PLV ((UINTN)(3) << PAGE_PLV_SHIFT) +#define PAGE_GLOBAL ((UINTN)(1) << PAGE_GLOBAL_SHIFT) +#define PAGE_HUGE ((UINTN)(1) << PAGE_HUGE_SHIFT) +#define PAGE_HGLOBAL ((UINTN)(1) << PAGE_HGLOBAL_SHIFT) +#define PAGE_NO_READ ((UINTN)(1) << PAGE_NO_READ_SHIFT) +#define PAGE_NO_EXEC ((UINTN)(1) << PAGE_NO_EXEC_SHIFT) +#define PAGE_RPLV ((UINTN)(1) << PAGE_RPLV_SHIFT) +#define CACHE_MASK ((UINTN)(3) << CACHE_SHIFT) +#define PFN_SHIFT (EFI_PAGE_SHIFT - 12 + PAGE_PFN_SHIFT) + +#define PLV_KERNEL 0 +#define PLV_USER 3 + +#define PAGE_USER (PLV_USER << PAGE_PLV_SHIFT) +#define PAGE_KERNEL (PLV_KERN << PAGE_PLV_SHIFT) + +#define CACHE_SUC (0 << CACHE_SHIFT) /* Strong-ordered UnCached= */ +#define CACHE_CC (1 << CACHE_SHIFT) /* Coherent Cached */ +#define CACHE_WUC (2 << CACHE_SHIFT) /* Weak-ordered UnCached */ +#endif // PTE_H_ --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96448): https://edk2.groups.io/g/devel/message/96448 Mute This Topic: https://groups.io/mt/95082585/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96450+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96450+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652805; cv=none; d=zohomail.com; s=zohoarc; b=VZ5SfDBA5jTVfGsxB1FTTksDOgbplLo7NbLRBl5N9v3PiCXdyaK8CXHaCoUmGQ5I5yG+0kubUg6nrkvnskXhc3JAsAV1Dl/E4KjgrJKXrEsN49BLj+THLlQCNr4e8sAeHra1gaK+x9uw2Gdm8zpSUCKHjqFx+p23ThZlk4xYBTI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652805; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=sOXFYZ7AyYxLGRVvEuyymIgP8Au1HQUxCAN7gnMiIqU=; b=CaZqXUBkaOumv/maWJ0HfYZ+nYeQvzTeLoAtFxAFP02tGuHhrae/zdi9rk3AB2mnjcr/3YYZYfLQ0UaxKxqgfG8Xrj5V+71h/nPco2vUhQ+Dc6mruS6U4uEs/F5vnURQ/NDJ/HXbUsFwweASIm4nfK/qRZdCFq+VuyOJ/EPRMB8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96450+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652805186532.1750642665173; Wed, 16 Nov 2022 18:40:05 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id IRYFYY1788612xNQ6TxXjG6E; Wed, 16 Nov 2022 18:40:04 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6325.1668652801703071335 for ; Wed, 16 Nov 2022 18:40:02 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxXbYAn3VjDSQIAA--.11323S3; Thu, 17 Nov 2022 10:40:00 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S8; Thu, 17 Nov 2022 10:39:59 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 06/16] Platform/Loongson: Add StableTimerLib. Date: Thu, 17 Nov 2022 10:39:32 +0800 Message-Id: <58f2f65a06a8d1f093245632a6ac82e21877f033.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S8 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvJXoW3Kw45ZF4rGw1xKryDCF4DJwb_yoWkJFyfpr sxZ3W7Kr18Gr45Aw13J3WjgFy5Aw43Cr98GFs8Cr18A3yDA3s3Ww1ktFW0qFyfZrW3Wry0 q3yIga1UuF48J3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bnkFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4 AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF 7I0E14v26F4j6r4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6x kF7I0E14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020E x4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E74AGY7Cv6cx26rWlOx8S6xCaFV Cjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7VAKI48JMxAIw28IcVCjz48v 1sIEY20_WwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I 0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAI cVC0I7IYx2IY67AKxVW5JVW7JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcV CF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: jELItKBqhTnCMuuJgbUhJE6Jx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652804; bh=2XktWrKRyq+AdC21xxCv1jAINAa2rAuLJWQY/cenqzY=; h=Cc:Date:From:Reply-To:Subject:To; b=pEvn5U/uoYsXrEx7zdZxszyDTXh36T22AkNjX+BCxFpgjFRS7LzoXtetpWNiJySsgLq JvFtb1Fu3X+IGg21RKLvw0H7T5qbK/aml/46Nfe13Dxzs7x3pyvQb6WRd5w436g6XqRlC /DNEcbT5ByNRMIl1O2t3wYgpQM/K4TGJRZw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652805856100018 Content-Type: text/plain; charset="utf-8" This library provides a delay interface and a timing interface. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Include/Library/StableTimer.h | 59 +++++ .../Library/StableTimerLib/Count.S | 52 ++++ .../Library/StableTimerLib/TimerLib.c | 236 ++++++++++++++++++ .../Library/StableTimerLib/TimerLib.inf | 32 +++ 4 files changed, 379 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/Stab= leTimer.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/Count.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/TimerLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/TimerLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer= .h b/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer.h new file mode 100644 index 0000000000..93f5b66c34 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer.h @@ -0,0 +1,59 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Csr - Cpu Status Register + - Calc - Calculation + - Freq - frequency +**/ + +#ifndef STABLE_TIMER_H_ +#define STABLE_TIMER_H_ +#include "Library/Cpu.h" + +/** + Gets the timer count value. + + @param[] VOID + + @retval timer count value. +**/ +extern +UINTN +EFIAPI +LoongArchReadTime ( + VOID + ); + +/** + Calculate the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +CalcConstFreq ( + VOID + ); + +/* + Reads data from the specified CPUCFG register. + + @param[OUT] Val Pointer to the variable used to store the CPUCFG regi= ster value. + @param[IN] reg Specifies the register number of the CPUCFG to read t= he data. + + @retval none + */ +extern +VOID +LoongArchReadCpuCfg ( + UINT64 *Val, + UINT64 reg + ); + +#endif // STABLE_TIMER_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Coun= t.S b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Count.S new file mode 100644 index 0000000000..4e0e718381 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Count.S @@ -0,0 +1,52 @@ +#-------------------------------------------------------------------------= ----- +# +# Count for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ----- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" + +ASM_GLOBAL ASM_PFX(CpuSetIP) +ASM_GLOBAL ASM_PFX(LoongArchReadTime) +ASM_GLOBAL ASM_PFX(LoongArchReadCpuCfg) + +# +# Set cpu interrupts +# @param A0 The interrupt number +# + +ASM_PFX(CpuSetIP): + csrrd T0, LOONGARCH_CSR_ECFG + or T0, T0, A0 + csrwr T0, LOONGARCH_CSR_ECFG + jirl ZERO, RA, 0 + +# +#Gets the timer count value. +#@param[] VOID +#@retval timer count value. +# + +ASM_PFX(LoongArchReadTime): + rdtime.d A0, ZERO + jirl ZERO, RA, 0 + +# +# Read Csr CPUCFG register. +# @param A0 Pointer to the variable used to store the CPUCFG register = value. +# @param A1 Specifies the register number of the CPUCFG to read the da= ta. +# @retval none +# + +ASM_PFX(LoongArchReadCpuCfg): + cpucfg T0, A1 + stptr.d T0, A0, 0 + jirl ZERO, RA, 0 diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Time= rLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib= .c new file mode 100644 index 0000000000..135fb22611 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib.c @@ -0,0 +1,236 @@ +/** @file + Generic LoongArch implementation of TimerLib.h + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Freq - Frequency + - Csr - Cpu Status Register + - calc - calculate +**/ + +#include +#include +#include +#include +#include "Library/StableTimer.h" +#include "Library/Cpu.h" + +UINT32 StableTimerFreq =3D 0; + +/** + Calculate the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +CalcConstFreq ( + VOID + ) +{ + UINT32 Result; + UINT32 BaseFreq; + UINT32 ClockMultiplier; + UINT32 ClockDivide; + UINT64 Val; + + LoongArchReadCpuCfg (&Val, LOONGARCH_CPUCFG4); + BaseFreq =3D (UINT32)Val; + LoongArchReadCpuCfg (&Val, LOONGARCH_CPUCFG5); + Result =3D (UINT32)Val; + ClockMultiplier =3D Result & 0xffff; + ClockDivide =3D (Result >> 16) & 0xffff; + + if ((!BaseFreq) || (!ClockMultiplier) || (!ClockDivide)) { + return 0; + } else { + return (BaseFreq * ClockMultiplier / ClockDivide); + } +} +/** + Get the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +GetFreq ( + VOID + ) +{ + if (StableTimerFreq) { + } else { + StableTimerFreq =3D CalcConstFreq (); + } + + return StableTimerFreq; +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + + UINTN Count; + UINTN Ticks; + UINTN Start; + UINTN End; + + Count =3D GetFreq (); + Count =3D (Count * MicroSeconds) / 1000000; + Start =3D LoongArchReadTime (); + End =3D Start + Count; + + do { + Ticks =3D LoongArchReadTime (); + } while (Ticks < End); + + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + UINT32 MicroSeconds; + + if (NanoSeconds % 1000 =3D=3D 0) { + MicroSeconds =3D NanoSeconds/1000; + } else { + MicroSeconds =3D NanoSeconds/1000 + 1; + } + MicroSecondDelay (MicroSeconds); + + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + Retrieves the current value of a 64-bit free running performance counter= . The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties (). + + @return The current value of the free running performance counter. +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return LoongArchReadTime (); +} +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter s= tarts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end wi= th + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartV= alue + is less than EndValue, then the performance counter counts up. If StartV= alue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a Start= Value + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of = 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with bef= ore + it rolls over. + + @return The frequency in Hz. +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue !=3D NULL) { + *StartValue =3D BIT2; + } + + if (EndValue !=3D NULL) { + *EndValue =3D BIT48 - 1; + } + + return GetFreq (); +} + +/** + Converts elapsed ticks of performance counter to time in nanoseconds. + + This function converts the elapsed ticks of running performance counter = to + time value in unit of nanoseconds. + + @param Ticks The number of elapsed ticks of running performance cou= nter. + + @return The elapsed time in nanoseconds. +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency =3D GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time =3D --------- x 1,000,000,000 + // Frequency + // + NanoSeconds =3D MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remai= nder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder should < = 2^(64-30) =3D 2^34, + // i.e. highest bit set in Remainder should <=3D 33. + // + Shift =3D MAX (0, HighBitSet64 (Remainder) - 33); + Remainder =3D RShiftU64 (Remainder, (UINTN) Shift); + Frequency =3D RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds +=3D DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u)= , Frequency, NULL); + + return NanoSeconds; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Time= rLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerL= ib.inf new file mode 100644 index 0000000000..86f243998b --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib.inf @@ -0,0 +1,32 @@ +## @file +# Generic LoongArch implementation of TimerLib.h +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TimerLib + FILE_GUID =3D 740389C7-CC44-4A2F-88DC-89D97D312E= 7C + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TimerLib + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + TimerLib.c + Count.S + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + IoLib --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96450): https://edk2.groups.io/g/devel/message/96450 Mute This Topic: https://groups.io/mt/95082587/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96455+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96455+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652809; cv=none; d=zohomail.com; s=zohoarc; b=ANEOXiBrWYYKvkVyzeWPMKbyUp2gfFw66y/qAKDvsJRGhR7dkUFTGHv2ZJRKMrQfANxZYYolbuBgkucsIJRxVgOcdetXy03i+aNHdc9fOyXUwdS2Or9SAJUCc9DbhSHGOye8DoyPaZh8gqvPPvZ96d0pFUEP5v3gdy/A4YJSSB0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652809; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=vKxMPi2PDSz1nJRPd5WYZZoKLc83Tt17tqe5ckJwqQc=; b=gpAwcOB9CAS1TRAaXPP6JCBZHFydvGAiKSANxJG+0rUiydqmCEMtnzG4JpkhElIz4NM4cxN8JxxU9Lq7ZlcCpjdJjjtLA3z8u4axCLIiyZEnQTQchVwEPljo/hZyiQKHi+obWZtb9G1eC1L/4iL9Q/v9IEUbiQgUoooPU1B3TS0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96455+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652809631220.9264717470346; Wed, 16 Nov 2022 18:40:09 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ayvxYY1788612xI6x8UB2p9X; Wed, 16 Nov 2022 18:40:07 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6329.1668652804148160661 for ; Wed, 16 Nov 2022 18:40:05 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxKdgAn3VjEiQIAA--.21671S3; Thu, 17 Nov 2022 10:40:00 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S9; Thu, 17 Nov 2022 10:40:00 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 07/16] Platform/Loongson: Support PEI phase. Date: Thu, 17 Nov 2022 10:39:33 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S9 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWfAw1kKrWDAFWUKFykuw18uFg_yoW5Zw1xXo W8JF92kw4UGw1rXw1kG3ZrtrWxZF1Yva1aqr1rZa4UAFs0yr13tF98JasrGw15AFn8Awn8 Gw4fGa97JFW2q3s5n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqm1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: zhAM7X090J6VIJXFfVVY0mLKx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652807; bh=6va5BHIBkn8vZDrB9HPUWbSS10zDdKZ0N9wIPJuSBwA=; h=Cc:Date:From:Reply-To:Subject:To; b=Ip0UqXy/01oLaSs/CNikxfOzjjXTw7ar80C6jcZouUD8b0ShHOTssxaTdks+pA0aP+I EwivcRFqOeHzCdI7ULnse12jByF6ihmqz1Nd1OU0JhiS1RJ3qjAAq/69AWt0O2Fqz1XWt fJvv9otrJ/rAn2eNQb9Ul3EMNmt6wz9ypZE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652809877100040 Content-Type: text/plain; charset="utf-8" Platform PEI module for LoongArch platform initialization. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Loongson/LoongArchQemuPkg/Loongson.dec | 25 + .../Loongson/LoongArchQemuPkg/Loongson.dsc | 69 +++ .../Loongson/LoongArchQemuPkg/Loongson.fdf | 51 +++ .../LoongArchQemuPkg/PlatformPei/Fv.c | 58 +++ .../LoongArchQemuPkg/PlatformPei/MemDetect.c | 104 +++++ .../LoongArchQemuPkg/PlatformPei/Platform.c | 433 ++++++++++++++++++ .../LoongArchQemuPkg/PlatformPei/Platform.h | 86 ++++ .../PlatformPei/PlatformPei.inf | 74 +++ 8 files changed, 900 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/PlatformPei/Fv.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetec= t.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform= .c create mode 100644 Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform= .h create mode 100644 Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform= Pei.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dec index 61f600b20d..023df1dd2a 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec @@ -27,12 +27,37 @@ =20 [Guids] gLoongArchQemuPkgTokenSpaceGuid =3D { 0x0e0383ce, 0x0151, 0x4d01, { 0x8= 0, 0x0e, 0x3f, 0xef, 0x8b, 0x27, 0x6d, 0x52 } } + gEarly16550UartBaseAddressGuid =3D { 0xea67ca3e, 0x1f54, 0x436b, { 0x9= 7, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } } =20 ## In the PcdsFixedAtBuild and PcdsDynamic areas, numbers start at 0x0. [PcdsFixedAtBuild, PcdsDynamic] gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase|0x0|UINT64|0x00000000 gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize|0x0|UINT32|0x00000001 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase|0x0|UINT64|0x00000003 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvSize|0x0|UINT32|0x00000004 + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase|0x0|UINT64|0x00000009 + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreePadding|256|UINT32|0x000000= 0a + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase|0|UINT64|0x0000000b gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize|0|UINT32|0x0000000c + gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop|0x0|UINT64|0x0000000d + gLoongArchQemuPkgTokenSpaceGuid.PcdRamRegionsBottom|0x0|UINT64|0x0000000e gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|0x0|UINT64|0x0000000f gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvSize|0x0|UINT32|0x00000010 + +## In the PcdsFixedAtBuild.LOONGARCH64 area, numbers start at 0x10000. +[PcdsFixedAtBuild.LOONGARCH64] + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00010000 + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00010001 + +## In the PcdsDynamic area, numbers start at 0x20000. +[PcdsDynamic] + gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize|0x40000000|UINT64|0x00020000 + gLoongArchQemuPkgTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0|UINT64|0x000= 20001 + gLoongArchQemuPkgTokenSpaceGuid.PcdFwCfgDataAddress|0x0|UINT64|0x00020002 + gLoongArchQemuPkgTokenSpaceGuid.PcdSwapPageDir|0x0|UINT64|0x00020003 + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPgd|0x0|UINT64|0x00020004 + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPud|0x0|UINT64|0x00020005 + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd|0x0|UINT64|0x00020006 + gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte|0x0|UINT64|0x00020007 + gLoongArchQemuPkgTokenSpaceGuid.PcdRtcBaseAddress|0x00000000|UINT64|0x00= 020008 diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dsc index 049be907dd..8d196ae8c1 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc @@ -56,17 +56,59 @@ =20 [LibraryClasses.common] PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/StableTimerLib/TimerLib.inf PrintLib | MdePkg/Library/BasePrintLib/BasePrint= Lib.inf BaseMemoryLib | MdePkg/Library/BaseMemoryLib/BaseMemo= ryLib.inf BaseLib | MdePkg/Library/BaseLib/BaseLib.inf + PerformanceLib | MdePkg/Library/BasePerformanceLibNull= /BasePerformanceLibNull.inf PeCoffLib | MdePkg/Library/BasePeCoffLib/BasePeCo= ffLib.inf + CacheMaintenanceLib | MdePkg/Library/BaseCacheMaintenanceLi= b/BaseCacheMaintenanceLib.inf + UefiDecompressLib | MdePkg/Library/BaseUefiDecompressLib/= BaseUefiDecompressLib.inf PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf IoLib | MdePkg/Library/BaseIoLibIntrinsic/Bas= eIoLibIntrinsic.inf PlatformHookLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf SerialPortLib | MdeModulePkg/Library/BaseSerialPortLi= b16550/BaseSerialPortLib16550.inf DebugPrintErrorLevelLib | MdePkg/Library/BaseDebugPrintErrorLev= elLib/BaseDebugPrintErrorLevelLib.inf + FdtLib | EmbeddedPkg/Library/FdtLib/FdtLib.inf PeCoffExtraActionLib | MdePkg/Library/BasePeCoffExtraActionL= ibNull/BasePeCoffExtraActionLibNull.inf DebugAgentLib | MdeModulePkg/Library/DebugAgentLibNul= l/DebugAgentLibNull.inf + PeiServicesLib | MdePkg/Library/PeiServicesLib/PeiServ= icesLib.inf + +[LibraryClasses.common.SEC] + PcdLib | MdePkg/Library/BasePcdLibNull/BasePcd= LibNull.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusC= odeLib/PeiReportStatusCodeLib.inf + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib= /PeiMemoryAllocationLib.inf + SerialPortLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/SerialPortLib/EarlySerialPortLib16550.inf + +[LibraryClasses.common.PEI_CORE] + PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib= /PeiMemoryAllocationLib.inf + PeiCoreEntryPoint | MdePkg/Library/PeiCoreEntryPoint/PeiC= oreEntryPoint.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusC= odeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib | MdeModulePkg/Library/OemHookStatusCod= eLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf + QemuFwCfgLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/QemuFwCfgLib/QemuFwCfgPeiLib.inf + MmuLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/MmuLib/MmuBaseLibPei.inf + SerialPortLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/SerialPortLib/EarlySerialPortLib16550.inf + +[LibraryClasses.common.PEIM] + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib= /PeiMemoryAllocationLib.inf + PeimEntryPoint | MdePkg/Library/PeimEntryPoint/PeimEnt= ryPoint.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusC= odeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib | MdeModulePkg/Library/OemHookStatusCod= eLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf + PeiResourcePublicationLib | MdePkg/Library/PeiResourcePublication= Lib/PeiResourcePublicationLib.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectio= nLib/PeiExtractGuidedSectionLib.inf + PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/PeiQem= uFwCfgS3LibFwCfg.inf + QemuFwCfgLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/QemuFwCfgLib/QemuFwCfgPeiLib.inf + MmuLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/MmuLib/MmuBaseLibPei.inf + SerialPortLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/SerialPortLib/EarlySerialPortLib16550.inf =20 ##########################################################################= ###### # @@ -118,8 +160,16 @@ # ASSERT_BREAKPOINT_ENABLED 0x10 # ASSERT_DEADLOOP_ENABLED 0x20 =20 +##########################################################################= ############# gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase | 0= x10000 gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize | 0= x10000 + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase | 0= x100000 + # + # minimal memory for uefi bios should be 512M + # 0x00000000 - 0x10000000 + # 0x90000000 - 0xA0000000 + # + gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop | 0= x10000000 =20 [PcdsPatchableInModule.common] gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0 @@ -130,3 +180,22 @@ # SEC Phase modules # Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf + + # + # PEI Phase modules + # + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompre= ssLib.inf + } + + Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.fdf index 9685795cda..8e257f2392 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf @@ -45,9 +45,60 @@ READ_LOCK_STATUS =3D TRUE =20 INF Platform/Loongson/LoongArchQemuPkg/Sec/SecMain.inf =20 +##########################################################################= ########################### +[FV.PEIFV] +FvNameGuid =3D 6f856a84-de7d-4af9-93a3-342b4ecb46eb +BlockSize =3D $(BLOCK_SIZE) +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE + +APRIORI PEI { + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +} + +# +# PEI Phase modules +# + +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +INF Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf + ##########################################################################= ########################### [Rule.Common.SEC] FILE SEC =3D $(NAMED_GUID) { TE TE Align =3D Auto $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING =3D"$(MODULE_NAME)" Optional } + +##########################################################################= ########################### +[Rule.Common.PEI_CORE] + FILE PEI_CORE =3D $(NAMED_GUID) { + TE TE Align=3DAuto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING =3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### +[Rule.Common.PEIM] + FILE PEIM =3D $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=3DAuto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Fv.c b/Platform= /Loongson/LoongArchQemuPkg/PlatformPei/Fv.c new file mode 100644 index 0000000000..06b2807d6c --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Fv.c @@ -0,0 +1,58 @@ +/** @file + Build FV related hobs for platform. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiPei.h" +#include "Platform.h" +#include +#include +#include +#include + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n")); + + // + // Create a memory allocation HOB for the PEI FV. + // + BuildMemoryAllocationHob ( + PcdGet64 (PcdSecPeiTempRamBase), + PcdGet32 (PcdSecPeiTempRamSize), + EfiBootServicesData + ); + + // + // Let DXE know about the DXE FV + // + BuildFvHob (PcdGet64 (PcdFlashDxeFvBase), PcdGet32 (PcdFlashDxeFvSize)); + + // + // Let PEI know about the DXE FV so it can find the DXE Core + // + DEBUG ((DEBUG_INFO, "DXEFV base:%p size:%x\n", (VOID *) (UINTN)PcdGet64 = (PcdFlashDxeFvBase), + PcdGet32 (PcdFlashDxeFvSize))); + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *) (UINTN)PcdGet64 (PcdFlashDxeFvBase), + PcdGet32 (PcdFlashDxeFvSize), + NULL, + NULL + ); + + return EFI_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c b/P= latform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c new file mode 100644 index 0000000000..fad4cff8d8 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/MemDetect.c @@ -0,0 +1,104 @@ +/** @file + Memory Detection for Virtual Machines. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Platform.h" + +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 Base; + UINT64 Size; + UINT64 RamTop; + + // + // Determine the range of memory to use during PEI + // + Base =3D PcdGet64 (PcdSecPeiTempRamBase) + PcdGet32 (PcdSecPeiTempRamSiz= e); + RamTop =3D PcdGet64 (PcdUefiRamTop); + Size =3D RamTop - Base; + + // + // Publish this memory to the PEI Core + // + Status =3D PublishSystemMemory (Base, Size); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Publish Memory Initialize done.\n")); + return Status; +} + +/** + Peform Memory Detection + Publish system RAM and reserve memory regions +**/ +VOID +InitializeRamRegions ( + VOID + ) +{ + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + LOONGARCH_MEMMAP_ENTRY MemoryMapEntry; + LOONGARCH_MEMMAP_ENTRY *StartEntry; + LOONGARCH_MEMMAP_ENTRY *pEntry; + UINTN Processed; + + Status =3D QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/memmap error Status %d \n", __fun= c__, __LINE__, Status)); + return ; + } + if (FwCfgSize % sizeof MemoryMapEntry !=3D 0) { + DEBUG ((DEBUG_ERROR, "no MemoryMapEntry FwCfgSize:%d\n", FwCfgSize)); + return ; + } + + QemuFwCfgSelectItem (FwCfgItem); + StartEntry =3D AllocatePages (EFI_SIZE_TO_PAGES (FwCfgSize)); + QemuFwCfgReadBytes (FwCfgSize, StartEntry); + for (Processed =3D 0; Processed < (FwCfgSize / sizeof MemoryMapEntry); P= rocessed++) { + pEntry =3D StartEntry + Processed; + if (pEntry->Length =3D=3D 0) { + continue; + } + + DEBUG ((DEBUG_INFO, "MemmapEntry Base %p length %p type %d\n", pEntry= ->BaseAddr, pEntry->Length, pEntry->Type)); + if (pEntry->Type !=3D EfiAcpiAddressRangeMemory) { + continue; + } + + AddMemoryRangeHob ( pEntry->BaseAddr, pEntry->BaseAddr + pEntry->Lengt= h); + } +} diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c b/Pl= atform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c new file mode 100644 index 0000000000..32b6518f8f --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.c @@ -0,0 +1,433 @@ +/** @file + Platform PEI driver + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Mem - Memory +**/ + +// +// The package level header files this module uses +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" + +/* TODO */ +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] =3D { + { EfiReservedMemoryType, 0x004 }, + { EfiRuntimeServicesData, 0x024 }, + { EfiRuntimeServicesCode, 0x030 }, + { EfiBootServicesCode, 0x180 }, + { EfiBootServicesData, 0xF00 }, + { EfiMaxMemoryType, 0x000 } +}; + +// +// Module globals +// +CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode =3D { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMasterBootModePpiGuid, + NULL +}; + +/** + Create Reserved type memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} +/** + Create system type memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +/** + Create memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddMemoryBaseSizeHob (MemoryBase, (UINT64) (MemoryLimit - MemoryBase)); +} +/** + Create memory type information hand off block. + + @param VOID + + @return VOID +**/ +VOID +MemMapInitialization ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "=3D=3D%a=3D=3D\n", __func__)); + // + // Create Memory Type Information HOB + // + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof (mDefaultMemoryTypeInformation) + ); +} +/** Get the UART base address of the console serial-port from the DT. + + This function fetches the node referenced in the "stdout-path" + property of the "chosen" node and returns the base address of + the console UART. + + @param [in] Fdt Pointer to a Flattened Device Tree (= Fdt). + @param [out] SerialConsoleAddress If success, contains the base address + of the console serial-port. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND Console serial-port info not found in DT. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GetSerialConsolePortAddress ( + IN CONST VOID *Fdt, + OUT UINT64 *SerialConsoleAddress + ) +{ + CONST CHAR8 *Prop; + INT32 PropSize; + CONST CHAR8 *Path; + INT32 PathLen; + INT32 ChosenNode; + INT32 SerialConsoleNode; + INT32 Len; + CONST CHAR8 *NodeStatus; + CONST UINT64 *RegProperty; + + if ((Fdt =3D=3D NULL) || (fdt_check_header (Fdt) !=3D 0)) { + return EFI_INVALID_PARAMETER; + } + + // The "chosen" node resides at the root of the DT. Fetch it. + ChosenNode =3D fdt_path_offset (Fdt, "/chosen"); + if (ChosenNode < 0) { + return EFI_NOT_FOUND; + } + + Prop =3D fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize); + if (PropSize < 0) { + return EFI_NOT_FOUND; + } + + // Determine the actual path length, as a colon terminates the path. + Path =3D ScanMem8 (Prop, ':', PropSize); + if (Path =3D=3D NULL) { + PathLen =3D AsciiStrLen (Prop); + } else { + PathLen =3D Path - Prop; + } + + // Aliases cannot start with a '/', so it must be the actual path. + if (Prop[0] =3D=3D '/') { + SerialConsoleNode =3D fdt_path_offset_namelen (Fdt, Prop, PathLen); + } else { + // Lookup the alias, as this contains the actual path. + Path =3D fdt_get_alias_namelen (Fdt, Prop, PathLen); + if (Path =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + SerialConsoleNode =3D fdt_path_offset (Fdt, Path); + } + + NodeStatus =3D fdt_getprop (Fdt, SerialConsoleNode, "status", &Len); + if ((NodeStatus !=3D NULL) && (AsciiStrCmp (NodeStatus, "okay") !=3D 0))= { + return EFI_NOT_FOUND; + } + + RegProperty =3D fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len); + if (Len !=3D 16) { + return EFI_INVALID_PARAMETER; + } + + *SerialConsoleAddress =3D fdt64_to_cpu (ReadUnaligned64 (RegProperty)); + + return EFI_SUCCESS; +} + +/** Get the Rtc base address from the DT. + + This function fetches the node referenced in the "loongson,ls7a-rtc" + property of the "reg" node and returns the base address of + the RTC. + + @param [in] Fdt Pointer to a Flattened Device Tree (= Fdt). + @param [out] RtcBaseAddress If success, contains the base address + of the Rtc. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND RTC info not found in DT. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GetRtcAddress ( + IN CONST VOID *Fdt, + OUT UINT64 *RtcBaseAddress + ) +{ + INT32 Node; + INT32 Prev; + CONST CHAR8 *Type; + INT32 Len; + CONST UINT64 *RegProp; + EFI_STATUS Status; + + if ((Fdt =3D=3D NULL) || (fdt_check_header (Fdt) !=3D 0)) { + return EFI_INVALID_PARAMETER; + } + + Status =3D EFI_NOT_FOUND; + for (Prev =3D 0;; Prev =3D Node) { + Node =3D fdt_next_node (Fdt, Prev, NULL); + if (Node < 0) { + break; + } + + // + // Check for memory node + // + Type =3D fdt_getprop (Fdt, Node, "compatible", &Len); + if ((Type) + && (AsciiStrnCmp (Type, "loongson,ls7a-rtc", Len) =3D=3D 0)) + { + // + // Get the 'reg' property of this node. For now, we will assume + // two 8 byte quantities for base and size, respectively. + // + RegProp =3D fdt_getprop (Fdt, Node, "reg", &Len); + if ((RegProp !=3D 0) + && (Len =3D=3D (2 * sizeof (UINT64)))) + { + *RtcBaseAddress =3D SwapBytes64 (RegProp[0]); + Status =3D RETURN_SUCCESS; + DEBUG ((DEBUG_INFO, "%a Len %d RtcBase %llx\n",__func__, Len, *Rtc= BaseAddress)); + break; + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT rtc node\n", + __FUNCTION__)); + break; + } + } + } + + return Status; +} +/** + Misc Initialization. + + @param VOID + + @return VOID +**/ +VOID +MiscInitialization ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "=3D=3D%a=3D=3D\n", __func__)); + // + // Creat CPU HOBs. + // + BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize= )); +} +/** + add fdt hand off block. + + @param VOID + + @return VOID +**/ +VOID +AddFdtHob (VOID) +{ + VOID *Base; + VOID *NewBase; + UINTN FdtSize; + UINTN FdtPages; + UINT64 *FdtHobData; + UINT64 *UartHobData; + UINT64 SerialConsoleAddress; + UINT64 RtcBaseAddress; + RETURN_STATUS Status; + + Base =3D (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeBase); + ASSERT (Base !=3D NULL); + + Status =3D GetSerialConsolePortAddress (Base, &SerialConsoleAddress); + if (RETURN_ERROR (Status)) { + return; + } + UartHobData =3D BuildGuidHob (&gEarly16550UartBaseAddressGuid, sizeof *U= artHobData); + ASSERT (UartHobData !=3D NULL); + *UartHobData =3D SerialConsoleAddress; + + Status =3D GetRtcAddress(Base, &RtcBaseAddress); + if (RETURN_ERROR (Status)) { + return; + } + Status =3D PcdSet64S (PcdRtcBaseAddress, RtcBaseAddress); + if (RETURN_ERROR (Status)) { + return; + } + + FdtSize =3D fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreePadding); + FdtPages =3D EFI_SIZE_TO_PAGES (FdtSize); + NewBase =3D AllocatePages (FdtPages); + ASSERT (NewBase !=3D NULL); + fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages)); + + FdtHobData =3D BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData); + ASSERT (FdtHobData !=3D NULL); + *FdtHobData =3D (UINTN)NewBase; +} + +/** + Fetch the size of system memory from QEMU. + + @param VOID + + @return VOID +**/ +VOID +SystemMemorySizeInitialization ( + VOID + ) +{ + UINT64 RamSize; + RETURN_STATUS PcdStatus; + + QemuFwCfgSelectItem (QemuFwCfgItemRamSize); + RamSize=3D QemuFwCfgRead64 (); + DEBUG ((DEBUG_INFO, "%a: QEMU reports %dM system memory\n", __FUNCTION__, + RamSize/1024/1024)); + + // + // If the fw_cfg key or fw_cfg entirely is unavailable, no change to PCD. + // + if (RamSize =3D=3D 0) { + return; + } + + // + // Otherwise, set RamSize to PCD. + // + PcdStatus =3D PcdSet64S (PcdRamSize, RamSize); + ASSERT_RETURN_ERROR (PcdStatus); +} + +/** + Perform Platform PEI initialization. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +EFIAPI +InitializePlatform ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n")); + + Status =3D PeiServicesInstallPpi (&mPpiListBootMode); + ASSERT_EFI_ERROR (Status); + + SystemMemorySizeInitialization (); + PublishPeiMemory (); + PeiFvInitialization (); + InitializeRamRegions (); + MemMapInitialization (); + MiscInitialization (); + AddFdtHob (); + ConfigureMmu (); + + return EFI_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.h b/Pl= atform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.h new file mode 100644 index 0000000000..38d358b335 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/Platform.h @@ -0,0 +1,86 @@ +/** @file + Platform PEI module include file. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PLATFORM_H_ +#define PLATFORM_H_ + +#include + +/** + Create system type memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +/** + Create memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +/** + Create Reserved type memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ); +/** + Publish system RAM and reserve memory regions + + @return VOID +**/ +VOID +InitializeRamRegions ( + VOID + ); + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ); + +#endif // PLATFORM_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf= b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf new file mode 100644 index 0000000000..268efac585 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf @@ -0,0 +1,74 @@ +## @file +# Platform PEI driver +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformPei + FILE_GUID =3D 4c0e81e5-e8e3-4eef-b24b-19b686e9ab53 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InitializePlatform + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + Fv.c + MemDetect.c + Platform.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + OvmfPkg/OvmfPkg.dec + +[Ppis] + gEfiPeiMasterBootModePpiGuid + +[Guids] + gEfiMemoryTypeInformationGuid + gEarly16550UartBaseAddressGuid + gFdtHobGuid + +[LibraryClasses] + DebugLib + BaseMemoryLib + HobLib + IoLib + PeiResourcePublicationLib + PeiServicesLib + PeiServicesTablePointerLib + PeimEntryPoint + QemuFwCfgLib + PcdLib + TimerLib + MmuLib + MemoryAllocationLib + +[Pcd] + gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreePadding + gLoongArchQemuPkgTokenSpaceGuid.PcdRtcBaseAddress + +[FixedPcd] + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvSize + gLoongArchQemuPkgTokenSpaceGuid.PcdRamRegionsBottom + gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamBase + gLoongArchQemuPkgTokenSpaceGuid.PcdSecPeiTempRamSize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + +[Depex] + TRUE --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96455): https://edk2.groups.io/g/devel/message/96455 Mute This Topic: https://groups.io/mt/95082594/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96453+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96453+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652806; cv=none; d=zohomail.com; s=zohoarc; b=V9PCszoS5ojH5eRHp/8FbTE/qziUOSUyMHeA1AyP12WomgLOCWynOP3NzxVnsvGnntkxMYCihxov6BPptpw3rR8PVbxvJfvgNa/g8Pc/VeqBoTLmhVaRLnUk9vnO+6AHb/jPqi45KPLBq8LJp2U3kYHkhjpbxG94iwxRHkw4IRQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652806; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=LfR9K2PQJuuk1nXH7+Em0TTTuJm9tRGMTEPfrmP/yZU=; b=OeK5IFfLUWYNd5pvtlAEfiYBnuc+AInXERP32drCyhjRLP586zNRNMTNl5ZRYdq3FKf73eFUOtvecW4gE4TbxW4CiVJhqlGQWosjp+SyxsPeeInwxXymSphkESRZzqj5mzDZL8o5gi6wcz/0SAMz75gkpVF5goKY+cQdoJLo//s= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96453+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652806505425.6825244568006; Wed, 16 Nov 2022 18:40:06 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id NXmyYY1788612xZwDBJzGe2i; Wed, 16 Nov 2022 18:40:05 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6327.1668652803256908886 for ; Wed, 16 Nov 2022 18:40:04 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxTbcBn3VjFiQIAA--.11670S3; Thu, 17 Nov 2022 10:40:01 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S10; Thu, 17 Nov 2022 10:40:00 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 08/16] Platform/Loongson: Add CPU DXE driver. Date: Thu, 17 Nov 2022 10:39:34 +0800 Message-Id: <34b8a81eb04f70180133628848e77c33fe4f1c75.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S10 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWDAFWxKr1kZw1xXFWkKryxuFg_yoWruw1DWo W5Za92yw47J348Ja97C3Z3G3yxXF18uFs5Jr40yFsYgF90gF15CFW0y3ZxGw1fJF45XrZr GFyxX3Z7GFZIqrn5n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqm1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: xJljQ0xa6V0uynvaBVxzdmPrx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652805; bh=Um6376CszVp56u+G+Ys4pQUa/q1cgmO3fW5XD5LB4pA=; h=Cc:Date:From:Reply-To:Subject:To; b=xG2d6kQiMZD8Cx6LpnhQwSOqIUxYwGd8QSEbRfvUr1TKkGz8Uiel3kIXCW2SJPEeNKJ bhZI/jF1SSohjwcqkfxLPOyQWJl84kyOpe9iJNGuQ9YbnAlXsmCcDFSxvVR9FdHzTkvKA UHfW6H1tLBEw7tnGJB5DA2k8MDcF5WPY2Kk= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652807876100034 Content-Type: text/plain; charset="utf-8" The driver produces EFI_CPU_ARCH_PROTOCOL, Initialize the exception entry address. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.c | 367 ++++++++++++++++++ .../LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.h | 199 ++++++++++ .../Drivers/CpuDxe/CpuDxe.inf | 59 +++ .../Drivers/CpuDxe/LoongArch64/Exception.c | 335 ++++++++++++++++ .../Drivers/CpuDxe/LoongArch64/Fpu.S | 97 +++++ .../Drivers/CpuDxe/LoongArch64/LoongArch.S | 321 +++++++++++++++ 6 files changed, 1378 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDx= e.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDx= e.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDx= e.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/Loong= Arch64/Exception.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/Loong= Arch64/Fpu.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/Loong= Arch64/LoongArch.S diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.c b/P= latform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.c new file mode 100644 index 0000000000..23f824d82b --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.c @@ -0,0 +1,367 @@ +/** @file + CPU DXE Module to produce CPU ARCH Protocol + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CpuDxe.h" + +BOOLEAN mInterruptState =3D FALSE; + +/* + This function flushes the range of addresses from Start to Start+Length + from the processor's data cache. If Start is not aligned to a cache line + boundary, then the bytes before Start to the preceding cache line bounda= ry + are also flushed. If Start+Length is not aligned to a cache line boundar= y, + then the bytes past Start+Length to the end of the next cache line bound= ary + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate mu= st be + supported. If the data cache is fully coherent with all DMA operations, = then + this function can just return EFI_SUCCESS. If the processor does not sup= port + flushing a range of the data cache, then the entire data cache can be fl= ushed. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param Start The beginning physical address to flush from th= e processor's data + cache. + @param Length The number of bytes to flush from the processor= 's data cache. This + function may flush more bytes than Length speci= fies depending upon + the granularity of the flush operation that the= processor supports. + @param FlushType Specifies the type of flush operation to perfor= m. + + @retval EFI_SUCCESS The address range from Start to Start+Leng= th was flushed from + the processor's data cache. + @retval EFI_UNSUPPORTEDT The processor does not support the cache f= lush type specified + by FlushType. + @retval EFI_DEVICE_ERROR The address range from Start to Start+Leng= th could not be flushed + from the processor's data cache. +**/ +EFI_STATUS +EFIAPI +CpuFlushCpuDataCache ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length, + IN EFI_CPU_FLUSH_TYPE FlushType + ) +{ + switch (FlushType) { + case EfiCpuFlushTypeWriteBack: + WriteBackDataCacheRange ((VOID *) (UINTN)Start, (UINTN)Length); + break; + case EfiCpuFlushTypeInvalidate: + InvalidateDataCacheRange ((VOID *) (UINTN)Start, (UINTN)Length); + break; + case EfiCpuFlushTypeWriteBackInvalidate: + WriteBackInvalidateDataCacheRange ((VOID *) (UINTN)Start, (UINTN)Len= gth); + break; + default: + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +/** + This function enables interrupt processing by the processor. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS Interrupts are enabled on the processor. + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the pro= cessor. +**/ +EFI_STATUS +EFIAPI +CpuEnableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ) +{ + EnableInterrupts (); + + mInterruptState =3D TRUE; + return EFI_SUCCESS; +} + +/** + This function disables interrupt processing by the processor. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS Interrupts are disabled on the processor. + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the pr= ocessor. +**/ +EFI_STATUS +EFIAPI +CpuDisableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ) +{ + DisableInterrupts (); + + mInterruptState =3D FALSE; + return EFI_SUCCESS; +} + +/** + This function retrieves the processor's current interrupt state a return= s it in + State. If interrupts are currently enabled, then TRUE is returned. If in= terrupts + are currently disabled, then FALSE is returned. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param State A pointer to the processor's current interrupt = state. Set to TRUE if + interrupts are enabled and FALSE if interrupts = are disabled. + + @retval EFI_SUCCESS The processor's current interrupt state wa= s returned in State. + @retval EFI_INVALID_PARAMETER State is NULL. +**/ +EFI_STATUS +EFIAPI +CpuGetInterruptState ( + IN EFI_CPU_ARCH_PROTOCOL *This, + OUT BOOLEAN *State + ) +{ + if (State =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *State =3D mInterruptState; + return EFI_SUCCESS; +} + +/** + This function generates an INIT on the processor. If this function succe= eds, then the + processor will be reset, and control will not be returned to the caller.= If InitType is + not supported by this processor, or the processor cannot programmaticall= y generate an + INIT without help from external hardware, then EFI_UNSUPPORTED is return= ed. If an error + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param InitType The type of processor INIT to perform. + + @retval EFI_SUCCESS The processor INIT was performed. This ret= urn code should never be seen. + @retval EFI_UNSUPPORTED The processor INIT operation specified by = InitType is not supported + by this processor. + @retval EFI_DEVICE_ERROR The processor INIT failed. +**/ +EFI_STATUS +EFIAPI +CpuInit ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_CPU_INIT_TYPE InitType + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function registers and enables the handler specified by InterruptHa= ndler for a processor + interrupt or exception type specified by InterruptType. If InterruptHand= ler is NULL, then the + handler for the processor interrupt or exception type specified by Inter= ruptType is uninstalled. + The installed handler is called once for each processor interrupt or exc= eption. + + @param InterruptType Interrupt Type. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the h= andler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt wa= s successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handle= r for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler fo= r InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType i= s not supported. +**/ +EFI_STATUS +EFIAPI +CpuRegisterInterruptHandler ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + return RegisterInterruptHandler (InterruptType, InterruptHandler); +} + +/** + Returns a timer value from one of the CPU's internal timers. There is no + inherent time interval between ticks but is a function of the CPU freque= ncy. + + @param This - Protocol instance structure. + @param TimerIndex - Specifies which CPU timer is requested. + @param TimerValue - Pointer to the returned timer value. + @param TimerPeriod - A pointer to the amount of time that passes + in femtoseconds (10-15) for each increment + of TimerValue. If TimerValue does not + increment at a predictable rate, then 0 is + returned. The amount of time that has + passed between two calls to GetTimerValue() + can be calculated with the formula + (TimerValue2 - TimerValue1) * TimerPeriod. + This parameter is optional and may be NULL. + + @retval EFI_SUCCESS - If the CPU timer count was returned. + @retval EFI_UNSUPPORTED - If the CPU does not have any readable ti= mers. + @retval EFI_DEVICE_ERROR - If an error occurred while reading the t= imer. + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is= NULL. +**/ +EFI_STATUS +EFIAPI +CpuGetTimerValue ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINT32 TimerIndex, + OUT UINT64 *TimerValue, + OUT UINT64 *TimerPeriod OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function modifies the attributes for the memory region specified by= BaseAddress and + Length from their current attributes to the attributes specified by Attr= ibutes. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param BaseAddress The physical address that is the start address = of a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memor= y region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_ACCESS_DENIED The attributes for the memory resource ran= ge specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to m= odify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more= bytes of the memory + resource range specified by BaseAddress an= d Length. + The bit mask of attributes is not support = for the memory resource + range specified by BaseAddress and Length. +**/ +EFI_STATUS +EFIAPI +CpuSetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 EfiAttributes + ) +{ + EFI_STATUS Status; + UINTN LoongArchAttributes; + UINTN RegionBaseAddress; + UINTN RegionLength; + UINTN RegionLoongArchAttributes; + + if ((BaseAddress & (SIZE_4KB - 1)) !=3D 0) { + // Minimum granularity is SIZE_4KB (4KB on ARM) + DEBUG ((DEBUG_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum gr= anularity is SIZE_4KB\n", + BaseAddress, + Length, + EfiAttributes)); + + return EFI_UNSUPPORTED; + } + // Convert the 'Attribute' into LoongArch Attribute + LoongArchAttributes =3D EfiAttributeToLoongArchAttribute (EfiAttributes); + + // Get the region starting from 'BaseAddress' and its 'Attribute' + RegionBaseAddress =3D BaseAddress; + Status =3D GetLoongArchMemoryRegion (RegionBaseAddress, BaseAddress + Le= ngth, + &RegionLength, &RegionLoongArchAttributes); + + LoongArchSetMemoryAttributes (BaseAddress, Length, EfiAttributes); + // Data & Instruction Caches are flushed when we set new memory attribut= es. + // So, we only set the attributes if the new region is different. + if (EFI_ERROR (Status) || (RegionLoongArchAttributes !=3D LoongArchAttri= butes) || + ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) + { + return LoongArchSetMemoryAttributes (BaseAddress, Length, EfiAttribute= s); + } + return EFI_SUCCESS; +} + +/** + Callback function for idle events. + + @param Event Event whose notification function is being= invoked. + @param Context The pointer to the notification function's= context, + which is implementation-dependent. + + @param VOID +**/ +VOID +EFIAPI +IdleLoopEventCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + CpuSleep (); +} + +// +// Globals used to initialize the protocol +// +EFI_HANDLE CpuHandle =3D NULL; +EFI_CPU_ARCH_PROTOCOL Cpu =3D { + CpuFlushCpuDataCache, + CpuEnableInterrupt, + CpuDisableInterrupt, + CpuGetInterruptState, + CpuInit, + CpuRegisterInterruptHandler, + CpuGetTimerValue, + CpuSetMemoryAttributes, + 0, // NumberOfTimers + 4, // DmaBufferAlignment +}; + +/** + Initialize the state information for the CPU Architectural Protocol. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS Thread can be successfully created + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Cannot create the thread +**/ +EFI_STATUS +CpuDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT IdleLoopEvent; + + InitializeExceptions (&Cpu); + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &CpuHandle, + &gEfiCpuArchProtocolGuid, &Cpu, + NULL + ); + + // + // Setup a callback for idle events + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + IdleLoopEventCallback, + NULL, + &gIdleLoopEventGuid, + &IdleLoopEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.h b/P= latform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.h new file mode 100644 index 0000000000..43cb976aa2 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.h @@ -0,0 +1,199 @@ +/** @file + CPU DXE Module to produce CPU ARCH Protocol and CPU MP Protocol + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef CPU_DXE_H_ +#define CPU_DXE_H_ + +#include + +/** + This function registers and enables the handler specified by InterruptHa= ndler for a processor + interrupt or exception type specified by InteruptNum. If InterruptHandle= r is NULL, then the + handler for the processor interrupt or exception type specified by Inter= uptNum is uninstalled. + The installed handler is called once for each processor interrupt or exc= eption. + + @param InteruptNum A number of the processor's current interrupt. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this para= meter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt wa= s successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handle= r for InteruptNum was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler fo= r InteruptNum was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InteruptNum is = not supported. +**/ +EFI_STATUS +RegisterInterruptHandler ( + IN EFI_EXCEPTION_TYPE InteruptNum, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +/** + This function registers and enables the handler specified by InterruptHa= ndler for a processor + interrupt or exception type specified by InteruptNum. If InterruptHandle= r is NULL, then the + handler for the processor interrupt or exception type specified by Inter= uptNum is uninstalled. + The installed handler is called once for each processor interrupt or exc= eption. + + @param InteruptNum A number of the processor's current interrupt. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this para= meter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt wa= s successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handle= r for InteruptNum was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler fo= r InteruptNum was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InteruptNum is = not supported. +**/ +EFI_STATUS +RegisterDebuggerInterruptHandler ( + IN EFI_EXCEPTION_TYPE InteruptNum, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +/** + This function modifies the attributes for the memory region specified by= BaseAddress and + Length from their current attributes to the attributes specified by Attr= ibutes. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param BaseAddress The physical address that is the start address = of a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memor= y region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_ACCESS_DENIED The attributes for the memory resource ran= ge specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to m= odify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more= bytes of the memory + resource range specified by BaseAddress an= d Length. + The bit mask of attributes is not support = for the memory resource + range specified by BaseAddress and Length. +**/ +EFI_STATUS +EFIAPI +CpuSetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** Exception module initialization + This function sets the exception base address. + + @param Cpu A pointer to the CPU architecture protocol structure. + + @retval EFI_SUCCESS Initialization succeeded + @retval EFI_NOT_FOUND Could not Found resources. + @retval EFI_OUT_OF_RESOURCES No enough resources. +**/ +EFI_STATUS +InitializeExceptions ( + IN EFI_CPU_ARCH_PROTOCOL *Cpu + ); + +/** Common exception entry + Exception handling is the entry point for the C environment, + This function does different things depending on the exception type. + + @param SystemContext The system context at the time of the exception. + + @retval VOID. +**/ +VOID +EFIAPI +CommonExceptionEntry ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ); + +extern CHAR8 LoongArchException[], LoongArchExceptionEnd[]; +/** Set Exception Base Address + + @param addr Exception Base Address. + + @retval The Old Exception Base Address. +**/ +extern +UINT64 +SetEbase ( + EFI_PHYSICAL_ADDRESS addr + ); +/* + Load the FPU with signalling NANS. This bit pattern we're using has + the property that no matter whether considered as single or as double + precision represents signaling NANS. + + @param fcsr The value to initialize FCSR0 + + @retval The Old Exception Base Address. + */ +extern +VOID +InitFpu ( + UINT32 fcsr + ); + +/* + Read Csr EUEN register. + + @param CsrEuen Pointer to the variable used to store the EUEN register = value + + @retval none + */ +extern +VOID +LoongArchReadqCsrEuen ( + UINT64 *CsrEuen + ); + +/* + Write Csr EUEN register. + + @param The value used to write to the EUEN register + + @retval none + */ +extern +VOID +LoongArchWriteqCsrEuen ( + UINT64 CsrEuen + ); + +/* + Enables floating-point unit + + @param VOID + + @retval VOID + */ +extern +VOID +LoongArchEnableFpu ( + VOID + ); + +/* + Disable floating-point unit + + @param VOID + + @retval VOID + */ +extern +VOID +LoongArchDisableFpu ( + VOID + ); + +#endif // CPU_DXE_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.inf b= /Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.inf new file mode 100644 index 0000000000..96aabfefb8 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.inf @@ -0,0 +1,59 @@ +## @file +# CPU driver installs CPU Architecture Protocol and CPU MP protocol. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D CpuDxe + FILE_GUID =3D bf954921-25c1-48c0-9bfb-8d0cd7ee92da + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D CpuDxeInitialize + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources.Common] + CpuDxe.c + CpuDxe.h + +[Sources.LOONGARCH64] + LoongArch64/Exception.c + LoongArch64/LoongArch.S + LoongArch64/Fpu.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + CacheMaintenanceLib + CpuLib + DebugLib + DxeServicesTableLib + HobLib + PeCoffGetEntryPointLib + UefiDriverEntryPoint + UefiLib + MmuLib + +[Protocols] + gEfiCpuArchProtocolGuid + gEfiMpServiceProtocolGuid + +[Guids] + gEfiDebugImageInfoTableGuid + gIdleLoopEventGuid + +[Depex] + TRUE diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/= Exception.c b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64= /Exception.c new file mode 100644 index 0000000000..793ae90e4f --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/Excepti= on.c @@ -0,0 +1,335 @@ +/** @file + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - ESTAT - Exception Status + - ECFG - Exception Configure + - ERA - Exception Return Address + - BADV - Bad Virtual Address + - BADI - Bad Instructions + - Epc or EPC or epc - Exception Program Counter + - pc or PC or pc - Program Counter + - CRMD - Current Mode + - PRMD - Previous Mode + - CsrEuen - Cpu Status Register Extern Unit Enable + - fpu or fp or FP - Float Point Unit + - LOONGARCH - Loongson Arch + - Irq - Interrupt ReQuest +**/ + +#include "Library/Cpu.h" +#include +#include +#include +#include +#include +#include "CpuDxe.h" +#include +#include +#include + +EFI_EXCEPTION_CALLBACK gInterruptHandler[MAX_LOONGARCH_INTERRUPT + 1]; +EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_LOONGARCH_INTERRUPT= + 1]; + +/** + This function registers and enables the handler specified by InterruptHa= ndler for a processor + interrupt or exception type specified by InteruptNum. If InterruptHandle= r is NULL, then the + handler for the processor interrupt or exception type specified by Inter= uptNum is uninstalled. + The installed handler is called once for each processor interrupt or exc= eption. + + @param InteruptNum A number of the processor's current interrupt. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRU= PT_HANDLER that is called + when a processor interrupt occurs. If this para= meter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt wa= s successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handle= r for InteruptNum was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler fo= r InteruptNum was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InteruptNum is = not supported. +**/ +EFI_STATUS +RegisterInterruptHandler ( + IN EFI_EXCEPTION_TYPE InteruptNum, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + if (InteruptNum > MAX_LOONGARCH_INTERRUPT) { + return EFI_UNSUPPORTED; + } + + if ((InterruptHandler !=3D NULL) + && (gInterruptHandler[InteruptNum] !=3D NULL)) + { + return EFI_ALREADY_STARTED; + } + + gInterruptHandler[InteruptNum] =3D InterruptHandler; + + return EFI_SUCCESS; +} + +/** + This function calls the corresponding exception handler based on the exc= eption type. + + @param SystemContext The system context at the time of the exception. + + @retval VOID +**/ +STATIC VOID +EFIAPI +CommonInterruptHandler ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ) +{ + INT32 Pending; + INT32 InterruptNum; + /*Interrupt [13-0] NMI IPI TI PCOV hw IP10-IP2 soft IP1-IP0*/ + Pending =3D ((SystemContext.SystemContextLoongArch64->ESTAT) & + (SystemContext.SystemContextLoongArch64->ECFG) & 0x1fff); + for (InterruptNum =3D 0; InterruptNum < MAX_LOONGARCH_INTERRUPT; Interru= ptNum++) { + if (Pending & (1 << InterruptNum)) { + if (gInterruptHandler[InterruptNum] !=3D NULL) { + gInterruptHandler[InterruptNum] (InterruptNum, SystemContext); + } else { + DEBUG ((DEBUG_INFO, "Pending: 0x%0x, InterruptNum: 0x%0x\n", Pendi= ng, InterruptNum)); + } + } + } +} + +/** + Use the EFI Debug Image Table to lookup the FaultAddress and find which = PE/COFF image + it came from. As long as the PE/COFF image contains a debug directory en= try a + string can be returned. For ELF and Mach-O images the string points to t= he Mach-O or ELF + image. Microsoft tools contain a pointer to the PDB file that contains t= he debug information. + + @param FaultAddress Address to find PE/COFF image for. + @param ImageBase Return load address of found image + @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for t= he image that was found + + @retval NULL FaultAddress not in a loaded PE/COFF image. + @retval Path and file name of PE/COFF image. +**/ +CHAR8 * +GetImageName ( + IN UINTN FaultAddress, + OUT UINTN *ImageBase, + OUT UINTN *PeCoffSizeOfHeaders + ) +{ + EFI_STATUS Status; + EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugTableHeader; + EFI_DEBUG_IMAGE_INFO *DebugTable; + UINTN Entry; + CHAR8 *Address; + + Status =3D EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid,= (VOID **)&DebugTableHeader); + if (EFI_ERROR (Status)) { + return NULL; + } + + DebugTable =3D DebugTableHeader->EfiDebugImageInfoTable; + if (DebugTable =3D=3D NULL) { + return NULL; + } + + Address =3D (CHAR8 *)(UINTN)FaultAddress; + for (Entry =3D 0; Entry < DebugTableHeader->TableSize; Entry++, DebugTab= le++) { + if (DebugTable->NormalImage !=3D NULL) { + if ((DebugTable->NormalImage->ImageInfoType =3D=3D EFI_DEBUG_IMAGE_I= NFO_TYPE_NORMAL) && + (DebugTable->NormalImage->LoadedImageProtocolInstance !=3D NULL)= ) { + if ((Address >=3D (CHAR8 *)DebugTable->NormalImage->LoadedImagePro= tocolInstance->ImageBase) && + (Address <=3D ((CHAR8 *)DebugTable->NormalImage->LoadedImagePr= otocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolIns= tance->ImageSize))) { + *ImageBase =3D (UINTN)DebugTable->NormalImage->LoadedImageProtoc= olInstance->ImageBase; + *PeCoffSizeOfHeaders =3D PeCoffGetSizeOfHeaders ((VOID *)(UINTN)= *ImageBase); + return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->Loade= dImageProtocolInstance->ImageBase); + } + } + } + } + return NULL; +} + +/** + pass a file name string that contains the path, return file name. + + @param FullName Path and file name + + @retval file name. +**/ +STATIC +CONST CHAR8 * +BaseName ( + IN CONST CHAR8 *FullName + ) +{ + CONST CHAR8 *Str; + + Str =3D FullName + AsciiStrLen (FullName); + + while (--Str > FullName) { + if (*Str =3D=3D '/' || *Str =3D=3D '\\') { + return Str + 1; + } + } + return Str; +} + +/** Default Exception Handler Function + This function is called when an exception occurs that cannot be handled, + and this function prints the system context information when the interru= pt occurred + + @param SystemContext The system context at the time of the exception. + + @retval VOID. +**/ +STATIC +VOID +EFIAPI +DefaultHandler ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ) +{ + CHAR8 *ImageName; + UINTN ImageBase; + UINTN Epc; + UINTN PeCoffSizeOfHeader; + + DEBUG ((DEBUG_ERROR, "CRMD 0x%llx\n", SystemContext.SystemContextLoon= gArch64->CRMD)); + DEBUG ((DEBUG_ERROR, "PRMD 0x%llx\n", SystemContext.SystemContextLoon= gArch64->PRMD)); + DEBUG ((DEBUG_ERROR, "ECFG 0x%llx\n", SystemContext.SystemContextLoong= Arch64->ECFG)); + DEBUG ((DEBUG_ERROR, "ESTAT 0x%llx\n", SystemContext.SystemContextLoo= ngArch64->ESTAT)); + DEBUG ((DEBUG_ERROR, "ERA 0x%llx\n", SystemContext.SystemContextLoon= gArch64->ERA)); + DEBUG ((DEBUG_ERROR, "BADV 0x%llx\n", SystemContext.SystemContextLoo= ngArch64->BADV)); + DEBUG ((DEBUG_ERROR, "BADI 0x%llx\n", SystemContext.SystemContextLoongA= rch64->BADI)); + + Epc =3D SystemContext.SystemContextLoongArch64->ERA; + ImageName =3D GetImageName (Epc, &ImageBase, &PeCoffSizeOfHeader); + if (ImageName !=3D NULL) { + DEBUG ((DEBUG_ERROR, "PC 0x%012lx (0x%012lx+0x%08x) [ 0] %a\n", + Epc, ImageBase, + Epc - ImageBase, BaseName (ImageName))); + } else { + DEBUG ((DEBUG_ERROR, "PC 0x%012lx\n", Epc)); + } + + while (1); +} + +/** Common exception entry + Exception handling is the entry point for the C environment, + This function does different things depending on the exception type. + + @param SystemContext The system context at the time of the exception. + + @retval VOID. +**/ +VOID +EFIAPI +CommonExceptionEntry ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ) +{ + INT32 ExceptionType; + UINT64 CsrEuen; + UINT64 FpuStatus; + + ExceptionType =3D SystemContext.SystemContextLoongArch64->ESTAT & CSR_ES= TAT_EXC; + ExceptionType =3D ExceptionType >> CSR_ESTAT_EXC_SHIFT; + + LoongArchReadqCsrEuen (&CsrEuen); + FpuStatus =3D CsrEuen & CSR_EUEN_FPEN; + switch (ExceptionType) { + case EXC_INT: + /* + * handle interrupt exception + */ + CommonInterruptHandler (SystemContext); + if (!FpuStatus) { + LoongArchReadqCsrEuen (&CsrEuen); + if (CsrEuen & CSR_EUEN_FPEN) { + /* + * Since Hw FP is enabled during interrupt handler, + * disable FP + */ + CsrEuen &=3D ~CSR_EUEN_FPEN; + LoongArchWriteqCsrEuen (CsrEuen); + } + } + break; + case EXC_FPDIS: + /* + * Hardware FP disabled exception, + * Enable and init FP registers here + */ + LoongArchEnableFpu (); + InitFpu(FPU_CSR_RN); + break; + default: + DefaultHandler(SystemContext); + break; + } +} + +/** Exception module initialization + This function sets the exception base address. + + @param Cpu A pointer to the CPU architecture protocol structure. + + @retval EFI_SUCCESS Initialization succeeded + @retval EFI_NOT_FOUND Could not Found resources. + @retval EFI_OUT_OF_RESOURCES No enough resources. +**/ +EFI_STATUS +InitializeExceptions ( + IN EFI_CPU_ARCH_PROTOCOL *Cpu + ) +{ + EFI_STATUS Status; + BOOLEAN IrqEnabled; + EFI_PHYSICAL_ADDRESS Address; + + ZeroMem (gInterruptHandler, sizeof (*gInterruptHandler)); + + // + // Disable interrupts + // + Cpu->GetInterruptState (Cpu, &IrqEnabled); + Cpu->DisableInterrupt (Cpu); + + // + // EFI does not use the FIQ, but a debugger might so we must disable + // as we take over the exception vectors. + // + Status =3D gBS->AllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + 1, + &Address + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DEBUG ((DEBUG_INFO, "Set Exception Base Address\n")); + CopyMem ((char *)Address, LoongArchException, (LoongArchExceptionEnd - L= oongArchException)); + InvalidateInstructionCacheRange ((char *)Address, (LoongArchExceptionEnd= - LoongArchException)); + + SetEbase (Address); + DEBUG ((DEBUG_INFO, "LoongArchException address: 0x%p\n", Address)); + DEBUG ((DEBUG_INFO, "LoongArchExceptionEnd address: 0x%p\n", Address + (= LoongArchExceptionEnd - LoongArchException))); + + DEBUG ((DEBUG_INFO, "InitializeExceptions, IrqEnabled =3D %x\n", IrqEnab= led)); + if (IrqEnabled) { + // + // Restore interrupt state + // + Status =3D Cpu->EnableInterrupt (Cpu); + } + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/= Fpu.S b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/Fpu.S new file mode 100644 index 0000000000..79a20c66a2 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/Fpu.S @@ -0,0 +1,97 @@ +#-------------------------------------------------------------------------= ----- +# +# Fpu for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - CsrEuen - Cpu Status Register Extern Unit Enable +# - FPEN - FPU Enable +# - fpu or fp or FP - Float Point Unit +#-------------------------------------------------------------------------= ---- +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif +#include "Library/Cpu.h" +#include "CpuDxe.h" + +ASM_GLOBAL ASM_PFX(InitFpu) +ASM_GLOBAL ASM_PFX(LoongArchEnableFpu) +ASM_GLOBAL ASM_PFX(LoongArchDisableFpu) + +# +# Load the FPU with signalling NANS. This bit pattern we're using has +# the property that no matter whether considered as single or as double +# precision represents signaling NANS. +# +# The value to initialize FCSR0 to comes in $A0. +# + +ASM_PFX(InitFpu): + li.d T1, CSR_EUEN_FPEN + csrxchg T1, T1, LOONGARCH_CSR_EUEN + + movgr2fcsr FCSR0, A0 + li.d T1, -1 # SNaN + movgr2fr.d $f0, T1 + movgr2fr.d $f1, T1 + movgr2fr.d $f2, T1 + movgr2fr.d $f3, T1 + movgr2fr.d $f4, T1 + movgr2fr.d $f5, T1 + movgr2fr.d $f6, T1 + movgr2fr.d $f7, T1 + movgr2fr.d $f8, T1 + movgr2fr.d $f9, T1 + movgr2fr.d $f10, T1 + movgr2fr.d $f11, T1 + movgr2fr.d $f12, T1 + movgr2fr.d $f13, T1 + movgr2fr.d $f14, T1 + movgr2fr.d $f15, T1 + movgr2fr.d $f16, T1 + movgr2fr.d $f17, T1 + movgr2fr.d $f18, T1 + movgr2fr.d $f19, T1 + movgr2fr.d $f20, T1 + movgr2fr.d $f21, T1 + movgr2fr.d $f22, T1 + movgr2fr.d $f23, T1 + movgr2fr.d $f24, T1 + movgr2fr.d $f25, T1 + movgr2fr.d $f26, T1 + movgr2fr.d $f27, T1 + movgr2fr.d $f28, T1 + movgr2fr.d $f29, T1 + movgr2fr.d $f30, T1 + movgr2fr.d $f31, T1 + + jirl ZERO, RA, 0 + +# +# Enables floating-point unit +# @param VOID +# @retval VOID +# + +ASM_PFX(LoongArchEnableFpu): + li.d T0, 1 + li.d T1, CSR_EUEN_FPEN_SHIFT + sll.d T0, T0, T1 + csrxchg T0, T0, LOONGARCH_CSR_EUEN + jirl ZERO, RA,0 + +# +# Disable floating-point unit +# @param VOID +# @retval VOID +# + +ASM_PFX(LoongArchDisableFpu): + li.d T0, 1 + li.d T1, CSR_EUEN_FPEN_SHIFT + sll.d T0, T0, T1 + csrxchg ZERO, T0, LOONGARCH_CSR_EUEN + jirl ZERO, RA,0 diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/= LoongArch.S b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64= /LoongArch.S new file mode 100644 index 0000000000..e463cf44f2 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/LoongArch64/LoongAr= ch.S @@ -0,0 +1,321 @@ +#-------------------------------------------------------------------------= ----- +# +# LoongArch for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - CsrEuen - Cpu Status Register Extern Unit Enable +# - fpu - Float Point Unit +# - LOONGARCH - Loongson Arch +# - Ebase - Exception Base Address +#-------------------------------------------------------------------------= ---- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" +#include "CpuDxe.h" + +#define RSIZE 8 /* 64 bit mode register size */ +#define RLOGSIZE 3 + +ASM_GLOBAL ASM_PFX(Exception_handler) +ASM_GLOBAL ASM_PFX(LoongArchException) +ASM_GLOBAL ASM_PFX(SetEbase) +ASM_GLOBAL ASM_PFX(LoongArchReadqCsrEuen) +ASM_GLOBAL ASM_PFX(LoongArchWriteqCsrEuen) + +# +# Main exception handler. Not really a leaf routine but not a normal +# function either. Save away the entire cpu state end enter exception mo= de. +# + +ASM_PFX(Exception_handler): + csrrd SP, LOONGARCH_CSR_KS1 + + addi.d T0, $r0, -0x10 + and SP, SP, T0 + addi.d SP, SP, -((CSR_NUM + BASE_NUM + FP_BASE_NUM) * RSIZE) + + st.d RA, SP, RA_NUM * RSIZE + st.d GP, SP, GP_NUM * RSIZE + st.d A0, SP, A0_NUM * RSIZE + st.d A1, SP, A1_NUM * RSIZE + st.d A2, SP, A2_NUM * RSIZE + st.d A3, SP, A3_NUM * RSIZE + st.d A4, SP, A4_NUM * RSIZE + st.d A5, SP, A5_NUM * RSIZE + st.d A6, SP, A6_NUM * RSIZE + st.d A7, SP, A7_NUM * RSIZE + st.d T1, SP, T1_NUM * RSIZE + st.d T2, SP, T2_NUM * RSIZE + st.d T3, SP, T3_NUM * RSIZE + st.d T4, SP, T4_NUM * RSIZE + st.d T5, SP, T5_NUM * RSIZE + st.d T6, SP, T6_NUM * RSIZE + st.d T7, SP, T7_NUM * RSIZE + st.d T8, SP, T8_NUM * RSIZE + st.d TP, SP, TP_NUM * RSIZE + st.d FP, SP, FP_NUM * RSIZE + st.d S0, SP, S0_NUM * RSIZE + st.d S1, SP, S1_NUM * RSIZE + st.d S2, SP, S2_NUM * RSIZE + st.d S3, SP, S3_NUM * RSIZE + st.d S4, SP, S4_NUM * RSIZE + st.d S5, SP, S5_NUM * RSIZE + st.d S6, SP, S6_NUM * RSIZE + st.d S7, SP, S7_NUM * RSIZE + st.d S8, SP, S8_NUM * RSIZE + + # + # save T0/SP from scratch registers on stack + # + csrrd T0, LOONGARCH_CSR_KS0 + st.d T0, SP, T0_NUM * RSIZE + csrrd T0, LOONGARCH_CSR_KS1 + st.d T0, SP, SP_NUM * RSIZE + + csrrd T0, LOONGARCH_CSR_CRMD + st.d T0, SP, (LOONGARCH_CSR_CRMD + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_PRMD + st.d T0, SP, (LOONGARCH_CSR_PRMD + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_ECFG + st.d T0, SP, (LOONGARCH_CSR_ECFG + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_ESTAT + st.d T0, SP, (LOONGARCH_CSR_ESTAT + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_EPC + st.d T0, SP, (LOONGARCH_CSR_EPC+ BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_BADV + st.d T0, SP, (LOONGARCH_CSR_BADV + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_BADI + st.d T0, SP, (LOONGARCH_CSR_BADI + BASE_NUM) * RSIZE + csrrd T0, LOONGARCH_CSR_EUEN + st.d T0, SP, (LOONGARCH_CSR_EUEN + BASE_NUM) * RSIZE + + # + # Save FPU context + # + ori T1, ZERO, CSR_EUEN_FPEN + and T2, T0, T1 + beqz T2, 1f + + fst.d $f0, SP, (FP0_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f1, SP, (FP1_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f2, SP, (FP2_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f3, SP, (FP3_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f4, SP, (FP4_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f5, SP, (FP5_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f6, SP, (FP6_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f7, SP, (FP7_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f8, SP, (FP8_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f9, SP, (FP9_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f10, SP, (FP10_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f11, SP, (FP11_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f12, SP, (FP12_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f13, SP, (FP13_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f14, SP, (FP14_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f15, SP, (FP15_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f16, SP, (FP16_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f17, SP, (FP17_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f18, SP, (FP18_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f19, SP, (FP19_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f20, SP, (FP20_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f21, SP, (FP21_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f22, SP, (FP22_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f23, SP, (FP23_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f24, SP, (FP24_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f25, SP, (FP25_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f26, SP, (FP26_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f27, SP, (FP27_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f28, SP, (FP28_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f29, SP, (FP29_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f30, SP, (FP30_NUM + FP_BASE_INDEX) * RSIZE + fst.d $f31, SP, (FP31_NUM + FP_BASE_INDEX) * RSIZE + + movfcsr2gr T3, FCSR0 + st.d T3, SP, (FCSR_NUM + FP_BASE_INDEX) * RSIZE + movcf2gr T3, $fcc0 + or T2, T3, ZERO + movcf2gr T3, $fcc1 + bstrins.d T2, T3, 0xf, 0x8 + movcf2gr T3, $fcc2 + bstrins.d T2, T3, 0x17, 0x10 + movcf2gr T3, $fcc3 + bstrins.d T2, T3, 0x1f, 0x18 + movcf2gr T3, $fcc4 + bstrins.d T2, T3, 0x27, 0x20 + movcf2gr T3, $fcc5 + bstrins.d T2, T3, 0x2f, 0x28 + movcf2gr T3, $fcc6 + bstrins.d T2, T3, 0x37, 0x30 + movcf2gr T3, $fcc7 + bstrins.d T2, T3, 0x3f, 0x38 + st.d T2, SP, (FCC_NUM + FP_BASE_INDEX) * RSIZE +1: + or A0, SP, ZERO + bl CommonExceptionEntry + /*disable interrupt*/ + li.d T0, (1 << 2) + csrxchg ZERO, T0, LOONGARCH_CSR_CRMD + + ld.d T0, SP, (LOONGARCH_CSR_PRMD + BASE_NUM) * RSIZE + csrwr T0, LOONGARCH_CSR_PRMD + ld.d T0, SP, (LOONGARCH_CSR_ECFG + BASE_NUM) * RSIZE + csrwr T0, LOONGARCH_CSR_ECFG + ld.d T0, SP, (LOONGARCH_CSR_EPC + BASE_NUM) * RSIZE + csrwr T0, LOONGARCH_CSR_EPC + + ld.d T0, SP, (LOONGARCH_CSR_EUEN + BASE_NUM) * RSIZE + ori T1, ZERO, CSR_EUEN_FPEN + and T2, T0, T1 + beqz T2, 2f + + # + # check previous FP state + # restore FP contect if FP enabled + # + fld.d $f0, SP, (FP0_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f1, SP, (FP1_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f2, SP, (FP2_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f3, SP, (FP3_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f4, SP, (FP4_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f5, SP, (FP5_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f6, SP, (FP6_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f7, SP, (FP7_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f8, SP, (FP8_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f9, SP, (FP9_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f10, SP, (FP10_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f11, SP, (FP11_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f12, SP, (FP12_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f13, SP, (FP13_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f14, SP, (FP14_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f15, SP, (FP15_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f16, SP, (FP16_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f17, SP, (FP17_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f18, SP, (FP18_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f19, SP, (FP19_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f20, SP, (FP20_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f21, SP, (FP21_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f22, SP, (FP22_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f23, SP, (FP23_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f24, SP, (FP24_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f25, SP, (FP25_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f26, SP, (FP26_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f27, SP, (FP27_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f28, SP, (FP28_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f29, SP, (FP29_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f30, SP, (FP30_NUM + FP_BASE_INDEX) * RSIZE + fld.d $f31, SP, (FP31_NUM + FP_BASE_INDEX) * RSIZE + + ld.d T0, SP, (FCSR_NUM + FP_BASE_INDEX) * RSIZE + movgr2fcsr FCSR0, T0 + ld.d T0, SP, (FCC_NUM + FP_BASE_INDEX) * RSIZE + bstrpick.d T1, T0, 7, 0 + movgr2cf $fcc0, T1 + bstrpick.d T1, T0, 15, 8 + movgr2cf $fcc1, T1 + bstrpick.d T1, T0, 23, 16 + movgr2cf $fcc2, T1 + bstrpick.d T1, T0, 31, 24 + movgr2cf $fcc3, T1 + bstrpick.d T1, T0, 39, 32 + movgr2cf $fcc4, T1 + bstrpick.d T1, T0, 47, 40 + movgr2cf $fcc5, T1 + bstrpick.d T1, T0, 55, 48 + movgr2cf $fcc6, T1 + bstrpick.d T1, T0, 63, 56 + movgr2cf $fcc7, T1 +2: + ld.d RA, SP, RA_NUM * RSIZE + ld.d GP, SP, GP_NUM * RSIZE + ld.d A0, SP, A0_NUM * RSIZE + ld.d A1, SP, A1_NUM * RSIZE + ld.d A2, SP, A2_NUM * RSIZE + ld.d A3, SP, A3_NUM * RSIZE + ld.d A4, SP, A4_NUM * RSIZE + ld.d A5, SP, A5_NUM * RSIZE + ld.d A6, SP, A6_NUM * RSIZE + ld.d A7, SP, A7_NUM * RSIZE + ld.d T0, SP, T0_NUM * RSIZE + ld.d T1, SP, T1_NUM * RSIZE + ld.d T2, SP, T2_NUM * RSIZE + ld.d T3, SP, T3_NUM * RSIZE + ld.d T4, SP, T4_NUM * RSIZE + ld.d T5, SP, T5_NUM * RSIZE + ld.d T6, SP, T6_NUM * RSIZE + ld.d T7, SP, T7_NUM * RSIZE + ld.d T8, SP, T8_NUM * RSIZE + ld.d TP, SP, TP_NUM * RSIZE + ld.d FP, SP, FP_NUM * RSIZE + ld.d S0, SP, S0_NUM * RSIZE + ld.d S1, SP, S1_NUM * RSIZE + ld.d S2, SP, S2_NUM * RSIZE + ld.d S3, SP, S3_NUM * RSIZE + ld.d S4, SP, S4_NUM * RSIZE + ld.d S5, SP, S5_NUM * RSIZE + ld.d S6, SP, S6_NUM * RSIZE + ld.d S7, SP, S7_NUM * RSIZE + ld.d S8, SP, S8_NUM * RSIZE + + ld.d SP, SP, SP_NUM * RSIZE + ertn + +# +# Exception trampoline copied down to RAM after initialization. +# + +ASM_PFX(LoongArchException): + csrwr T0, LOONGARCH_CSR_KS0 + csrwr SP, LOONGARCH_CSR_KS1 + pcaddi T0, 0 + ld.d T0, T0, 16 + jirl ZERO, T0, 0 + nop +1: + .quad Exception_handler +.globl LoongArchExceptionEnd +LoongArchExceptionEnd: + +# +# Set Exception Base Address. +# + +ASM_PFX(SetEbase): + # + # clear Vint cofigure + # all exceptions share the same interrupt entry + # + csrrd T0, LOONGARCH_CSR_ECFG + li.d T1, ~0x70000 + and T0, T0, T1 + csrwr T0, LOONGARCH_CSR_ECFG + + # set ebase + csrwr A0, LOONGARCH_CSR_EBASE + jirl ZERO, RA, 0 + +# +# Read Csr EUEN register. +# @param A0 Pointer to the variable used to store the EUEN register val= ue +# @retval none +# + +ASM_PFX(LoongArchReadqCsrEuen): + csrrd T0, LOONGARCH_CSR_EUEN + stptr.d T0, A0, 0 + jirl ZERO, RA,0 + +# +# Write Csr EUEN register. +# @param A0 The value used to write to the EUEN register +# @retval none +# + +ASM_PFX(LoongArchWriteqCsrEuen): + csrwr A0, LOONGARCH_CSR_EUEN + jirl ZERO, RA,0 --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96453): https://edk2.groups.io/g/devel/message/96453 Mute This Topic: https://groups.io/mt/95082591/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96452+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96452+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652805; cv=none; d=zohomail.com; s=zohoarc; b=PFX3FELKVdqU3LvX7nj9FIieC28kFeVDqEUEvGEfJ8MGTPAcoeyTQ/fnYhvMUclLZaPzUxMqrT+7zX24AI04zImWrvWQSFtnIuTVxa+Ncl46CSOtmjURJjJujK6VxCoPuRQcZgRqDXfUFo3q/8Z67QP3eh6kCCr6EP3m6wu2VVE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652805; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=EJvCPS8KJgTxQHVJisV+Y873HxXjHk2K5nifi1fjR+o=; b=LlH9zT8BqvmPL6pvTmV1Nah/aHbI8RyPdSJAI6LRfXMvrDkLCFTVfHgOp/Vh7CKrLRpb05v+sT0hMz/MV6jPv3xtKEFeauXEhdSvHxC/AUvo7zwFTD3kZjcJn7C6rQz/U0wsG1vHEzaRYQ64XczIyiwQt9OHoDpzyYHimFC2w3g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96452+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652805387479.0715526817364; Wed, 16 Nov 2022 18:40:05 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ehYZYY1788612x8VxgwRAkZU; Wed, 16 Nov 2022 18:40:05 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.6221.1668652803351892451 for ; Wed, 16 Nov 2022 18:40:03 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8DxOdgCn3VjGyQIAA--.21614S3; Thu, 17 Nov 2022 10:40:02 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S11; Thu, 17 Nov 2022 10:40:01 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 09/16] Platform/Loongson: Add PciCpuIoDxe driver. Date: Thu, 17 Nov 2022 10:39:35 +0800 Message-Id: <69b201a624f57a493e2b33050962d6bd44b20f69.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S11 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWfXrW3tF13CrW8Cw13AFyftFb_yoW5Zry7Co W093yIvws8Jw1rGrZ5C3sYya17XFnrWFsaqF4rAF1UWa1qqrn8Ka4rX3WUG34rt3yDuayD Ja4UX3yxJrsYqa4fn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqm1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: Z3fy9w5BEyyughxhrV9OOD0rx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652805; bh=aU5al3PyWzwBz9gfT1bLMpor2mPhhvlcSF2ygfYDJtg=; h=Cc:Date:From:Reply-To:Subject:To; b=fRWT9P7KidhbwTr8Q982IbA/Habd6RJLmRH78tg8skJSFp/Y8xMSZZtCKjWAq79iKZS iOe8BtgAihJDzOqkoqn/2HpJysqqcyqqi+lgkhtdSlyy8kjndFldsA6E/8ZqH8SOvxitS 6AN16LJ+nXTTTUDS78lq5aRMvOCKA89ETwM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652805843100016 Content-Type: text/plain; charset="utf-8" Add PCI CpuIo protocol.there is no fix translation offset between I/O port accesses and MMIO accesses. Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL to add the translation for IO access. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 538 ++++++++++++++++++ .../Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.h | 207 +++++++ .../Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 44 ++ 3 files changed, 789 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe= /PciCpuIo2Dxe.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe= /PciCpuIo2Dxe.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe= /PciCpuIo2Dxe.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpu= Io2Dxe.c b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo= 2Dxe.c new file mode 100644 index 0000000000..25417ff101 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c @@ -0,0 +1,538 @@ +/** @file + Produces the CPU I/O 2 Protocol. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include "PciCpuIo2Dxe.h" + +// +// Handle for the CPU I/O 2 Protocol +// +STATIC EFI_HANDLE mHandle =3D NULL; + +// +// Lookup table for increment values based on transfer widths +// +STATIC CONST UINT8 mInStride[] =3D { + 1, // EfiCpuIoWidthUint8 + 2, // EfiCpuIoWidthUint16 + 4, // EfiCpuIoWidthUint32 + 8, // EfiCpuIoWidthUint64 + 0, // EfiCpuIoWidthFifoUint8 + 0, // EfiCpuIoWidthFifoUint16 + 0, // EfiCpuIoWidthFifoUint32 + 0, // EfiCpuIoWidthFifoUint64 + 1, // EfiCpuIoWidthFillUint8 + 2, // EfiCpuIoWidthFillUint16 + 4, // EfiCpuIoWidthFillUint32 + 8 // EfiCpuIoWidthFillUint64 +}; + +// +// Lookup table for increment values based on transfer widths +// +STATIC CONST UINT8 mOutStride[] =3D { + 1, // EfiCpuIoWidthUint8 + 2, // EfiCpuIoWidthUint16 + 4, // EfiCpuIoWidthUint32 + 8, // EfiCpuIoWidthUint64 + 1, // EfiCpuIoWidthFifoUint8 + 2, // EfiCpuIoWidthFifoUint16 + 4, // EfiCpuIoWidthFifoUint32 + 8, // EfiCpuIoWidthFifoUint64 + 0, // EfiCpuIoWidthFillUint8 + 0, // EfiCpuIoWidthFillUint16 + 0, // EfiCpuIoWidthFillUint32 + 0 // EfiCpuIoWidthFillUint64 +}; + +/** + Check parameters to a CPU I/O 2 Protocol service request. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port= operation. + @param[in] Width Signifies the width of the I/O or Memory opera= tion. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The n= umber of + bytes moved is Width size * Count, starting at= Address. + @param[in] Buffer For read operations, the destination buffer to= store the results. + For write operations, the source buffer from w= hich to write data. + + @retval EFI_SUCCESS The parameters for this request pass the = checks. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +CpuIoCheckParameter ( + IN BOOLEAN MmioOperation, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT64 MaxCount; + UINT64 Limit; + + // + // Check to see if Buffer is NULL + // + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if Width is in the valid range + // + if ((UINT32)Width >=3D EfiCpuIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + // + // For FIFO type, the target address won't increase during the access, + // so treat Count as 1 + // + if ((Width >=3D EfiCpuIoWidthFifoUint8) + && (Width <=3D EfiCpuIoWidthFifoUint64)) + { + Count =3D 1; + } + + // + // Check to see if Width is in the valid range for I/O Port operations + // + Width =3D (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + if ((!MmioOperation) + && (Width =3D=3D EfiCpuIoWidthUint64)) + { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if Address is aligned + // + if ((Address & (UINT64) (mInStride[Width] - 1)) !=3D 0) { + return EFI_UNSUPPORTED; + } + + // + // Check to see if any address associated with this transfer exceeds the= maximum + // allowed address. The maximum address implied by the parameters passe= d in is + // Address + Size * Count. If the following condition is met, then the = transfer + // is not supported. + // + // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_POR= T_ADDRESS) + 1 + // + // Since MAX_ADDRESS can be the maximum integer value supported by the C= PU and Count + // can also be the maximum integer value supported by the CPU, this range + // check must be adjusted to avoid all overflow conditions. + // + // The following form of the range check is equivalent but assumes that + // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). + // + Limit =3D (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); + if (Count =3D=3D 0) { + if (Address > Limit) { + return EFI_UNSUPPORTED; + } + } else { + MaxCount =3D RShiftU64 (Limit, Width); + if (MaxCount < (Count - 1)) { + return EFI_UNSUPPORTED; + } + if (Address > LShiftU64 (MaxCount - Count + 1, Width)) { + return EFI_UNSUPPORTED; + } + } + + // + // Check to see if Buffer is aligned + // + if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != =3D 0) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Reads memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuMemoryServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + Status =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select loop based on the width of the transfer + // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + for (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buff= er +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint64) { + *((UINT64 *)Uint8Buffer) =3D MmioRead64 ((UINTN)Address); + } + } + return EFI_SUCCESS; +} + +/** + Writes memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuMemoryServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + Status =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select loop based on the width of the transfer + // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + for (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buff= er +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint64) { + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); + } + } + return EFI_SUCCESS; +} + +/** + Reads I/O registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuIoServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + Status =3D CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + Address +=3D PcdGet64 (PcdPciIoTranslation); + + // + // Select loop based on the width of the transfer + // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + + for (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buff= er +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); + } + } + return EFI_SUCCESS; +} + +/** + Write I/O registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuIoServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + // + // Make sure the parameters are valid + // + Status =3D CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + Address +=3D PcdGet64 (PcdPciIoTranslation); + + // + // Select loop based on the width of the transfer + // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + + for (Uint8Buffer =3D (UINT8 *)Buffer; Count > 0; Address +=3D InStride, = Uint8Buffer +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + } + } + return EFI_SUCCESS; +} + +// +// CPU I/O 2 Protocol instance +// +STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 =3D { + { + CpuMemoryServiceRead, + CpuMemoryServiceWrite + }, + { + CpuIoServiceRead, + CpuIoServiceWrite + } +}; + +/** + The user Entry Point for module CpuIo2Dxe. The user code starts with thi= s function. + + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry po= int. +**/ +EFI_STATUS +EFIAPI +PciCpuIo2Initialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid); + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mHandle, + &gEfiCpuIo2ProtocolGuid, &mCpuIo2, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpu= Io2Dxe.h b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo= 2Dxe.h new file mode 100644 index 0000000000..2489429df7 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.h @@ -0,0 +1,207 @@ +/** @file + Internal include file for the CPU I/O 2 Protocol. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCI_CPU_IO2_DXE_H_ +#define PCI_CPU_IO2_DXE_H_ + +#define MAX_IO_PORT_ADDRESS 0xFFFF + +/** + Reads memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuMemoryServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Writes memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuMemoryServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ); + +/** + Reads I/O registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuIoServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Write I/O registers. + + The I/O operations are carried out exactly as requested. The caller is r= esponsible + for satisfying any alignment and I/O width restrictions that a PI System= on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, = will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read= or + write operation is performed Count times from the first element of Buffe= r. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system. +**/ +EFI_STATUS +EFIAPI +CpuIoServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ); + +#endif // PCI_CPU_IO2_DXE_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpu= Io2Dxe.inf b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpu= Io2Dxe.inf new file mode 100644 index 0000000000..a8a14cddd2 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.= inf @@ -0,0 +1,44 @@ +## @file +# Produces the CPU I/O 2 Protocol by using the services of the I/O Librar= y. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PciCpuIo2Dxe + FILE_GUID =3D 168D1A6E-F4A5-448A-9E95-795661BB3067 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D PciCpuIo2Initialize + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + PciCpuIo2Dxe.c + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation + +[Protocols] + gEfiCpuIo2ProtocolGuid ## PRODUCES + +[Depex] + TRUE --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96452): https://edk2.groups.io/g/devel/message/96452 Mute This Topic: https://groups.io/mt/95082590/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96454+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96454+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652807; cv=none; d=zohomail.com; s=zohoarc; b=ZJ3Em6jmYGRv1u+88UOU5MI9AuN55BXdrLCDX0AzG2QKh04BGH4C/4D1ppf0u7DKrB3yMXOMgh/FUzhEUDpQWC60C4ZNIFo6+qDBhXw/XK4itOv8aFnAC+68fIk+uy+5vkkKi8flV/5XFGgCrHL1ekYNr3TSYe5VEYGpf+fJcV4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652807; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=byMiM0H1lplzfXcD30Bm1202DLm/WW6gLd8cI6IoUng=; b=I+uPMeWPbLNjkwr751G9Ve+U0Js9YoJ5sVOhBhyvLMsJi8IGViDZ85igkPyNi4On4EsctQaESr9m0Zk77R9MIZwgfui7C9G24Xz8vu0CL5Uehf6FufvNRuODGfHMYE9Ikul3s3lZtKCILB4odR1kobB3kyvVqm7tjWjCFJJStU4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96454+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652807832832.4360954977026; Wed, 16 Nov 2022 18:40:07 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id GLE9YY1788612xb0nt7ARL9K; Wed, 16 Nov 2022 18:40:06 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6330.1668652804199042492 for ; Wed, 16 Nov 2022 18:40:04 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Cx7NgCn3VjIyQIAA--.23343S3; Thu, 17 Nov 2022 10:40:02 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S12; Thu, 17 Nov 2022 10:40:02 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 10/16] Platform/Loongson: Add timer Dxe driver. Date: Thu, 17 Nov 2022 10:39:36 +0800 Message-Id: <0bbf61fc028704ad5ee9cea7e29debf1d015a9df.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S12 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWfKryrCr1kCF43GFWUCw1rJFb_yoW8try8Co W8uFZFvw18Gr18Xa95JFyxJa42qF1kuws0qr4vgFykCFnYy3Z8Kr9Fyry5Kw1fZrWrJF4D A34xWa4kJF43X3Z5n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqm1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0x vE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv 6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: HYr9meavuY0ArHh9WnCZl9G3x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652806; bh=SXKjfpB45vm19bTMndr2GBBFZtPVfHtKxg81VI15c2c=; h=Cc:Date:From:Reply-To:Subject:To; b=Rh+D0V4+e9nmLGerxvg7ooY+RMkpo4vW7OCNhelEN+h1gKZrC9GK/H5PAM+iDaiVZ+s 4m88Z1PoC3yHh4BshQzPWeVa4St7vFFf+l6VPCklqx8sHat5xycEq7x03QvfVKQnqpY2P Fr+nhQ1oRboVw9DuqBSvtYMAyagUgA0/RcM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652809882100041 Content-Type: text/plain; charset="utf-8" This driver produces Timer Architectural Protocol, Registers a timer interrupt and initializes the timer. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Drivers/StableTimerDxe/Timer.c | 388 ++++++++++++++++++ .../Drivers/StableTimerDxe/Timer.h | 172 ++++++++ .../Drivers/StableTimerDxe/TimerConfig.S | 38 ++ .../Drivers/StableTimerDxe/TimerDxe.inf | 44 ++ 4 files changed, 642 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerD= xe/Timer.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerD= xe/Timer.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerD= xe/TimerConfig.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerD= xe/TimerDxe.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Time= r.c b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Timer.c new file mode 100644 index 0000000000..e09da71272 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Timer.c @@ -0,0 +1,388 @@ +/** @file + Timer Architectural Protocol as defined in the DXE CIS + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "Library/Cpu.h" +#include +#include +#include "Timer.h" +#include +#include + +// +// The handle onto which the Timer Architectural Protocol will be installed +// +EFI_HANDLE mTimerHandle =3D NULL; +EFI_EVENT EfiExitBootServicesEvent =3D (EFI_EVENT)NULL; + +// +// The Timer Architectural Protocol that this driver produces +// +EFI_TIMER_ARCH_PROTOCOL mTimer =3D { + TimerDriverRegisterHandler, + TimerDriverSetTimerPeriod, + TimerDriverGetTimerPeriod, + TimerDriverGenerateSoftInterrupt +}; + +// +// Pointer to the CPU Architectural Protocol instance +// +EFI_CPU_ARCH_PROTOCOL *mCpu; + +// +// The notification function to call on every timer interrupt. +// A bug in the compiler prevents us from initializing this here. +// +EFI_TIMER_NOTIFY mTimerNotifyFunction; + +// +// The current period of the timer interrupt +// +volatile UINT64 mTimerPeriod =3D 0; +volatile UINT64 mTimerTicks =3D 0; + +// +// Const frequence in Hz +// +extern UINT32 StableTimerFreq; + +/** + Sets the counter value for timer. + + @param Count The 16-bit counter value to program into stable timer. + + @retval VOID +**/ +VOID +SetPitCount ( + IN UINT64 Count + ) +{ + if (Count <=3D 4) { + return; + } + + Count &=3D LOONGARCH_CSR_TMCFG_TIMEVAL; + Count |=3D LOONGARCH_CSR_TMCFG_EN | LOONGARCH_CSR_TMCFG_PERIOD; + LoongarchWriteqTmcfg (Count); +} + +/** + Timer Interrupt Handler. + + @param InterruptType The type of interrupt that occurred + @param SystemContext A pointer to the system context when the interru= pt occurred + + @retval VOID +**/ +VOID +EFIAPI +TimerInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_TPL OriginalTPL; + + OriginalTPL =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // Clear interrupt. + // + LoongarchWriteqTintclr (0x1); + + if (mTimerNotifyFunction !=3D NULL) { + // + // @bug : This does not handle missed timer interrupts + // + mTimerNotifyFunction (mTimerPeriod); + } + + gBS->RestoreTPL (OriginalTPL); +} + +/** + This function registers the handler NotifyFunction so it is called every= time + the timer interrupt fires. It also passes the amount of time since the = last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS= is + returned. If the CPU does not support registering a timer interrupt han= dler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a h= andler + when a handler is already registered, then EFI_ALREADY_STARTED is return= ed. + If an attempt is made to unregister a handler when a handler is not regi= stered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ER= ROR + is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fire= s. This + function executes at TPL_HIGH_LEVEL. The DXE Co= re will + register a handler for the timer interrupt, so i= t can know + how much time has passed. This information is u= sed to + signal timer based events. NULL will unregister= the handler. + + @retval EFI_SUCCESS The timer handler was registered. + @retval EFI_UNSUPPORTED The platform does not support time= r interrupts. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a = handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a hand= ler was not + previously registered. + @retval EFI_DEVICE_ERROR The timer handler could not be reg= istered. +**/ +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +{ + // + // Check for invalid parameters + // + if ((NotifyFunction =3D=3D NULL) + && (mTimerNotifyFunction =3D=3D NULL)) + { + return EFI_INVALID_PARAMETER; + } + + if ((NotifyFunction !=3D NULL) + && mTimerNotifyFunction !=3D NULL) + { + return EFI_ALREADY_STARTED; + } + + mTimerNotifyFunction =3D NotifyFunction; + + return EFI_SUCCESS; +} + +/** + This function adjusts the period of timer interrupts to the value specif= ied + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. = If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer inter= rupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust t= he + interrupt controller so that a CPU interrupt is not generated when the t= imer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS= units. If + the timer hardware is not programmable, then EFI_= UNSUPPORTED is + returned. If the timer is programmable, then the= timer period + will be rounded up to the nearest timer period th= at is supported + by the timer hardware. If TimerPeriod is set to = 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period o= f the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed d= ue to a device error. +**/ +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +{ + UINT64 TimerCount; + + if (TimerPeriod =3D=3D 0) { + // + // Disable timer interrupt for a TimerPeriod of 0 + // + mCpu->DisableInterrupt (mCpu); + } else { + + TimerCount =3D TimerPeriod * StableTimerFreq / 10000000ULL; + + if (TimerCount >=3D BIT48) { + TimerCount =3D 0; + } + + // + // Program the stable timer with the new count value + // + mTimerTicks =3D TimerCount; + SetPitCount (TimerCount); + + // + // Enable timer interrupt + // + mCpu->EnableInterrupt (mCpu); + } + + // + // Save the new timer period + // + mTimerPeriod =3D TimerPeriod; + + return EFI_SUCCESS; +} + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPer= iod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 = is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 = ns units. If + 0 is returned, then the timer is currently disabl= ed. + + @retval EFI_SUCCESS The timer period was returned in TimerPer= iod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. +**/ +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + if (TimerPeriod =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *TimerPeriod =3D mTimerPeriod; + + return EFI_SUCCESS; +} + +/** + Disable the timer + DXE Core will disable the timer after all the event handlers have run. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +ExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + /* + * Disable timer interrupt when exiting boot service + */ + LoongarchWriteqTmcfg (0); +} + +/** + This function generates a soft timer interrupt. If the platform does not= support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCE= SS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.Reg= isterHandler () + service, then a soft timer interrupt will be generated. If the timer int= errupt is + enabled when this service is called, then the registered handler will be= invoked. The + registered handler should not be able to distinguish a hardware-generate= d timer + interrupt from a software-generated timer interrupt. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTED The platform does not support the generation o= f soft timer interrupts. +**/ +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Initialize the Timer Architectural Protocol driver + + @param ImageHandle ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Timer Architectural Protocol created + @retval EFI_OUT_OF_RESOURCES Not enough resources available to initial= ize driver. + @retval EFI_DEVICE_ERROR A device error occurred attempting to ini= tialize the driver. +**/ +EFI_STATUS +EFIAPI +StableTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 TimerVector; + + // + // Initialize the pointer to our notify function. + // + mTimerNotifyFunction =3D NULL; + + // + // Make sure the Timer Architectural Protocol is not already installed i= n the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); + + // + // Find the CPU architectural protocol. + // + Status =3D gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **= ) &mCpu); + ASSERT_EFI_ERROR (Status); + + // + // Force the timer to be disabled + // + Status =3D TimerDriverSetTimerPeriod (&mTimer, 0); + ASSERT_EFI_ERROR (Status); + + // + // Calculate const frequence + // + StableTimerFreq =3D CalcConstFreq (); + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DStable timer freq = %d Hz=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n", StableTimerFreq)); + + // + // Install interrupt handler for Stable Timer #0 (ISA IRQ0) + // + TimerVector =3D EXCEPT_LOONGARCH_INT_TIMER; + Status =3D mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInter= ruptHandler); + ASSERT_EFI_ERROR (Status); + + // + // Enable TI local timer interrupt + // + CpuSetIP (1 << 11); + + // + // Force the timer to be enabled at its default period + // + Status =3D TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATI= ON); + ASSERT_EFI_ERROR (Status); + + // + // Install the Timer Architectural Protocol onto a new handle + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mTimerHandle, + &gEfiTimerArchProtocolGuid, &mTimer, + NULL + ); + + ASSERT_EFI_ERROR (Status); + + // Register for an ExitBootServicesEvent + Status =3D gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, = ExitBootServicesEvent, NULL, + &EfiExitBootServicesEvent); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Time= r.h b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Timer.h new file mode 100644 index 0000000000..84036cab00 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Timer.h @@ -0,0 +1,172 @@ +/** @file + Private data structures + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef TIMER_H_ +#define TIMER_H_ + +#include + +#define DEFAULT_TIMER_TICK_DURATION 100000 //10ms =3D 100000 100 ns units +#define SR_IP7 (1 << 15) +// +// Function Prototypes +// +extern UINT32 EFIAPI CpuGetCompare(VOID); +extern VOID EFIAPI CpuSetCompare(IN UINT32 val); +extern VOID EFIAPI CpuSetIP(IN UINT32 val); +extern VOID EFIAPI ClearC0Cause(IN UINT32 val); +extern VOID EFIAPI ClearC0Status(IN UINT32 val); +/** + Initialize the Timer Architectural Protocol driver + + @param ImageHandle ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Timer Architectural Protocol created + @retval EFI_OUT_OF_RESOURCES Not enough resources available to initial= ize driver. + @retval EFI_DEVICE_ERROR A device error occurred attempting to ini= tialize the driver. +**/ +EFI_STATUS +EFIAPI +TimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + This function adjusts the period of timer interrupts to the value specif= ied + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. = If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer inter= rupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust t= he + interrupt controller so that a CPU interrupt is not generated when the t= imer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The rate to program the timer interrupt in 100 nS= units. If + the timer hardware is not programmable, then EFI_= UNSUPPORTED is + returned. If the timer is programmable, then the= timer period + will be rounded up to the nearest timer period th= at is supported + by the timer hardware. If TimerPeriod is set to = 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period o= f the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed d= ue to a device error. +**/ +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ); + +/** + This function adjusts the period of timer interrupts to the value specif= ied + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. = If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer inter= rupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust t= he + interrupt controller so that a CPU interrupt is not generated when the t= imer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS= units. If + the timer hardware is not programmable, then EFI_= UNSUPPORTED is + returned. If the timer is programmable, then the= timer period + will be rounded up to the nearest timer period th= at is supported + by the timer hardware. If TimerPeriod is set to = 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period o= f the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed d= ue to a device error. +**/ +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ); + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPer= iod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 = is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 = ns units. If + 0 is returned, then the timer is currently disabl= ed. + + @retval EFI_SUCCESS The timer period was returned in TimerPer= iod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. +**/ +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ); + +/** + This function generates a soft timer interrupt. If the platform does not= support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCE= SS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.Reg= isterHandler() + service, then a soft timer interrupt will be generated. If the timer int= errupt is + enabled when this service is called, then the registered handler will be= invoked. The + registered handler should not be able to distinguish a hardware-generate= d timer + interrupt from a software-generated timer interrupt. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTED The platform does not support the generation o= f soft timer interrupts. +**/ +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ); + +/** + Write Csr TMCFG register. + + @param A0 The value used to write to the TMCFG register + + @retval none +**/ +extern +VOID +LoongarchWriteqTmcfg ( + IN UINT64 Val + ); + +/** + Write Csr TINTCLR register. + + @param A0 The value used to write to the TINTCLR register + + @retval none +**/ +extern +VOID +LoongarchWriteqTintclr ( + IN UINT64 Val + ); + +#endif // TIMER_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Time= rConfig.S b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Timer= Config.S new file mode 100644 index 0000000000..2f364c193d --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/TimerConfig= .S @@ -0,0 +1,38 @@ +#-------------------------------------------------------------------------= ----- +# +# Timer Cfg for LoongArch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ----- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" + +ASM_GLOBAL ASM_PFX(LoongarchWriteqTmcfg) +ASM_GLOBAL ASM_PFX(LoongarchWriteqTintclr) + +# +# Write Csr TMCFG register. +# @param A0 The value used to write to the TMCFG register +# @retval none +# + +ASM_PFX(LoongarchWriteqTmcfg): + csrwr A0, LOONGARCH_CSR_TMCFG + jirl ZERO, RA,0 + +# +# Write Csr TINTCLR register. +# @param A0 The value used to write to the TINTCLR register +# @retval none +# + +ASM_PFX(LoongarchWriteqTintclr): + csrwr A0, LOONGARCH_CSR_TINTCLR + jirl ZERO, RA,0 diff --git a/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/Time= rDxe.inf b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/TimerD= xe.inf new file mode 100644 index 0000000000..d4a07c8759 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/TimerDxe.inf @@ -0,0 +1,44 @@ +## @file +# Stable timer driver that provides Timer Arch protocol. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Timer + MODULE_UNI_FILE =3D Timer.uni + FILE_GUID =3D AEBE2648-47A9-40FA-83FD-06AA88443BB2 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D StableTimerDriverInitialize + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + Timer.h + Timer.c + TimerConfig.S + +[Packages] + MdePkg/MdePkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[LibraryClasses] + UefiBootServicesTableLib + BaseLib + DebugLib + UefiDriverEntryPoint + IoLib + TimerLib + +[Protocols] + gEfiCpuArchProtocolGuid ## CONSUMES + gEfiTimerArchProtocolGuid ## PRODUCES + +[depex] + TRUE --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96454): https://edk2.groups.io/g/devel/message/96454 Mute This Topic: https://groups.io/mt/95082592/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96456+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96456+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652813; cv=none; d=zohomail.com; s=zohoarc; b=h8pcsxG5cHoQSZP1DAlgKuMQqzhBqK6g7krMAhGW6OSvTOB+iAZu4Q7gBxzm68jDflR7XgB5ywLwV3M+KfhnIoA49jozasI/hCyltM7ia3DIIVinigUameMHBD5gE/tXuHgq3J37dlbWEvWiZO5hrrMTms2py41aV/wbvp3jmUg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652813; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=A2vJ1R+vpFah0iX3j5BXo7di/7045ne02edyJlP58AY=; b=kCDjY7jqI3S2xAPVg/na7uY/dOH7RhVVLHH8lYVRVOoyoDZR966IdXe18UdjcrO2/w/dWELPogNwzgZGr6/al4lABre4mGk5Q9Heo1sI15PojP5goUsIWX6d6V6L03DGST9AoLWo4wOSwRLAPQUAXo5jhHhyYDm5rENSuPV+yhI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96456+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652813325974.4039608313985; Wed, 16 Nov 2022 18:40:13 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id IMrXYY1788612xAZLaIl1Duz; Wed, 16 Nov 2022 18:40:08 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.6223.1668652804765432150 for ; Wed, 16 Nov 2022 18:40:05 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxbbcDn3VjKCQIAA--.18405S3; Thu, 17 Nov 2022 10:40:03 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S13; Thu, 17 Nov 2022 10:40:02 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 11/16] Platform/Loongson: Add RealTime Clock lib. Date: Thu, 17 Nov 2022 10:39:37 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S13 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoW3CFy7tr18tr1DXrWkWFWfKrg_yoW8JF1Uto WxtFWSgw48Jr18uasa93s7Cr42gFZIqa1Sqr1FqFWjyan8Ar1DtFyUta42gryxArykAwsx KryfA3ykJFWaqFW8n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqG1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: Z4k0VjQp7HDDQdTzkYGstio5x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652808; bh=e3CB2JJfd44CGM9I4KPGzMGXc+uc5z8GM43KFSRqw9U=; h=Cc:Date:From:Reply-To:Subject:To; b=DUAsKQhAX/FoZUWQudwwd2weLHte8EkKWyW0K2pJi6MNN21lzzsXdR0S7oyIyx5Me5l K0Yu7v7r8URj/jaCHpXTaO8f2hpNkjJScXUPJoSa/TFDU3Q+Z5dn+RH+5YtSJDf2h4Mh9 x/J1k22CK0lWK5DdnKJDnjuw7mygj1PgS7Q= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652815987100001 Content-Type: text/plain; charset="utf-8" This library provides interfaces such as real-time clock initialization to get time and setting time. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../LsRealTimeClockLib/LsRealTimeClock.h | 40 +++ .../LsRealTimeClockLib/LsRealTimeClockLib.c | 335 ++++++++++++++++++ .../LsRealTimeClockLib/LsRealTimeClockLib.inf | 47 +++ 3 files changed, 422 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeCl= ockLib/LsRealTimeClock.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeCl= ockLib/LsRealTimeClockLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeCl= ockLib/LsRealTimeClockLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/= LsRealTimeClock.h b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeCl= ockLib/LsRealTimeClock.h new file mode 100644 index 0000000000..6567ec80db --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/LsRealT= imeClock.h @@ -0,0 +1,40 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2022, Loongson Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef LS_REAL_TIME_CLOCK_H_ +#define LS_REAL_TIME_CLOCK_H_ + +#define TOY_WRITE0_REG 0x24 +#define TOY_WRITE1_REG 0x28 +#define TOY_READ0_REG 0x2c +#define TOY_READ1_REG 0x30 +#define RTC_CTRL_REG 0x40 + +/* TOY Enable bits */ +#define RTC_ENABLE_BIT (1UL << 13) +#define TOY_ENABLE_BIT (1UL << 11) +#define OSC_ENABLE_BIT (1UL << 8) + +/* + * shift bits and filed mask + */ +#define TOY_MON_MASK 0x3f +#define TOY_DAY_MASK 0x1f +#define TOY_HOUR_MASK 0x1f +#define TOY_MIN_MASK 0x3f +#define TOY_SEC_MASK 0x3f +#define TOY_MSEC_MASK 0xf + +#define TOY_MON_SHIFT 26 +#define TOY_DAY_SHIFT 21 +#define TOY_HOUR_SHIFT 16 +#define TOY_MIN_SHIFT 10 +#define TOY_SEC_SHIFT 4 + +#endif // LS_REAL_TIME_CLOCK_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/= LsRealTimeClockLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTim= eClockLib/LsRealTimeClockLib.c new file mode 100644 index 0000000000..4315c2074d --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/LsRealT= imeClockLib.c @@ -0,0 +1,335 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2022, Loongson Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "LsRealTimeClock.h" + +STATIC BOOLEAN mInitialized =3D FALSE; +STATIC EFI_EVENT mRtcVirtualAddrChangeEvent; +STATIC UINTN mRtcBase; +/* + Enable Real-time clock. + + @param VOID + + @retval VOID + */ +VOID +InitRtc ( + VOID + ) +{ + UINTN Val; + + if (!mInitialized) { + /* enable rtc */ + mRtcBase =3D (UINTN)PcdGet64 (PcdRtcBaseAddress); + Val =3D MmioRead32 (mRtcBase + RTC_CTRL_REG); + Val |=3D TOY_ENABLE_BIT | OSC_ENABLE_BIT; + MmioWrite32 (mRtcBase + RTC_CTRL_REG, Val); + mInitialized =3D TRUE; + } +} + +/** + Returns the current time and date information, and the time-keeping capa= bilities + of the hardware platform. + + @param Time A pointer to storage to receive a snapsho= t of the current time. + @param Capabilities An optional pointer to a buffer to receiv= e the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to ha= rdware error. + @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an= authentication failure. +**/ +EFI_STATUS +EFIAPI +LibGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities + ) +{ + UINT32 Val; + + // Ensure Time is a valid pointer + if (Time =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Val =3D MmioRead32 (mRtcBase + TOY_READ1_REG); + Time->Year =3D Val + 1900; + + Val =3D MmioRead32 (mRtcBase + TOY_READ0_REG); + Time->Month =3D (Val >> TOY_MON_SHIFT) & TOY_MON_MASK; + Time->Day =3D (Val >> TOY_DAY_SHIFT) & TOY_DAY_MASK; + Time->Hour =3D (Val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; + Time->Minute =3D (Val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; + Time->Second =3D (Val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; + Time->Nanosecond =3D 0; + return EFI_SUCCESS; +} + +/** + Sets the current local time and date information. + + @param Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardw= are error. +**/ +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + UINT32 Val; + + // Initialize the hardware if not already done + + Val =3D 0; + Val |=3D (Time->Second << TOY_SEC_SHIFT); + Val |=3D (Time->Minute << TOY_MIN_SHIFT); + Val |=3D (Time->Hour << TOY_HOUR_SHIFT); + Val |=3D (Time->Day << TOY_DAY_SHIFT); + Val |=3D (Time->Month << TOY_MON_SHIFT); + MmioWrite32 (mRtcBase + TOY_WRITE0_REG, Val); + + Val =3D Time->Year - 1900; + MmioWrite32 (mRtcBase + TOY_WRITE1_REG, Val); + return EFI_SUCCESS; +} + +/** + Returns the current wakeup alarm clock setting. + + @param Enabled Indicates if the alarm is currently enable= d or disabled. + @param Pending Indicates if the alarm signal is pending a= nd requires acknowledgement. + @param Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Any parameter is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due= to a hardware error. +**/ +EFI_STATUS +EFIAPI +LibGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + Sets the system wakeup alarm clock time. + + @param Enabled Enable or disable the wakeup alarm. + @param Time If Enable is TRUE, the time to set the wak= eup alarm for. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm w= as enabled. If + Enable is FALSE, then the wakeup alarm was= disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a = hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this pl= atform. +**/ +EFI_STATUS +EFIAPI +LibSetWakeupTime ( + IN BOOLEAN Enabled, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +LibRtcVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Only needed if you are going to support the OS calling RTC functions = in virtual mode. + // You will need to call EfiConvertPointer (). To convert any stored phy= sical addresses + // to virtual address. After the OS transitions to calling in virtual mo= de, all future + // runtime calls will be made in virtual mode. + // + EfiConvertPointer (0x0, (VOID**)&mRtcBase); + return; +} + +/** Add the RTC controller address range to the memory map. + + @param [in] ImageHandle The handle to the image. + @param [in] RtcPageBase Base address of the RTC controller. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Flash device not found. +**/ +EFI_STATUS +KvmtoolRtcMapMemory ( + IN EFI_HANDLE ImageHandle, + IN EFI_PHYSICAL_ADDRESS RtcPageBase + ) +{ + EFI_STATUS Status; + + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, "Failed to add memory space. Status =3D %r\n", + Status + )); + return Status; + } + + Status =3D gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + EfiGcdMemoryTypeMemoryMappedIo, + 0, + EFI_PAGE_SIZE, + &RtcPageBase, + ImageHandle, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate memory space. Status =3D %r\n", + Status + )); + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + return Status; + } + + Status =3D gDS->SetMemorySpaceAttributes ( + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to set memory attributes. Status =3D %r\n", + Status + )); + + gDS->FreeMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + } + + return Status; +} + +/** + This is the declaration of an EFI image entry point. This can be the ent= ry point to an application + written to this specification, an EFI boot service driver, or an EFI run= time driver. + + @param ImageHandle Handle that identifies the loaded image. + @param SystemTable System Table for this image. + + @retval EFI_SUCCESS The operation completed successfully. +**/ +EFI_STATUS +EFIAPI +LibRtcInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + InitRtc (); + Status =3D KvmtoolRtcMapMemory (ImageHandle, (mRtcBase & ~EFI_PAGE_MASK)= ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to map memory for loongson 7A RTC. Status =3D %r\n", + Status + )); + return Status; + } + + // Setup the setters and getters + gRT->GetTime =3D LibGetTime; + gRT->SetTime =3D LibSetTime; + + // Install the protocol + Handle =3D NULL; + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiRealTimeClockArchProtocolGuid, NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + LibRtcVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mRtcVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/= LsRealTimeClockLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealT= imeClockLib/LsRealTimeClockLib.inf new file mode 100644 index 0000000000..5aa95650f8 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/LsRealTimeClockLib/LsRealT= imeClockLib.inf @@ -0,0 +1,47 @@ +## @file +# +# Copyright (c) 2022, Loongson Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D LsRealTimeClockLib + FILE_GUID =3D 9793a3da-1869-4fdf-88b1-c6484341f50b + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D RealTimeClockLib + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + LsRealTimeClockLib.c + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + +[LibraryClasses] + IoLib + UefiLib + DebugLib + PcdLib + DxeServicesTableLib + UefiRuntimeLib + +[Pcd] + gLoongArchQemuPkgTokenSpaceGuid.PcdRtcBaseAddress + +[Guids] + gEfiEventVirtualAddressChangeGuid + +[Protocols] + gEfiRealTimeClockArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Depex] + TRUE --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96456): https://edk2.groups.io/g/devel/message/96456 Mute This Topic: https://groups.io/mt/95082595/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96457+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96457+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652810; cv=none; d=zohomail.com; s=zohoarc; b=ejQz8hKJpXSVrlMDvYXvqD1Skre7wXbzxx2iUYMhY7znu3i79aprGxgsBnBhm0Ngpr+lUt5ZJUbH3A/xe8t/YfIIGaZ8kwb0LRFz9K8c3LaydUWUxwLM5+CdmKDl230GzKT8aUBcs01JjfUDoJWKQEux3w46DdCSgje19Sr4xn8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652810; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=OY4w/2GhXRhbacXzU4IPjYmKC5b/wrGOTwEPy11EqXU=; b=Mau1firTzW3dbMUS4wSQfsUsOn6s2ii8Q8tZpE0ME+lfBiqGCZCl7caoRwS7InGs0Hs+1pa/XpWDtUTXoo7a+V8I9M/x0+Q4c7pIOwXj/PlLh39Xc6KUYEWwk5WJ4cl+8qd9svPSTN2EPU8KYW+H2w0Z0GzajdzjlzJ6y6TGbk0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96457+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652810697845.8516986903363; Wed, 16 Nov 2022 18:40:10 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id C1oYYY1788612x8GRUBljwKr; Wed, 16 Nov 2022 18:40:09 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.6224.1668652805423555399 for ; Wed, 16 Nov 2022 18:40:05 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxjdoDn3VjLCQIAA--.23104S3; Thu, 17 Nov 2022 10:40:03 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S14; Thu, 17 Nov 2022 10:40:03 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 12/16] Platform/Loongson: Add Platform Boot Manager Lib. Date: Thu, 17 Nov 2022 10:39:38 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S14 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWfuryrurWDXr4xXFW8CF18uFg_yoW5Ar1fWo WIkFy8Aw1kKr4xWa4kGr1kGa1xXFnFgwsxXr1vvF1UWanF9w1Ygas8X3Z8t3sxAF1kZ3W7 Ja4fJas3AFWSqF95n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqG1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: wiUEH5JRjE1toPZ7A31qkJZEx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652809; bh=uJan8NFS7dbpSN99qRk8uVci5cwzh1pKHzP5KuK/K7I=; h=Cc:Date:From:Reply-To:Subject:To; b=RNmFcvU8vazbD/uZLyCVy2HcywdrtP+g7TCnsm5BJEHeiewwl+lhhPYPYYjIXD29+y/ Uwub4RUdXnIuxfadtx9Q7N8R3ixa3Ja+yUZrjZOF3T9fOddmpRP2p/G9xwo2k9dD5DOvr 2SR7Oa7x5cdzCEnxnzReWv3DB4zd8l9uU/0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652811851100047 Content-Type: text/plain; charset="utf-8" The Library provides Boot Manager interfaces. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../PlatformBootManagerLib/PlatformBm.c | 742 ++++++++++++++++++ .../PlatformBootManagerLib/PlatformBm.h | 112 +++ .../PlatformBootManagerLib.inf | 75 ++ .../PlatformBootManagerLib/QemuKernel.c | 81 ++ 4 files changed, 1010 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PlatformBoot= ManagerLib/PlatformBm.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PlatformBoot= ManagerLib/PlatformBm.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PlatformBoot= ManagerLib/PlatformBootManagerLib.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/PlatformBoot= ManagerLib/QemuKernel.c diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManager= Lib/PlatformBm.c b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootM= anagerLib/PlatformBm.c new file mode 100644 index 0000000000..eb7f4241f0 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManagerLib/Pla= tformBm.c @@ -0,0 +1,742 @@ +/** @file + Implementation for PlatformBootManagerLib library class interfaces. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlatformBm.h" + +STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole =3D { + // + // VENDOR_DEVICE_PATH SerialDxe + // + { + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_P= ATH) }, + SERIAL_DXE_FILE_GUID + }, + + // + // UART_DEVICE_PATH Uart + // + { + { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PAT= H) }, + 0, // Reserved + FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate + FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits + FixedPcdGet8 (PcdUartDefaultParity), // Parity + FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits + }, + + // + // VENDOR_DEFINED_DEVICE_PATH TermType + // + { + { + MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, + DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH) + } + // + // Guid to be filled in dynamically + // + }, + + // + // EFI_DEVICE_PATH_PROTOCOL End + // + { + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, + DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL) + } +}; + +STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard =3D { + // + // USB_CLASS_DEVICE_PATH Keyboard + // + { + { + MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, + DP_NODE_LEN (USB_CLASS_DEVICE_PATH) + }, + 0xFFFF, // VendorId: any + 0xFFFF, // ProductId: any + 3, // DeviceClass: HID + 1, // DeviceSubClass: boot + 1 // DeviceProtocol: keyboard + }, + + // + // EFI_DEVICE_PATH_PROTOCOL End + // + { + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, + DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL) + } +}; + +/** + Locate all handles that carry the specified protocol, filter them with a + callback function, and pass each handle that passes the filter to another + callback. + + @param[in] ProtocolGuid The protocol to look for. + + @param[in] Filter The filter function to pass each handle to. If = this + parameter is NULL, then all handles are process= ed. + + @param[in] Process The callback function to pass each handle to th= at + clears the filter. +**/ +VOID +FilterAndProcess ( + IN EFI_GUID *ProtocolGuid, + IN FILTER_FUNCTION Filter OPTIONAL, + IN CALLBACK_FUNCTION Process + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN NoHandles; + UINTN Idx; + + Status =3D gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid, + NULL /* SearchKey */, &NoHandles, &Handles); + if (EFI_ERROR (Status)) { + // + // This is not an error, just an informative condition. + // + DEBUG ((DEBUG_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, + Status)); + return; + } + + ASSERT (NoHandles > 0); + for (Idx =3D 0; Idx < NoHandles; ++Idx) { + CHAR16 *DevicePathText; + STATIC CHAR16 Fallback[] =3D L""; + + // + // The ConvertDevicePathToText () function handles NULL input transpar= ently. + // + DevicePathText =3D ConvertDevicePathToText ( + DevicePathFromHandle (Handles[Idx]), + FALSE, // DisplayOnly + FALSE // AllowShortcuts + ); + if (DevicePathText =3D=3D NULL) { + DevicePathText =3D Fallback; + } + + if ((Filter =3D=3D NULL) + || (Filter (Handles[Idx], DevicePathText))) + { + Process (Handles[Idx], DevicePathText); + } + + if (DevicePathText !=3D Fallback) { + FreePool (DevicePathText); + } + } + gBS->FreePool (Handles); +} + +/** + This FILTER_FUNCTION checks if a handle corresponds to a PCI display dev= ice. + + @param Handle The handle to check + @param ReportText A pointer to a string at the time of the error. + + @retval TURE THe handle corresponds to a PCI display device. + @retval FALSE THe handle does not corresponds to a PCI display de= vice. +**/ +BOOLEAN +EFIAPI +IsPciDisplay ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + Status =3D gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid, + (VOID**)&PciIo); + if (EFI_ERROR (Status)) { + // + // This is not an error worth reporting. + // + return FALSE; + } + + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */, + sizeof Pci / sizeof (UINT32), &Pci); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status)= ); + return FALSE; + } + + return IS_PCI_DISPLAY (&Pci); +} + +/** + This CALLBACK_FUNCTION attempts to connect a handle non-recursively, ask= ing + the matching driver to produce all first-level child handles. + + @param Handle The handle to connect. + @param ReportText A pointer to a string at the time of the error. + + @retval VOID +**/ +VOID +EFIAPI +Connect ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ) +{ + EFI_STATUS Status; + + Status =3D gBS->ConnectController ( + Handle, // ControllerHandle + NULL, // DriverImageHandle + NULL, // RemainingDevicePath -- produce all children + FALSE // Recursive + ); + DEBUG ((EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE, "%a: %s: %r\n", + __FUNCTION__, ReportText, Status)); +} + +/** + This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the + handle, and adds it to ConOut and ErrOut. + + @param Handle The handle to retrieves. + @param ReportText A pointer to a string at the time of the error. + + @retval VOID +**/ +VOID +EFIAPI +AddOutput ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath =3D DevicePathFromHandle (Handle); + if (DevicePath =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: %s: handle %p: device path not found\n", + __FUNCTION__, ReportText, Handle)); + return; + } + + Status =3D EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__, + ReportText, Status)); + return; + } + + Status =3D EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__, + ReportText, Status)); + return; + } + + DEBUG ((DEBUG_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTIO= N__, + ReportText)); +} +/** + Register the boot option. + + @param FileGuid File Guid. + @param Description Option descriptor. + @param Attributes Option Attributes. + + @retval VOID +**/ +VOID +PlatformRegisterFvBootOption ( + IN EFI_GUID *FileGuid, + IN CHAR16 *Description, + IN UINT32 Attributes + ) +{ + EFI_STATUS Status; + INTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath =3D DevicePathFromHandle (LoadedImage->DeviceHandle); + ASSERT (DevicePath !=3D NULL); + DevicePath =3D AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + ASSERT (DevicePath !=3D NULL); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + + OptionIndex =3D EfiBootManagerFindLoadOption ( + &NewOption, BootOptions, BootOptionCount + ); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +/** + Remove all MemoryMapped (...)/FvFile (...) and Fv (...)/FvFile (...) boo= t options + whose device paths do not resolve exactly to an FvFile in the system. + + This removes any boot options that point to binaries built into the firm= ware + and have become stale due to any of the following: + - FvMain's base address or size changed (historical), + - FvMain's FvNameGuid changed, + - the FILE_GUID of the pointed-to binary changed, + - the referenced binary is no longer built into the firmware. + + EfiBootManagerFindLoadOption () used in PlatformRegisterFvBootOption () = only + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index =3D 0; Index < BootOptionCount; ++Index) { + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; + EFI_STATUS Status; + EFI_HANDLE FvHandle; + + // + // If the device path starts with neither MemoryMapped (...) nor Fv (.= ..), + // then keep the boot option. + // + Node1 =3D BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) =3D=3D HARDWARE_DEVICE_PATH + && DevicePathSubType (Node1) =3D=3D HW_MEMMAP_DP) + && !(DevicePathType (Node1) =3D=3D MEDIA_DEVICE_PATH + && DevicePathSubType (Node1) =3D=3D MEDIA_PIWG_FW_VOL_DP)) + { + continue; + } + + // + // If the second device path node is not FvFile (...), then keep the b= oot + // option. + // + Node2 =3D NextDevicePathNode (Node1); + if ((DevicePathType (Node2) !=3D MEDIA_DEVICE_PATH) + || (DevicePathSubType (Node2) !=3D MEDIA_PIWG_FW_FILE_DP)) + { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by the + // boot option. If this lookup fails (i.e., the boot option references= a + // firmware volume that doesn't exist), then we'll proceed to delete t= he + // boot option. + // + SearchNode =3D Node1; + Status =3D gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the F= vFile + // identified by GUID. + // + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; + UINTN BufferSize; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + + Status =3D gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2Protoc= olGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode =3D (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer=3D=3DNULL means we request metadata only: BufferSize, Foun= dType, + // FileAttributes. + // + Status =3D FvProtocol->ReadFile ( + FvProtocol, + &FvFileNode->FvFileName, // NameGuid + NULL, // Buffer + &BufferSize, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // The FvFile was found. Keep the boot option. + // + continue; + } + } + + // + // Delete the boot option. + // + Status =3D EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString =3D ConvertDevicePathToText (BootOptions[Index].Fil= ePath, + FALSE, FALSE); + DEBUG (( + EFI_ERROR (Status) ? EFI_D_WARN : DEBUG_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString =3D=3D NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString !=3D NULL) { + FreePool (DevicePathString); + } + ); + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +/** + Register the boot option And Keys. + + @param VOID + + @retval VOID +**/ +VOID +PlatformRegisterOptionsAndKeys ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_INPUT_KEY Esc; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode =3D SCAN_NULL; + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + Status =3D EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + ASSERT_EFI_ERROR (Status); + + // + // Map F2 and ESC to Boot Manager Menu + // + F2.ScanCode =3D SCAN_F2; + F2.UnicodeChar =3D CHAR_NULL; + Esc.ScanCode =3D SCAN_ESC; + Esc.UnicodeChar =3D CHAR_NULL; + Status =3D EfiBootManagerGetBootManagerMenu (&BootOption); + ASSERT_EFI_ERROR (Status); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); +} + +// +// BDS Platform Functions +// +/** + Do the platform init, can be customized by OEM/IBV + Possible things that can be done in PlatformBootManagerBeforeConsole: + > Update console variable: 1. include hot-plug devices; + > 2. Clear ConIn and add SOL for AMT + > Register new Driver#### or Boot#### + > Register new Key####: e.g.: F12 + > Signal ReadyToLock event + > Authentication action: 1. connect Auth devices; + > 2. Identify auto logon user. +**/ +VOID +EFIAPI +PlatformBootManagerBeforeConsole ( + VOID + ) +{ + RETURN_STATUS PcdStatus; + + // + // Signal EndOfDxe PI Event + // + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); + + // + // Dispatch deferred images after EndOfDxe event. + // + EfiBootManagerDispatchDeferredImages (); + + // + // Locate the PCI root bridges and make the PCI bus driver connect each, + // non-recursively. This will produce a number of child handles with Pci= Io on + // them. + // + FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect); + + // + // Signal the ACPI platform driver that it can download QEMU ACPI tables. + // + EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid); + + // + // Find all display class PCI devices (using the handles from the previo= us + // step), and connect them non-recursively. This should produce a number= of + // child handles with GOPs on them. + // + FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); + + // + // Now add the device path of all handles with GOP on them to ConOut and + // ErrOut. + // + FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput); + + // + // Add the hardcoded short-form USB keyboard device path to ConIn. + // + EfiBootManagerUpdateConsoleVariable (ConIn, + (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL); + + // + // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut. + // + CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid); + EfiBootManagerUpdateConsoleVariable (ConIn, + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); + EfiBootManagerUpdateConsoleVariable (ConOut, + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); + + // + // Set the front page timeout from the QEMU configuration. + // + PcdStatus =3D PcdSet16S (PcdPlatformBootTimeOut, + GetFrontPageTimeoutFromQemu ()); + ASSERT_RETURN_ERROR (PcdStatus); + + // + // Register platform-specific boot options and keyboard shortcuts. + // + PlatformRegisterOptionsAndKeys (); +} + +/** + Do the platform specific action after the console is ready + Possible things that can be done in PlatformBootManagerAfterConsole: + > Console post action: + > Dynamically switch output mode from 100x31 to 80x25 for certain sena= rino + > Signal console ready platform customized event + > Run diagnostics like memory testing + > Connect certain devices + > Dispatch aditional option roms + > Special boot: e.g.: USB boot, enter UI +**/ +VOID +EFIAPI +PlatformBootManagerAfterConsole ( + VOID + ) +{ + // + // Show the splash screen. + // + BootLogoEnableLogo (); + + // + // Connect the rest of the devices. + // + EfiBootManagerConnectAll (); + + // + // Process QEMU's -kernel command line option. Note that the kernel boot= ed + // this way should receive ACPI tables, which is why we connect all devi= ces + // first (see above) -- PCI enumeration blocks ACPI table installation, = if + // there is a PCI host. + // + TryRunningQemuKernel (); + + // + // Enumerate all possible boot options, then filter and reorder them bas= ed on + // the QEMU configuration. + // + EfiBootManagerRefreshAllBootOption (); + + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption ( + &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE + ); + + RemoveStaleFvFileOptions (); + SetBootOrderFromQemu (); +} + +/** + This function is called each second during the boot manager waits the + timeout. + + @param TimeoutRemain The remaining timeout. +**/ +VOID +EFIAPI +PlatformBootManagerWaitCallback ( + IN UINT16 TimeoutRemain + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; + UINT16 Timeout; + + Timeout =3D PcdGet16 (PcdPlatformBootTimeOut); + + Black.Raw =3D 0x00000000; + White.Raw =3D 0x00FFFFFF; + + BootLogoUpdateProgress ( + White.Pixel, + Black.Pixel, + L"Start boot option", + White.Pixel, + (Timeout - TimeoutRemain) * 100 / Timeout, + 0 + ); +} + +/** + The function is called when no boot option could be launched, + including platform recovery options and options pointing to applications + built into firmware volumes. + + If this function returns, BDS attempts to enter an infinite loop. +**/ +VOID +EFIAPI +PlatformBootManagerUnableToBoot ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; + UINTN Index; + + // + // BootManagerMenu doesn't contain the correct information when return s= tatus + // is EFI_NOT_FOUND. + // + Status =3D EfiBootManagerGetBootManagerMenu (&BootManagerMenu); + if (EFI_ERROR (Status)) { + return; + } + // + // Normally BdsDxe does not print anything to the system console, but th= is is + // a last resort -- the end-user will likely not see any DEBUG messages + // logged in this situation. + // + // AsciiPrint () will NULL-check gST->ConOut internally. We check gST->C= onIn + // here to see if it makes sense to request and wait for a keypress. + // + if (gST->ConIn !=3D NULL) { + AsciiPrint ( + "%a: No bootable option or device was found.\n" + "%a: Press any key to enter the Boot Manager Menu.\n", + gEfiCallerBaseName, + gEfiCallerBaseName + ); + Status =3D gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); + ASSERT_EFI_ERROR (Status); + ASSERT (Index =3D=3D 0); + + // + // Drain any queued keys. + // + while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) { + // + // just throw away Key + // + } + } + + for (;;) { + EfiBootManagerBoot (&BootManagerMenu); + } +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManager= Lib/PlatformBm.h b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootM= anagerLib/PlatformBm.h new file mode 100644 index 0000000000..f20c78252f --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManagerLib/Pla= tformBm.h @@ -0,0 +1,112 @@ +/** @file + Head file for BDS Platform specific code + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PLATFORM_BM_H_ +#define PLATFORM_BM_H_ + +#include + +#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >>= 8) } + +#define SERIAL_DXE_FILE_GUID { \ + 0xD3987D4B, 0x971A, 0x435F, \ + { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \ + } + +#define ALIGN_UP(addr, align) \ + ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH SerialDxe; + UART_DEVICE_PATH Uart; + VENDOR_DEFINED_DEVICE_PATH TermType; + EFI_DEVICE_PATH_PROTOCOL End; +} PLATFORM_SERIAL_CONSOLE; +#pragma pack () + +#pragma pack (1) +typedef struct { + USB_CLASS_DEVICE_PATH Keyboard; + EFI_DEVICE_PATH_PROTOCOL End; +} PLATFORM_USB_KEYBOARD; +#pragma pack () + +/** + Check if the handle satisfies a particular condition. + + @param[in] Handle The handle to check. + @param[in] ReportText A caller-allocated string passed in for reporting + purposes. It must never be NULL. + + @retval TRUE The condition is satisfied. + @retval FALSE Otherwise. This includes the case when the condition coul= d not + be fully evaluated due to an error. +**/ +typedef +BOOLEAN +(EFIAPI *FILTER_FUNCTION) ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ); + +/** + Process a handle. + + @param[in] Handle The handle to process. + @param[in] ReportText A caller-allocated string passed in for reporting + purposes. It must never be NULL. +**/ +typedef +VOID +(EFIAPI *CALLBACK_FUNCTION) ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ); + +/** + * execute from kernel entry point. + * + * @param[in] Argc The count of args. + * @param[in] Argv The pointer to args array. + * @param[in] Bpi The pointer to bootparaminterface struct. + * @param[in] Vec The fourth args for kernel. + ***/ +typedef +VOID +(EFIAPI *EFI_KERNEL_ENTRY_POINT) ( + IN UINTN Argc, + IN VOID *Argv, + IN VOID *Bpi, + IN VOID *Vec + ); + +/** + Download the kernel, the initial ramdisk, and the kernel command line fr= om + QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two + image files, and load and start the kernel from it. + + The kernel will be instructed via its command line to load the initrd fr= om + the same Simple FileSystem. + + @retval EFI_NOT_FOUND Kernel image was not found. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + @retval EFI_PROTOCOL_ERROR Unterminated kernel command line. + + @return Error codes from any of the underlying + functions. On success, the function doesn't + return. +**/ +EFI_STATUS +EFIAPI +TryRunningQemuKernel ( + VOID + ); + +#endif // PLATFORM_BM_H_ diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManager= Lib/PlatformBootManagerLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library= /PlatformBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 0000000000..0ea6fea5c5 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManagerLib/Pla= tformBootManagerLib.inf @@ -0,0 +1,75 @@ +## @file +# Implementation for PlatformBootManagerLib library class interfaces. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformBootManagerLib + FILE_GUID =3D 469184E8-FADA-41E4-8823-012CA19B40D4 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformBootManagerLib|DXE_DRIVER + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + PlatformBm.c + QemuKernel.c + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + BootLogoLib + DebugLib + DevicePathLib + MemoryAllocationLib + PcdLib + PrintLib + QemuBootOrderLib + QemuLoadImageLib + QemuFwCfgLib + UefiBootManagerLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeServicesTableLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + +[Guids] + gEfiFileInfoGuid + gEfiFileSystemInfoGuid + gEfiFileSystemVolumeLabelInfoIdGuid + gEfiEndOfDxeEventGroupGuid + gRootBridgesConnectedEventGroupGuid + gUefiShellFileGuid + gEfiLoongsonBootparamsTableGuid ## SOMETIM= ES_PRODUCES ## SystemTable + gEfiTtyTermGuid + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiFirmwareVolume2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gEfiSimpleFileSystemProtocolGuid diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManager= Lib/QemuKernel.c b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootM= anagerLib/QemuKernel.c new file mode 100644 index 0000000000..386003a8d7 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/PlatformBootManagerLib/Qem= uKernel.c @@ -0,0 +1,81 @@ +/** @file + Try to run Linux kernel. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - mem - Memory + - Bpi - Boot Parameter Interface + - FwCfg - FirmWare Configure +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Download the kernel, the initial ramdisk, and the kernel command line fr= om + QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two + image files, and load and start the kernel from it. + + The kernel will be instructed via its command line to load the initrd fr= om + the same Simple FileSystem. + + @retval EFI_NOT_FOUND Kernel image was not found. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + @retval EFI_PROTOCOL_ERROR Unterminated kernel command line. + + @return Error codes from any of the underlying + functions. On success, the function doesn't + return. +**/ +EFI_STATUS +TryRunningQemuKernel ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE KernelImageHandle; + + Status =3D QemuLoadKernelImage (&KernelImageHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event. + // + EfiSignalEventReadyToBoot (); + + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT) + ); + + // + // Start the image. + // + Status =3D QemuStartKernelImage (&KernelImageHandle); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: QemuStartKernelImage(): %r\n", + __FUNCTION__, + Status + )); + } + + QemuUnloadKernelImage (KernelImageHandle); + + return Status; +} --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96457): https://edk2.groups.io/g/devel/message/96457 Mute This Topic: https://groups.io/mt/95082596/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96458+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96458+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652813; cv=none; d=zohomail.com; s=zohoarc; b=KqP0Sa4bnEp1vNREwXl5x9Ss1hKX2IDwWjGkrR/fOxpMzes2fTc+l0Ms89dnKor9P1SEqLl0C9SpEoXUustrwWsBRj8YBNKSgaFBw52O0nRRz0dkdA+ltSbY52IH0Klfl4C9IYdzlf216vFyncldXiKSw+VAVvU5vA0yuS7bv6s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652813; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=k13zESDh7WGva5kilqpSyu3cBFADkR0/ogx8KqFVTnk=; b=NOVFWScv5RdxP1/+9PSePKj6Q9F8n7KAqkTCQBXs820TGu66KSPm+rpQhx3ZHfO6Yvl7AuTf6upp+m2t9DO3x8Ej4VGqTpfy4vNh8qB4nxMtkV6twT2jqRFz8sosFgRVZ5DnVYbUcov/AQ1Qs1ELrKvEcqcpZp4DDOQVl6bwQJQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96458+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 166865281381276.10736228666099; Wed, 16 Nov 2022 18:40:13 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 9YNvYY1788612x8C7JepkvrU; Wed, 16 Nov 2022 18:40:13 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6333.1668652806314502036 for ; Wed, 16 Nov 2022 18:40:07 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxXbYEn3VjMiQIAA--.11325S3; Thu, 17 Nov 2022 10:40:04 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S15; Thu, 17 Nov 2022 10:40:03 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 13/16] Platform/Loongson: Add Reset System Lib. Date: Thu, 17 Nov 2022 10:39:39 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S15 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWftr1fCw13ZF18ZrWxJFy7Wrg_yoW8tr4rto W2gan7t3y8Jrs5u397Wrn3GF4IqFsYq398ZF1rJFWDJrWDZr109FWkXa48JF9aqF15XF45 GayfJ3yrJrZagF4kn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqG1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: IDY0ZBwuE49LfETt4JytYKXzx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652813; bh=1VfCOzRIIjSwF/Vw5nZYv3z8TkwKOqs0qbfWUrXK+mM=; h=Cc:Date:From:Reply-To:Subject:To; b=HzmPPpFJIWJXMrJMi3UkKMhHD0gjNFslrwaUm0xkbwe5Hf3QwjIA4LjuFPyFNAGaF78 0ZK8Eeqcvv5BK0IkuHPXizDh+dq3bZUgnA9ySAIQDewfoY1Ok+AOrisvwf09CTVnvF6zi rYWVXkNQpksu7pIZDL7IGfadRPCMwJvYBO0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652816018100004 Content-Type: text/plain; charset="utf-8" This library provides interfaces related to restart and shutdown. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../BaseResetSystemAcpiGed.c | 146 ++++++++++ .../BaseResetSystemAcpiGedLib.inf | 37 +++ .../DxeResetSystemAcpiGed.c | 257 ++++++++++++++++++ .../DxeResetSystemAcpiGedLib.inf | 41 +++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.c | 128 +++++++++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.h | 23 ++ 6 files changed, 632 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/BaseResetSystemAcpiGed.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/BaseResetSystemAcpiGedLib.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/DxeResetSystemAcpiGed.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/DxeResetSystemAcpiGedLib.inf create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/ResetSystemAcpiGed.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemA= cpiLib/ResetSystemAcpiGed.h diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= BaseResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/Reset= SystemAcpiLib/BaseResetSystemAcpiGed.c new file mode 100644 index 0000000000..0df629ffcd --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseRes= etSystemAcpiGed.c @@ -0,0 +1,146 @@ +/** @file + Base ResetSystem library implementation. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include "ResetSystemAcpiGed.h" +#include + +/** + Get configuration item data by the firmware configuration file name. + + @param[in] Name - Name of file to look up. + + @return VOID* The Pointer of Value of Firmware Configuration it= em read. +**/ +VOID * +GetFwCfgData( +CONST CHAR8 *Name +) +{ + FIRMWARE_CONFIG_ITEM FwCfgItem; + EFI_STATUS Status; + UINTN FwCfgSize; + VOID *Data; + + Status =3D QemuFwCfgFindFile (Name, &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read %s error Status %d \n", __func__, __= LINE__, Name, Status)); + return NULL; + } + + Data =3D AllocatePool (FwCfgSize); + if (Data =3D=3D NULL) { + return NULL; + } + + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (FwCfgSize, Data); + + return Data; +} + +/** + Find the power manager related info from ACPI table + + @retval RETURN_SUCCESS Successfully find out all the required inform= ation. + @retval RETURN_NOT_FOUND Failed to find the required info. +**/ +STATIC EFI_STATUS +GetPowerManagerByParseAcpiInfo (VOID) +{ + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt =3D NULL; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp =3D NULL; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt =3D NULL; + EFI_ACPI_DESCRIPTION_HEADER *Rsdt =3D NULL; + VOID *AcpiTables =3D NULL; + UINT32 *Entry32 =3D NULL; + UINTN Entry32Num; + UINT32 *Signature =3D NULL; + UINTN Idx; + + Rsdp =3D GetFwCfgData ("etc/acpi/rsdp"); + if (Rsdp =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/rsdp error \n", __func__, __= LINE__)); + return RETURN_NOT_FOUND; + } + + AcpiTables =3D GetFwCfgData ("etc/acpi/tables"); + if (AcpiTables =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/tables error \n", __func__, = __LINE__)); + FreePool (Rsdp); + return RETURN_NOT_FOUND; + } + + Rsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->Rsdt= Address); + Entry32 =3D (UINT32 *)(Rsdt + 1); + Entry32Num =3D (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> = 2; + for (Idx =3D 0; Idx < Entry32Num; Idx++) { + Signature =3D (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables); + if (*Signature =3D=3D EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNAT= URE) { + Fadt =3D (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n")); + goto Done; + } + } + + Xsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->Xsdt= Address); + Entry32 =3D (UINT32 *)(Xsdt + 1); + Entry32Num =3D (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> = 2; + for (Idx =3D 0; Idx < Entry32Num; Idx++) { + Signature =3D (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables); + if (*Signature =3D=3D EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNAT= URE) { + Fadt =3D (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n")); + goto Done; + } + } + + FreePool (Rsdp); + FreePool (AcpiTables); + DEBUG ((DEBUG_ERROR, " Fadt Not Found\n")); + return RETURN_NOT_FOUND; + +Done: + mPowerManager.ResetRegAddr =3D Fadt->ResetReg.Address; + mPowerManager.ResetValue =3D Fadt->ResetValue; + mPowerManager.SleepControlRegAddr =3D Fadt->SleepControlReg.Address; + mPowerManager.SleepStatusRegAddr =3D Fadt->SleepStatusReg.Address; + + FreePool (Rsdp); + FreePool (AcpiTables); + return RETURN_SUCCESS; +} + +/** + The constructor function to initialize mPowerManager. + + @retval EFI_SUCCESS initialize mPowerManager success. + @retval RETURN_NOT_FOUND Failed to initialize mPowerManager. +**/ +EFI_STATUS +ResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D GetPowerManagerByParseAcpiInfo (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__)); + } + + ASSERT (mPowerManager.SleepControlRegAddr); + ASSERT (mPowerManager.SleepStatusRegAddr); + ASSERT (mPowerManager.ResetRegAddr); + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= BaseResetSystemAcpiGedLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/= ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..120dd7dcff --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseRes= etSystemAcpiGedLib.inf @@ -0,0 +1,37 @@ +## @file +# Base library instance for ResetSystem library class for loongarhch +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D ResetSystemLib + FILE_GUID =3D 3d6faf60-804a-4ca9-a36a-1a92416919d0 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D ResetSystemLib|SEC PEI_CORE PEIM DXE_= CORE + CONSTRUCTOR =3D ResetSystemLibConstructor + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + BaseResetSystemAcpiGed.c + ResetSystemAcpiGed.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + QemuFwCfgLib + MemoryAllocationLib + IoLib diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= DxeResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetS= ystemAcpiLib/DxeResetSystemAcpiGed.c new file mode 100644 index 0000000000..ef48946ae4 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeRese= tSystemAcpiGed.c @@ -0,0 +1,257 @@ +/** @file + Dxe ResetSystem library implementation. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include // EfiConvertPointer() +#include +#include +#include "ResetSystemAcpiGed.h" +#include + +/** + Modifies the attributes to Runtime type for a page size memory region. + + @param BaseAddress Specified start address + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + @retval EFI_UNSUPPORTED The processor does not support one or more= bytes of the memory + resource range specified by BaseAddress an= d Length. + @retval EFI_UNSUPPORTED The bit mask of attributes is not support = for the memory resource + range specified by BaseAddress and Length. + @retval EFI_ACCESS_DEFINED The attributes for the memory resource ran= ge specified by + BaseAddress and Length cannot be modified. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to m= odify the attributes of + the memory resource range. + @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU a= rchitectural protocol is + not available yet. +**/ +EFI_STATUS +SetMemoryAttributesRunTime ( + UINTN Address + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + + Address &=3D ~EFI_PAGE_MASK; + + Status =3D gDS->GetMemorySpaceDescriptor (Address, &Descriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: GetMemorySpaceDescriptor failed\n", __FUNCTIO= N__)); + return Status; + } + + if (Descriptor.GcdMemoryType =3D=3D EfiGcdMemoryTypeNonExistent) { + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Address, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: AddMemorySpace failed\n", __FUNCTION__)); + return Status; + } + + Status =3D gDS->SetMemorySpaceAttributes ( + Address, + EFI_PAGE_SIZE, + EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUN= CTION__, __LINE__)); + return Status; + } + } else if (!(Descriptor.Attributes & EFI_MEMORY_RUNTIME)) { + Status =3D gDS->SetMemorySpaceAttributes ( + Address, + EFI_PAGE_SIZE, + Descriptor.Attributes | EFI_MEMORY_RUNTIME + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUN= CTION__, __LINE__)); + return Status; + } + } + return EFI_SUCCESS; +} + +/** + Find the power manager related info from ACPI table + + @retval RETURN_SUCCESS Successfully find out all the required inform= ation. + @retval RETURN_NOT_FOUND Failed to find the required info. +**/ +STATIC EFI_STATUS +GetPowerManagerByParseAcpiInfo ( + VOID +) +{ + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt =3D NULL; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp =3D NULL; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt =3D NULL; + EFI_ACPI_DESCRIPTION_HEADER *Rsdt =3D NULL; + UINT32 *Entry32 =3D NULL; + UINTN Entry32Num; + UINT32 *Signature =3D NULL; + UINTN Idx; + EFI_STATUS Status; + + Status =3D EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)= &Rsdp); + if (EFI_ERROR (Status)) { + Status =3D EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID= **)&Rsdp); + } + + if (EFI_ERROR (Status) || (Rsdp =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp =3D=3D NULL\n")); + return RETURN_NOT_FOUND; + } + + Rsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress; + Entry32 =3D (UINT32 *)(UINTN)(Rsdt + 1); + Entry32Num =3D (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> = 2; + for (Idx =3D 0; Idx < Entry32Num; Idx++) { + Signature =3D (UINT32 *)(UINTN)Entry32[Idx]; + if (*Signature =3D=3D EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNAT= URE) { + Fadt =3D (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n")); + goto Done; + } + } + + Xsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *)Rsdp->XsdtAddress; + Entry32 =3D (UINT32 *)(Xsdt + 1); + Entry32Num =3D (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> = 2; + for (Idx =3D 0; Idx < Entry32Num; Idx++) { + Signature =3D (UINT32 *)(UINTN)Entry32[Idx]; + if (*Signature =3D=3D EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNAT= URE) { + Fadt =3D (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n")); + goto Done; + } + } + + DEBUG ((DEBUG_ERROR, " Fadt Not Found\n")); + return RETURN_NOT_FOUND; + +Done: + mPowerManager.ResetRegAddr =3D Fadt->ResetReg.Address; + mPowerManager.ResetValue =3D Fadt->ResetValue; + mPowerManager.SleepControlRegAddr =3D Fadt->SleepControlReg.Address; + mPowerManager.SleepStatusRegAddr =3D Fadt->SleepStatusReg.Address; + return RETURN_SUCCESS; +} + +/** + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS= _CHANGE + event. It converts a pointer to a new virtual address. + + @param[in] Event Event whose notification function is being invok= ed. + @param[in] Context Pointer to the notification function's context +**/ +VOID +EFIAPI +ResetSystemLibAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0, (VOID **)&mPowerManager.SleepControlRegAddr); + EfiConvertPointer (0, (VOID **)&mPowerManager.SleepStatusRegAddr); + EfiConvertPointer (0, (VOID **)&mPowerManager.ResetRegAddr); +} + +/** + Notification function of ACPI Table change. + + This is a notification function registered on ACPI Table change event. + It saves the Century address stored in ACPI FADT table. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context. +**/ +STATIC VOID +AcpiNotificationEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status =3D GetPowerManagerByParseAcpiInfo (); + if (EFI_ERROR (Status)) { + return ; + } + + DEBUG ((DEBUG_INFO, "%a: sleepControl %llx\n", __FUNCTION__, mPowerManag= er.SleepControlRegAddr)); + ASSERT (mPowerManager.SleepControlRegAddr); + Status =3D SetMemoryAttributesRunTime (mPowerManager.SleepControlRegAdd= r); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__)); + return ; + } + + DEBUG ((DEBUG_INFO, "%a: sleepStatus %llx\n", __FUNCTION__, mPowerManage= r.SleepStatusRegAddr)); + ASSERT (mPowerManager.SleepStatusRegAddr); + Status =3D SetMemoryAttributesRunTime (mPowerManager.SleepStatusRegAddr= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__)); + return ; + } + + DEBUG ((DEBUG_INFO, "%a: ResetReg %llx\n", __FUNCTION__, mPowerManager.R= esetRegAddr)); + ASSERT (mPowerManager.ResetRegAddr); + Status =3D SetMemoryAttributesRunTime (mPowerManager.ResetRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__)); + } + return ; +} + +/** + The constructor function to Register ACPI Table change event and Address= Change Event. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. +**/ +EFI_STATUS +EFIAPI +ResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + EFI_EVENT ResetSystemVirtualNotifyEvent; + + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiNotificationEvent, + NULL, + &gEfiAcpiTableGuid, + &Event + ); + + // + // Register SetVirtualAddressMap () notify function + // + Status =3D gBS->CreateEvent ( + EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, + TPL_NOTIFY, + ResetSystemLibAddressChangeEvent, + NULL, + &ResetSystemVirtualNotifyEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= DxeResetSystemAcpiGedLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/R= esetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..48c7ea2dc3 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeRese= tSystemAcpiGedLib.inf @@ -0,0 +1,41 @@ +## @file +# DXE library instance for ResetSystem library class for loongarch. +# +# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D ResetSystemLib + FILE_GUID =3D 3d6faf60-804a-4ca9-a36a-1a92416919d0 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D ResetSystemLib|DXE_DRIVER DXE_RUNTIME= _DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR =3D ResetSystemLibConstructor + +# +# VALID_ARCHITECTURES =3D LOONGARCH64 +# + +[Sources] + DxeResetSystemAcpiGed.c + ResetSystemAcpiGed.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DxeServicesTableLib + IoLib + UefiLib + +[Guids] + gEfiAcpi10TableGuid ## PRODUCES ## S= ystemTable + gEfiAcpiTableGuid ## PRODUCES ## S= ystemTable diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= ResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSyst= emAcpiLib/ResetSystemAcpiGed.c new file mode 100644 index 0000000000..d15cc70b4b --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSy= stemAcpiGed.c @@ -0,0 +1,128 @@ +/** @file + ResetSystem library implementation. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include // CpuDeadLoop() +#include +#include // ResetCold() +#include +#include "ResetSystemAcpiGed.h" + +POWER_MANAGER mPowerManager; + +/** + Calling this function causes a system-wide reset. This sets + all circuitry within the system to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + System reset should not return, if it returns, it means the system does + not support cold reset. +**/ +STATIC VOID +AcpiGedReset ( + VOID + ) +{ + MmioWrite8 ( + (UINTN)mPowerManager.ResetRegAddr, + mPowerManager.ResetValue + ); + + CpuDeadLoop (); +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI S5 states. + + * */ +STATIC VOID +AcpiGedShutdown ( + VOID + ) +{ + MmioWrite8 ( + (UINTN)mPowerManager.SleepControlRegAddr, + (1 << 5) /* enable bit */ | + (5 << 2) /* typ =3D=3D S5 */ + ); + + CpuDeadLoop (); +} + +/** + This function causes a system-wide reset (cold reset), in which + all circuitry within the system returns to its initial state. This type = of + reset is asynchronous to system operation and operates without regard to + cycle boundaries. + + If this function returns, it means that the system does not support cold + reset. +**/ +VOID EFIAPI +ResetCold ( + VOID + ) +{ + AcpiGedReset (); +} + +/** + This function causes a system-wide initialization (warm reset), in which= all + processors are set to their initial state. Pending cycles are not corrup= ted. + + If this function returns, it means that the system does not support warm + reset. +**/ +VOID EFIAPI +ResetWarm ( + VOID + ) +{ + AcpiGedReset (); +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string = passed + into ResetData. If the platform does not recognize the EFI_GUID in Reset= Data + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated str= ing, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + AcpiGedReset (); +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + If this function returns, it means that the system does not support shut= down + reset. +**/ +VOID EFIAPI +ResetShutdown ( + VOID + ) +{ + AcpiGedShutdown (); +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/= ResetSystemAcpiGed.h b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSyst= emAcpiLib/ResetSystemAcpiGed.h new file mode 100644 index 0000000000..e504e870f9 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSy= stemAcpiGed.h @@ -0,0 +1,23 @@ +/** @file + ResetSystem lib head file. + + Copyright (c) 2022 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef RESET_SYSTEM_ACPI_GED_H_ +#define RESET_SYSTEM_ACPI_GED_H_ + +#include + +typedef struct { + UINT64 SleepControlRegAddr; + UINT64 SleepStatusRegAddr; + UINT64 ResetRegAddr; + UINT8 ResetValue; +} POWER_MANAGER; + +extern POWER_MANAGER mPowerManager; +#endif // RESET_SYSTEM_ACPI_GED_H_ --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96458): https://edk2.groups.io/g/devel/message/96458 Mute This Topic: https://groups.io/mt/95082597/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96459+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96459+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652814; cv=none; d=zohomail.com; s=zohoarc; b=a+WVgP0UAXyKKiJQEE+LqygLxmJXa7pfH6JSFO3IrgLDQLwfJRSw7gVG5r6TgvlcVGIf8QBamEs9D3uXOV3XlCn4fnkRFavamIhI2TATAtOfhgbC4D69zI3TDbYWBGNzHCFqcANRx9ZMoJiez5I411pO/OiRp45mVyOrloX+qHU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652814; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=m13Cf2phOuRXjxqizwolYtVVrMzBcP9bLBD1QFUkAsY=; b=S2eSX+DqDDn40BDMCQWl6gYjlJz3OjR59DRhpzcdGgeUT7vCY2JY1e1U8XQkSpfhUoYQpve7nNpov7FPWc0seKVtwAlTMCeRjd5zEJtDV5uA7SPJsXJhvVYTRsto/HaZHN/djwEUVDsXBQPckC6RuP0cVE/HUK8kKIEcb351JLk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96459+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 166865281465518.12652773656191; Wed, 16 Nov 2022 18:40:14 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id LNgWYY1788612xb0p4iyUYhR; Wed, 16 Nov 2022 18:40:13 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6335.1668652806827706832 for ; Wed, 16 Nov 2022 18:40:08 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8BxfdoFn3VjOCQIAA--.23875S3; Thu, 17 Nov 2022 10:40:05 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S16; Thu, 17 Nov 2022 10:40:04 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 14/16] Platform/Loongson: Add Hob Dxe Lib. Date: Thu, 17 Nov 2022 10:39:40 +0800 Message-Id: <9ef52965ae5aaff7941fe4e8a7c21c0dce71b7db.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S16 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoW3tFyDWr4UWw13Ar1kAr1DJrb_yoW8CF47Zo Wj9FykAa1DKr18uF93Kr97Gay3ZF42gr45ZrWUXFWjq3Wvv343W3yfua1UX3s8XrW8Zr1D G34fZasayF4IqF93n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqG1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: ZgHrydA1Y5PwGonlDbfEQ1gCx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652813; bh=zW3H7S8yAAmNOOOUzcbPtuOch2wYgOK/hbHD/EUPXcM=; h=Cc:Date:From:Reply-To:Subject:To; b=sOdbiVzmqYmuyd+99S+dR+azdVRDsEDXtCQT3R2LDHK7yCFuXCBOfnnr6Q9XoG52q7m cpSsPEMwxcPyMa3RBU9pGA4yZDH1JQUJvWWtFQ624NVcqb+NODon0CrjhIodTHmJWDEUE PByLdmQdjQgmSONg+FepUzk2lwNzlN3CvPY= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652815998100002 Content-Type: text/plain; charset="utf-8" This library provides interfaces related to Dxe Hob. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Library/VirtDxeHobLib/HobLib.c | 590 ++++++++++++++++++ .../Library/VirtDxeHobLib/VirtDxeHobLib.inf | 34 + 2 files changed, 624 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLi= b/HobLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLi= b/VirtDxeHobLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/HobLi= b.c b/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/HobLib.c new file mode 100644 index 0000000000..4594bc2990 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/HobLib.c @@ -0,0 +1,590 @@ +/** @file + HOB Library implementation for Dxe Phase with DebugLib dependency removed + + Copyright (c) 2022, Loongson Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#define ASSERT(Expression) \ + do { \ + if (!(Expression)) { \ + CpuDeadLoop (); \ + } \ + } while (FALSE) + +#include +#include +#include +#include +#include + +VOID *mHobList =3D NULL; + +/** + The constructor function caches the pointer to HOB list. + + The constructor function gets the start address of HOB list from system = configuration table. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor successfully gets HobList. + @retval Other value The constructor can't get HobList. +**/ +EFI_STATUS +EFIAPI +HobLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN Index; + + for (Index =3D 0; Index < SystemTable->NumberOfTableEntries; Index++) { + if (CompareGuid (&gEfiHobListGuid, &(SystemTable->ConfigurationTable[I= ndex].VendorGuid))) { + mHobList =3D SystemTable->ConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + Returns the pointer to the HOB list. + + This function returns the pointer to first HOB in the list. + For PEI phase, the PEI service GetHobList() can be used to retrieve the = pointer + to the HOB list. For the DXE phase, the HOB list pointer can be retriev= ed through + the EFI System Table by looking up theHOB list GUID in the System Config= uration Table. + Since the System Configuration Table does not exist that the time the DX= E Core is + launched, the DXE Core uses a global variable from the DXE Core Entry Po= int Library + to manage the pointer to the HOB list. + + If the pointer to the HOB list is NULL, then ASSERT(). + + @return The pointer to the HOB list. +**/ +VOID * +EFIAPI +GetHobList ( + VOID + ) +{ + ASSERT (mHobList !=3D NULL); + return mHobList; +} + +/** + Returns the next instance of a HOB type from the starting HOB. + + This function searches the first instance of a HOB type from the startin= g HOB pointer. + If there does not exist such HOB type from the starting HOB pointer, it = will return NULL. + In contrast with macro GET_NEXT_HOB(), this function does not skip the s= tarting HOB pointer + unconditionally: it returns HobStart back if HobStart itself meets the r= equirement; + caller is required to use GET_NEXT_HOB() if it wishes to skip current Ho= bStart. + + If HobStart is NULL, then ASSERT(). + + @param Type The HOB type to return. + @param HobStart The starting HOB pointer to search from. + + @return The next instance of a HOB type from the starting HOB. +**/ +VOID * +EFIAPI +GetNextHob ( + IN UINT16 Type, + IN CONST VOID *HobStart + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + ASSERT (HobStart !=3D NULL); + + Hob.Raw =3D (UINT8 *)HobStart; + // + // Parse the HOB list until end of list or matching type is found. + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType =3D=3D Type) { + return Hob.Raw; + } + + Hob.Raw =3D GET_NEXT_HOB (Hob); + } + + return NULL; +} + +/** + Returns the first instance of a HOB type among the whole HOB list. + + This function searches the first instance of a HOB type among the whole = HOB list. + If there does not exist such HOB type in the HOB list, it will return NU= LL. + + If the pointer to the HOB list is NULL, then ASSERT(). + + @param Type The HOB type to return. + + @return The next instance of a HOB type from the starting HOB. +**/ +VOID * +EFIAPI +GetFirstHob ( + IN UINT16 Type + ) +{ + VOID *HobList; + + HobList =3D GetHobList (); + return GetNextHob (Type, HobList); +} + +/** + Returns the next instance of the matched GUID HOB from the starting HOB. + + This function searches the first instance of a HOB from the starting HOB= pointer. + Such HOB should satisfy two conditions: + its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to = the input Guid. + If there does not exist such HOB from the starting HOB pointer, it will = return NULL. + Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_S= IZE () + to extract the data section and its size information, respectively. + In contrast with macro GET_NEXT_HOB(), this function does not skip the s= tarting HOB pointer + unconditionally: it returns HobStart back if HobStart itself meets the r= equirement; + caller is required to use GET_NEXT_HOB() if it wishes to skip current Ho= bStart. + + If Guid is NULL, then ASSERT(). + If HobStart is NULL, then ASSERT(). + + @param Guid The GUID to match with in the HOB list. + @param HobStart A pointer to a Guid. + + @return The next instance of the matched GUID HOB from the starting HOB. +**/ +VOID * +EFIAPI +GetNextGuidHob ( + IN CONST EFI_GUID *Guid, + IN CONST VOID *HobStart + ) +{ + EFI_PEI_HOB_POINTERS GuidHob; + + GuidHob.Raw =3D (UINT8 *)HobStart; + while ((GuidHob.Raw =3D GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob= .Raw)) !=3D NULL) { + if (CompareGuid (Guid, &GuidHob.Guid->Name)) { + break; + } + + GuidHob.Raw =3D GET_NEXT_HOB (GuidHob); + } + + return GuidHob.Raw; +} + +/** + Returns the first instance of the matched GUID HOB among the whole HOB l= ist. + + This function searches the first instance of a HOB among the whole HOB l= ist. + Such HOB should satisfy two conditions: + its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to = the input Guid. + If there does not exist such HOB from the starting HOB pointer, it will = return NULL. + Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_S= IZE () + to extract the data section and its size information, respectively. + + If the pointer to the HOB list is NULL, then ASSERT(). + If Guid is NULL, then ASSERT(). + + @param Guid The GUID to match with in the HOB list. + + @return The first instance of the matched GUID HOB among the whole HOB l= ist. +**/ +VOID * +EFIAPI +GetFirstGuidHob ( + IN CONST EFI_GUID *Guid + ) +{ + VOID *HobList; + + HobList =3D GetHobList (); + return GetNextGuidHob (Guid, HobList); +} + +/** + Get the system boot mode from the HOB list. + + This function returns the system boot mode information from the + PHIT HOB in HOB list. + + If the pointer to the HOB list is NULL, then ASSERT(). + + @param VOID + + @return The Boot Mode. +**/ +EFI_BOOT_MODE +EFIAPI +GetBootModeHob ( + VOID + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; + + HandOffHob =3D (EFI_HOB_HANDOFF_INFO_TABLE *)GetHobList (); + + return HandOffHob->BootMode; +} + +/** + Builds a HOB for a loaded PE32 module. + + This function builds a HOB for a loaded PE32 module. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If ModuleName is NULL, then ASSERT(). + If there is no additional space for HOB creation, then ASSERT(). + + @param ModuleName The GUID File Name of the module. + @param MemoryAllocationModule The 64 bit physical address of the modul= e. + @param ModuleLength The length of the module in bytes. + @param EntryPoint The 64 bit physical address of the modul= e entry point. +**/ +VOID +EFIAPI +BuildModuleHob ( + IN CONST EFI_GUID *ModuleName, + IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule, + IN UINT64 ModuleLength, + IN EFI_PHYSICAL_ADDRESS EntryPoint + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a HOB that describes a chunk of system memory. + + This function builds a HOB that describes a chunk of system memory. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + + @param ResourceType The type of resource described by this HOB. + @param ResourceAttribute The resource attributes of the memory descri= bed by this HOB. + @param PhysicalStart The 64 bit physical address of memory descri= bed by this HOB. + @param NumberOfBytes The length of the memory described by this H= OB in bytes. +**/ +VOID +EFIAPI +BuildResourceDescriptorHob ( + IN EFI_RESOURCE_TYPE ResourceType, + IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, + IN EFI_PHYSICAL_ADDRESS PhysicalStart, + IN UINT64 NumberOfBytes + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a customized HOB tagged with a GUID for identification and returns + the start address of GUID HOB data. + + This function builds a customized HOB tagged with a GUID for identificat= ion + and returns the start address of GUID HOB data so that caller can fill t= he customized data. + The HOB Header and Name field is already stripped. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If Guid is NULL, then ASSERT(). + If there is no additional space for HOB creation, then ASSERT(). + If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). + HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0x= FFF8. + + @param Guid The GUID to tag the customized HOB. + @param DataLength The size of the data payload for the GUID HOB. + + @retval NULL The GUID HOB could not be allocated. + @retval others The start address of GUID HOB data. +**/ +VOID * +EFIAPI +BuildGuidHob ( + IN CONST EFI_GUID *Guid, + IN UINTN DataLength + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); + return NULL; +} + +/** + Builds a customized HOB tagged with a GUID for identification, copies th= e input data to the HOB + data field, and returns the start address of the GUID HOB data. + + This function builds a customized HOB tagged with a GUID for identificat= ion and copies the input + data to the HOB data field and returns the start address of the GUID HOB= data. It can only be + invoked during PEI phase; for DXE phase, it will ASSERT() since PEI HOB = is read-only for DXE phase. + The HOB Header and Name field is already stripped. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If Guid is NULL, then ASSERT(). + If Data is NULL and DataLength > 0, then ASSERT(). + If there is no additional space for HOB creation, then ASSERT(). + If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). + HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0x= FFF8. + + @param Guid The GUID to tag the customized HOB. + @param Data The data to be copied into the data field of the G= UID HOB. + @param DataLength The size of the data payload for the GUID HOB. + + @retval NULL The GUID HOB could not be allocated. + @retval others The start address of GUID HOB data. +**/ +VOID * +EFIAPI +BuildGuidDataHob ( + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN DataLength + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); + return NULL; +} + +/** + Builds a Firmware Volume HOB. + + This function builds a Firmware Volume HOB. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + If the FvImage buffer is not at its required alignment, then ASSERT(). + + @param BaseAddress The base address of the Firmware Volume. + @param Length The size of the Firmware Volume in bytes. +**/ +VOID +EFIAPI +BuildFvHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a EFI_HOB_TYPE_FV2 HOB. + + This function builds a EFI_HOB_TYPE_FV2 HOB. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + If the FvImage buffer is not at its required alignment, then ASSERT(). + + @param BaseAddress The base address of the Firmware Volume. + @param Length The size of the Firmware Volume in bytes. + @param FvName The name of the Firmware Volume. + @param FileName The name of the file. +**/ +VOID +EFIAPI +BuildFv2Hob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN CONST EFI_GUID *FvName, + IN CONST EFI_GUID *FileName + ) +{ + ASSERT (FALSE); +} + +/** + Builds a EFI_HOB_TYPE_FV3 HOB. + + This function builds a EFI_HOB_TYPE_FV3 HOB. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + If the FvImage buffer is not at its required alignment, then ASSERT(). + + @param BaseAddress The base address of the Firmware Volume. + @param Length The size of the Firmware Volume in bytes. + @param AuthenticationStatus The authentication status. + @param ExtractedFv TRUE if the FV was extracted as a file wit= hin + another firmware volume. FALSE otherwise. + @param FvName The name of the Firmware Volume. + Valid only if IsExtractedFv is TRUE. + @param FileName The name of the file. + Valid only if IsExtractedFv is TRUE. +**/ +VOID +EFIAPI +BuildFv3Hob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT32 AuthenticationStatus, + IN BOOLEAN ExtractedFv, + IN CONST EFI_GUID *FvName OPTIONAL, + IN CONST EFI_GUID *FileName OPTIONAL + ) +{ + ASSERT (FALSE); +} + +/** + Builds a Capsule Volume HOB. + + This function builds a Capsule Volume HOB. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If the platform does not support Capsule Volume HOBs, then ASSERT(). + If there is no additional space for HOB creation, then ASSERT(). + + @param BaseAddress The base address of the Capsule Volume. + @param Length The size of the Capsule Volume in bytes. +**/ +VOID +EFIAPI +BuildCvHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a HOB for the CPU. + + This function builds a HOB for the CPU. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + + @param SizeOfMemorySpace The maximum physical memory addressability o= f the processor. + @param SizeOfIoSpace The maximum physical I/O addressability of t= he processor. +**/ +VOID +EFIAPI +BuildCpuHob ( + IN UINT8 SizeOfMemorySpace, + IN UINT8 SizeOfIoSpace + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a HOB for the Stack. + + This function builds a HOB for the stack. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + + @param BaseAddress The 64 bit physical address of the Stack. + @param Length The length of the stack in bytes. +**/ +VOID +EFIAPI +BuildStackHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a HOB for the BSP store. + + This function builds a HOB for BSP store. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + + @param BaseAddress The 64 bit physical address of the BSP. + @param Length The length of the BSP store in bytes. + @param MemoryType Type of memory allocated by this HOB. +**/ +VOID +EFIAPI +BuildBspStoreHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN EFI_MEMORY_TYPE MemoryType + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} + +/** + Builds a HOB for the memory allocation. + + This function builds a HOB for the memory allocation. + It can only be invoked during PEI phase; + for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. + + If there is no additional space for HOB creation, then ASSERT(). + + @param BaseAddress The 64 bit physical address of the memory. + @param Length The length of the memory allocation in bytes. + @param MemoryType Type of memory allocated by this HOB. +**/ +VOID +EFIAPI +BuildMemoryAllocationHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN EFI_MEMORY_TYPE MemoryType + ) +{ + // + // PEI HOB is read only for DXE phase + // + ASSERT (FALSE); +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/VirtD= xeHobLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/Vir= tDxeHobLib.inf new file mode 100644 index 0000000000..074e706a0a --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/VirtDxeHobLib/VirtDxeHobLi= b.inf @@ -0,0 +1,34 @@ +## @file +# Instance of HOB Library using HOB list from EFI Configuration Table, with +# DebugLib dependency removed +# +# HOB Library implementation that retrieves the HOB List +# from the System Configuration Table in the EFI System Table. +# +# Copyright (c) 2022, Loongson Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D VirtDxeHobLib + FILE_GUID =3D 3CD90EEC-EBF3-425D-AAE8-B16215AC4F50 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D HobLib|DXE_DRIVER DXE_RUNTIME_DRIVER = UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR =3D HobLibConstructor + +[Sources] + HobLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseMemoryLib + +[Guids] + gEfiHobListGuid ## CONSUMES ## SystemTable --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96459): https://edk2.groups.io/g/devel/message/96459 Mute This Topic: https://groups.io/mt/95082598/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96461+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96461+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652816; cv=none; d=zohomail.com; s=zohoarc; b=Bp93+KJEtcjUOtzss2IqMunJPzkdTaAdXaAsDmQI26qIHT/SC+uOFQTcU5LVvMv2ZOogyTZq0eSmarlH0kChdr5kSuEYlhPY5f9bOUnv70zCfH4JcHty6Xb1oCLP16f/0NTqf464Fa28Sl88QpAQLShmnmtSu/qsLGxSkGIs/hU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652816; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=bAVgWeSFWl34xOzM3mxQkUDeR7+eUVLxke4NLSHxsuE=; b=dpUtSJG3VVODo2s1hqIePA+qxBmGaRiT2A9326SO3Bb5TebautnE5T9aVHsuFQnVY/53vnjXQRXYGxvXwtgroT6tSNgBpPw5cZd5CfjBlmJDTQBLZvvA7Zn2683PqXBy52UUIFsy2z1A1GQynyuI4MkJRQIt//3MdBWmPMj0yQo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96461+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652816339591.2087522711566; Wed, 16 Nov 2022 18:40:16 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id HAkZYY1788612xwD05ZRi0DR; Wed, 16 Nov 2022 18:40:16 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6337.1668652809163477071 for ; Wed, 16 Nov 2022 18:40:10 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8BxLtsGn3VjPiQIAA--.23364S3; Thu, 17 Nov 2022 10:40:06 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S17; Thu, 17 Nov 2022 10:40:05 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 15/16] Platform/Loongson: Support Dxe Date: Thu, 17 Nov 2022 10:39:41 +0800 Message-Id: <16562a4259c6933473e02def0582e1b202b5b53b.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S17 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWDAryruFW7uw48Gw43Zr4xZwb_yoWrAw4kto WxJF1jyr45tr1kJ3yUKFsxtryxZw4avr4Yqr18Zw1kAF4Utr12vrWDtwnrWr1DAFn8Ar1D G3y5A3y8tFW7twn7n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqC1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2js IEc7CjxVAFwI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI 8VC2zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VCjz48v1sIEY20_WwAm72CE4I kC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64vIr41l42xK82IY6x8E rcxFaVAv8VWrMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2 IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI 42IY6xIIjxv20xvE14v26F1j6w1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIx AIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26F4j6r4UJwCI42IY6I8E 87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: ThqViFTLdJPh9nZyxeE8KfhZx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652816; bh=NbbSnDiF2U8V9rHQKtKQyFX2ihMkG5S1vHJfVlBOOJE=; h=Cc:Date:From:Reply-To:Subject:To; b=qOg7r1Y5y5VK8ay92oitV/5tOqr0sHw88YrfBXiKawUXi4nSxRvjDH4ioxHuM7nlZKT JH4sMCoTvtHs/o6tlB6qbaUXjqJHM7Gq/2F1yW+8sTZbrxv6I+OTkA88/sX6V3MlDhftM 2E9GvXUnRVI7nLPw82/eB1Ee+74LPzzVg2k= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652817989100010 Content-Type: text/plain; charset="utf-8" Support Dxe for LoogArch. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- .../Loongson/LoongArchQemuPkg/Loongson.dec | 13 + .../Loongson/LoongArchQemuPkg/Loongson.dsc | 446 ++++++++++++++++++ .../Loongson/LoongArchQemuPkg/Loongson.fdf | 243 ++++++++++ .../LoongArchQemuPkg/Loongson.fdf.inc | 8 + 4 files changed, 710 insertions(+) diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dec index 023df1dd2a..e638b835e4 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dec +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dec @@ -27,14 +27,22 @@ =20 [Guids] gLoongArchQemuPkgTokenSpaceGuid =3D { 0x0e0383ce, 0x0151, 0x4d01, { 0x8= 0, 0x0e, 0x3f, 0xef, 0x8b, 0x27, 0x6d, 0x52 } } + gEfiLoongsonBootparamsTableGuid =3D { 0x4660f721, 0x2ec5, 0x416a, { 0x8= 9, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } } gEarly16550UartBaseAddressGuid =3D { 0xea67ca3e, 0x1f54, 0x436b, { 0x9= 7, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } } =20 +[Protocols] + ## In the PcdsFixedAtBuild and PcdsDynamic areas, numbers start at 0x0. [PcdsFixedAtBuild, PcdsDynamic] gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase|0x0|UINT64|0x00000000 gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvSize|0x0|UINT32|0x00000001 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvOffset|0x0|UINT64|0x00000002 gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase|0x0|UINT64|0x00000003 gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvSize|0x0|UINT32|0x00000004 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecModuleBase|0x0|UINT64|0x00000= 005 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecModuleSize|0x0|UINT32|0x00000= 006 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashEventLogBase|0x0|UINT64|0x000000= 07 + gLoongArchQemuPkgTokenSpaceGuid.PcdFlashEventLogSize|0x0|UINT32|0x000000= 08 gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreeBase|0x0|UINT64|0x00000009 gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceTreePadding|256|UINT32|0x000000= 0a =20 @@ -49,6 +57,8 @@ [PcdsFixedAtBuild.LOONGARCH64] gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00010000 gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00010001 + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceSpaceStartAddress|0x10000000|U= INT32|0x00010002 + gLoongArchQemuPkgTokenSpaceGuid.PcdDeviceSpaceLength|0x80000000|UINT32|= 0x00010003 =20 ## In the PcdsDynamic area, numbers start at 0x20000. [PcdsDynamic] @@ -61,3 +71,6 @@ gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPmd|0x0|UINT64|0x00020006 gLoongArchQemuPkgTokenSpaceGuid.PcdInvalidPte|0x0|UINT64|0x00020007 gLoongArchQemuPkgTokenSpaceGuid.PcdRtcBaseAddress|0x00000000|UINT64|0x00= 020008 + +## In the PcdsFeatureFlag area, numbers start at 0x30000. +[PcdsFeatureFlag] diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.dsc index 8d196ae8c1..2d63f7d168 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc @@ -24,6 +24,25 @@ FLASH_DEFINITION =3D Platform/Loongson/LoongArchQemuPkg/Lo= ongson.fdf TTY_TERMINAL =3D FALSE =20 + # + # Defines for default states. These can be changed on the command line. + # -D FLAG=3DVALUE + DEFINE TTY_TERMINAL =3D FALSE + DEFINE SECURE_BOOT_ENABLE =3D FALSE + DEFINE TPM2_ENABLE =3D FALSE + DEFINE TPM2_CONFIG_ENABLE =3D FALSE + + # + # Network definition + # + DEFINE NETWORK_IP6_ENABLE =3D FALSE + DEFINE NETWORK_HTTP_BOOT_ENABLE =3D FALSE + DEFINE NETWORK_SNP_ENABLE =3D FALSE + DEFINE NETWORK_TLS_ENABLE =3D FALSE + DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS =3D TRUE + DEFINE NETWORK_ISCSI_ENABLE =3D FALSE + +!include NetworkPkg/NetworkDefines.dsc.inc ##########################################################################= ## # # Defines for default states. These can be changed on the command line. @@ -37,6 +56,8 @@ # GCC:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES =20 +!include NetworkPkg/NetworkBuildOptions.dsc.inc + [BuildOptions.LOONGARCH64.EDKII.SEC] *_*_*_CC_FLAGS =3D =20 @@ -46,6 +67,14 @@ [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] GCC:*_*_LOONGARCH64_DLINK_FLAGS =3D -z common-page-size=3D0x10000 =20 +##########################################################################= ###### +# +# SKU Identification section - list of all SKU IDs supported by this Platf= orm. +# +##########################################################################= ###### +[SkuIds] + 0|DEFAULT + ##########################################################################= ###### # # Library Class section - list of all Library Classes needed by this Platf= orm. @@ -59,20 +88,93 @@ TimerLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/StableTimerLib/TimerLib.inf PrintLib | MdePkg/Library/BasePrintLib/BasePrint= Lib.inf BaseMemoryLib | MdePkg/Library/BaseMemoryLib/BaseMemo= ryLib.inf + + # Networking Requirements +!include NetworkPkg/NetworkLibs.dsc.inc +!if $(NETWORK_TLS_ENABLE) =3D=3D TRUE + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf +!endif + BaseLib | MdePkg/Library/BaseLib/BaseLib.inf + SafeIntLib | MdePkg/Library/BaseSafeIntLib/BaseSaf= eIntLib.inf + TimeBaseLib | EmbeddedPkg/Library/TimeBaseLib/TimeB= aseLib.inf + BmpSupportLib | MdeModulePkg/Library/BaseBmpSupportLi= b/BaseBmpSupportLib.inf + SynchronizationLib | MdePkg/Library/BaseSynchronizationLib= /BaseSynchronizationLib.inf + CpuLib | MdePkg/Library/BaseCpuLib/BaseCpuLib.= inf PerformanceLib | MdePkg/Library/BasePerformanceLibNull= /BasePerformanceLibNull.inf PeCoffLib | MdePkg/Library/BasePeCoffLib/BasePeCo= ffLib.inf CacheMaintenanceLib | MdePkg/Library/BaseCacheMaintenanceLi= b/BaseCacheMaintenanceLib.inf UefiDecompressLib | MdePkg/Library/BaseUefiDecompressLib/= BaseUefiDecompressLib.inf + UefiHiiServicesLib | MdeModulePkg/Library/UefiHiiServicesL= ib/UefiHiiServicesLib.inf + HiiLib | MdeModulePkg/Library/UefiHiiLib/UefiH= iiLib.inf + CapsuleLib | MdeModulePkg/Library/DxeCapsuleLibNul= l/DxeCapsuleLibNull.inf + DxeServicesLib | MdePkg/Library/DxeServicesLib/DxeServ= icesLib.inf + DxeServicesTableLib | MdePkg/Library/DxeServicesTableLib/Dx= eServicesTableLib.inf PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf + PciLib | MdePkg/Library/BasePciLibPciExpress/B= asePciLibPciExpress.inf + PciExpressLib | OvmfPkg/Library/BaseCachingPciExpress= Lib/BaseCachingPciExpressLib.inf + PciCapLib | OvmfPkg/Library/BasePciCapLib/BasePci= CapLib.inf + PciCapPciSegmentLib | OvmfPkg/Library/BasePciCapPciSegmentL= ib/BasePciCapPciSegmentLib.inf + PciCapPciIoLib | OvmfPkg/Library/UefiPciCapPciIoLib/Ue= fiPciCapPciIoLib.inf + DxeHardwareInfoLib | OvmfPkg/Library/HardwareInfoLib/DxeHa= rdwareInfoLib.inf IoLib | MdePkg/Library/BaseIoLibIntrinsic/Bas= eIoLibIntrinsic.inf PlatformHookLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf SerialPortLib | MdeModulePkg/Library/BaseSerialPortLi= b16550/BaseSerialPortLib16550.inf + EfiResetSystemLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf + ResetSystemLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf + + UefiLib | MdePkg/Library/UefiLib/UefiLib.inf + UefiBootServicesTableLib | MdePkg/Library/UefiBootServicesTableL= ib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib | MdePkg/Library/UefiRuntimeServicesTab= leLib/UefiRuntimeServicesTableLib.inf + UefiDriverEntryPoint | MdePkg/Library/UefiDriverEntryPoint/U= efiDriverEntryPoint.inf + UefiApplicationEntryPoint | MdePkg/Library/UefiApplicationEntryPo= int/UefiApplicationEntryPoint.inf + DevicePathLib | MdePkg/Library/UefiDevicePathLibDevic= ePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + FileHandleLib | MdePkg/Library/UefiFileHandleLib/Uefi= FileHandleLib.inf + SecurityManagementLib | MdeModulePkg/Library/DxeSecurityManag= ementLib/DxeSecurityManagementLib.inf + UefiUsbLib | MdePkg/Library/UefiUsbLib/UefiUsbLib.= inf + SerializeVariablesLib | OvmfPkg/Library/SerializeVariablesLib= /SerializeVariablesLib.inf + CustomizedDisplayLib | MdeModulePkg/Library/CustomizedDispla= yLib/CustomizedDisplayLib.inf DebugPrintErrorLevelLib | MdePkg/Library/BaseDebugPrintErrorLev= elLib/BaseDebugPrintErrorLevelLib.inf + TpmMeasurementLib | MdeModulePkg/Library/TpmMeasurementLi= bNull/TpmMeasurementLibNull.inf + AuthVariableLib | MdeModulePkg/Library/AuthVariableLibN= ull/AuthVariableLibNull.inf + VarCheckLib | MdeModulePkg/Library/VarCheckLib/VarC= heckLib.inf + VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLi= b/VariablePolicyLib.inf + VariablePolicyHelperLib | MdeModulePkg/Library/VariablePolicyHe= lperLib/VariablePolicyHelperLib.inf + SortLib | MdeModulePkg/Library/UefiSortLib/Uefi= SortLib.inf FdtLib | EmbeddedPkg/Library/FdtLib/FdtLib.inf + PciSegmentLib | MdePkg/Library/BasePciSegmentLibPci/B= asePciSegmentLibPci.inf + PciHostBridgeLib | OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPc= iHostBridgeLib.inf + PciHostBridgeUtilityLib | OvmfPkg/Library/PciHostBridgeUtilityL= ib/PciHostBridgeUtilityLib.inf + MmuLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/MmuLib/MmuBaseLib.inf + FileExplorerLib | MdeModulePkg/Library/FileExplorerLib/= FileExplorerLib.inf + +!if $(HTTP_BOOT_ENABLE) =3D=3D TRUE + HttpLib | MdeModulePkg/Library/DxeHttpLib/DxeHt= tpLib.inf +!endif + UefiBootManagerLib | MdeModulePkg/Library/UefiBootManagerL= ib/UefiBootManagerLib.inf + OrderedCollectionLib | MdePkg/Library/BaseOrderedCollectionR= edBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + ReportStatusCodeLib | MdePkg/Library/BaseReportStatusCodeLi= bNull/BaseReportStatusCodeLibNull.inf + + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPoin= tLib/BasePeCoffGetEntryPointLib.inf PeCoffExtraActionLib | MdePkg/Library/BasePeCoffExtraActionL= ibNull/BasePeCoffExtraActionLibNull.inf DebugAgentLib | MdeModulePkg/Library/DebugAgentLibNul= l/DebugAgentLibNull.inf + CpuExceptionHandlerLib | MdeModulePkg/Library/CpuExceptionHand= lerLibNull/CpuExceptionHandlerLibNull.inf + + PlatformBootManagerLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/PlatformBootManagerLib/PlatformBootManagerLib.inf + BootLogoLib | MdeModulePkg/Library/BootLogoLib/Boot= LogoLib.inf + QemuBootOrderLib | OvmfPkg/Library/QemuBootOrderLib/Qemu= BootOrderLib.inf + QemuFwCfgSimpleParserLib | OvmfPkg/Library/QemuFwCfgSimpleParser= Lib/QemuFwCfgSimpleParserLib.inf + QemuLoadImageLib | OvmfPkg/Library/GenericQemuLoadImageL= ib/GenericQemuLoadImageLib.inf + + # + # Virtio Support + # + VirtioLib | OvmfPkg/Library/VirtioLib/VirtioLib.i= nf + FrameBufferBltLib | MdeModulePkg/Library/FrameBufferBltLi= b/FrameBufferBltLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCf= gLibMmio.inf + DebugLib | MdePkg/Library/BaseDebugLibSerialPort= /BaseDebugLibSerialPort.inf PeiServicesLib | MdePkg/Library/PeiServicesLib/PeiServ= icesLib.inf + VariableFlashInfoLib | MdeModulePkg/Library/BaseVariableFlas= hInfoLib/BaseVariableFlashInfoLib.inf =20 [LibraryClasses.common.SEC] PcdLib | MdePkg/Library/BasePcdLibNull/BasePcd= LibNull.inf @@ -110,17 +212,96 @@ MmuLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/MmuLib/MmuBaseLibPei.inf SerialPortLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/SerialPortLib/EarlySerialPortLib16550.inf =20 +[LibraryClasses.common.DXE_CORE] + HobLib | MdePkg/Library/DxeCoreHobLib/DxeCoreH= obLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeC= oreEntryPoint.inf + MemoryAllocationLib | MdeModulePkg/Library/DxeCoreMemoryAll= ocationLib/DxeCoreMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusC= odeLib/DxeReportStatusCodeLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/Base= PciExpressLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtP= ciPcdProducerLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/VirtDxeHobLib/VirtDxeHobLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeC= oreEntryPoint.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLi= b/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/RuntimeDxeReport= StatusCodeLib/RuntimeDxeReportStatusCodeLib.inf + UefiRuntimeLib | MdePkg/Library/UefiRuntimeLib/UefiRun= timeLib.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectio= nLib/PeiExtractGuidedSectionLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQem= uFwCfgS3LibFwCfg.inf + RealTimeClockLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/LsRealTimeClockLib/LsRealTimeClockLib.inf + VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLi= b/VariablePolicyLibRuntimeDxe.inf + QemuFwCfgLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/QemuFwCfgLib/QemuFwCfgPeiLib.inf + EfiResetSystemLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf + ResetSystemLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/Base= PciExpressLib.inf +!if $(TARGET) !=3D RELEASE + DebugLib | MdePkg/Library/DxeRuntimeDebugLibSeri= alPort/DxeRuntimeDebugLibSerialPort.inf +!endif + +[LibraryClasses.common.UEFI_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/VirtDxeHobLib/VirtDxeHobLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeC= oreEntryPoint.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLi= b/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusC= odeLib/DxeReportStatusCodeLib.inf + UefiScsiLib | MdePkg/Library/UefiScsiLib/UefiScsiLi= b.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectio= nLib/PeiExtractGuidedSectionLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCf= gLibMmio.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtP= ciPcdProducerLib.inf + +[LibraryClasses.common.DXE_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/VirtDxeHobLib/VirtDxeHobLib.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLi= b/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusC= odeLib/DxeReportStatusCodeLib.inf + UefiScsiLib | MdePkg/Library/UefiScsiLib/UefiScsiLi= b.inf + CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandle= rLib/DxeCpuExceptionHandlerLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectio= nLib/DxeExtractGuidedSectionLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQem= uFwCfgS3LibFwCfg.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCf= gLibMmio.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtP= ciPcdProducerLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/Base= PciExpressLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | Platform/Loongson/LoongArchQemuPkg/Li= brary/VirtDxeHobLib/VirtDxeHobLib.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLi= b/UefiMemoryAllocationLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectio= nLib/DxeExtractGuidedSectionLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtP= ciPcdProducerLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/Base= PciExpressLib.inf + ##########################################################################= ###### # # Pcd Section - list of all EDK II PCD Entries defined by this Platform. # ##########################################################################= ###### +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport | F= ALSE +# gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial | T= RUE +# gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory | T= RUE + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress | T= RUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport | T= RUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport | F= ALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport | F= ALSE + gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation | T= RUE + gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation | T= RUE [PcdsFixedAtBuild] ## BaseLib ## gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength | 1= 000000 gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength | 1= 000000 gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength | 1= 000000 + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout | 1= 0000000 =20 + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize | 1 + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange | F= ALSE + gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler | 0= x10 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize | 0= x2000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize | 0= x8000 + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress | 0= x0 + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize | 48 + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize | 32 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask | 0= x07 gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0= x8000004F =20 # Use MMIO for accessing Serial port registers. @@ -170,6 +351,65 @@ # 0x90000000 - 0xA0000000 # gLoongArchQemuPkgTokenSpaceGuid.PcdUefiRamTop | 0= x10000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions | 0= x06 + + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | {= 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0x= f4, 0x66, 0x23, 0x31 } + + # + # Network Pcds + # +!include NetworkPkg/NetworkPcds.dsc.inc + + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0= x10000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0= x20000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0= x10000 + +##########################################################################= ###### +# +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Pla= tform +# +##########################################################################= ###### +[PcdsDynamicDefault] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration | F= ALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution | 8= 00 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution | 6= 00 + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut | 2 + + # Set video resolution for text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution | 6= 40 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution | 4= 80 + + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion | 0= x0300 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev | 0= x0 + + gLoongArchQemuPkgTokenSpaceGuid.PcdRamSize | 0= x40000000 + + ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI + # enumeration to complete before installing ACPI tables. + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration |TR= UE + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation |0x0 + # set PcdPciExpressBaseAddress to MAX_UINT64, which signifies that this + # PCD and PcdPciDisableBusEnumeration above have not been assigned yet + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress |0x= FFFFFFFFFFFFFFFF + + # + # IPv4 and IPv6 PXE Boot support. + # + gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport | 0= x01 + gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport | 0= x01 + + # + # SMBIOS entry point version + # + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0300 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 + gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|TRUE =20 [PcdsPatchableInModule.common] gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0 @@ -199,3 +439,209 @@ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf } + + # + # DXE Phase modules + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL | MdeModulePkg/Library/LzmaCustomDe= compressLib/LzmaCustomDecompressLib.inf + DevicePathLib | MdePkg/Library/UefiDevicePathLib/= UefiDevicePathLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSe= ctionLib/DxeExtractGuidedSectionLib.inf + } + + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCod= eRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRun= timeDxe.inf + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.inf + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntim= eDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/TimerDxe.inf + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf + MdeModulePkg/Universal/Metronome/Metronome.inf + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + + # + # Variable + # + + OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf { + + PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.i= nf + } + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + } + + # + # Platform Driver + # + OvmfPkg/VirtioBlkDxe/VirtioBlk.inf + OvmfPkg/VirtioScsiDxe/VirtioScsi.inf + OvmfPkg/VirtioRngDxe/VirtioRng.inf + + # + # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs + # + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf + + # + #BDS + # + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf { + + DevicePathLib | MdePkg/Library/UefiDevicePathLib/= UefiDevicePathLib.inf + PcdLib | MdePkg/Library/BasePcdLibNull/Bas= ePcdLibNull.inf + } + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Logo/LogoDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanc= eManagerUiLib.inf + } + + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf { + + NULL|OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierLibNull.inf + } + + # + # Network Support + # +#!include NetworkPkg/NetworkComponents.dsc.inc + +# NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf { +# +# NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf +# } + +!if $(NETWORK_TLS_ENABLE) =3D=3D TRUE + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { + + NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf + } +!endif + OvmfPkg/VirtioNetDxe/VirtioNet.inf + + # + # IDE/SCSI + # + OvmfPkg/SataControllerDxe/SataControllerDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + + # + # SMBIOS Support + # + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf { + + NULL | OvmfPkg/Library/SmbiosVersionLib/= DetectSmbiosVersionLib.inf + } + OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + + # + # PCI + # + Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf= { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressL= ib.inf + } + EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressL= ib.inf + } + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressL= ib.inf + } + OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf + OvmfPkg/Virtio10Dxe/Virtio10.inf + + # + # Console + # + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf= { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + + # + # Video + # + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf + OvmfPkg/VirtioGpuDxe/VirtioGpu.inf + OvmfPkg/PlatformDxe/Platform.inf + + # + # Usb Support + # + MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + + # + # ACPI Support + # + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsRes= ourceTableDxe.inf + OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + } + + # + #app + # + ShellPkg/Application/Shell/Shell.inf { + + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComman= dLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comm= andsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comm= andsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comm= andsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Co= mmandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comm= andsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1= CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1= CommandsLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandlePar= singLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcf= gCommandLib.inf + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + } diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf b/Platform/Loo= ngson/LoongArchQemuPkg/Loongson.fdf index 8e257f2392..784f255910 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf @@ -22,6 +22,14 @@ $(SECFV_OFFSET)|$(SECFV_SIZE) gLoongArchQemuPkgTokenSpaceGuid.PcdFlashSecFvBase|gLoongArchQemuPkgTokenSp= aceGuid.PcdFlashSecFvSize FV =3D SECFV =20 +$(PEIFV_OFFSET)|$(PEIFV_SIZE) +gLoongArchQemuPkgTokenSpaceGuid.PcdFlashPeiFvBase|gLoongArchQemuPkgTokenSp= aceGuid.PcdFlashPeiFvSize +FV =3D PEIFV + +$(DXEFV_OFFSET)|$(DXEFV_SIZE) +gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase|gLoongArchQemuPkgTokenSp= aceGuid.PcdFlashDxeFvSize +FV =3D FVMAIN_COMPACT + ##########################################################################= ########################### [FV.SECFV] FvNameGuid =3D 587d4265-5e71-41da-9c35-4258551f1e22 @@ -79,6 +87,179 @@ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf INF Platform/Loongson/LoongArchQemuPkg/PlatformPei/PlatformPei.inf =20 +##########################################################################= ########################### +[FV.DXEFV] +FvNameGuid =3D 5d19a5b3-130f-459b-a292-9270a9e6bc62 +BlockSize =3D $(BLOCK_SIZE) +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE + +APRIORI DXE { + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +} + +# +# DXE Phase modules +# +INF MdeModulePkg/Core/Dxe/DxeMain.inf + +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatus= CodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandler= RuntimeDxe.inf +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF Platform/Loongson/LoongArchQemuPkg/Drivers/CpuDxe/CpuDxe.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF Platform/Loongson/LoongArchQemuPkg/Drivers/StableTimerDxe/TimerDxe.inf +INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf +INF MdeModulePkg/Universal/Metronome/Metronome.inf +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRun= timeDxe.inf +INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + +# +# Variable +# +INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +# +# PCI +# +INF Platform/Loongson/LoongArchQemuPkg/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.= inf +INF EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf +INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf +INF OvmfPkg/Virtio10Dxe/Virtio10.inf + +# +# Platform Driver +# +INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf +INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf +INF OvmfPkg/VirtioRngDxe/VirtioRng.inf +INF OvmfPkg/VirtioNetDxe/VirtioNet.inf + +# +# Console +# +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf +INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf +INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.= inf + +# +#Video +# +INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf +INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf +INF OvmfPkg/PlatformDxe/Platform.inf + +# +# SATA/SCSI +# +INF OvmfPkg/SataControllerDxe/SataControllerDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + +# +# Usb Support +# +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf +INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + +# +#BDS +# +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Logo/LogoDxe.inf +INF MdeModulePkg/Application/UiApp/UiApp.inf +INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf + +# +#Smbios +# +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf +INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + +# +#Acpi +# +INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf +INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphics= ResourceTableDxe.inf +INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf + +# +# Network modules +#!include NetworkPkg/Network.fdf.inc + +# +# File system +# +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf +INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf + +# +#Boot OS +# +INF ShellPkg/Application/Shell/Shell.inf + +##########################################################################= ########################### +[FV.FVMAIN_COMPACT] +FvNameGuid =3D af8c3fe8-9ce8-4548-884a-e3f4dd91f040 +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE + +FILE FV_IMAGE =3D 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED= =3D TRUE { + SECTION FV_IMAGE =3D DXEFV + } + } + ##########################################################################= ########################### [Rule.Common.SEC] FILE SEC =3D $(NAMED_GUID) { @@ -102,3 +283,65 @@ INF Platform/Loongson/LoongArchQemuPkg/PlatformPei/Pl= atformPei.inf } =20 ##########################################################################= ########################### +[Rule.Common.DXE_CORE] + FILE DXE_CORE =3D $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### +[Rule.Common.DXE_DRIVER] + FILE DRIVER =3D $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +##########################################################################= ########################### +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER =3D $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### +[Rule.Common.UEFI_DRIVER] + FILE DRIVER =3D $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER =3D $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING=3D"$(MODULE_NAME)" Optional + VERSION STRING=3D"$(INF_VERSION)" Optional BUILD_NUM=3D$(BUILD_NUMBE= R) + } + +##########################################################################= ########################### +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION =3D $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING=3D"$(MODULE_NAME)" Optional + } + +##########################################################################= ########################### +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION =3D $(NAMED_GUID) { + PE32 PE32 |.efi + UI STRING=3D"$(MODULE_NAME)" Optional + VERSION STRING=3D"$(INF_VERSION)" Optional BUILD_NUM=3D$(BUILD_NUMBE= R) + } + +##########################################################################= ########################### +[Rule.Common.USER_DEFINED.ACPITABLE] + FILE FREEFORM =3D $(NAMED_GUID) { + RAW ACPI |.acpi + RAW ASL |.aml + } diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc b/Platform= /Loongson/LoongArchQemuPkg/Loongson.fdf.inc index 6f17909748..e30c4629f7 100644 --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf.inc @@ -19,3 +19,11 @@ DEFINE FD_SIZE =3D 0x400000 #Set Sec base address and size in flash DEFINE SECFV_OFFSET =3D 0x00000000 DEFINE SECFV_SIZE =3D 0x00010000 + +#Set Pei base address and size in flash +DEFINE PEIFV_OFFSET =3D 0x00010000 +DEFINE PEIFV_SIZE =3D 0x00040000 + +#Set Dxe base address and size in flash +DEFINE DXEFV_OFFSET =3D 0x00050000 +DEFINE DXEFV_SIZE =3D 0x00350000 --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96461): https://edk2.groups.io/g/devel/message/96461 Mute This Topic: https://groups.io/mt/95082600/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Dec 21 12:50:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96460+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96460+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1668652817; cv=none; d=zohomail.com; s=zohoarc; b=Scab7qyQ+nGnlZgNMGVUgxhLVD6ajR9KETxq768wUXdusd27P2Y1TQ9RcP74kcFk8mbaLYQTYxSp8XJgceb/TNmBp2NWYypT82NvI9eBeTkE0smbwpzjKyVVPbv1P3JJtgXx4Tbd1g5igZkPRd2sffgTAapz0n4GysCPHr0mLlE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668652817; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=k3p2eDQUmN26nvz0kyNpcJqCg/sPdshyqIMWjF8bfWI=; b=bzJFW4JWeMN7GJlQdRdcLBBsflfHH8FPT+VuwU3WSn2x4tMU5HX9jztAU8Qoc951xIYlvvvDa2vlS3RyUpqSMzk8gVleadksTfP1KIiMVvVMq1Zf92GSuhtGOmpEwrcibMexqTPnf7G3m4mbhhaIaT7XmR+4UXJaXbRnHacnzXI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96460+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668652817828117.14966799095077; Wed, 16 Nov 2022 18:40:17 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id pm4AYY1788612xUkVvHFjyH8; Wed, 16 Nov 2022 18:40:15 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.6226.1668652809210133884 for ; Wed, 16 Nov 2022 18:40:09 -0800 X-Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxfbYHn3VjQyQIAA--.11795S3; Thu, 17 Nov 2022 10:40:07 +0800 (CST) X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S18; Thu, 17 Nov 2022 10:40:06 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-devel] [edk2-platforms][PATCH V6 16/16] Platform/Loongson: Add Readme. Date: Thu, 17 Nov 2022 10:39:42 +0800 Message-Id: <9e8ca74f63df87170d65b82bbcb11964d4e2147a.1668652102.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S18 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxAr17GFWxJr47KFW7uF1DGFg_yoWrtF1kpF 13Z3WfKr18Jr1jv390k3y8u3yUZrn5Cr97JrWkAr4Uuas8XryDZa9Fya1FyanrA340q3Wq kry0kw4jkF1UuaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bexFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4 AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF 7I0E14v26r4UJVWxJr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lixianglai@loongson.cn X-Gm-Message-State: t58gOnaOz8uualIIQpKN8Lcjx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668652815; bh=I8Y1AQGxkuwQfBjmEI9sw0/DmEXT6VHlKN+40UXYZjw=; h=Cc:Date:From:Reply-To:Subject:To; b=Sxgqc6bJqTbr909pq2BNYJuaMFg9ISIxPN1NMOkm2Nlfv2iQ40wr421/wvmHDGp0U+C Mgb5hb61rIXWWw/7PYQq0aO7GOnqWO0EVztp0xVruQYagqB2nZMok3+xy5qFcHrir3imP eLSkBC5tOYyinDN2uOxuZIonMpusqkuEbpA= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668652819903100015 Content-Type: text/plain; charset="utf-8" Add Readme for LoogArch and Modify the Readme in the root directory. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao Li --- Platform/Loongson/LoongArchQemuPkg/Readme.md | 60 ++++++++++++++++++++ Readme.md | 9 +++ 2 files changed, 69 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Readme.md diff --git a/Platform/Loongson/LoongArchQemuPkg/Readme.md b/Platform/Loongs= on/LoongArchQemuPkg/Readme.md new file mode 100644 index 0000000000..7b11905f14 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Readme.md @@ -0,0 +1,60 @@ +# Introduction + + This document provides the guideline to build UEFI firmware for Qemu of = LoongArch. + + LoongArch is the general processor architecture of Loongson. + + We can get the latest LoongArch documents or LoongArch tools at https://= github.com/loongson/. + +# How to build (X86 Linux Environment) + + 1. Install LoongArch cross-tools on X86 machines. + Download cross-tools from https://github.com/loongson/build-tools ,The= n config cross-tools env. + For Example: + + $ wget https://github.com/loongson/build-tools/releases/download/2022.= 09.06/loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz + $ tar -vxf loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz -C /opt + $ export PATH=3D/opt/cross-tools/bin:$PATH + + Note: Please obtain the latest cross-compilation tools from https://gi= thub.com/loongson/build-tools . + + 2. Follow edk2-platforms/Readme.md to obtaining source code,And config b= uild env. + For Example: + + $ export WORKSPACE=3D/work/git/tianocore + $ mkdir -p $WORKSPACE + $ cd $WORKSPACE + $ git clone https://github.com/tianocore/edk2.git + $ git submodule update --init + $ git clone https://github.com/tianocore/edk2-platforms.git + $ git submodule update --init + $ git clone https://github.com/tianocore/edk2-non-osi.git + $ export PACKAGES_PATH=3D$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-o= si + + 3. Config cross compiler prefix. + For Example: + + $ export GCC5_LOONGARCH64_PREFIX=3Dloongarch64-unknown-linux-gnu- + + 4.Set up the build environment And build BaseTool. + For Example: + + $. edk2/edksetup.sh + $make -C edk2/BaseTools + + 5.Build platform. + For Exmaple: + + $build --buildtarget=3DDEBUG --tagname=3DGCC5 --arch=3DLOONGARCH64 --= platform=3DPlatform/Loongson/LoongArchQemuPkg/Loongson.dsc + + After a successful build, the resulting images can be found in `Build/{P= latform Name}/{TARGET}_{TOOL_CHAIN_TAG}/FV/QEMU_EFI.fd`. + + A compile script is provided here: + + #!/bin/bash + export WORKSPACE=3D/work/git/tianocore + export PACKAGES_PATH=3D$WORKSPACE/edk2:$WORKSPACE/edk2-platforms + export GCC5_LOONGARCH64_PREFIX=3Dloongarch64-unknown-linux-gnu- + . edk2/edksetup.sh + make -C edk2/BaseTools + build --buildtarget=3DDEBUG --tagname=3DGCC5 --arch=3DLOONGARCH64 --p= latform=3DPlatform/Loongson/LoongArchQemuPkg/Loongson.dsc diff --git a/Readme.md b/Readme.md index 62876b4b7d..93e4dc5255 100644 --- a/Readme.md +++ b/Readme.md @@ -57,6 +57,7 @@ IA32 | i?86-linux-gnu-* _or_ x86_64-linux-= gnu- IPF | ia64-linux-gnu X64 | x86_64-linux-gnu- RISCV64 | riscv64-unknown-elf- +LOONGARCH64 | loongarch64-unknown-linux- =20 \* i386, i486, i586 or i686 =20 @@ -71,6 +72,11 @@ RISC-V open source community provides GCC toolchains for [riscv64-unknown-elf](https://github.com/riscv/riscv-gnu-toolchain) compiled to run on x86 Linux. =20 +### GCC for LoongArch +Loonson open source community provides GCC toolchains for +[loongarch64-unknown-elf](https://github.com/loongson/build-tools) +compiled to run on x86 Linux + ### clang Clang does not require separate cross compilers, but it does need a target-specific binutils. These are included with any prepackaged GCC tool= chain @@ -257,6 +263,9 @@ For more information, see the ##### Minnowboard Max/Turbot based on Intel Valleyview2 SoC * [Minnowboard Max](Platform/Intel/Vlv2TbltDevicePkg) =20 +## Loongson +* [LoongArchQemu](Platform/Loongson/LoongArchQemuPkg) + ## Marvell * [Armada 70x0](Platform/Marvell/Armada70x0Db) * [Armada 80x0](Platform/Marvell/Armada80x0Db) --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96460): https://edk2.groups.io/g/devel/message/96460 Mute This Topic: https://groups.io/mt/95082599/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-