source: rtems/bsps/powerpc/qoriq/start/mmu-config.c @ 8f8ccee

5
Last change on this file since 8f8ccee was 9964895, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/18 at 08:35:35

bsps: Move startup files to bsps

Adjust build support files to new directory layout.

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQMMU
5 *
6 * @brief MMU implementation.
7 */
8
9/*
10 * Copyright (c) 2011, 2018 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <bsp.h>
24#include <bsp/bootcard.h>
25#include <bsp/fdt.h>
26#include <bsp/linker-symbols.h>
27#include <bsp/mmu.h>
28#include <bsp/qoriq.h>
29
30#include <sys/param.h>
31
32#include <libfdt.h>
33
34#include <rtems/config.h>
35
36#define TEXT __attribute__((section(".bsp_start_text")))
37#define DATA __attribute__((section(".bsp_start_data")))
38
39typedef struct {
40        uintptr_t begin;
41        uintptr_t size;
42        uint32_t mas2;
43        uint32_t mas3;
44        uint32_t mas7;
45} entry;
46
47#define ENTRY_X(b, s) { \
48        .begin = (uintptr_t) b, \
49        .size = (uintptr_t) s, \
50        .mas2 = 0, \
51        .mas3 = FSL_EIS_MAS3_SX \
52}
53
54#define ENTRY_R(b, s) { \
55        .begin = (uintptr_t) b, \
56        .size = (uintptr_t) s, \
57        .mas2 = 0, \
58        .mas3 = FSL_EIS_MAS3_SR \
59}
60
61#ifdef RTEMS_SMP
62  #define ENTRY_RW_MAS2 FSL_EIS_MAS2_M
63#else
64  #define ENTRY_RW_MAS2 0
65#endif
66
67#define ENTRY_RW(b, s) { \
68        .begin = (uintptr_t) b, \
69        .size = (uintptr_t) s, \
70        .mas2 = ENTRY_RW_MAS2, \
71        .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
72}
73
74#define ENTRY_IO(b, s) { \
75        .begin = (uintptr_t) b, \
76        .size = (uintptr_t) s, \
77        .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
78        .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
79}
80
81#define ENTRY_DEV(b, s) { \
82        .begin = (uintptr_t) b, \
83        .size = (uintptr_t) s, \
84        .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
85        .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
86        .mas7 = QORIQ_MMU_DEVICE_MAS7 \
87}
88
89/*
90 * MMU entry for BMan and QMan software portals.
91 *
92 * The M bit must be set if stashing is used, see 3.3.8.6 DQRR Entry Stashing
93 * and 3.3.8 Software Portals in T4240DPAARM.
94 *
95 * The G bit must be set, otherwise ECC errors in the QMan software portals
96 * will occur.  No documentation reference for this is available.
97 */
98#define ENTRY_DEV_CACHED(b, s) { \
99        .begin = (uintptr_t) b, \
100        .size = (uintptr_t) s, \
101        .mas2 = FSL_EIS_MAS2_M | FSL_EIS_MAS2_G, \
102        .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
103        .mas7 = QORIQ_MMU_DEVICE_MAS7 \
104}
105
106#define WORKSPACE_ENTRY_INDEX 0
107
108static entry DATA config[] = {
109        /* Must be first entry, see WORKSPACE_ENTRY_INDEX */
110        ENTRY_RW(bsp_section_work_begin, bsp_section_work_size),
111
112        #if defined(RTEMS_MULTIPROCESSING) && \
113            defined(QORIQ_INTERCOM_AREA_BEGIN) && \
114            defined(QORIQ_INTERCOM_AREA_SIZE)
115                {
116                        .begin = QORIQ_INTERCOM_AREA_BEGIN,
117                        .size = QORIQ_INTERCOM_AREA_SIZE,
118                        .mas2 = FSL_EIS_MAS2_M,
119                        .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW
120                },
121        #endif
122        ENTRY_X(bsp_section_start_begin, bsp_section_start_size),
123        ENTRY_R(bsp_section_fast_text_load_begin, bsp_section_fast_text_size),
124        ENTRY_X(bsp_section_fast_text_begin, bsp_section_fast_text_size),
125        ENTRY_X(bsp_section_text_begin, bsp_section_text_size),
126        ENTRY_R(bsp_section_rodata_load_begin, bsp_section_rodata_size),
127        ENTRY_R(bsp_section_rodata_begin, bsp_section_rodata_size),
128        ENTRY_R(bsp_section_fast_data_load_begin, bsp_section_fast_data_size),
129        ENTRY_RW(bsp_section_fast_data_begin, bsp_section_fast_data_size),
130        ENTRY_R(bsp_section_data_load_begin, bsp_section_data_size),
131        ENTRY_RW(bsp_section_data_begin, bsp_section_data_size),
132        ENTRY_RW(bsp_section_sbss_begin, bsp_section_sbss_size),
133        ENTRY_RW(bsp_section_bss_begin, bsp_section_bss_size),
134        ENTRY_RW(bsp_section_rwextra_begin, bsp_section_rwextra_size),
135        ENTRY_RW(bsp_section_stack_begin, bsp_section_stack_size),
136        ENTRY_IO(bsp_section_nocache_begin, bsp_section_nocache_size),
137        ENTRY_IO(bsp_section_nocachenoload_begin, bsp_section_nocachenoload_size),
138#ifndef QORIQ_IS_HYPERVISOR_GUEST
139#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
140        /* BMan Portals */
141        ENTRY_DEV_CACHED(&qoriq_bman_portal[0][0], sizeof(qoriq_bman_portal[0])),
142        ENTRY_DEV(&qoriq_bman_portal[1][0], sizeof(qoriq_bman_portal[1])),
143        /* QMan Portals */
144        ENTRY_DEV_CACHED(&qoriq_qman_portal[0][0], sizeof(qoriq_qman_portal[0])),
145        ENTRY_DEV(&qoriq_qman_portal[1][0], sizeof(qoriq_qman_portal[1])),
146#endif
147        ENTRY_DEV(&qoriq, sizeof(qoriq))
148#endif
149};
150
151static DATA char memory_path[] = "/memory";
152
153#ifdef QORIQ_IS_HYPERVISOR_GUEST
154static void TEXT add_dpaa_bqman_portals(
155        qoriq_mmu_context *context,
156        const void *fdt,
157        const char *compatible
158)
159{
160        int node;
161
162        node = -1;
163
164        while (true) {
165                const void *val;
166                int len;
167                uintptr_t paddr;
168                uintptr_t size;
169
170                node = fdt_node_offset_by_compatible(fdt, node, compatible);
171                if (node < 0) {
172                        break;
173                }
174
175                val = fdt_getprop(fdt, node, "reg", &len);
176                if (len != 32) {
177                        continue;
178                }
179
180                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
181                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
182
183                qoriq_mmu_add(
184                        context,
185                        paddr,
186                        paddr + size - 1,
187                        0,
188                        FSL_EIS_MAS2_M | FSL_EIS_MAS2_G,
189                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
190                        QORIQ_MMU_DEVICE_MAS7
191                );
192
193                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
194                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[3]);
195
196                qoriq_mmu_add(
197                        context,
198                        paddr,
199                        paddr + size - 1,
200                        0,
201                        FSL_EIS_MAS2_I | FSL_EIS_MAS2_G,
202                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
203                        QORIQ_MMU_DEVICE_MAS7
204                );
205        }
206}
207
208static void TEXT add_dpaa_bpool(qoriq_mmu_context *context, const void *fdt)
209{
210        int node;
211
212        node = -1;
213
214        while (true) {
215                const void *val;
216                int len;
217                uintptr_t config_count;
218                uintptr_t size;
219                uintptr_t paddr;
220
221                node = fdt_node_offset_by_compatible(fdt, node, "fsl,bpool");
222                if (node < 0) {
223                        break;
224                }
225
226                val = fdt_getprop(fdt, node, "fsl,bpool-ethernet-cfg", &len);
227                if (len != 24) {
228                        continue;
229                }
230
231                config_count = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
232                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
233                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
234
235                qoriq_mmu_add(
236                        context,
237                        paddr,
238                        paddr + config_count * size - 1,
239                        0,
240                        FSL_EIS_MAS2_M,
241                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
242                        0
243                );
244        }
245}
246#endif
247
248static void TEXT config_fdt_adjust(const void *fdt)
249{
250        int node;
251
252        node = fdt_path_offset_namelen(
253                fdt,
254                memory_path,
255                (int) sizeof(memory_path) - 1
256        );
257
258        if (node >= 0) {
259                int len;
260                const void *val;
261                uint64_t mem_begin;
262                uint64_t mem_size;
263
264                val = fdt_getprop(fdt, node, "reg", &len);
265                if (len == 8) {
266                        mem_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
267                        mem_size = fdt32_to_cpu(((fdt32_t *) val)[1]);
268                } else if (len == 16) {
269                        mem_begin = fdt64_to_cpu(((fdt64_t *) val)[0]);
270                        mem_size = fdt64_to_cpu(((fdt64_t *) val)[1]);
271                } else {
272                        mem_begin = 0;
273                        mem_size = 0;
274                }
275
276#ifndef __powerpc64__
277                mem_size = MIN(mem_size, 0x80000000U);
278#endif
279
280                if (
281                        mem_begin == 0
282                                && mem_size > (uintptr_t) bsp_section_work_end
283                                && (uintptr_t) bsp_section_nocache_end
284                                        < (uintptr_t) bsp_section_work_end
285                ) {
286                        /* Assign new value to allow a bsp_restart() */
287                        config[WORKSPACE_ENTRY_INDEX].size = (uintptr_t) mem_size
288                                - (uintptr_t) bsp_section_work_begin;
289                }
290        }
291}
292
293void TEXT qoriq_mmu_config(bool boot_processor, int first_tlb, int scratch_tlb)
294{
295        qoriq_mmu_context context;
296        const void *fdt;
297        int max_count;
298        int i;
299
300        for (i = 0; i < QORIQ_TLB1_ENTRY_COUNT; ++i) {
301                if (i != scratch_tlb) {
302                        qoriq_tlb1_invalidate(i);
303                }
304        }
305
306        fdt = bsp_fdt_get();
307        qoriq_mmu_context_init(&context);
308
309#ifdef QORIQ_IS_HYPERVISOR_GUEST
310        add_dpaa_bqman_portals(&context, fdt, "fsl,bman-portal");
311        add_dpaa_bqman_portals(&context, fdt, "fsl,qman-portal");
312        add_dpaa_bpool(&context, fdt);
313        max_count = QORIQ_TLB1_ENTRY_COUNT - 1;
314#else
315        max_count = (3 * QORIQ_TLB1_ENTRY_COUNT) / 4;
316#endif
317
318        if (boot_processor) {
319                config_fdt_adjust(fdt);
320        }
321
322        for (i = 0; i < (int) (sizeof(config) / sizeof(config [0])); ++i) {
323                const entry *cur = &config [i];
324                if (cur->size > 0) {
325                        qoriq_mmu_add(
326                                &context,
327                                cur->begin,
328                                cur->begin + cur->size - 1,
329                                0,
330                                cur->mas2,
331                                cur->mas3,
332                                cur->mas7
333                        );
334                }
335        }
336
337        qoriq_mmu_partition(&context, max_count);
338        qoriq_mmu_write_to_tlb1(&context, first_tlb);
339}
340
341void TEXT bsp_work_area_initialize(void)
342{
343        const entry *we = &config[WORKSPACE_ENTRY_INDEX];
344        uintptr_t begin = we->begin;
345        uintptr_t end = begin + we->size;
346
347#ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
348        begin += rtems_configuration_get_interrupt_stack_size();
349#endif
350
351        bsp_work_area_initialize_default((void *) begin, end - begin);
352}
Note: See TracBrowser for help on using the repository browser.