Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

soc: xlnx: zynqmp: overhaul the Cortex-R MPU setup #79221

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ibirnbaum
Copy link
Member

@ibirnbaum ibirnbaum commented Sep 30, 2024

To this day, the MPU region definitions provided for the ZynqMP/UltraScale+'s Cortex-R cores, which are pretty old code by now, cause various problems on actual hardware, which qemu_cortex_r5 tends to ignore:

  • The RAM region is not associated with the device tree at all. The RAM base address is always hardcoded to 0, which obviously causes problems if the RAM base address isn't at that location according to the device tree.
  • The RAM region's size is fixed, also not associated with the device tree.
  • The RAM region's definition, if starting at address 0, doesn't just contain RAM, but also includes both the ATCM (with the exception vectors right at the start) and BTCM memory areas, whose availability isn't universally guaranteed, and which may have a 'black hole' between them depending on the operational mode of the R-Core cluster (with QEMU generously ignoring this). There are no facilities to explicitly locate data in the TCMs and use them in the intended fashion according to the technical reference manual. There's also no way to control which part of section .text ends up in the TCMs and from what point of the text section on, regular RAM is used. Half of some random function may end up at the very upper end of the BTCM, and the other half continues on from the start of RAM behind the BTCM.

For the first two items, the macros CONFIG_SRAM_BASE_ADDRESS and REGION_SRAM_SIZE exist, which haven't been referenced prior.

Also, XIP wasn't considered and local macro definitions for region properties were used although global ones are already provided.

Therefore, the proposed overhaul changes the following:

  • Leave the sram0 declaration at base address 0x0 for all in-tree boards which already use it, but move the declaration over to the boards' device trees. If it works for them and the inclusion of ATCM and BTCM isn't an issue there, great.
  • Remove the universal sram0 declaration from the SoC level, as having different offset addresses (beyond the TCMs) and sizes now actually becomes an option, enabling effective memory map layout specification for memory resource management / exclusion when operating in parallel with the A-cores. Specify sram0 at the board level as the ZynqMP doesn't come with integrated, always fixed-size RAM like the common microcontrollers, but with flexible RAM sizes instead, depending on the RAM chip attached on the target hardware.
  • Reference the region property macros provided in arm_mpu_v7m.h instead of using local declarations
  • Add a (potentially overlapping) region declaration which implements R/O for .text and .rodata
  • Handle R/O and XN properties for the flash0 region depending on whether CONFIG_XIP is set or not.
  • Modify the linker command script so that the region size bit mask for the ROM region is computed correctly.
  • and as a minor extra for qemu_cortex_r5: so far, this target has only been able to provide 32MB of RAM with a non-zero offset address (must be a multiple of the region size, so (0x0 + 32MB)) due to only specifying a total ATCM + BTCM + RAM size of 64 MB starting at 0x0 in the device tree parsed by QEMU, so having 64MB @ (0x0 + 64MB) didn't work. Therefore, increase the RAM size in the QEMU device tree for qemu_cortex_r5.

I'm well aware that tying the RAM region size to the device tree directly contradicts #61008 which dates back to last year. However, I do believe that this was never a good idea to start with: generally opening up 2 GB of RAM address space in an SoC where the R-cores and the A-cores share the RAM just so that openamp SHMs could be effortlessly randomly placed at an address that may or may not be beyond the range actually used by the Zephyr image seems extremely risky when considering the possibility of parallel Linux operation on the A-cores. Also, this is a feature that is not generally used by everyone developing for the ZynqMP R-cores. Memory ranges for such specific use cases can be declared on a need-to-have basis in the respective target's device tree or in application-specifc overlays, the MPU setup will consider such additional region declarations automatically via mpu_configure_regions_from_dt(). If there's any board definitions or samples in-tree that make use of this feature on the ZynqMP, I can have a look on how to set up the SHM memory regions properly and add the fixes to this branch.

Move the unmodified sram0 memory area declaration to this board's
device tree due to its removal from the SoC device tree.

Signed-off-by: Immo Birnbaum <[email protected]>
…d DT

Move the unmodified sram0 memory area declaration to this board's
device tree due to its removal from the SoC device tree.

Signed-off-by: Immo Birnbaum <[email protected]>
Expand the RAM area beginning behind the BTCM to allow the use
of a 64MB SRAM area starting at 0x4000000, which is the lowest
possible 64MB area with a non-zero start address that doesn't
overlap with the ATCM and BTCM memory areas.

Signed-off-by: Immo Birnbaum <[email protected]>
Declare the sram0 area for this board to start at 0x4000000
and to be 64MB in size. The base address is the lowest possible
multiple of 64MB which doesn't have its base address at 0,
therefore preventing the mixed use of regular RAM and the
ATCM/BTCM and the possible issues of having a 'black hole'
between the ATCM and BTCM areas or the BTCM being completely
disabled.

Signed-off-by: Immo Birnbaum <[email protected]>
Remove the universal, unconditional declaration of the RAM area
at the SoC level, due to:

- the hardcoded base address 0 overlapping the exception vectors,
  the ATCM and the BTCM areas.
- the availability of the BTCM not being guaranteed unconditionally
  (config pin dependant)
- the possibility of having a 'black hole' between the ATCM and
  the BTCM depending on the operating mode of the R-cores cluster,
  which leads to a part of the text section being unavailable
- qemu not properly implementing the configuration-dependant
  behaviour of the ATCM and BTCM areas.

Signed-off-by: Immo Birnbaum <[email protected]>
update the directive that calculates the ROM region size
bit mask for the MPU setup.

Signed-off-by: Immo Birnbaum <[email protected]>
Overhaul the MPU region definitions that are being
configured when the MPU is set up:
- drop local attribute definitions in favor of those
  already provided in arm_mpu_v7m.h
- actually tie the RAM region to the device tree
- set up a (potentially overlapping) R/O region for
  .text and .rodata, which hasn't existed so far
- Consider XIP
- Consider OCM only when not running a testsuite
  (comp. zephyrproject-rtos#79627)

Signed-off-by: Immo Birnbaum <[email protected]>
Apply the same modifications made to the ZynqMP's memory
regions to the cortex_r8_virtual SoC which was mainlined
while the fixes for the ZynqMP were being developed
(minus the OCM mapping, as there's no indication that this
type of memory was considered).

The cortex_r8_virtual appears to be a stripped down copy
of the old qemu_cortex_r5 codebase, therefore, the duplicated
MPU regions have the same flaws as qemu_cortex_r5 or any
actual ZynqMP-based target for that matter.

Signed-off-by: Immo Birnbaum <[email protected]>
Copy link
Collaborator

@michalsimek michalsimek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not upstream QEMU but AMD/Xilinx qemu fork. Is there any warning about it?
From my perspective having dtb as blob in source code is not a good idea. Isn't there a better way to put there dts and dtc will convert it as the part or build process.
Another reason is that it is hard to review what has been changed from between one dtb and another dtb.

@ithinuel
Copy link
Collaborator

You can refer to https://docs.zephyrproject.org/latest/contribute/bin_blobs.html for the policy around binary blobs in Zephyr.

@michalsimek
Copy link
Collaborator

You can refer to https://docs.zephyrproject.org/latest/contribute/bin_blobs.html for the policy around binary blobs in Zephyr.

Thanks.
"The Zephyr Project does not host binary blobs in its Git repositories or anywhere else."
In this case it is just DT file and source code can be seen but I know it doesn't look nice.

@ibirnbaum
Copy link
Member Author

ibirnbaum commented Oct 25, 2024

Should there be a warning regarding the fact that Xilinx's fork of QEMU is used? If there were any functional issues with this version, this would become obvious with pretty much every PR as the QEMU targets are tested as part of the CI. Admittedly, there seem to be a few hiccups in there (aside from the afforementioned not caring about the black hole between the ATCM and the BTCM that exists on actual hardware, for example, there's just nothing in the clock configuration registers within the Zynq-7000's SLCR), but I'd only see a benefit in switching over if those issues were proven fixed in mainline QEMU. As this version is, along with other QEMU flavors, shipped with the SDK, it's not a case of having accidentially downloaded the wrong flavor of QEMU.

Agreed, the case of QEMU only working with DTB's is inconvenient, as you can't easily diff. So adding the textual description that the RAM size was changed was the best that could be done here. However, I wouldn't see the DTB as a blob as in a firmware blob, for example. Your suggestion of having the device tree for QEMU in DTS format and converting it during the build process is rather something that I'd see in the area of the build framework / west integration, as QEMU is integrated all the way into (at least) west's run and debugserver commands. The link is likely board.cmake. I'd suggest writing an Enhancement Suggestion to the folks in charge of the build system.

@michalsimek
Copy link
Collaborator

I am new to this project and things around it but descriptions for AMD/Xilinx Qemu has never been pushed to my upstream projects. It is only kept in downstream repositories.
The reason was that maintainers wanted to use upstream Qemu only. That's the reason why I am pushing Microblaze V to QEMU source code too even we have internal QEMU working based on DT.
Is there any support for other emulators inside Zephyr? Because if yes, AMD Qemu could be consider as another emulator or it's flavor and integration could be done in a similar way.

@stephanosio
Copy link
Member

stephanosio commented Oct 25, 2024

QEMU source code too even we have internal QEMU working based on DT.
Is there any support for other emulators inside Zephyr? Because if yes, AMD Qemu could be consider as another emulator or it's flavor and integration could be done in a similar way.

We already have Xilinx QEMU in the Zephyr SDK and it is currently being used to test ZynqMP platforms in the upstream CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants