Hello, the patch
https://git.rtems.org/rtems/commit/?id=a4d7e4cee77d16b0e34ef543f0804e7eb2954137 introduced some problems. It tries to adapt the work area based on the size of the available memory. In theory this is a good idea but the implementation doesn't work. The line uint32_t mem = (spec.spec >> (4 + 4 + 8 + 4)) & 0xf; always returns something > 8 on raspberries newer than the first pi 1 boards. The highest bit in this field indicates that it is a new style revision code. See https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md So currently for all except for very old boards the code is skipped. On old boards (like my pi 1) it will be executed. But the memory sizes in the rpi_mem array are missing a few factors 1024 and therefore the calculated address is entirely wrong and leads to an exception. I tried to fix it (see attached patch) but I run into multiple new problems: - The MMU is configured based on the values from the linker command file. Therefore if the work area is set to something bigger, an access violation happens. - In the linker command file there is a stack, a nocache section and a nocacheheap after the work section. Also all three are currently zero, it seems dangerous to ignore them in case they are non-zero in the future. I could think of multiple possible solutions: 1. Revert that patch entirely (and maybe some code it replaced) and just live with 256MB on the Pi. 2. Basically 1 but make the size configurable with for example different linker scripts. 3. Take a really detailed look at the problem and fix all problems listed above. I started with three but I would now favor one or two because the more I look into the Pi hardware the less I like the processor and the hardware. It's a great platform for running Linux where you don't have to do anything. But the hardware and processor are both poorly documented and not well supported by debug tools so that it's not really a lot of fun to work with it on that level. Best regards Christian
>From 20200335524e2b43cbbaffa50fcec757576876aa Mon Sep 17 00:00:00 2001 From: Christian Mauderer <o...@c-mauderer.de> Date: Sat, 21 Dec 2019 16:23:29 +0100 Subject: [PATCH] bsp/raspberrypi: Fix size of work area. The calculation for the real memory size (based on the board revision) should be done based on the real SDRAM start address (which is 0x0) and not based on the RTEMS work area (which can depend on the code size). FIXME: - Adapt memory management. - Is there a possible collision with stack? --- bsps/arm/raspberrypi/include/bsp/vc.h | 11 +++++ bsps/arm/raspberrypi/start/bspgetworkarea.c | 46 +++++++++++++++------ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/bsps/arm/raspberrypi/include/bsp/vc.h b/bsps/arm/raspberrypi/include/bsp/vc.h index 107b6acf0c..422d28cdd9 100644 --- a/bsps/arm/raspberrypi/include/bsp/vc.h +++ b/bsps/arm/raspberrypi/include/bsp/vc.h @@ -138,6 +138,17 @@ int bcm2835_mailbox_get_board_model( bcm2835_get_board_spec_entries *_entries ); int bcm2835_mailbox_get_board_revision( bcm2835_get_board_spec_entries *_entries ); +/* + * See the official documentation for the format of the revision codes: + * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md + */ +#define BCM2835_REVISION_IS_NEW_STYLE(revision) ((revision & (1 << 23)) != 0) +#define BCM2835_REVISION_MEMORY_SIZE(revision) ((revision >> 20) & 0x7) +#define BCM2835_REVISION_MANUFACTURER(revision) ((revision >> 16) & 0xf) +#define BCM2835_REVISION_PROCESSOR(revision) ((revision >> 12) & 0xf) +#define BCM2835_REVISION_TYPE(revision) ((revision >> 4) & 0xff) +#define BCM2835_REVISION_REVISION(revision) ((revision >> 0) & 0xf) + typedef struct { uint64_t board_serial; } bcm2835_get_board_serial_entries; diff --git a/bsps/arm/raspberrypi/start/bspgetworkarea.c b/bsps/arm/raspberrypi/start/bspgetworkarea.c index 6521dcf352..34a487b61d 100644 --- a/bsps/arm/raspberrypi/start/bspgetworkarea.c +++ b/bsps/arm/raspberrypi/start/bspgetworkarea.c @@ -47,12 +47,19 @@ extern char WorkAreaBase[]; void bsp_work_area_initialize(void) { + uintptr_t real_ram_base; uintptr_t work_base; uintptr_t ram_end; bcm2835_get_board_spec_entries spec = { 0 }; work_base = (uintptr_t) WorkAreaBase; + /* SDRAM starts at 0 for raspberry. To allow a NULL-Pointer protection the + * RamBase from the linker command file can start at a later address. This + * variable gives the real start address of the RAM independent what the + * linker command file tells. */ + real_ram_base = (uintptr_t) 0; + /* * Get the board revision and use it to determine the size of the * SDRAM. Get the VC memory entry to determine the size of the VC @@ -67,20 +74,35 @@ void bsp_work_area_initialize(void) #endif if (bcm2835_mailbox_get_board_revision( &spec ) >= 0) { - uint32_t mem = (spec.spec >> (4 + 4 + 8 + 4)) & 0xf; - if (mem < 5) { - bcm2835_get_vc_memory_entries vc = { 0 }; - const uint32_t rpi_mem[5] = { - 256 * 1024, - 512 * 1024, - 1 * 1024, - 2 * 1024, - 4 * 1024 + uint32_t mem_mb = 256u; + bcm2835_get_vc_memory_entries vc = { 0 }; + if (BCM2835_REVISION_IS_NEW_STYLE(spec.spec)) { + uint32_t mem = BCM2835_REVISION_MEMORY_SIZE(spec.spec); + if (mem < 5) { + const uint32_t rpi_mem_mb[5] = { + 256u, + 512u, + 1u * 1024u, + 2u * 1024u, + 4u * 1024u, + }; + mem_mb = rpi_mem_mb[mem]; + } + } else { + const uint32_t known_512mb[] = { + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0013, 0x0014 }; - ram_end = work_base + rpi_mem[mem]; - if (bcm2835_mailbox_get_vc_memory( &vc ) >= 0) - ram_end -= vc.size; + size_t i; + for (i = 0; i < (sizeof(known_512mb)/sizeof(known_512mb[0])); ++i) { + if (spec.spec == known_512mb) { + ram_end = real_ram_base + 512u * 1024u * 1024u; + break; + } + } } + ram_end = real_ram_base + mem_mb * 1024u * 1024u; + if (bcm2835_mailbox_get_vc_memory( &vc ) >= 0) + ram_end -= vc.size; } bsp_work_area_initialize_default( (void *) work_base, ram_end - work_base ); -- 2.24.1
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel