1 /** @file
2 
3   Copyright (c) 2017-2018, Arm Limited. All rights reserved.
4 
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7   System Control and Management Interface V1.0
8     http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
9     DEN0056A_System_Control_and_Management_Interface.pdf
10 **/
11 
12 #ifndef ARM_MTL_LIB_H_
13 #define ARM_MTL_LIB_H_
14 
15 #include <Uefi/UefiBaseType.h>
16 
17 // Ideally we don't need packed struct. However we can't rely on compilers.
18 #pragma pack(1)
19 
20 typedef struct {
21   UINT32 Reserved1;
22   UINT32 ChannelStatus;
23   UINT64 Reserved2;
24   UINT32 Flags;
25   UINT32 Length;
26   UINT32 MessageHeader;
27 
28   // NOTE: Since EDK2 does not allow flexible array member [] we declare
29   // here array of 1 element length. However below is used as a variable
30   // length array.
31   UINT32 Payload[1];    // size less object gives offset to payload.
32 } MTL_MAILBOX;
33 
34 #pragma pack()
35 
36 // Channel Type, Low-priority, and High-priority
37 typedef enum {
38   MTL_CHANNEL_TYPE_LOW = 0,
39   MTL_CHANNEL_TYPE_HIGH = 1
40 } MTL_CHANNEL_TYPE;
41 
42 typedef struct {
43   UINT64 PhysicalAddress;
44   UINT32 ModifyMask;
45   UINT32 PreserveMask;
46 } MTL_DOORBELL;
47 
48 typedef struct {
49   MTL_CHANNEL_TYPE ChannelType;
50   MTL_MAILBOX      * CONST MailBox;
51   MTL_DOORBELL     DoorBell;
52 } MTL_CHANNEL;
53 
54 /** Wait until channel is free.
55 
56   @param[in] Channel                Pointer to a channel.
57   @param[in] TimeOutInMicroSeconds  Time out in micro seconds.
58 
59   @retval EFI_SUCCESS               Channel is free.
60   @retval EFI_TIMEOUT               Time out error.
61 **/
62 EFI_STATUS
63 MtlWaitUntilChannelFree (
64   IN MTL_CHANNEL  *Channel,
65   IN UINTN        TimeOutInMicroSeconds
66   );
67 
68 /** Return the address of the message payload.
69 
70   @param[in] Channel   Pointer to a channel.
71 
72   @retval UINT32*      Pointer to the payload.
73 **/
74 UINT32*
75 MtlGetChannelPayload (
76   IN MTL_CHANNEL  *Channel
77   );
78 
79 /** Return pointer to a channel for the requested channel type.
80 
81   @param[in] ChannelType        ChannelType, Low or High priority channel.
82                                 MTL_CHANNEL_TYPE_LOW or
83                                 MTL_CHANNEL_TYPE_HIGH
84 
85   @param[out] Channel           Holds pointer to the channel.
86 
87   @retval EFI_SUCCESS           Pointer to channel is returned.
88   @retval EFI_UNSUPPORTED       Requested channel type not supported.
89 **/
90 EFI_STATUS
91 MtlGetChannel (
92   IN  MTL_CHANNEL_TYPE  ChannelType,
93   OUT MTL_CHANNEL       **Channel
94   );
95 
96 /** Mark the channel busy and ring the doorbell.
97 
98   @param[in] Channel               Pointer to a channel.
99   @param[in] MessageHeader         Message header.
100 
101   @param[out] PayloadLength        Message length.
102 
103   @retval EFI_SUCCESS              Message sent successfully.
104   @retval EFI_DEVICE_ERROR         Channel is busy.
105 **/
106 EFI_STATUS
107 MtlSendMessage (
108   IN  MTL_CHANNEL  *Channel,
109   IN  UINT32       MessageHeader,
110   OUT UINT32       PayloadLength
111   );
112 
113 /** Wait for a response on a channel.
114 
115   If channel is free after sending message, it implies SCP responded
116   with a response on the channel.
117 
118   @param[in] Channel               Pointer to a channel.
119 
120   @retval EFI_SUCCESS              Message received successfully.
121   @retval EFI_TIMEOUT              Time out error.
122 **/
123 EFI_STATUS
124 MtlReceiveMessage (
125   IN  MTL_CHANNEL  *Channel,
126   OUT UINT32       *MessageHeader,
127   OUT UINT32       *PayloadLength
128   );
129 
130 #endif  /* ARM_MTL_LIB_H_ */
131 
132