source: rtems/c/src/lib/libbsp/powerpc/qoriq/startup/mmu-config.c @ 95a4b1f

5
Last change on this file since 95a4b1f was 95a4b1f, checked in by Sebastian Huber <sebastian.huber@…>, on 08/02/17 at 13:48:03

bsp/qoriq: Enable > 2GiB memory

Update #3082.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQMMU
5 *
6 * @brief MMU implementation.
7 */
8
9/*
10 * Copyright (c) 2011, 2017 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#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
139        /* BMan Portals */
140        ENTRY_DEV_CACHED(&qoriq_bman_portal[0][0], sizeof(qoriq_bman_portal[0])),
141        ENTRY_DEV(&qoriq_bman_portal[1][0], sizeof(qoriq_bman_portal[1])),
142        /* QMan Portals */
143        ENTRY_DEV_CACHED(&qoriq_qman_portal[0][0], sizeof(qoriq_qman_portal[0])),
144        ENTRY_DEV(&qoriq_qman_portal[1][0], sizeof(qoriq_qman_portal[1])),
145#endif
146        ENTRY_DEV(&qoriq, sizeof(qoriq))
147};
148
149static DATA char memory_path[] = "/memory";
150
151static void TEXT config_fdt_adjust(void)
152{
153        const void *fdt = bsp_fdt_get();
154        int node;
155
156        node = fdt_path_offset_namelen(
157                fdt,
158                memory_path,
159                (int) sizeof(memory_path) - 1
160        );
161
162        if (node >= 0) {
163                int len;
164                const void *val;
165                uint64_t begin;
166                uint64_t size;
167
168                val = fdt_getprop(fdt, node, "reg", &len);
169                if (len == 8) {
170                        begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
171                        size = fdt32_to_cpu(((fdt32_t *) val)[1]);
172                } else if (len == 16) {
173                        begin = fdt64_to_cpu(((fdt64_t *) val)[0]);
174                        size = fdt64_to_cpu(((fdt64_t *) val)[1]);
175                } else {
176                        begin = 0;
177                        size = 0;
178                }
179
180#ifndef __powerpc64__
181                size = MIN(size, 0x80000000U);
182#endif
183
184                if (
185                        begin == 0
186                                && size > (uintptr_t) bsp_section_work_end
187                                && (uintptr_t) bsp_section_nocache_end
188                                        < (uintptr_t) bsp_section_work_end
189                ) {
190                        config[WORKSPACE_ENTRY_INDEX].size += (uintptr_t) size
191                                - (uintptr_t) bsp_section_work_end;
192                }
193        }
194}
195
196void TEXT qoriq_mmu_config(bool boot_processor, int first_tlb, int scratch_tlb)
197{
198        qoriq_mmu_context context;
199        int i = 0;
200
201        if (boot_processor) {
202                config_fdt_adjust();
203        }
204
205        qoriq_mmu_context_init(&context);
206
207        for (i = 0; i < QORIQ_TLB1_ENTRY_COUNT; ++i) {
208                if (i != scratch_tlb) {
209                        qoriq_tlb1_invalidate(i);
210                }
211        }
212
213        for (i = 0; i < (int) (sizeof(config) / sizeof(config [0])); ++i) {
214                const entry *cur = &config [i];
215                if (cur->size > 0) {
216                        qoriq_mmu_add(
217                                &context,
218                                cur->begin,
219                                cur->begin + cur->size - 1,
220                                0,
221                                cur->mas2,
222                                cur->mas3,
223                                cur->mas7
224                        );
225                }
226        }
227
228        qoriq_mmu_partition(&context, (3 * QORIQ_TLB1_ENTRY_COUNT) / 4);
229        qoriq_mmu_write_to_tlb1(&context, first_tlb);
230}
231
232void TEXT bsp_work_area_initialize(void)
233{
234        const entry *we = &config[WORKSPACE_ENTRY_INDEX];
235        uintptr_t begin = we->begin;
236        uintptr_t end = begin + we->size;
237
238#ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
239        begin += rtems_configuration_get_interrupt_stack_size();
240#endif
241
242        bsp_work_area_initialize_default((void *) begin, end - begin);
243}
Note: See TracBrowser for help on using the repository browser.