File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp.h>
0037 #include <bsp/bootcard.h>
0038 #include <bsp/fdt.h>
0039 #include <bsp/linker-symbols.h>
0040 #include <bsp/mmu.h>
0041 #include <bsp/qoriq.h>
0042
0043 #include <sys/param.h>
0044
0045 #include <libfdt.h>
0046
0047 #include <rtems/config.h>
0048 #include <rtems/sysinit.h>
0049
0050 #define TEXT __attribute__((section(".bsp_start_text")))
0051 #define DATA __attribute__((section(".bsp_start_data")))
0052
0053 typedef struct {
0054 uintptr_t begin;
0055 uintptr_t size;
0056 uint32_t mas2;
0057 uint32_t mas3;
0058 uint32_t mas7;
0059 } entry;
0060
0061 #define ENTRY_X(b, s) { \
0062 .begin = (uintptr_t) b, \
0063 .size = (uintptr_t) s, \
0064 .mas2 = 0, \
0065 .mas3 = FSL_EIS_MAS3_SX \
0066 }
0067
0068 #define ENTRY_R(b, s) { \
0069 .begin = (uintptr_t) b, \
0070 .size = (uintptr_t) s, \
0071 .mas2 = 0, \
0072 .mas3 = FSL_EIS_MAS3_SR \
0073 }
0074
0075 #ifdef RTEMS_SMP
0076 #define ENTRY_RW_MAS2 FSL_EIS_MAS2_M
0077 #else
0078 #define ENTRY_RW_MAS2 0
0079 #endif
0080
0081 #define ENTRY_RW(b, s) { \
0082 .begin = (uintptr_t) b, \
0083 .size = (uintptr_t) s, \
0084 .mas2 = ENTRY_RW_MAS2, \
0085 .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
0086 }
0087
0088 #define ENTRY_IO(b, s) { \
0089 .begin = (uintptr_t) b, \
0090 .size = (uintptr_t) s, \
0091 .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
0092 .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
0093 }
0094
0095 #define ENTRY_DEV(b, s) { \
0096 .begin = (uintptr_t) b, \
0097 .size = (uintptr_t) s, \
0098 .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
0099 .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
0100 .mas7 = QORIQ_MMU_DEVICE_MAS7 \
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 #define ENTRY_DEV_CACHED(b, s) { \
0113 .begin = (uintptr_t) b, \
0114 .size = (uintptr_t) s, \
0115 .mas2 = FSL_EIS_MAS2_M | FSL_EIS_MAS2_G, \
0116 .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
0117 .mas7 = QORIQ_MMU_DEVICE_MAS7 \
0118 }
0119
0120 #define WORKSPACE_ENTRY_INDEX 0
0121
0122 static entry DATA config[] = {
0123
0124 ENTRY_RW(bsp_section_work_begin, bsp_section_work_size),
0125
0126 #if defined(RTEMS_MULTIPROCESSING) && \
0127 defined(QORIQ_INTERCOM_AREA_BEGIN) && \
0128 defined(QORIQ_INTERCOM_AREA_SIZE)
0129 {
0130 .begin = QORIQ_INTERCOM_AREA_BEGIN,
0131 .size = QORIQ_INTERCOM_AREA_SIZE,
0132 .mas2 = FSL_EIS_MAS2_M,
0133 .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW
0134 },
0135 #endif
0136 ENTRY_X(bsp_section_start_begin, bsp_section_start_size),
0137 ENTRY_R(bsp_section_fast_text_load_begin, bsp_section_fast_text_size),
0138 ENTRY_X(bsp_section_fast_text_begin, bsp_section_fast_text_size),
0139 ENTRY_X(bsp_section_text_begin, bsp_section_text_size),
0140 ENTRY_R(bsp_section_rodata_load_begin, bsp_section_rodata_size),
0141 ENTRY_R(bsp_section_rodata_begin, bsp_section_rodata_size),
0142 ENTRY_R(bsp_section_fast_data_load_begin, bsp_section_fast_data_size),
0143 ENTRY_RW(bsp_section_fast_data_begin, bsp_section_fast_data_size),
0144 ENTRY_R(bsp_section_data_load_begin, bsp_section_data_size),
0145 ENTRY_RW(bsp_section_data_begin, bsp_section_data_size),
0146 ENTRY_RW(bsp_section_sbss_begin, bsp_section_sbss_size),
0147 ENTRY_RW(bsp_section_bss_begin, bsp_section_bss_size),
0148 ENTRY_RW(bsp_section_rtemsstack_begin, bsp_section_rtemsstack_size),
0149 ENTRY_RW(bsp_section_noinit_begin, bsp_section_noinit_size),
0150 ENTRY_RW(bsp_section_stack_begin, bsp_section_stack_size),
0151 ENTRY_IO(bsp_section_nocache_begin, bsp_section_nocache_size),
0152 ENTRY_IO(bsp_section_nocachenoload_begin, bsp_section_nocachenoload_size),
0153 #ifndef QORIQ_IS_HYPERVISOR_GUEST
0154 #if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
0155
0156 ENTRY_DEV_CACHED(&qoriq_bman_portal[0][0], sizeof(qoriq_bman_portal[0])),
0157 ENTRY_DEV(&qoriq_bman_portal[1][0], sizeof(qoriq_bman_portal[1])),
0158
0159 ENTRY_DEV_CACHED(&qoriq_qman_portal[0][0], sizeof(qoriq_qman_portal[0])),
0160 ENTRY_DEV(&qoriq_qman_portal[1][0], sizeof(qoriq_qman_portal[1])),
0161 #endif
0162 ENTRY_DEV(&qoriq, sizeof(qoriq))
0163 #endif
0164 };
0165
0166 static DATA char memory_path[] = "/memory";
0167
0168 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0169 static void TEXT add_dpaa_bqman_portals(
0170 qoriq_mmu_context *context,
0171 const void *fdt,
0172 const char *compatible
0173 )
0174 {
0175 int node;
0176
0177 node = -1;
0178
0179 while (true) {
0180 const void *val;
0181 int len;
0182 uintptr_t paddr;
0183 uintptr_t size;
0184
0185 node = fdt_node_offset_by_compatible(fdt, node, compatible);
0186 if (node < 0) {
0187 break;
0188 }
0189
0190 val = fdt_getprop(fdt, node, "reg", &len);
0191 if (len != 32) {
0192 continue;
0193 }
0194
0195 paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
0196 size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
0197
0198 qoriq_mmu_add(
0199 context,
0200 paddr,
0201 paddr + size - 1,
0202 0,
0203 FSL_EIS_MAS2_M | FSL_EIS_MAS2_G,
0204 FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
0205 QORIQ_MMU_DEVICE_MAS7
0206 );
0207
0208 paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
0209 size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[3]);
0210
0211 qoriq_mmu_add(
0212 context,
0213 paddr,
0214 paddr + size - 1,
0215 0,
0216 FSL_EIS_MAS2_I | FSL_EIS_MAS2_G,
0217 FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
0218 QORIQ_MMU_DEVICE_MAS7
0219 );
0220 }
0221 }
0222
0223 static void TEXT add_dpaa_bpool(qoriq_mmu_context *context, const void *fdt)
0224 {
0225 int node;
0226
0227 node = -1;
0228
0229 while (true) {
0230 const void *val;
0231 int len;
0232 uintptr_t config_count;
0233 uintptr_t size;
0234 uintptr_t paddr;
0235
0236 node = fdt_node_offset_by_compatible(fdt, node, "fsl,bpool");
0237 if (node < 0) {
0238 break;
0239 }
0240
0241 val = fdt_getprop(fdt, node, "fsl,bpool-ethernet-cfg", &len);
0242 if (len != 24) {
0243 continue;
0244 }
0245
0246 config_count = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
0247 size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
0248 paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
0249
0250 qoriq_mmu_add(
0251 context,
0252 paddr,
0253 paddr + config_count * size - 1,
0254 0,
0255 FSL_EIS_MAS2_M,
0256 FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
0257 0
0258 );
0259 }
0260 }
0261 #endif
0262
0263 static void TEXT config_fdt_adjust(const void *fdt)
0264 {
0265 int node;
0266
0267 node = fdt_path_offset_namelen(
0268 fdt,
0269 memory_path,
0270 (int) sizeof(memory_path) - 1
0271 );
0272
0273 if (node >= 0) {
0274 int len;
0275 const void *val;
0276 uint64_t mem_begin;
0277 uint64_t mem_size;
0278
0279 val = fdt_getprop(fdt, node, "reg", &len);
0280 if (len == 8) {
0281 mem_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
0282 mem_size = fdt32_to_cpu(((fdt32_t *) val)[1]);
0283 } else if (len == 16) {
0284 mem_begin = fdt64_to_cpu(((fdt64_t *) val)[0]);
0285 mem_size = fdt64_to_cpu(((fdt64_t *) val)[1]);
0286 } else {
0287 mem_begin = 0;
0288 mem_size = 0;
0289 }
0290
0291 #ifndef __powerpc64__
0292 mem_size = MIN(mem_size, 0x80000000U);
0293 #endif
0294
0295 if (
0296 mem_begin == 0
0297 && mem_size > (uintptr_t) bsp_section_work_end
0298 && (uintptr_t) bsp_section_nocache_end
0299 < (uintptr_t) bsp_section_work_end
0300 ) {
0301
0302 config[WORKSPACE_ENTRY_INDEX].size = (uintptr_t) mem_size
0303 - (uintptr_t) bsp_section_work_begin;
0304 }
0305 }
0306 }
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 static void TEXT add_pcie_regions(qoriq_mmu_context *context, const void *fdt)
0338 {
0339 int node;
0340
0341 node = -1;
0342
0343 while (true) {
0344 static const size_t range_length = 7 * 4;
0345 const void *val;
0346 int len;
0347
0348 node = fdt_node_offset_by_compatible(
0349 fdt,
0350 node,
0351 "fsl,mpc8548-pcie"
0352 );
0353 if (node < 0) {
0354 break;
0355 }
0356
0357 val = fdt_getprop(fdt, node, "ranges", &len);
0358 if (len % range_length != 0) {
0359 continue;
0360 }
0361
0362 while (len >= range_length) {
0363 uint32_t pci_addr_flags;
0364 uintptr_t pci_addr;
0365 uintptr_t cpu_addr;
0366 uintptr_t size;
0367 const uint32_t *cells;
0368
0369 cells = val;
0370 pci_addr_flags = fdt32_to_cpu(cells[0]);
0371 pci_addr = fdt64_to_cpu(*(fdt64_t *)(&cells[1]));
0372 cpu_addr = fdt64_to_cpu(*(fdt64_t *)(&cells[3]));
0373 size = fdt64_to_cpu(*(fdt64_t *)(&cells[5]));
0374
0375 if (pci_addr_flags == 0x02000000 &&
0376 pci_addr == cpu_addr) {
0377
0378 qoriq_mmu_add(
0379 context,
0380 cpu_addr,
0381 cpu_addr + size - 1,
0382 0,
0383 FSL_EIS_MAS2_I | FSL_EIS_MAS2_G,
0384 FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
0385 0
0386 );
0387 }
0388 len -= range_length;
0389 val += range_length;
0390 }
0391 }
0392 }
0393
0394 void TEXT qoriq_mmu_config(bool boot_processor, int first_tlb, int scratch_tlb)
0395 {
0396 qoriq_mmu_context context;
0397 const void *fdt;
0398 int max_count;
0399 int i;
0400
0401 for (i = 0; i < QORIQ_TLB1_ENTRY_COUNT; ++i) {
0402 if (i != scratch_tlb) {
0403 qoriq_tlb1_invalidate(i);
0404 }
0405 }
0406
0407 fdt = bsp_fdt_get();
0408 qoriq_mmu_context_init(&context);
0409
0410 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0411 add_dpaa_bqman_portals(&context, fdt, "fsl,bman-portal");
0412 add_dpaa_bqman_portals(&context, fdt, "fsl,qman-portal");
0413 add_dpaa_bpool(&context, fdt);
0414 max_count = QORIQ_TLB1_ENTRY_COUNT - 1;
0415 #else
0416 max_count = (3 * QORIQ_TLB1_ENTRY_COUNT) / 4;
0417 #endif
0418
0419 if (boot_processor) {
0420 config_fdt_adjust(fdt);
0421 }
0422
0423 for (i = 0; i < (int) (sizeof(config) / sizeof(config [0])); ++i) {
0424 const entry *cur = &config [i];
0425 if (cur->size > 0) {
0426 qoriq_mmu_add(
0427 &context,
0428 cur->begin,
0429 cur->begin + cur->size - 1,
0430 0,
0431 cur->mas2,
0432 cur->mas3,
0433 cur->mas7
0434 );
0435 }
0436 }
0437
0438 add_pcie_regions(&context, fdt);
0439
0440 qoriq_mmu_partition(&context, max_count);
0441 qoriq_mmu_write_to_tlb1(&context, first_tlb);
0442 }
0443
0444 static Memory_Area _Memory_Areas[1];
0445
0446 static const Memory_Information _Memory_Information =
0447 MEMORY_INFORMATION_INITIALIZER(_Memory_Areas);
0448
0449 static void bsp_memory_initialize(void)
0450 {
0451 const entry *we = &config[WORKSPACE_ENTRY_INDEX];
0452
0453 _Memory_Initialize_by_size(
0454 &_Memory_Areas[0],
0455 (void *) we->begin,
0456 we->size
0457 );
0458 }
0459
0460 RTEMS_SYSINIT_ITEM(
0461 bsp_memory_initialize,
0462 RTEMS_SYSINIT_MEMORY,
0463 RTEMS_SYSINIT_ORDER_MIDDLE
0464 );
0465
0466 const Memory_Information *_Memory_Get(void)
0467 {
0468 return &_Memory_Information;
0469 }