1/** @addtogroup FCI
2 * @{
3 * @file
4 * Declaration of FastCall helper functions.
5 *
6 * @attention Helper functions are mostly RealView (ARM CC) specific.
7 *
8 * Holds the functions for SIQ, YIELD and FastCall for switching to the secure world.
9 * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote
20 *    products derived from this software without specific prior
21 *    written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
24 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef MCIFCFUNC_H_
37#define MCIFCFUNC_H_
38
39#include "mcifc.h"
40/**
41 * Execute a secure monitor call (SMC).
42 *
43 * @param mode SMC mode affects the way SMC is handled
44 *
45 * @attention This function shall not be used directly. Use N_Siq() or Yield() instead.
46 */
47__smc(0) void smc(int32_t mode);
48
49/**
50 * N-SIQ switch from NWd to SWd.
51 * Execution will continue in the SWd. The notification queue will be drained by the MC4 and MC4 system schedules its services.
52 */
53inline void N_Siq(void) { smc(MC_SMC_N_SIQ); }
54
55/**
56 * Yield switch from NWd to SWd.
57 * Execution will continue in the SWd without scheduling MC4 services.
58 */
59inline void Yield(void) { smc(MC_SMC_N_YIELD); }
60
61/** Wrapper structure for parameter passing in registers.
62 *  This structure is used as a "wrapper" return value for functions that
63 *  return data in the registers r0 to r3. With the RealView compiler such
64 *  function are declare as:  _value_in_regs reg_r0_r1_r2_r3_t foo()
65
66 */
67typedef struct {
68    uint32_t r0;
69    uint32_t r1;
70    uint32_t r2;
71    uint32_t r3;
72} reg_r0_r1_r2_r3_t;
73
74/** Parameterized SMC for FastCalls.
75 * @attention This function shall not be used directly.
76 */
77__smc(0) __value_in_regs  reg_r0_r1_r2_r3_t smcFc(
78        uint32_t r0,
79        uint32_t r1,
80        uint32_t r2,
81        uint32_t r3
82);
83
84/** FastCall helper function.
85 * @attention This function shall not be used directly.
86 */
87inline static __value_in_regs reg_r0_r1_r2_r3_t fastCall(
88        uint32_t r0,
89        uint32_t r1,
90        uint32_t r2,
91        uint32_t r3
92) {
93    return smcFc(r0,r1,r2,r3);
94}
95
96/**
97 * Initialize the MobiCore.
98 * The FcMc4init FastCall shall be used to set up the MCI. The function passes the message buffers used in the MCI to the MC4 system.
99 * As long as the buffers are not set up the MC4 message passing mechanisms (notifications, MCP commands) are not available.
100 * NQ buffer and MCP buffer as well as length calculations are described in the "MobiCore4 Driver Interface Specification".
101 * <br> The fastCallInit() will not check the parameters for validity. Instead the MC4 will perform a check on first usage of the parameters.
102 *
103 * @image html DoxyMciBuffer.png "MCI buffer"
104 * @image latex DoxyMciBuffer.png "MCI buffer" width=12cm
105 *
106 * @param base      Physical start address of the MCI buffer. Must be 4kB aligned.
107 * @param nqOffset  Offset in bytes  to the beginning of the NQ buffer.
108 * @param nqLength  Length of the NQ buffer in bytes.
109 * @param mcpOffset Offset in bytes to the beginning of the MCP buffer.
110 * @param mcpLength Length of the MCP buffer in bytes
111 *
112 */
113inline static uint32_t fastCallInit(
114        uint8_t *base,
115        uint32_t  nqOffset,
116        uint32_t  nqLength,
117        uint32_t  mcpOffset,
118        uint32_t  mcpLength
119) {
120
121    reg_r0_r1_r2_r3_t ret;
122
123    ret = fastCall(
124            MC_FC_INIT,
125            (uint32_t)base,
126            ((nqOffset << 16) | (nqLength & 0xFFFF)),
127            ((mcpOffset << 16) | (mcpLength & 0xFFFF)) );
128
129
130    return ret.r1;
131}
132
133
134/** Get status information about MobiCore.
135 * The FcMcGetInfo FastCall provides information about the current state of the MobiCore.
136 * In certain states extended information is provided.
137 *
138 * @param extInfoId Extended info word to be obtained.
139 * @param mc4state Current state of the MobiCore.
140 * @param extInfo Extended information depending on state.
141 */
142inline static uint32_t fastCallGetInfo(
143        uint32_t extInfoId,
144        uint32_t *mc4state,
145        uint32_t *extInfo
146) {
147    reg_r0_r1_r2_r3_t ret;
148
149    ret = fastCall(MC_FC_INFO,extInfoId,0,0);
150
151    if (MC_FC_RET_OK == ret.r1)
152    {
153        *mc4state = ret.r2;
154        *extInfo = ret.r3;
155    }
156
157    return ret.r1;
158}
159
160/**
161 * Power management.
162 * The power management FastCall is platform specific.
163 *
164 * @param param0  platform specific parameter.
165 * @param param1  platform specific parameter.
166 * @param param2  platform specific parameter.
167 */
168inline static uint32_t fastCallPower(
169        uint32_t param0,
170        uint32_t param1,
171        uint32_t param2
172) {
173
174    reg_r0_r1_r2_r3_t ret;
175
176    ret = fastCall(
177            MC_FC_POWER,
178            param0,
179            param1,
180            param2 );
181
182    return ret.r1;
183}
184
185#endif /* MCIFCFUNC_H_ */
186/**
187 * @}*/
188