Skip to content

Commit

Permalink
AmpereAltraPkg: Add TPM2 support
Browse files Browse the repository at this point in the history
In Ampere Altra, TPM is a secured device and can only be accessed
in S-EL0 secure partition. Upper layers like UEFI and Operating Systems
need the intermediate Secured Partition Manager (SPM) in Trusted
Firmware BL31 to establish a communication with the TPM device which is
physically connected to the Socket 0 SPI bus 1.

The communication interface, designed as TPM CRB buffer, is inline with
the TPM2.0 Mobile Command Response Buffer Interface specification.

This patch introduces TPM2 support for Ampere Altra Mt. Jade platform
based on edk2 implementation. Due to differences in platform design, the
TPM2 code has been forked from the edk2/SecurityPkg and adapted to meet
our specific requirements. The implementation focuses on meeting the
mandatory TPM2 functionality and does not include all TPM2 or PPI
features, limiting the scope to what is essential for Ampere platforms.
We may expand the implementation later if more features are needed.

Signed-off-by: Nhi Pham <[email protected]>
  • Loading branch information
nhivp committed Oct 11, 2024
1 parent 1a176da commit 6c76e93
Show file tree
Hide file tree
Showing 30 changed files with 7,979 additions and 2 deletions.
144 changes: 143 additions & 1 deletion Platform/Ampere/JadePkg/Ac02AcpiTables/CommonDevices.asi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @file

Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2023 - 2024, Ampere Computing LLC. All rights reserved.<BR>

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

Expand Down Expand Up @@ -521,6 +521,148 @@ Device(NVDR) {
}
}

Device(TPM0) {
Name (_HID, "NNNN0000")
Name (_CID, "MSFT0101")
Name (_UID, 0)
Name (CRBB, 0x10000000)
Name (CRBL, 0x10000000)

Name (RBUF, ResourceTemplate ()
{
Memory32Fixed (ReadWrite, 0x88500000, 0x1000, PCRE)
})

Method (_CRS, 0x0, Serialized) {

// Declare fields in PCRE
CreateDWordField(RBUF, ^PCRE._BAS, BASE)
CreateDWordField(RBUF, ^PCRE._LEN, LENG)

// Store Updatable values into them
Store(CRBB, BASE)
Store(CRBL, LENG)

Return (RBUF)
}

Method(_STR,0)
{
Return (Unicode ("TPM 2.0 Device"))
}

Method (_STA, 0)
{
if(TPMF)
{
Return (0x0f) //Enable resources
}
Return (0x0)
}

//
// Add opregions for doorbell and PPI CRB
// The addresses for these operation regions should be patched
// with information from HOB
//
OperationRegion (TPMD, SystemMemory, 0x100000542010, 0x04)
Field (TPMD, DWordAcc, NoLock, Preserve) {
DBB0, 32 // Doorbell out register
}

// PPI request CRB
OperationRegion (TPMC, SystemMemory, 0x88542038, 0x0C)
Field (TPMC, DWordAcc, NoLock, Preserve) {
PPIO, 32, // current PPI request
PPIR, 32, // last PPI request
PPIS, 32, // last PPI request status
}

// Create objects to hold return values
Name (PKG2, Package (2) { Zero, Zero })
Name (PKG3, Package (3) { Zero, Zero, Zero })

Method (_DSM, 0x4, Serialized) {
// Handle Physical Presence Interface(PPI) DSM method
If (LEqual (Arg0, ToUUID ("3DDDFAA6-361B-4eb4-A424-8D10089D1653"))) {
Switch (ToInteger (Arg2)) {
//
// Standard DSM query
//
Case (0) {
Return (Buffer () { 0xFF, 0x01 })
}

//
// Get Physical Presence Interface Version - support 1.3
//
Case (1) {
Return ("1.3")
}

//
// Submit TPM operation to pre-OS (Deprecated)
//
Case (2) {
Return (One) // Not supported
}

//
// Get pending TPM operation requested by OS
//
Case (3) {
PKG2[Zero] = Zero // Success
PKG2[One] = PPIO // current PPI request
Return (PKG2)
}

//
// Platform-specific action to transition to Pre-OS env
//
Case (4) {
Return (0x2) // Reboot
}

//
// TPM operation Response to OS
//
Case (5) {
PKG3[Zero] = Zero // Success
PKG3[One] = PPIR // last PPI request
PKG3[2] = PPIS // last PPI request status
Return (PKG3)
}

//
// Preferred language code (Deprecated)
//
Case (6) {
Return (0x3) // Not implemented
}

//
// Submit TPM operation to pre-OS env 2
//
Case (7) {
Local0 = DerefOf (Arg3 [Zero])
// Write current PPI request and then to the doorbell
Store (Local0, PPIO)
Store (0x6a000000, DBB0) // MsgType: 6, Handler: 0xa (TPM-PPI)
Return (Zero)
}

//
// Get User confirmation status for op
//
Case (8) {
Return (0x4) // Allowed and physically present user not required
}
}
}
Return (Buffer () {0})
}
}

//
// LED Device
Device(LED) {
Expand Down
3 changes: 2 additions & 1 deletion Platform/Ampere/JadePkg/Ac02AcpiTables/Dsdt.asl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @file
Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2023 - 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
Expand All @@ -10,6 +10,7 @@ DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
//
// Board Model
Name(\BDMD, "Altra Max Jade Board")
Name(TPMF, 0) // TPM presence
Name(AERF, 0) // PCIe AER Firmware-First

Include ("MHPP.asi")
Expand Down
146 changes: 146 additions & 0 deletions Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
// Board Model
Name(\BDMD, "Jade Board")
Name(AERF, 0) // PCIe AER Firmware-First
Name(TPMF, 0) // TPM presence

Include ("MHPP.asi")

Expand Down Expand Up @@ -1020,6 +1021,151 @@ DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
}
}

Device (TPM0) {
//
// TPM 2.0
//

//
// TAG for patching TPM2.0 _HID
//
Name (_HID, "NNNN0000")
Name (_CID, "MSFT0101")
Name (_UID, 0)

Name (CRBB, 0x10000000)
Name (CRBL, 0x10000000)

Name (RBUF, ResourceTemplate () {
Memory32Fixed (ReadWrite, 0x88500000, 0x1000, PCRE)
})

Method (_CRS, 0x0, Serialized) {
// Declare fields in PCRE
CreateDWordField(RBUF, ^PCRE._BAS, BASE)
CreateDWordField(RBUF, ^PCRE._LEN, LENG)

// Store updatable values into them
Store(CRBB, BASE)
Store(CRBL, LENG)

Return (RBUF)
}

Method (_STR,0) {
Return (Unicode ("TPM 2.0 Device"))
}

Method (_STA, 0) {
if (TPMF) {
Return (0x0f) //Enable resources
}
Return (0x0)
}

//
// Add opregions for doorbell and PPI CRB
// The addresses for these operation regions should be patched
// with information from HOB
//
OperationRegion (TPMD, SystemMemory, 0x100000542010, 0x04)
Field (TPMD, DWordAcc, NoLock, Preserve) {
DBB0, 32 // Doorbell out register
}

// PPI request CRB
OperationRegion (TPMC, SystemMemory, 0x88542038, 0x0C)
Field (TPMC, DWordAcc, NoLock, Preserve) {
PPIO, 32, // current PPI request
PPIR, 32, // last PPI request
PPIS, 32, // last PPI request status
}

// Create objects to hold return values
Name (PKG2, Package (2) { Zero, Zero })
Name (PKG3, Package (3) { Zero, Zero, Zero })

Method (_DSM, 0x4, Serialized) {
// Handle Physical Presence Interface(PPI) DSM method
If (LEqual (Arg0, ToUUID ("3DDDFAA6-361B-4eb4-A424-8D10089D1653"))) {
Switch (ToInteger (Arg2)) {
//
// Standard DSM query
//
Case (0) {
Return (Buffer () { 0xFF, 0x01 })
}

//
// Get Physical Presence Interface Version - support 1.3
//
Case (1) {
Return ("1.3")
}

//
// Submit TPM operation to pre-OS (Deprecated)
//
Case (2) {
Return (One) // Not supported
}

//
// Get pending TPM operation requested by OS
//
Case (3) {
PKG2[Zero] = Zero // Success
PKG2[One] = PPIO // current PPI request
Return (PKG2)
}

//
// Platform-specific action to transition to Pre-OS env
//
Case (4) {
Return (0x2) // Reboot
}

//
// TPM operation Response to OS
//
Case (5) {
PKG3[Zero] = Zero // Success
PKG3[One] = PPIR // last PPI request
PKG3[2] = PPIS // last PPI request status
Return (PKG3)
}

//
// Preferred language code (Deprecated)
//
Case (6) {
Return (0x3) // Not implemented
}

//
// Submit TPM operation to pre-OS env 2
//
Case (7) {
Local0 = DerefOf (Arg3 [Zero])
// Write current PPI request and then to the doorbell
Store (Local0, PPIO)
Store (0x6a000000, DBB0) // MsgType: 6, Handler: 0xa (TPM-PPI)
Return (Zero)
}

//
// Get User confirmation status for op
//
Case (8) {
Return (0x4) // Allowed and physically present user not required
}
}
}
Return (Buffer () {0})
}
}

//
// LED Device
//
Expand Down
1 change: 1 addition & 0 deletions Platform/Ampere/JadePkg/Jade.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
DEFINE FIRMWARE_VER = 0.01.001
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE TPM2_ENABLE = TRUE
DEFINE INCLUDE_TFTP_COMMAND = TRUE
DEFINE PLATFORM_CONFIG_UUID = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5

Expand Down
12 changes: 12 additions & 0 deletions Platform/Ampere/JadePkg/Jade.fdf
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ APRIORI PEI {
}
}

!if $(TPM2_ENABLE) == TRUE
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
INF Silicon/Ampere/AmpereAltraPkg/Drivers/Tcg2Pei/Tcg2Pei.inf
!endif

[FV.FvMain]
FvAlignment = 16
ERASE_POLARITY = 1
Expand Down Expand Up @@ -340,6 +345,13 @@ APRIORI DXE {
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
!endif

!if $(TPM2_ENABLE) == TRUE
INF Silicon/Ampere/AmpereAltraPkg/Drivers/Tcg2Dxe/Tcg2Dxe.inf
INF Silicon/Ampere/AmpereAltraPkg/Drivers/Tcg2Config/Tcg2ConfigDxe.inf
INF Silicon/Ampere/AmpereAltraPkg/Drivers/Tcg2AcpiDxe/Tcg2AcpiDxe.inf
INF MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf
!endif

#
# Bds
#
Expand Down
Loading

0 comments on commit 6c76e93

Please sign in to comment.