forked from tianocore/edk2-platforms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM/JunoPkg: Adding SCMI MTL library
This change adds a new Mailbox Transport Layer library for the Juno platform. This library is required for ArmScmiDxe driver communication with the SCP. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Girish Pathak <[email protected]> Reviewed-by: Leif Lindholm <[email protected]>
- Loading branch information
1 parent
adf5023
commit b3b892d
Showing
6 changed files
with
349 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 198 additions & 0 deletions
198
Platform/ARM/JunoPkg/Library/ArmJunoMtlLib/ArmJunoMtlLib.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
/** @file | ||
Copyright (c) 2017-2018, Arm Limited. All rights reserved. | ||
This program and the accompanying materials | ||
are licensed and made available under the terms and conditions of the BSD License | ||
which accompanies this distribution. The full text of the license may be found at | ||
http://opensource.org/licenses/bsd-license.php | ||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | ||
System Control and Management Interface V1.0 | ||
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ | ||
DEN0056A_System_Control_and_Management_Interface.pdf | ||
**/ | ||
|
||
#include <Uefi/UefiBaseType.h> | ||
#include <Uefi/UefiSpec.h> | ||
#include <Library/ArmLib.h> | ||
#include <Library/ArmMtlLib.h> | ||
#include <Library/DebugLib.h> | ||
#include <Library/IoLib.h> | ||
#include <Library/MemoryAllocationLib.h> | ||
#include <Library/PcdLib.h> | ||
#include <Library/UefiBootServicesTableLib.h> | ||
|
||
#include "ArmJunoMtlPrivateLib.h" | ||
|
||
// Each channel has a shared mailbox and a doorbell register. | ||
STATIC CONST MTL_CHANNEL Channels[NUM_CHANNELS] = { | ||
// Low priority channel. | ||
{ | ||
MTL_CHANNEL_TYPE_LOW, | ||
(MTL_MAILBOX*)(MTL_MAILBOX_BASE), | ||
DOORBELL_LOW | ||
}, | ||
// High priority channel | ||
{ | ||
MTL_CHANNEL_TYPE_HIGH, | ||
(MTL_MAILBOX*)(MTL_MAILBOX_BASE + MTL_MAILBOX_HIGH_PRIORITY_OFFSET), | ||
DOORBELL_HIGH | ||
} | ||
}; | ||
|
||
/** Wait until channel is free. | ||
@param[in] Channel Pointer to a channel. | ||
@param[in] TimeOutInMicroSeconds Time out in micro seconds. | ||
@retval EFI_SUCCESS Channel is free. | ||
@retval EFI_TIMEOUT Time out error. | ||
**/ | ||
EFI_STATUS | ||
MtlWaitUntilChannelFree ( | ||
IN MTL_CHANNEL *Channel, | ||
IN UINTN TimeOutInMicroSeconds | ||
) | ||
{ | ||
while (TimeOutInMicroSeconds != 0) { | ||
// If channel is free then we have received the reply. | ||
if (Channel->MailBox->ChannelStatus == MTL_CHANNEL_FREE) { | ||
return EFI_SUCCESS; | ||
} | ||
if (TimeOutInMicroSeconds < MTL_POLL_WAIT_TIME) { | ||
gBS->Stall (TimeOutInMicroSeconds); | ||
break; | ||
} | ||
// Wait for some arbitrary time. | ||
gBS->Stall (MTL_POLL_WAIT_TIME); | ||
TimeOutInMicroSeconds -= MTL_POLL_WAIT_TIME; | ||
} | ||
|
||
// No response from SCP. | ||
if (Channel->MailBox->ChannelStatus != MTL_CHANNEL_FREE) { | ||
ASSERT (FALSE); | ||
return EFI_TIMEOUT; | ||
} | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
/** Return the address of the message payload. | ||
@param[in] Channel Pointer to a channel. | ||
@retval UINT32* Pointer to the payload. | ||
**/ | ||
UINT32* | ||
MtlGetChannelPayload ( | ||
IN MTL_CHANNEL *Channel | ||
) | ||
{ | ||
return Channel->MailBox->Payload; | ||
} | ||
|
||
/** Return pointer to a channel for the requested channel type. | ||
@param[in] ChannelType ChannelType, Low or High priority channel. | ||
MTL_CHANNEL_TYPE_LOW or | ||
MTL_CHANNEL_TYPE_HIGH | ||
@param[out] Channel Holds pointer to the channel. | ||
@retval EFI_SUCCESS Pointer to channel is returned. | ||
@retval EFI_UNSUPPORTED Requested channel type not supported. | ||
**/ | ||
EFI_STATUS | ||
MtlGetChannel ( | ||
IN MTL_CHANNEL_TYPE ChannelType, | ||
OUT MTL_CHANNEL **Channel | ||
) | ||
{ | ||
if (ChannelType != MTL_CHANNEL_TYPE_LOW | ||
&& ChannelType != MTL_CHANNEL_TYPE_HIGH) { | ||
return EFI_UNSUPPORTED; | ||
} | ||
|
||
*Channel = (MTL_CHANNEL*)&Channels[ChannelType]; | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
/** Mark the channel busy and ring the doorbell. | ||
@param[in] Channel Pointer to a channel. | ||
@param[in] MessageHeader Message header. | ||
@param[out] PayloadLength Message length. | ||
@retval EFI_SUCCESS Message sent successfully. | ||
@retval EFI_DEVICE_ERROR Channel is busy. | ||
**/ | ||
EFI_STATUS | ||
MtlSendMessage ( | ||
IN MTL_CHANNEL *Channel, | ||
IN UINT32 MessageHeader, | ||
OUT UINT32 PayloadLength | ||
) | ||
{ | ||
MTL_MAILBOX *MailBox = Channel->MailBox; | ||
|
||
if (Channel->MailBox->ChannelStatus != MTL_CHANNEL_FREE) { | ||
return EFI_DEVICE_ERROR; | ||
} | ||
|
||
// Mark the channel busy before ringing doorbell. | ||
Channel->MailBox->ChannelStatus = MTL_CHANNEL_BUSY; | ||
ArmDataSynchronizationBarrier (); | ||
|
||
MailBox->Flags = MTL_POLL; | ||
MailBox->MessageHeader = MessageHeader; | ||
|
||
// Add length of message header. | ||
MailBox->Length = PayloadLength + sizeof (MessageHeader); | ||
|
||
// Ring the doorbell. It sets SET bit of the MHU register. | ||
MmioWrite32 ( | ||
Channel->DoorBell.PhysicalAddress, | ||
Channel->DoorBell.ModifyMask | ||
); | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
/** Wait for a response on a channel. | ||
If channel is free after sending message, it implies SCP responded | ||
with a response on the channel. | ||
@param[in] Channel Pointer to a channel. | ||
@retval EFI_SUCCESS Message received successfully. | ||
@retval EFI_TIMEOUT Time out error. | ||
**/ | ||
EFI_STATUS | ||
MtlReceiveMessage ( | ||
IN MTL_CHANNEL *Channel, | ||
OUT UINT32 *MessageHeader, | ||
OUT UINT32 *PayloadLength | ||
) | ||
{ | ||
EFI_STATUS Status; | ||
|
||
MTL_MAILBOX *MailBox = Channel->MailBox; | ||
|
||
Status = MtlWaitUntilChannelFree (Channel, RESPONSE_TIMEOUT); | ||
if (EFI_ERROR (Status)) { | ||
return Status; | ||
} | ||
|
||
*MessageHeader = MailBox->MessageHeader; | ||
|
||
// Deduct message header length. | ||
*PayloadLength = MailBox->Length - sizeof (*MessageHeader); | ||
|
||
return EFI_SUCCESS; | ||
} |
39 changes: 39 additions & 0 deletions
39
Platform/ARM/JunoPkg/Library/ArmJunoMtlLib/ArmJunoMtlLib.inf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#/** @file | ||
# Copyright (c) 2017-2018, Arm Limited. All rights reserved. | ||
# | ||
# This program and the accompanying materials | ||
# are licensed and made available under the terms and conditions of the BSD License | ||
# which accompanies this distribution. The full text of the license may be found at | ||
# http://opensource.org/licenses/bsd-license.php | ||
# | ||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | ||
#**/ | ||
|
||
[Defines] | ||
INF_VERSION = 0x00010019 | ||
BASE_NAME = ArmJunoMtlLib | ||
FILE_GUID = 21FB2D8F-C6C8-4B2C-A616-A30CB2FBA277 | ||
MODULE_TYPE = BASE | ||
VERSION_STRING = 1.0 | ||
LIBRARY_CLASS = ArmMtlLib | ||
|
||
[Sources.common] | ||
ArmJunoMtlLib.c | ||
|
||
[Packages] | ||
ArmPkg/ArmPkg.dec | ||
ArmPlatformPkg/ArmPlatformPkg.dec | ||
MdePkg/MdePkg.dec | ||
Platform/ARM/JunoPkg/ArmJuno.dec | ||
|
||
[LibraryClasses] | ||
ArmLib | ||
DebugLib | ||
IoLib | ||
UefiBootServicesTableLib | ||
|
||
[FixedPcd.common] | ||
gArmJunoTokenSpaceGuid.PcdArmMtlDoorBell | ||
gArmJunoTokenSpaceGuid.PcdArmMtlMailBoxBase | ||
gArmJunoTokenSpaceGuid.PcdArmMtlMailBoxSize |
94 changes: 94 additions & 0 deletions
94
Platform/ARM/JunoPkg/Library/ArmJunoMtlLib/ArmJunoMtlPrivateLib.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** @file | ||
Copyright (c) 2017-2018, Arm Limited. All rights reserved. | ||
This program and the accompanying materials | ||
are licensed and made available under the terms and conditions of the BSD License | ||
which accompanies this distribution. The full text of the license may be found at | ||
http://opensource.org/licenses/bsd-license.php | ||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | ||
System Control and Management Interface V1.0 | ||
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ | ||
DEN0056A_System_Control_and_Management_Interface.pdf | ||
Juno ARM Development Platform SoC | ||
https://www.arm.com/files/pdf/ | ||
DDI0515D1a_juno_arm_development_platform_soc_trm.pdf | ||
**/ | ||
|
||
#ifndef ARM_JUNO_MTL_PRIVATE_LIB_H_ | ||
#define ARM_JUNO_MTL_PRIVATE_LIB_H_ | ||
|
||
// Mailbox transport layer. | ||
#define MTL_DOORBELL_MODIFY_MASK (0x00000001U) | ||
#define MTL_DOORBELL_PRESERVE_MASK (~MTL_DOORBELL_MODIFY_MASK) | ||
|
||
#define MTL_DOORBELL_BASE (FixedPcdGet64 (PcdArmMtlDoorBell)) | ||
#define MTL_MAILBOX_BASE (FixedPcdGet64 (PcdArmMtlMailBoxBase)) | ||
#define MTL_MAILBOX_SIZE (FixedPcdGet32 (PcdArmMtlMailBoxSize)) | ||
|
||
#define MTL_POLL 0 | ||
#define MTL_INTR 1 | ||
|
||
/* For Juno, the mailbox for high priority is non-trusted SRAM + 256. | ||
NOTE: Below is not documented anywhere (yet) | ||
The payload sizes are 128 bytes. | ||
There are two channels: | ||
Channel 0 | ||
- Agent (OS) to Platform (SCP) memory base: non-trusted SRAM + 0 | ||
- Platform (SCP) to Agent (OS) memory base: non-trusted SRAM + 128 | ||
- Doorbell (both directions): MHU, bit 0 | ||
Channel 1 | ||
- Agent (OS) to Platform (SCP) memory base: non-trusted SRAM + 256 | ||
- Platform (SCP) to Agent (OS) memory base: non-trusted SRAM + 384 | ||
- Doorbell (both directions): MHU, bit 0 | ||
*/ | ||
#define MTL_MAILBOX_HIGH_PRIORITY_OFFSET (MTL_MAILBOX_SIZE * 2) | ||
|
||
// ARM MHU interrupt registers. | ||
#define CPU_INTR_L_SET 0x108 | ||
#define CPU_INTR_H_SET 0x128 | ||
|
||
// MTL uses MHU interrupt registers for communication with the SCP. | ||
#define MTL_DOORBELL_REGISTER_LOW (MTL_DOORBELL_BASE + CPU_INTR_L_SET) | ||
#define MTL_DOORBELL_REGISTER_HIGH (MTL_DOORBELL_BASE + CPU_INTR_H_SET) | ||
|
||
#define MTL_CHANNEL_BUSY 0 | ||
#define MTL_CHANNEL_FREE 1 | ||
|
||
// Response time out value on a MHU channel 20ms. | ||
#define RESPONSE_TIMEOUT 20000 | ||
|
||
/* As per SCMI spec. as a agent UEFI(or OS) can access only two channels | ||
(low or high priority) secure channel is only accessible | ||
to ARM Trusted firmware. */ | ||
#define NUM_CHANNELS 2 | ||
|
||
/* Each channel must use a doorbell register to interrupt the SCP firmware. | ||
on Juno these are MHU interrupt registers for low and high priority | ||
channels. */ | ||
#define DOORBELL_LOW { \ | ||
MTL_DOORBELL_REGISTER_LOW, \ | ||
MTL_DOORBELL_MODIFY_MASK, \ | ||
MTL_DOORBELL_PRESERVE_MASK \ | ||
} | ||
|
||
#define DOORBELL_HIGH { \ | ||
MTL_DOORBELL_REGISTER_HIGH, \ | ||
MTL_DOORBELL_MODIFY_MASK, \ | ||
MTL_DOORBELL_PRESERVE_MASK \ | ||
} | ||
|
||
// Arbitarary poll time. | ||
#define MTL_POLL_WAIT_TIME 100 | ||
|
||
#endif /* ARM_JUNO_MTL_PRIVATE_LIB_H_ */ | ||
|