Memory Map Information - Ducati

This page explains the current memory map on the Ducati and how the equivalent memory is set-aside using carveouts on the host processor. This is applicable only for the Android 4.0 Icecream kernels.

= SYS/BIOS Information =

Memory Definition Files
SYS/BIOS requires that a Platform be defined properly with the memory map to be used by each target processor. This is done through Platform.xdc files, and are defined in the SYS/BIOS RPMsg source code at: metaonly module Platform inherits xdc.platform.IPlatform { config ti.platforms.generic.Platform.Instance plat = ti.platforms.generic.Platform.create("plat", {            clockRate:      200.0,             catalogName:    "ti.catalog.arm.cortexm3",             deviceName:     "OMAP4430",             externalMemoryMap: [                 ["EXT_CODE",  {name: "EXT_CODE",  base: 0x00004000, len: 0x000FC000, space: "code", access: "RWX"}],                 ["EXT_DATA",  {name: "EXT_DATA",  base: 0x80000000, len: 0x00080000, space: "data", access: "RW"}],                 ["EXT_HEAP",  {name: "EXT_HEAP",  base: 0x80080000, len: 0x00080000, space: "data", access: "RW"}],                 ["TRACE_BUF", {name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW"}],                 ["EXC_DATA",  {name: "EXC_DATA",  base: 0x9F060000, len: 0x00010000, space: "data", access: "RW"}],                 ["PM_DATA",   {name: "PM_DATA",   base: 0x9F0E0000, len: 0x00020000, space: "data", access: "RWX"}], ],    }); instance :     override config string codeMemory = "EXT_CODE";     override config string dataMemory = "EXT_DATA";     override config string stackMemory = "EXT_DATA"; }
 * /src/ti/platform/omap4430/core0/Platform.xdc file

metaonly module Platform inherits xdc.platform.IPlatform { config ti.platforms.generic.Platform.Instance plat = ti.platforms.generic.Platform.create("plat", {            clockRate:      200.0,             catalogName:    "ti.catalog.arm.cortexm3",             deviceName:     "OMAP4430",             externalMemoryMap: [                 ["EXT_CODE",  {name: "EXT_CODE",  base: 0x00100000, len: 0x00500000, space: "code", access: "RWX"}],                 ["EXT_DATA",  {name: "EXT_DATA",  base: 0x80100000, len: 0x00500000, space: "data", access: "RW"}],                 ["EXT_HEAP",  {name: "EXT_HEAP",  base: 0x80600000, len: 0x05A00000, space: "data", access: "RW"}],                 ["TRACE_BUF", {name: "TRACE_BUF", base: 0x9F070000, len: 0x00060000, space: "data", access: "RW"}],                 ["EXC_DATA",  {name: "EXC_DATA",  base: 0x9F0D0000, len: 0x00010000, space: "data", access: "RW"}],                 ["PM_DATA",   {name: "PM_DATA",   base: 0x9F0E0000, len: 0x00020000, space: "data", access: "RWX"}], ],            ],     }); instance :     override config string codeMemory = "EXT_CODE";     override config string dataMemory = "EXT_DATA";     override config string stackMemory = "EXT_DATA"; }
 * /src/ti/platform/omap4430/core1/Platform.xdc file

The externalMemoryMap defines the valid memory regions that will be used by the linker for placing various ELF sections. All the above regions need to be backed up by proper external memory, and be mapped into the Ducati MMU. The codeMemory, dataMemory & stackMemory config parameters assign default memory regions into which the ELF code, data and stack memory sections are to be placed. Currently, the following memory regions are defined
 * 1) EXT_CODE: Region for all code sections
 * 2) EXT_DATA: Region for all data sections
 * 3) EXT_HEAP: Region for all memory heaps, this region is to be used for putting the heap memory, and not have any code or data regions.
 * 4) TRACE_BUF: Region for placing the shared memory circular trace buffer, size of this region limits the maximum the trace buffer can be.
 * 5) EXC_DATA: Region for assigning a section into which all the exception/remote processor crash information is dumped into.
 * 6) PM_DATA: Special Region to be used for the M3 Power Management Context Save & Restore and Standby-ready handshake with the remoteproc code.

Linker Section Mapping
The sample executable can always place a specific section into a specific memory region. An example below derived from /src/ti/configs/omap4430/DucatiCore0.cfg places some mandatory sections into specific dedicated regions. Program.sectMap[".resetVecs"].loadAddress = (Core.id + 1) * 0x400; Program.sectMap[".vecs"].loadAddress     = (Core.id + 1) * 0x400; Program.sectMap[".tracebuf"] = "TRACE_BUF"; Program.sectMap[".errorbuf"] = "EXC_DATA"; Program.sectMap[".example"] = new Program.SectionSpec; Program.sectMap[".example"].type = "NOINIT"; Program.sectMap[".example"].loadSegment = Program.platform.dataMemory;

The loadAddress places a specific section at a specific address location. In the above example, Core0's .resetVecs and .vecs sections are both placed at 0x400. The NOINIT type specifies that the section be not initialized by cinit processing when the Ducati is booting up. The loadSegment places the section in a memory region, and in the above example, the region for "example" data is being specified as the default data memory section configured in the Platform.xdc file.

Attribute MMU Configuration
All the memory that needs to be accessed by the Cortex-M3 and DSP processor cores need to be defined in the Attribute-MMU (AMMU) as well. Any address not defined in the AMMU will generate an AMMU fault/exception back to the core. The AMMU defines the different memory attributes like cacheability, posted/non-posted and other properties. Each AMMU has a number of entries, each of which can define properties for a fixed size of address space.

The two Cortex-M3 cores have a single AMMU. The AMMU is initially in bypass-state and is configured by SYS/BIOS during the bootup of the first processor. SYS/BIOS configures the AMMU using an AMMU configuration file, and the configuration entries are stored as constants in the base image. The external memory and peripheral memory used in the above examples for Ducati is demonstrated in a sample configuration file.

Resource Table
The Resource Table is a special section that needs to be present in the firmware binary, and needs to be linked into atleast one of the base-images. This section defines a resource table including different memory entries, that will be used by the remoteproc driver to program the MMU accordingly. As such, the memory entries that need to be defined should include all the external memory as well as any peripheral memory needed by both the Cortex M3 processors. The following is an excerpt from the resource definition file.

/* * Assign fixed RAM addresses to facilitate a fixed MMU table. * PHYS_MEM_IPC_VRING & PHYS_MEM_IPC_DATA MUST be together. */ ti_resources_IpcMemory_Resource resources[] = { { TYPE_TRACE, 0, 0, 0, 0, 0, 0, "0" }, { TYPE_TRACE, 1, 0, 0, 0, 0, 0, "1" }, { TYPE_ENTRYPOINT, 0, 0, 0, 0, 0, 0, "0" }, { TYPE_ENTRYPOINT, 1, 0, 0, 0, 0, 0, "1" }, { TYPE_CRASHDUMP, 0, 0, 0, 0, 0, 0, "0" }, { TYPE_CRASHDUMP, 1, 0, 0, 0, 0, 0, "1" }, { TYPE_DEVMEM, IPU_TILER_MODE_0_1, 0, L3_TILER_MODE_0_1, 0, SZ_256M, 0, "IPU_TILER_MODE_0_1" }, { TYPE_DEVMEM, IPU_TILER_MODE_2, 0, L3_TILER_MODE_2, 0, SZ_128M, 0, "IPU_TILER_MODE_2" }, { TYPE_DEVMEM, IPU_TILER_MODE_3, 0, L3_TILER_MODE_3, 0, SZ_128M, 0, "IPU_TILER_MODE_3" }, { TYPE_DEVMEM, IPU_PERIPHERAL_L4CFG, 0, L4_PERIPHERAL_L4CFG, 0, SZ_16M, 0, "IPU_PERIPHERAL_L4CFG" }, { TYPE_DEVMEM, IPU_PERIPHERAL_L4PER, 0, L4_PERIPHERAL_L4PER, 0, SZ_16M, 0,"IPU_PERIPHERAL_L4PER" }, { TYPE_DEVMEM, IPU_IVAHD_CONFIG, 0, L3_IVAHD_CONFIG, 0, SZ_16M, 0, "IPU_IVAHD_CONFIG" }, { TYPE_DEVMEM, IPU_IVAHD_SL2, 0, L3_IVAHD_SL2, 0, SZ_16M, 0, "IPU_IVAHD_SL2" }, /* IPU_MEM_IPC_VRING should be first irrespective of static or dynamic * carveout. */    { TYPE_CARVEOUT, IPU_MEM_IPC_VRING, 0, PHYS_MEM_IPC_VRING, 0, SZ_1M, 0, "IPU_MEM_IPC_VRING" }, { TYPE_CARVEOUT, IPU_MEM_IPC_DATA, 0, PHYS_MEM_IPC_DATA, 0, SZ_1M, 0, "IPU_MEM_IPC_DATA" }, { TYPE_CARVEOUT, IPU_MEM_TEXT, 0, PHYS_MEM_TEXT, 0, SZ_1M * 6, 0, "IPU_MEM_TEXT" }, { TYPE_CARVEOUT, IPU_MEM_DATA, 0, PHYS_MEM_DATA, 0, SZ_1M * 96, 0, "IPU_MEM_DATA" }, { TYPE_CARVEOUT, IPU_MEM_IOBUFS, 0, PHYS_MEM_IOBUFS, 0, SZ_1M * 90, 0, "IPU_MEM_IOBUFS" }, };
 * 1) define IPU_MEM_TEXT           0x0
 * 2) define IPU_MEM_DATA           0x80000000
 * 3) define IPU_MEM_IOBUFS         0x88000000
 * 4) define IPU_MEM_IPC_VRING      0xA0000000
 * 5) define IPU_MEM_IPC_DATA       0x9F000000
 * 1) define PHYS_MEM_IPC_VRING     0xB3A00000
 * 2) define PHYS_MEM_IPC_DATA      0xB3B00000
 * 3) define PHYS_MEM_TEXT          0xB3C00000
 * 4) define PHYS_MEM_DATA          0xB4300000
 * 5) define PHYS_MEM_IOBUFS        0xBA300000
 * 1) pragma DATA_SECTION(resourcesLen, ".resource_size")
 * 2) pragma DATA_SECTION(resources, ".resource_table")

Resource table entries are defined as

struct Resource { UInt32 type; UInt32 da_low;      /* Device Virtual Address */ UInt32 da_high; UInt32 pa_low;      /* Physical Address */ UInt32 pa_high; UInt32 size; UInt32 reserved; Char  name[48]; };

The resource table uses static fixed physical addresses and expects that the remoteproc's static pool is configured to cover this region. All the different TYPE_CARVEOUT regions are from a single contiguous carveout pool, as remoteproc currently only supports a single static pool. The addresses for TYPE_TRACE and TYPE_CRASHDUMP are filled-in during the post-processing step of the ELF baseimages.

The physical address in the above table for a TYPE_CARVEOUT entry can be given as 0 to let the kernel allocate and assign the memory for that region. The kernel needs to be configured to reserve a contiguous memory for this purpose, and is explained below. While the current RPMsg code can support this feature, it is currently not feasible to allow Multimedia applications to run (limitations will be fixed soon). Further, the static addresses are required for enabling the Secure Playback usecase.

= Kernel Information =

Board File Configuration
The static carveout needs to be set-aside from the kernel, and needs to be done early enough to avoid any ARM aliasing issues due to different memory attributes that may be given to memory associated with the kernel. This memory can be carved-out using bootargs, but this is non-standard and inelegant as this requires every developer/user to be aware of this. RPMsg uses memblock API during the board initialization to reserve the necessary memory. Following is the configuration from the Panda board files. OMAP4_ION_HEAP_SECURE_INPUT_SIZE) ... static void __init omap4_panda_reserve(void) {        /* do the static reservations first */         memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE);         memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE);         /* ipu needs to recognize secure input buffer area as well */         omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE + OMAP4_ION_HEAP_SECURE_INPUT_SIZE);        omap_ion_init;         omap_reserve; } MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")         /* Maintainer: David Anders - Texas Instruments Inc */         .boot_params    = 0x80000100,         .reserve        = omap4_panda_reserve,         .map_io         = omap4_panda_map_io,         .init_early     = omap4_panda_init_early,         .init_irq       = gic_init_irq,         .init_machine   = omap4_panda_init,         .timer          = &omap_timer, MACHINE_END
 * 1) define OMAP4_ION_HEAP_SECURE_INPUT_SIZE       (SZ_1M * 90)
 * 1) define PHYS_ADDR_SMC_SIZE     (SZ_1M * 3)
 * 2) define PHYS_ADDR_SMC_MEM      (0x80000000 + SZ_1G - PHYS_ADDR_SMC_SIZE)
 * 3) define PHYS_ADDR_DUCATI_SIZE  (SZ_1M * 105)
 * 4) define PHYS_ADDR_DUCATI_MEM   (PHYS_ADDR_SMC_MEM - PHYS_ADDR_DUCATI_SIZE - \
 * 1) ifdef CONFIG_ION_OMAP
 * 1) endif

The above carveout needs to match to that of the contiguous static memory used in the Resource Table on the SYS/BIOS-side. The omap_ipu_set_static_mempool allows this carveout to be queried by the remoteproc platform device file to fill in its memory pool information for both the static and dynamic carveout pools. This data is passed using the platform data onto the remoteproc platform driver.

Kernel MenuConfig Configuration
Instead of using board configuration files to set-aside a contiguous memory at a specific address, one can choose to have all the remote processor memory regions be allocated at a dynamic address. This gives the flexibility without having to match the kernel and SYS/BIOS-sides, but for this the Resource Table has to be defined properly.

The Physical carveout memory pool size needs to be configured in the kernel menuconfig step and needs to be large enough to cover all the TYPE_CARVEOUT memory regions on the SYS/BIOS-side. System Type ---> TI OMAP Common Features ---> <*> OMAP Virtio-based remote processor messaging support [*] OMAP RPMSG Recovery -*- Mailbox framework support (256) Mailbox kfifo default buffer size (bytes) -*- IOMMU support for OMAP devices [ ]  Export OMAP IOMMU internals in DebugFS (0x0) Physical carveout memory pool size (Byte)

Memory is reserved within the common omap_reserve function through the omap_ipu_reserve_sdram_memblock function. omap_reserve is usually called during every board initialization. The dynamic allocation is done using memblock_alloc & memblock_remove kernel functions. This memory is also carved-out and is not visible to the kernel.