1 /*******************************************************************************
2  * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * MPFS HAL Embedded Software
7  *
8  */
9 /*******************************************************************************
10  * @file mss_pmp.c
11  * @author Microchip-FPGA Embedded Systems Solutions
12  * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
13  *
14  */
15 /*=========================================================================*//**
16 
17  *//*=========================================================================*/
18 #include <stdio.h>
19 #include <string.h>
20 #include "mpfs_hal/mss_hal.h"
21 
22 /**
23  * \brief PMP configuration from Libero
24  *
25  */
26 const uint64_t pmp_values[][18] = {
27         /* hart 0 */
28         {LIBERO_SETTING_HART0_CSR_PMPCFG0,
29         LIBERO_SETTING_HART0_CSR_PMPCFG2,
30         LIBERO_SETTING_HART0_CSR_PMPADDR0,
31         LIBERO_SETTING_HART0_CSR_PMPADDR1,
32         LIBERO_SETTING_HART0_CSR_PMPADDR2,
33         LIBERO_SETTING_HART0_CSR_PMPADDR3,
34         LIBERO_SETTING_HART0_CSR_PMPADDR4,
35         LIBERO_SETTING_HART0_CSR_PMPADDR5,
36         LIBERO_SETTING_HART0_CSR_PMPADDR6,
37         LIBERO_SETTING_HART0_CSR_PMPADDR7,
38         LIBERO_SETTING_HART0_CSR_PMPADDR8,
39         LIBERO_SETTING_HART0_CSR_PMPADDR9,
40         LIBERO_SETTING_HART0_CSR_PMPADDR10,
41         LIBERO_SETTING_HART0_CSR_PMPADDR11,
42         LIBERO_SETTING_HART0_CSR_PMPADDR12,
43         LIBERO_SETTING_HART0_CSR_PMPADDR13,
44         LIBERO_SETTING_HART0_CSR_PMPADDR14,
45         LIBERO_SETTING_HART0_CSR_PMPADDR15},
46         /* hart 1 */
47         {LIBERO_SETTING_HART1_CSR_PMPCFG0,
48         LIBERO_SETTING_HART1_CSR_PMPCFG2,
49         LIBERO_SETTING_HART1_CSR_PMPADDR0,
50         LIBERO_SETTING_HART1_CSR_PMPADDR1,
51         LIBERO_SETTING_HART1_CSR_PMPADDR2,
52         LIBERO_SETTING_HART1_CSR_PMPADDR3,
53         LIBERO_SETTING_HART1_CSR_PMPADDR4,
54         LIBERO_SETTING_HART1_CSR_PMPADDR5,
55         LIBERO_SETTING_HART1_CSR_PMPADDR6,
56         LIBERO_SETTING_HART1_CSR_PMPADDR7,
57         LIBERO_SETTING_HART1_CSR_PMPADDR8,
58         LIBERO_SETTING_HART1_CSR_PMPADDR9,
59         LIBERO_SETTING_HART1_CSR_PMPADDR10,
60         LIBERO_SETTING_HART1_CSR_PMPADDR11,
61         LIBERO_SETTING_HART1_CSR_PMPADDR12,
62         LIBERO_SETTING_HART1_CSR_PMPADDR13,
63         LIBERO_SETTING_HART1_CSR_PMPADDR14,
64         LIBERO_SETTING_HART1_CSR_PMPADDR15},
65         /* hart 2 */
66         {LIBERO_SETTING_HART2_CSR_PMPCFG0,
67         LIBERO_SETTING_HART2_CSR_PMPCFG2,
68         LIBERO_SETTING_HART2_CSR_PMPADDR0,
69         LIBERO_SETTING_HART2_CSR_PMPADDR1,
70         LIBERO_SETTING_HART2_CSR_PMPADDR2,
71         LIBERO_SETTING_HART2_CSR_PMPADDR3,
72         LIBERO_SETTING_HART2_CSR_PMPADDR4,
73         LIBERO_SETTING_HART2_CSR_PMPADDR5,
74         LIBERO_SETTING_HART2_CSR_PMPADDR6,
75         LIBERO_SETTING_HART2_CSR_PMPADDR7,
76         LIBERO_SETTING_HART2_CSR_PMPADDR8,
77         LIBERO_SETTING_HART2_CSR_PMPADDR9,
78         LIBERO_SETTING_HART2_CSR_PMPADDR10,
79         LIBERO_SETTING_HART2_CSR_PMPADDR11,
80         LIBERO_SETTING_HART2_CSR_PMPADDR12,
81         LIBERO_SETTING_HART2_CSR_PMPADDR13,
82         LIBERO_SETTING_HART2_CSR_PMPADDR14,
83         LIBERO_SETTING_HART2_CSR_PMPADDR15},
84         /* hart 3 */
85         {LIBERO_SETTING_HART3_CSR_PMPCFG0,
86         LIBERO_SETTING_HART3_CSR_PMPCFG2,
87         LIBERO_SETTING_HART3_CSR_PMPADDR0,
88         LIBERO_SETTING_HART3_CSR_PMPADDR1,
89         LIBERO_SETTING_HART3_CSR_PMPADDR2,
90         LIBERO_SETTING_HART3_CSR_PMPADDR3,
91         LIBERO_SETTING_HART3_CSR_PMPADDR4,
92         LIBERO_SETTING_HART3_CSR_PMPADDR5,
93         LIBERO_SETTING_HART3_CSR_PMPADDR6,
94         LIBERO_SETTING_HART3_CSR_PMPADDR7,
95         LIBERO_SETTING_HART3_CSR_PMPADDR8,
96         LIBERO_SETTING_HART3_CSR_PMPADDR9,
97         LIBERO_SETTING_HART3_CSR_PMPADDR10,
98         LIBERO_SETTING_HART3_CSR_PMPADDR11,
99         LIBERO_SETTING_HART3_CSR_PMPADDR12,
100         LIBERO_SETTING_HART3_CSR_PMPADDR13,
101         LIBERO_SETTING_HART3_CSR_PMPADDR14,
102         LIBERO_SETTING_HART3_CSR_PMPADDR15},
103         /* hart 4 */
104         {LIBERO_SETTING_HART4_CSR_PMPCFG0,
105         LIBERO_SETTING_HART4_CSR_PMPCFG2,
106         LIBERO_SETTING_HART4_CSR_PMPADDR0,
107         LIBERO_SETTING_HART4_CSR_PMPADDR1,
108         LIBERO_SETTING_HART4_CSR_PMPADDR2,
109         LIBERO_SETTING_HART4_CSR_PMPADDR3,
110         LIBERO_SETTING_HART4_CSR_PMPADDR4,
111         LIBERO_SETTING_HART4_CSR_PMPADDR5,
112         LIBERO_SETTING_HART4_CSR_PMPADDR6,
113         LIBERO_SETTING_HART4_CSR_PMPADDR7,
114         LIBERO_SETTING_HART4_CSR_PMPADDR8,
115         LIBERO_SETTING_HART4_CSR_PMPADDR9,
116         LIBERO_SETTING_HART4_CSR_PMPADDR10,
117         LIBERO_SETTING_HART4_CSR_PMPADDR11,
118         LIBERO_SETTING_HART4_CSR_PMPADDR12,
119         LIBERO_SETTING_HART4_CSR_PMPADDR13,
120         LIBERO_SETTING_HART4_CSR_PMPADDR14,
121         LIBERO_SETTING_HART4_CSR_PMPADDR15},
122 };
123 
124 /**
125  * pmp_configure()
126  * Set PMP's up with configuration from Libero
127  * @param hart_id hart Id
128  * @return
129  */
pmp_configure(uint8_t hart_id)130 uint8_t pmp_configure(uint8_t hart_id) /* set-up with settings from Libero */
131 {
132 #if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
133     uint64_t pmp0cfg;
134 #endif
135     /* make sure enables are off */
136     write_csr(pmpcfg0, 0);
137     write_csr(pmpcfg2, 0);
138     /* set required addressing */
139     write_csr(pmpaddr0, pmp_values[hart_id][2]);
140     write_csr(pmpaddr1, pmp_values[hart_id][3]);
141     write_csr(pmpaddr2, pmp_values[hart_id][4]);
142     write_csr(pmpaddr3, pmp_values[hart_id][5]);
143     write_csr(pmpaddr4, pmp_values[hart_id][6]);
144     write_csr(pmpaddr5, pmp_values[hart_id][7]);
145     write_csr(pmpaddr6, pmp_values[hart_id][8]);
146     write_csr(pmpaddr7, pmp_values[hart_id][9]);
147     write_csr(pmpaddr8, pmp_values[hart_id][10]);
148     write_csr(pmpaddr9, pmp_values[hart_id][11]);
149     write_csr(pmpaddr10, pmp_values[hart_id][12]);
150     write_csr(pmpaddr11, pmp_values[hart_id][13]);
151     write_csr(pmpaddr12, pmp_values[hart_id][14]);
152     write_csr(pmpaddr13, pmp_values[hart_id][15]);
153     write_csr(pmpaddr14, pmp_values[hart_id][16]);
154     write_csr(pmpaddr15, pmp_values[hart_id][17]);
155 #if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
156     pmp0cfg = pmp_values[hart_id][0];
157     pmp_master_configs(hart_id, &pmp0cfg);
158     write_csr(pmpcfg0, pmp0cfg);
159     write_csr(pmpcfg2, pmp_values[hart_id][1]);
160 #else
161     write_csr(pmpcfg0, pmp_values[hart_id][0]);
162 #endif
163 
164     return(0);
165 }
166 
167 /*-------------------------------------------------------------------------*//**
168   Please note the first four PMP's are set to zero by MSS Configurator v2021.1
169   These will need to be set by the HSS. The first three relate to HSS footprint
170   The PMP4 is used to open a hole for debug region.
171 
172   | PMP | cfg  | L  | XWR | Detail                                             |
173   |-----|-----------|-----|----------------------------------------------------|
174   |  0  | 0x18 | N  |     | 256KB | Closes access for s and U mode             |
175   |  1  | 0x98 | Y  | X R | 256KB | Opens up area for m-mode only              |
176   |  2  | 0x98 | Y  | XRW |  64KB | OpenSBI scratch per scratch                |
177   |  3  | 0x98 | Y  | XRW |   4KB | Open window for debug                      |
178   |  .. | ..   | .. | ..  |  ..   | ..                                         |
179   |  15 | 0x18 | Y  |     |   -   | Close everything not opened                |
180 
181  @param pmp0cfg return with config for first four PMP's
182 
183  */
pmp_master_configs(uint8_t hart_id,uint64_t * pmp0cfg)184 __attribute__((weak))  void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg)
185 {
186     if ( hart_id == 0U )
187     {
188         *pmp0cfg = LIBERO_SETTING_HART0_CSR_PMPCFG0;
189         write_csr(pmpaddr0, pmp_values[hart_id][2]);
190         write_csr(pmpaddr1, pmp_values[hart_id][3]);
191         write_csr(pmpaddr2, pmp_values[hart_id][4]);
192         write_csr(pmpaddr3, pmp_values[hart_id][5]);
193     }
194     else
195     {
196         /*
197          * Example of closed memory map, must be created based on HSS footprint
198          */
199 #define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG0          0x2007FFFULL   /* 256K LIM */
200 #define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG1          0x200FFFFULL   /* 512K LIM */
201 #define OPEN_M_ACCESS_HSS_PMP1_LIM_EG0             0x2007FFFULL   /* 256K LIM */
202 #define OPEN_M_ACCESS_HSS_PMP1_LIM_EG1             0x200FFFFULL   /* 512K LIM */
203 #define OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG          0x280FFFFULL   /* 512K SCRATCHPAD */
204 #define OPEN_CONTEXT_ACCESS_LIM_PMP2_H1            0x2011FFFULL   /*  64K LIM */
205 #define OPEN_CONTEXT_ACCESS_LIM_PMP2_H2            0x2015FFFULL   /*  64K LIM */
206 #define OPEN_DEBUG_ACCESS_PMP3                     0x1FFULL
207 #define HSS_CLOSED_CFG_MASK                        ~0xFFFFFFFFULL
208 #define HSS_CLOSED_CFG                             0x9F9F9D18ULL
209         /*
210          * We will open 512K LIM and scratchpad in weak pmp_master_configs()
211          * for all harts.
212          */
213 #define  LIM_512K_FROM_BASE                        0x200FFFFULL   /* 512K LIM */
214 #define  SCRATCH_512K_FROM_BASE                    0x280FFFFULL   /* 512K LIM */
215         *pmp0cfg &= HSS_CLOSED_CFG_MASK;
216         *pmp0cfg |= 0x9F009F9FULL;  /* open 0,1 and 3 to allow open access */
217         write_csr(pmpaddr0, OPEN_M_ACCESS_HSS_PMP1_LIM_EG1);
218         write_csr(pmpaddr1, OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG);
219         write_csr(pmpaddr2, 0ULL);
220         write_csr(pmpaddr3, OPEN_DEBUG_ACCESS_PMP3);
221     }
222 
223     /*
224      *
225      */
226 #define LOCAL_PMP_SETTINGS
227 #ifdef LOCAL_PMP_SETTINGS
228 
229 #endif
230     return;
231 }
232