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

5
Last change on this file since eea21eac was eea21eac, checked in by Sebastian Huber <sebastian.huber@…>, on 12/13/19 at 05:18:36

bsps: Rework work area initialization

The work area initialization was done by the BSP through
bsp_work_area_initialize(). This approach predated the system
initialization through the system initialization linker set. The
workspace and C program heap were unconditionally initialized. The aim
is to support RTEMS application configurations which do not need the
workspace and C program heap. In these configurations, the workspace
and C prgram heap should not get initialized.

Change all bsp_work_area_initialize() to implement _Memory_Get()
instead. Move the dirty memory, sbrk(), per-CPU data, workspace, and
malloc() heap initialization into separate system initialization steps.
This makes it also easier to test the individual initialization steps.

This change adds a dependency to _Heap_Extend() to all BSPs. This
dependency will be removed in a follow up change.

Update #3838.

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