Memory Map Information - Ducati

From OMAPpedia

Revision as of 23:12, 20 January 2012 by Cjansson (Talk | contribs)
Jump to: navigation, search

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.

Contents

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";
}
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";
}

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 <sysbios-rpmsg>/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. Following is an excerpt from the resource file here:

#define IPU_MEM_TEXT            0x0
#define IPU_MEM_DATA            0x80000000
#define IPU_MEM_IOBUFS          0x88000000
#define IPU_MEM_IPC_VRING       0xA0000000
#define IPU_MEM_IPC_DATA        0x9F000000

#define PHYS_MEM_IPC_VRING      0xB3A00000
#define PHYS_MEM_IPC_DATA       0xB3B00000
#define PHYS_MEM_TEXT           0xB3C00000
#define PHYS_MEM_DATA           0xB4300000
#define PHYS_MEM_IOBUFS         0xBA300000

struct resource {
    u32 type;
    u32 da_low;       /* Device (Ducati virtual) Address */
    u32 da_high;
    u32 pa_low;       /* Physical Address */
    u32 pa_high;
    u32 size;
    u32 reserved;
    char name[48];
};

#pragma DATA_SECTION(resources, ".resource_table")
#pragma DATA_ALIGN(resources, 4096)
struct 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" },
};

The above 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.

#define OMAP4_ION_HEAP_SECURE_INPUT_SIZE        (SZ_1M * 90)

#define PHYS_ADDR_SMC_SIZE      (SZ_1M * 3)
#define PHYS_ADDR_SMC_MEM       (0x80000000 + SZ_1G - PHYS_ADDR_SMC_SIZE)
#define PHYS_ADDR_DUCATI_SIZE   (SZ_1M * 105)
#define PHYS_ADDR_DUCATI_MEM    (PHYS_ADDR_SMC_MEM - PHYS_ADDR_DUCATI_SIZE - \
                                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);
#ifdef CONFIG_ION_OMAP
        omap_ion_init();
#endif

        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 

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.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox