aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c
blob: da6f6f3400594ca912111f5bb985169a604c071c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

/**
 * @file    SAMA5D2x/sama_matrix.c
 * @brief   SAMA MATRIX support code.
 *
 * @addtogroup SAMA5D2x_MATRIX
 * @{
 */

#include "hal.h"

/*===========================================================================*/
/* Driver local definitions.                                                 */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported variables.                                                */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local types.                                                       */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local variables.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver constant                                                           */
/*===========================================================================*/
#define SCFG_OFFSET                         0x40u

/*===========================================================================*/
/* Driver local macros.                                                      */
/*===========================================================================*/
#define MATRIX_SCFG(value)                  (MATRIX_SCFG0 + (value * 4u))
#define MATRIX_SCFG_FIXED_DEFMSTR(value)    MATRIX_SCFG0_FIXED_DEFMSTR(value)
#define MATRIX_SCFG_DEFMSTR_TYPE(value)     MATRIX_SCFG0_DEFMSTR_TYPE(value)

/**
 * @brief   Enable write protection on MATRIX registers block.
 *
 * @param[in] mtxp       pointer to a MATRIX register block.
 *
 * @notapi
 */
#define mtxEnableWP(mtxp) {                                                \
  mtxp->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD | MATRIX_WPMR_WPEN;         \
}

/**
 * @brief   Disable write protection on MATRIX registers block.
 *
 * @param[in] matxp      pointer to a MATRIX register block.
 *
 * @notapi
 */
#define mtxDisableWP(mtxp) {                                               \
  mtxp->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD;                            \
}

/*===========================================================================*/
/* Driver exported functions.                                                */
/*===========================================================================*/
/**
 * @brief   Configures peripheral security
 *
 * @param[in] mtxp      pointer to a MATRIX register block.
 * @param[in] id        PERIPHERAL_ID.
 * @param[in] mode      SECURE_PER or NOT_SECURE_PER.
 *
 * @retval true         Peripheral is not secured.
 * @retval false        Peripheral is secured.
 *
 */
bool mtxConfigPeriphSecurity(Matrix *mtxp, uint32_t id, bool mode) {

  uint32_t mask;
  if (id < 74) {
    mask = id & 0x1F;
  }
  else {
    mask = (id & 0x1F) - 1;
  }
  mtxDisableWP(mtxp);
  if (mode) {
    mtxp->MATRIX_SPSELR[id / 32] |= (MATRIX_SPSELR_NSECP0 << mask);
  }
  else {
    mtxp->MATRIX_SPSELR[id / 32] &= ~(MATRIX_SPSELR_NSECP0 << mask);
  }
  mtxEnableWP(mtxp);

  return (MATRIX0->MATRIX_SPSELR[id / 32] & (MATRIX_SPSELR_NSECP0 << mask)) &
         (MATRIX1->MATRIX_SPSELR[id / 32] & (MATRIX_SPSELR_NSECP0 << mask));
}

/**
 * @brief    Associates slave with a kind of master
 * @note masterID is set only if type is fixed default master.
 *       Specifying the number of a master which is not connected
 *       to the selected slave is equivalent to clearing DEFMSTR_TYPE.
 *
 * @param[in] mtxp      pointer to a MATRIX register block.
 * @param[in] slaveID   Slave MATRIX ID.
 * @param[in] type      Select from
 *                        No default master,
 *                        Last access master,
 *                        Fixed default master.
 * @param[in] masterID  Master MATRIX ID.
 */
void mtxConfigDefaultMaster(Matrix *mtxp, uint8_t slaveID,
        uint8_t type, uint8_t masterID) {

  mtxDisableWP(mtxp);

  volatile uint32_t *scfgAddress = (uint32_t *) ((uint32_t) mtxp + SCFG_OFFSET + (4u * slaveID));
  *scfgAddress = MATRIX_SCFG_DEFMSTR_TYPE(type);

  if (type == FIXED_DEFAULT_MASTER) {
    *scfgAddress = MATRIX_SCFG_FIXED_DEFMSTR(masterID);
  }
  mtxEnableWP(mtxp);
}

/**
 * @brief   Configures slave security region
 *
 * @param[in] mtxp      pointer to a MATRIX register block.
 * @param[in] slaveID   Slave MATRIX ID.
 * @param[in] selMask   Securable area.
 * @param[in] readMask  Secure for read.
 * @param[in] writeMask Secure for write.
 */
void mtxConfigSlaveSec(Matrix *mtxp, uint8_t slaveID,
        uint8_t selMask, uint8_t readMask,
        uint8_t writeMask) {

  mtxDisableWP(mtxp);
  mtxp->MATRIX_SSR[slaveID] = selMask | (readMask << 8) |
                              (writeMask << 16);
  mtxEnableWP(mtxp);
}

/**
 * @brief   Configures split area of region
 *
 * @param[in] mtxp      pointer to a MATRIX register block.
 * @param[in] slaveID   Slave MATRIX ID.
 * @param[in] areaSize  Split size area.
 * @param[in] mask      Region securable area.
 */
void mtxSetSlaveSplitAddr(Matrix *mtxp, uint8_t slaveID,
         uint8_t areaSize, uint8_t mask) {

  mtxDisableWP(mtxp);
  uint8_t i = mask, j = 0;
  uint32_t value = 0;
  for (i = 1; (i <= mask) && (j < 32); i <<= 1, j += 4) {
    if (i & mask)
      value |= areaSize << j;
  }
  mtxp->MATRIX_SASSR[slaveID] = value;
  mtxEnableWP(mtxp);
}

/**
 * @brief   Configures size area of region
 * @note Not applicable to internal security type
 *
 * @param[in] mtxp      pointer to a MATRIX register block.
 * @param[in] slaveID   Slave MATRIX ID.
 * @param[in] areaSize  Size of total area.
 * @param[in] mask      Region securable area.
 */
void mtxSetSlaveRegionSize(Matrix *mtxp, uint8_t slaveID,
          uint8_t areaSize, uint8_t mask) {

  osalDbgCheck(slaveID != 0);

  mtxDisableWP(mtxp);
  uint8_t i = mask, j = 0;
  uint32_t value = 0;
  for (i = 1; (i <= mask) && (j < 32 ); i <<= 1, j += 4) {
    if (i & mask)
      value |= areaSize << j;
  }
  mtxp->MATRIX_SRTSR[slaveID] = value;
  mtxEnableWP(mtxp);
}

/**
 * @brief   Changes the mapping of the chip so that the remap area
 *          mirrors the internal ROM or the EBI CS0.
 */
void mtxRemapRom(void) {

  AXIMX->AXIMX_REMAP = 0;

  /* Invalidate I-Cache*/
  L1C_InvalidateICacheAll();

  /* Invalidate Region */
  cacheInvalidateRegion((void*)0, IRAM_SIZE);
}

/**
 * @brief   Changes the mapping of the chip so that the remap area
 *          mirrors the internal ROM or the EBI CS0.
 */
void mtxRemapRam(void) {

  AXIMX->AXIMX_REMAP = AXIMX_REMAP_REMAP0;

  /* Invalidate I-Cache*/
  L1C_InvalidateICacheAll();

  /* Clean I-Region */
  cacheCleanRegion((void*)IRAM_ADDR, IRAM_SIZE);
  /* Invalidate Region */
  cacheInvalidateRegion((void*)0, IRAM_SIZE);
}

/** @} */