Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:44

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreMemory
0007  *
0008  * @ingroup RTEMSBSPsARMCycV
0009  *
0010  * @brief This source file contains the arm/altera-cyclone-v implementation of
0011  *   _Memory_Get().
0012  */
0013 
0014 /*
0015  * Copyright (C) 2017, 2019 embedded brains GmbH & Co. KG
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  * 1. Redistributions of source code must retain the above copyright
0021  *    notice, this list of conditions and the following disclaimer.
0022  * 2. Redistributions in binary form must reproduce the above copyright
0023  *    notice, this list of conditions and the following disclaimer in the
0024  *    documentation and/or other materials provided with the distribution.
0025  *
0026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0036  * POSSIBILITY OF SUCH DAMAGE.
0037  */
0038 
0039 #include <bsp/bootcard.h>
0040 #include <bsp/fdt.h>
0041 #include <bsp/linker-symbols.h>
0042 
0043 #ifdef BSP_FDT_IS_SUPPORTED
0044 
0045 #include <bsp/arm-cp15-start.h>
0046 
0047 #include <libcpu/arm-cp15.h>
0048 
0049 #include <libfdt.h>
0050 
0051 #include <rtems/sysinit.h>
0052 
0053 #define AREA_COUNT_MAX 16
0054 
0055 static const char memory_path[] = "/memory";
0056 
0057 static const char reserved_memory_path[] = "/reserved-memory";
0058 
0059 static void adjust_memory_size(const void *fdt, Memory_Area *area)
0060 {
0061   int node;
0062 
0063   node = fdt_path_offset_namelen(
0064     fdt,
0065     memory_path,
0066     (int) sizeof(memory_path) - 1
0067   );
0068 
0069   if (node >= 0) {
0070     int len;
0071     const void *val;
0072     uintptr_t begin;
0073     uintptr_t size;
0074     uintptr_t a_bit;
0075 
0076     val = fdt_getprop(fdt, node, "reg", &len);
0077     if (len == 8) {
0078       begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
0079       size = fdt32_to_cpu(((fdt32_t *) val)[1]);
0080     } else {
0081       begin = 0;
0082       size = 0;
0083     }
0084 
0085     /*
0086      * Remove a bit to avoid problems with speculative memory accesses beyond
0087      * the valid memory area.
0088      */
0089     a_bit = 0x100000;
0090     if (size >= a_bit) {
0091       size -= a_bit;
0092     }
0093 
0094     if (
0095       begin == 0
0096         && size > (uintptr_t) bsp_section_work_end
0097         && (uintptr_t) bsp_section_nocache_end
0098           < (uintptr_t) bsp_section_work_end
0099     ) {
0100       _Memory_Set_end(area, (void *) (begin + size));
0101     }
0102   }
0103 }
0104 
0105 static Memory_Area *find_area(
0106   Memory_Area *areas,
0107   size_t area_count,
0108   uint32_t begin
0109 )
0110 {
0111   size_t i;
0112 
0113   for (i = 0; i < area_count; ++i) {
0114     uintptr_t b;
0115     uintptr_t e;
0116 
0117     b = (uintptr_t) _Memory_Get_begin(&areas[i]);
0118     e = (uintptr_t) _Memory_Get_end(&areas[i]);
0119 
0120     if (b <= begin && begin < e) {
0121       return &areas[i];
0122     }
0123   }
0124 
0125   return NULL;
0126 }
0127 
0128 static size_t remove_reserved_memory(
0129   const void *fdt,
0130   Memory_Area *areas,
0131   size_t area_count
0132 )
0133 {
0134   int node;
0135 
0136   node = fdt_path_offset_namelen(
0137     fdt,
0138     reserved_memory_path,
0139     (int) sizeof(reserved_memory_path) - 1
0140   );
0141 
0142   if (node >= 0) {
0143     node = fdt_first_subnode(fdt, node);
0144 
0145     while (node >= 0) {
0146       int len;
0147       const void *val;
0148       uintptr_t area_end;
0149       uintptr_t hole_begin;
0150       uintptr_t hole_end;
0151       Memory_Area *area;
0152 
0153       val = fdt_getprop(fdt, node, "reg", &len);
0154       if (len == 8) {
0155         hole_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
0156         hole_end = hole_begin + fdt32_to_cpu(((fdt32_t *) val)[1]);
0157       } else {
0158         rtems_panic("unexpected reserved memory area");
0159       }
0160 
0161       area = find_area(areas, area_count, hole_begin);
0162       area_end = (uintptr_t) _Memory_Get_end(area);
0163       _Memory_Set_end(area, (void *) hole_begin);
0164 
0165       if (hole_end <= area_end) {
0166         if (area_count >= AREA_COUNT_MAX) {
0167           rtems_panic("too many reserved memory areas");
0168         }
0169 
0170         area = &areas[area_count];
0171         ++area_count;
0172         _Memory_Initialize(area, (void *) hole_end, (void *) area_end);
0173       }
0174 
0175       node = fdt_next_subnode(fdt, node);
0176     }
0177   }
0178 
0179   return area_count;
0180 }
0181 
0182 static Memory_Area _Memory_Areas[AREA_COUNT_MAX];
0183 
0184 static void bsp_memory_initialize(void)
0185 {
0186   size_t area_count;
0187   const void *fdt;
0188   size_t i;
0189 
0190   _Memory_Initialize(
0191     &_Memory_Areas[0],
0192     bsp_section_work_begin,
0193     bsp_section_work_end
0194   );
0195 
0196   area_count = 1;
0197   fdt = bsp_fdt_get();
0198   adjust_memory_size(fdt, &_Memory_Areas[0]);
0199   area_count = remove_reserved_memory(fdt, &_Memory_Areas[0], area_count);
0200 
0201   for (i = 0; i < area_count; ++i) {
0202     arm_cp15_set_translation_table_entries(
0203       _Memory_Get_begin(&_Memory_Areas[i]),
0204       _Memory_Get_end(&_Memory_Areas[i]),
0205       ARMV7_MMU_READ_WRITE_CACHED
0206     );
0207   }
0208 }
0209 
0210 RTEMS_SYSINIT_ITEM(
0211   bsp_memory_initialize,
0212   RTEMS_SYSINIT_MEMORY,
0213   RTEMS_SYSINIT_ORDER_MIDDLE
0214 );
0215 
0216 #else /* !BSP_FDT_IS_SUPPORTED */
0217 
0218 static Memory_Area _Memory_Areas[] = {
0219   MEMORY_INITIALIZER(bsp_section_work_begin, bsp_section_work_end)
0220 };
0221 
0222 #endif /* BSP_FDT_IS_SUPPORTED */
0223 
0224 static const Memory_Information _Memory_Information =
0225   MEMORY_INFORMATION_INITIALIZER( _Memory_Areas );
0226 
0227 const Memory_Information *_Memory_Get( void )
0228 {
0229   return &_Memory_Information;
0230 }