The cos.xml File

Introduction

The cos.xml file contains configuration information for your application, such as code and data sizes, stack sizes, runtime parameters, and flags. This file is generated automatically by the SDK with default values that are appropriate for most applications.

When ready to master your application, the Wii U Application Configuration Tool helps you gather all of the configuration settings of your application and generates the production version of cos.xml. This tool is available separately from the SDK. Contact your local Nintendo developer support group for more information.

NOTE:
The cos.xml file is published with your application. It cannot be changed at runtime.

cos.xml is located in your application's /code directory at runtime. When you run your application with the caferun or cafex run launching command using PCFS, /code is mounted from the host PC directory that contains your RPX file, and the launching command creates the CAFE_CODE_DIR environment variable to refer to that host PC directory.

If cos.xml does not exist when you run your application, the launching command will create it in $CAFE_CODE_DIR using default values.

Description

This section describes the common parameters in cos.xml that may be modified during the development cycle.

Parameter Type Length
(Bytes)
Description
version unsignedInt 4 Data structure version of the cos.xml file. If the cos.xml data structure version for the application is older than the version in the SDK, the application version of the cos.xml file is replaced by the default version. This occurs when you run your application.
NOTE:
If you intend to run an application built with an older SDK on the current SDK, then when using the cafex run command, use the -L option to run the legacy application independent of the XML version.

If using XML files with mismatched versions, failure to use the -L option will prevent a title from launching through cafex run.
argstr string 4096 The name of the application and any arguments to be passed to the application.
cmdFlags unsignedInt 4 Bit flags that are passed to the application.
max_size hexBinary 4 Specifies the arena, or maximum amount of memory in bytes that is reserved for the application, including code and data. The default value is 1 GB for production systems, and 2 GB for development systems.
max_codesize hexBinary 4 Specifies the maximum amount of memory deducted from the arena (max_size) that is reserved for program code. The default value is 224 MB. The code size is deducted from max_size and the balance, (max_size - max_codesize + 1), is reserved for data and heap.

Maximum Code Memory

The following scenarios are used to specify maximum code memory, Calculating Maximum Code Memory (Debug Phase) and Calculating Maximum Code Memory (Release Phase).

Calculating Maximum Code Memory (Debug Phase)

The following methods can be used to obtain the code size for the max_codesize field in cos.xml. The options described below are suitable for the debug phase of application development:

  1. Use COS verbose level 2 when you run your application. When you include the "-v 2" option with caferun, you will be running with COS verbose level 2. In this mode, after the main program loads, a report is printed that lists the RPLs that are loaded and the memory that they are using. The information does not account for temporary space that the loader uses but clearly indicates everything that is loaded. You are not required to change the source code, but it is not as accurate if your application acquires RPLs.
  2. Get the Loader's heap statistics at runtime. The OSDynLoad_GetLoaderHeapStatistics function returns statistics on the heaps used by the loader at the time that the function is called. Call OSDynLoad_GetLoaderHeapStatistics at startup and when an RPL is loaded or unloaded so that you may track the maximum value seen throughout the life of your application. You may set up a callback that is called every time an RPL is loaded or unloaded using OSDynLoad_AddNotifyCallback. This is the easiest method if you manually acquire RPLs throughout your application, but requires that you modify the source code temporarily.
  3. Use the dumprpl build tool. The dumprpl tool dumps to stdout the contents of an RPX or RPL file that is generated by the preprpl[32|64] tool. When you specify the -loadsize option, information is printed about the amount of code and data memory that is required to load your application. You are not required to change the source code, but it is not as accurate as the other two options. It also requires that you know which RPLs are loaded for your application. To discover which RPLs are loaded, you perform the first few steps of the COS verbose level 2 option or the OSDynLoad_GetLoaderHeapStatistics option.

There are four build configurations that you should use to calculate the max_codesize.

You may get different max_codesize values with each of these configurations. If the max_codesize value is not set high enough, the game fails to load because it runs out of memory. It is recommended that you run your application and calculate the max_codesize using all four build configurations, with and without the Debugger, and then enter the highest number that you get in the max_codesize field in cos.xml. Some experimentation may be required to find the final max_codesize value.

Calculate the max_codesize in bytes using the following formula:

max_codesize = actual-loaded-size + heap-management-buffer + decompression-buffer + (shared-area-RPLs * 250)
NOTE:
The Wii U Error Viewer and Software Keyboard dynamically load RPLs on program creation. This information should be taken into account when calculating max_codesize. You should exercise your game thoroughly to load all game and system RPLs. For more information, see Using the Loader's heap statistics at runtime.

1. Using COS verbose level 2 to calculate the max_codesize value

When you use the "-v 2" option with the make run command, a verbose log is printed that helps you derive the max_codesize value and helps you find the state of the code memory area if the command fails.

The following table contains the commands for each of the build configurations.

make Command <OutputFileName>
make USER_RUN="-v 2 -R" run > <OutputFileName> make_run.txt
make USER_RUN="-v 2 -R" NDEBUG=TRUE run > <OutputFileName> make_ndebug_run.txt
make USER_RUN="-v 2 -R" multirun > <OutputFileName> make_multirun.txt
make USER_RUN="-v 2 -R" NDEBUG=TRUE multirun > <OutputFileName> make_ndebug_multirun.txt

NOTE:
In the commands above, use the -R option to run under the Debugger without starting the Debugger GUI.

In the following instructions, we use the helloworld demo and the DEBUG configuration to determine the amount of memory that our application uses. Repeat the instructions for the NDEBUG configuration listed in the table.

To calculate max_codesize using make run:

  1. Open a cafe.bat shell.
  2. At the command prompt, change directories to the location of your application. Using the helloworld demo as our example, type the following.
    cd "$CAFE_ROOT/system/src/demo/helloworld"
    
  3. Perform this step the first time that you build your application for the purpose of calculating or recalculating the max_codesize value. You do not need to perform this step for each of the build configurations.
    1. At the command prompt, type make clobber. This provides a known-good place to start your calculations by deleting previous build folders.
    2. At the command prompt, type make run USER_RUN="-q". This sets the CMDFLAGS value to 0 in cos.xml in the DEBUG folder.
    3. At the command prompt, type make NDEBUG=TRUE run USER_RUN="-q". This sets the CMDFLAGS value to 0 in cos.xml in the NDEBUG folder.
  4. At the command prompt, type the following.
    make USER_RUN="-v 2 -R" run > <OutputFileName>
    
    In our example, we type:
    make USER_RUN="-v 2 -R" run > make_debug_multirun.txt
    
    This command outputs the log to a file named make_debug_run.txt in the directory with your application.
  5. Open the make_debug_run.txt file with the text editor of your choice, and start scanning up from the bottom to locate the first lines that contain the word LOADER and the lines that follow that contain the word LOAD. In our example, we found the following information:
    ------------------PROCESS 15 GAIN FOREGROUND--------------------
    PROCESS 15 STARTING
    SYSLOG_LEVEL 2: Warnings and Notices Enabled, CafeOS Structures Integrity-Checked
    UserMode Core & Thread Initialization (3 Cores)
      Core 1 Complete, Default Thread 0x10049CA0
      Core 0 Complete, MSR 0x00005072, Default Thread 0x10049600
      Core 2 Complete, MSR 0x00005072, Default Thread 0x1004A340
    UserMode OS library build date: May 13 2013 10:34:24
    __AppFlags: 0x00000420
    OSBlockThreadsOnExit default for SDK version 20911
    
    LOADER: fixup start  CODE heap: used 57:796864, free 1:234071808, unused 710 largest free block 234071808
    LOADER: fixup done   CODE heap: used 58:797312, free 1:234071360, unused 709 largest free block 234071360
    LOADER: link done    CODE heap: used 45:708288, free 1:234160384, unused 722 largest free block 234160384
    
    nn_act:          TEXT 0x0203fe80:0x02073c10 DATA 0x1057a0c0:0x10595c08 LOAD 0x10595c20:0x105b4d30
    nn_acp:          TEXT 0x020744c0:0x020a9700 DATA 0x105b4e80:0x105cbdc8 LOAD 0x105cbde0:0x105ee270
    nn_save:         TEXT 0x02015680:0x0203f5c0 DATA 0x10552b00:0x10566c84 LOAD 0x10566ca0:0x10579f70
    nsysccr:         TEXT 0x010a6940:0x010af410 DATA 0x10219380:0x10221080 LOAD 0xfafd91c0:0xfafded90
    vpadbase:        TEXT 0x0110dac0:0x01111c90 DATA 0x102cf680:0x102d2c00 LOAD 0xfafadea0:0xfafb1df0
    vpad:            TEXT 0x01111d00:0x0111d670 DATA 0x102d2c00:0x102da6c4 LOAD 0xfafa8800:0xfafade90
    uvc:             TEXT 0x010bea80:0x010c0bb0 DATA 0x10239e40:0x1027e0c0 LOAD 0xfafd08c0:0xfafd3590
    tve:             TEXT 0x01081280:0x010a68d0 DATA 0x10211bc0:0x1021937c LOAD 0xfafdeda0:0xfafe6ff0
    tcl:             TEXT 0x010c0c00:0x010dae00 DATA 0x1027e100:0x102b6b9c LOAD 0xfafc7c20:0xfafd08b0
    dc:              TEXT 0x010fb840:0x0110da80 DATA 0x102c3f00:0x102cf664 LOAD 0xfafb1e00:0xfafb71d0
    avm:             TEXT 0x0111d6c0:0x0112e260 DATA 0x102da700:0x102e3f40 LOAD 0xfafa0e60:0xfafa87f0
    gx2:             TEXT 0x0112e2c0:0x011caf90 DATA 0x102e4000:0x1035ac0c LOAD 0xfaf85780:0xfafa0e50
    proc_ui:         TEXT 0x020a9f80:0x020ac6a0 DATA 0x105ee3c0:0x105f0b04 LOAD 0x105f0b20:0x105f47f0
    helloworld:      TEXT 0x02000000:0x02013f00 DATA 0x104ee400:0x1050e158 LOAD 0x1050e180:0x10515610
    coreinit:        TEXT 0x01018c00:0x01081240 DATA 0x10000000:0x10211bc0 LOAD 0xfafe7000:0xfafffff8
    
  6. Calculate the max_codesize in bytes using the following formula:
    max_codesize = actual-loaded-size + heap-management-buffer + decompression-buffer + (shared-area-RPLs * 250)
    1. Calculate the actual-loaded-size — The lines that start with LOADER contain information about the memory used for CODE heap. The numbers that immediately follow CODE heap are the number of blocks-used:code-heap-size (in bytes). Use the largest set of CODE heap numbers. In our example, we will use 58 blocks-used and 797312 code-heap-size in bytes.

      Multiply the code-heap-size by 1.15. In our example:
      actual-loaded-size = 797312 * 1.15 = 916909 bytes
    2. The heap-management-buffer is a fixed 12K for the heap overhead unless the blocks-used is greater than 768. In our example, the number of blocks-used is 58, so we add 12K for the heap overhead.
      max_codesize = 916909 + 12288 + decompression-buffer
    3. The decompression-buffer is a fixed 32K. In our example:
      max_codesize = 916909 + 12288 + 32768 = 961965
    4. Add 250 bytes per RPL in the shared area. The output from step 5 contains a list of all RPLs loaded in the application. On each line are pairs of TEXT, DATA, and LOAD addresses. Shared RPLs may be found by looking at the LOAD addresses: those starting with 0xf are in the shared area. In our helloworld example, there are 10 RPLs that are in the shared area: nsysccr.rpl, vpadbase.rpl, vpad.rpl, uvc.rpl, tve.rpl, tcl.rpl, dc.rpl, avm.rpl, gx2.rpl, and coreinit.rpl.
      max_codesize = 961965 + (10 * 250) = 964465
  7. Convert the max_codesize to a hex number. In our example:
    964465 converts to 0xEB771
  8. Rounding up to the next 128KB, we enter 0x100000 in the max_codesize field in cos.xml.

In the following instructions, we use the helloworld demo and the DEBUG with Multi configuration to determine the amount of memory that our application uses. Repeat the instructions for the NDEBUG with Multi configuration listed in the table.

To calculate max_codesize using make multirun:

  1. Open a cafe.bat shell.
  2. At the command prompt, change directories to the location of your application. Using the helloworld demo as our example, type the following.
    cd "$CAFE_ROOT/system/src/demo/helloworld"
    
  3. Perform this step the first time that you build your application for the purpose of calculating or recalculating the max_codesize value. You do not need to perform this step for each of the build configurations.
    1. At the command prompt, type make clobber. This provides a known-good place to start your calculations by deleting previous build folders.
    2. At the command prompt, type make run USER_RUN="-q". This sets the CMDFLAGS to 0 value in cos.xml in the DEBUG folder.
    3. At the command prompt, type make NDEBUG=TRUE run USER_RUN="-q". This sets the CMDFLAGS to 0 value in cos.xml in the NDEBUG folder.
  4. At the command prompt, type the following.
    make USER_RUN="-v 2 -R" multirun > <OutputFileName>
    
    In our example, we type:
    make USER_RUN="-v 2 -R" multirun > make_debug_multirun.txt
    
    This command outputs the log to a file named make_debug_multirun.txt in the directory with your application.
  5. Open the make_debug_multirun.txt file with the text editor of your choice, and start scanning up from the bottom to locate the first lines that contain the word LOADER and the lines that follow that contain the word LOAD. In our example, we found the following information:
    ------------------PROCESS 15 GAIN FOREGROUND--------------------
    PROCESS 15 STARTING
    SYSLOG_LEVEL 2: Warnings and Notices Enabled, CafeOS Structures Integrity-Checked
    UserMode Core & Thread Initialization (3 Cores)
      Core 1 Complete, Default Thread 0x10070EE0
      Core 0 Complete, MSR 0x00005072, Default Thread 0x10070840
      Core 2 Complete, MSR 0x00005072, Default Thread 0x10071580
    Debug Agent Report Mask = 0x1007b560
    UserMode OS library build date: May 13 2013 10:34:24
    __AppFlags: 0x00000421
    
    OSBlockThreadsOnExit default for SDK version 20911
    LOADER: fixup start  CODE heap: used 136:2548416, free 1:232320256, unused 631 largest free block 232320256
    LOADER: fixup done   CODE heap: used 137:2548864, free 1:232319808, unused 630 largest free block 232319808
    LOADER: link done    CODE heap: used 106:2307584, free 2:232561088, unused 660 largest free block 232548352
    
    nn_act:          TEXT 0x021c6500:0x021fa290 DATA 0x10424440:0x1043ff88 LOAD 0x1043ffa0:0x1045f0b0
    nn_acp:          TEXT 0x021fab40:0x0222fd80 DATA 0x1045f200:0x10476148 LOAD 0x10476160:0x104985f0
    nn_save:         TEXT 0x0219bd00:0x021c5c40 DATA 0x103fce80:0x10411004 LOAD 0x10411020:0x104242f0
    nsysccr:         TEXT 0x02192980:0x0219b450 DATA 0x103ef440:0x103f7140 LOAD 0x103f7160:0x103fcd30
    vpadbase:        TEXT 0x0218df00:0x021920d0 DATA 0x103e7e00:0x103eb380 LOAD 0x103eb3a0:0x103ef2f0
    vpad:            TEXT 0x02181d40:0x0218d6b0 DATA 0x103dab40:0x103e2604 LOAD 0x103e2620:0x103e7cb0
    uvc:             TEXT 0x0217f3c0:0x021814f0 DATA 0x10393a80:0x103d7d00 LOAD 0x103d7d20:0x103da9f0
    tve:             TEXT 0x02146ac0:0x0216c110 DATA 0x10373280:0x1037aa3c LOAD 0x1037aa60:0x10382cb0
    tcl:             TEXT 0x0212c080:0x02146280 DATA 0x10331a00:0x1036a49c LOAD 0x1036a4c0:0x10373150
    dc:              TEXT 0x0216c940:0x0217eb80 DATA 0x10382e00:0x1038e564 LOAD 0x1038e580:0x10393950
    avm:             TEXT 0x0211abc0:0x0212b760 DATA 0x10320640:0x10329e80 LOAD 0x10329ea0:0x10331830
    gx2:             TEXT 0x0207d640:0x0211a310 DATA 0x1028e200:0x10304e0c LOAD 0x10304e20:0x103204f0
    proc_ui:         TEXT 0x02230600:0x02232d20 DATA 0x10498740:0x1049ae84 LOAD 0x1049aea0:0x1049eb70
    helloworld:      TEXT 0x02000000:0x02013f00 DATA 0x10000000:0x1001fd58 LOAD 0x1001fd80:0x10027210
    coreinit:        TEXT 0x02014780:0x0207cdc0 DATA 0x10027240:0x10238e00 LOAD 0x10238e00:0x10251df8
    
  6. Calculate the max_codesize in bytes using the following formula:
    max_codesize = actual-loaded-size + heap-management-buffer + decompression-buffer
    1. Calculate the actual-loaded-size — The lines that start with LOADER contain information about the memory used for CODE heap. The numbers that immediately follow CODE heap are the number of blocks-used:code-heap-size (in bytes). Use the largest set of CODE heap numbers. In our example, we will use 137 blocks-used and 2548864 code-heap-size in bytes.

      You must account for the loader temp heap, which is generally less then 15% of the actual-loaded-size. To perform this, multiply the code-heap-size that you found by 1.15.
      actual-loaded-size = code-heap-size * 1.15
      In our example:
      actual-loaded-size = 2548864 * 1.15 = 2931194 bytes
    2. The heap-management-buffer is a fixed 12K for the heap overhead. It may be more if the number of CODE heap blocks-used is greater than 768. In our example, the number of blocks-used is 137, so we add 12K for the heap overhead.
      max_codesize = 2931194 + 12288 + decompression-buffer
    3. The decompression-buffer is a fixed 32K. In our example:
      max_codesize = 2931194 + 12288 + 32768 = 2976250
    4. Add 250 bytes per RPL in the shared area. The output from step 5 contains a list of all RPLs loaded in the application. On each line are pairs of TEXT, DATA, and LOAD addresses. Shared RPLs may be found by looking at the LOAD addresses: those starting with 0xf are in the shared area. In our helloworld example, none of the RPLs are shared.
      max_codesize = 2976250 + 0 = 2976250
  7. Convert the max_codesize to a hex number. In our example:
    2976250 converts to 0x2D69FA
  8. Rounding up, we enter 0x2E0000 in the max_codesize field in cos.xml.

2. Using the Loader's heap statistics at runtime to calculate the max_codesize value

The loader uses two heaps to load the RPX and RPLs – one heap for data and one for code. The data heap uses the default heap unless the game developer changes it. To obtain the maximum code size for your application, at the start of the application, before any additional RPLs are acquired, call OSDynLoad_GetLoaderHeapStatistics to set the baseline. Then, each time an RPL is loaded or unloaded, register a callback using OSDynLoad_AddNotifyCallback that calls OSDynLoad_GetLoaderHeapStatistics and track the highest code size seen.

With this setup, play through normally, ensuring that you access the areas where the most RPLs are loaded at a given time. For example, in a level, with a menu open, eject the disc to get the Error Viewer to open. After playing through, review the information that was gathered to determine the maximum code size seen and perform the calculations to derive the value to put into the max_codesize field in the cos.xml file.

To calculate max_codesize using the OSDynLoad_GetLoaderHeapStatistics function:

  1. Using the helloworld demo as an example, modify the code as follows:
    ...
    
    static u32 maxCodeSize = 0;
    static u32 maxRplCount = 0;
    
    static void UpdateMaxCodeSize()
    {
        OSDynLoad_LoaderHeapStatistics heapStats;
        int error;
        int rplCount;
    
        error = OSDynLoad_GetLoaderHeapStatistics(&heapStats);
        if (error != OSDYNLOAD_ERR_NONE) { OSHalt("Error getting Heap Stats!\n"); }
    	
        if (heapStats.mCodeHeap_MemBytesUsed > maxCodeSize)
        {
    	maxCodeSize = heapStats.mCodeHeap_MemBytesUsed;
        }
    	
        rplCount = OSDynLoad_GetNumberOfRPLs();
        if (rplCount > maxRplCount)
        {
    	maxRplCount = rplCount;
        }
    	
        OSReport("Max Code Size Seen: %u bytes across %d RPLs\n", maxCodeSize, maxRplCount);
    }
    
    static void RPLNotification(
        OSDynLoad_ModuleHandle handle,
        void *arg,
        BOOL isLoad,
        OSDynLoad_NotifyHdr const* notify)
    {
        UpdateMaxCodeSize();
    }
    
    ...
    
    int main(int argc, void **argv)
    {
       ...
    	OSDynLoad_AddNotifyCallback(&RPLNotification, NULL);
        UpdateMaxCodeSize();
        ...
    }
    
    ...
    
    
  2. Play through the application, ensuring that you access the areas where the most RPLs are loaded at a given time. Initially, maxCodeSize is set to 0. Each time an RPL is loaded or unloaded, maxCodeSize is updated. At the end of play, the last output line starting with "Max Code Size Seen" contains the highest maxCodeSize value.
  3. Calculate the max_codesize in bytes using the following formula:
    max_codesize = actual-loaded-size + heap-management-buffer + decompression-buffer
    1. Calculate the actual-loaded-size. To perform this, multiply the Max Code Size Seen by 1.15.
      actual-loaded-size = Max Code Size Seen * 1.15
    2. The heap-management-buffer is a fixed 12K for the heap overhead unless the number of blocks-used exceeds 768. To estimate the number of blocks used, multiple the maximum RPL count by 10. If the calculated value exceeds 768, use a value of 16-bytes per block.
      max_codesize = actual-loaded-size + 12288 + decompression-buffer
    3. The decompression-buffer is a fixed 32K. In our example:
      max_codesize = actual-loaded-size + 12288 + 32768
    4. Add 250 bytes per RPL.
      max_codesize = actual-loaded-size + 12288 + 32768 + (RPLs * 250)
  4. Convert the max_codesize to hex.
  5. Round up to the next 128KB, and then enter that value in the max_codesize field in cos.xml

3. Using the dumprpl build tool to calculate the max_codesize value

When you use the -loadsize option with the dumprpl command, a summary of the amount of code-area-memory that is required for the loading process is printed.

make Command dumprpl Arguments
make run Include the RPX file, any custom RPL files, and all system RPL files used in the application. For example: nn_act.rpl, nn_acp.rpl, nn_save.rpl, and proc_ui.rpl. Follow the instructions in To calculate max_codesize for a standard build using dumprpl.
make NDEBUG=TRUE run Include the RPX file, any custom RPL files, and all system RPL files used in the application. Follow the instructions in To calculate max_codesize for a standard build using dumprpl.
make multirun Include the RPX file, any custom RPL files, and all system RPL files used in the application. Follow the instructions in To calculate max_codesize for a Multi build using dumprpl.
make NDEBUG=TRUE multirun Include the RPX file, any custom RPL files, and all system RPL files used in the application. Follow the instructions in To calculate max_codesize for a Multi build using dumprpl.

For more information about the dumprpl build tool, see the dumprpl MAN page.

In the following instructions, we use the helloworld demo and the default DEBUG configuration to determine the amount of memory that our application uses. Repeat the instructions for the NDEBUG the configuration.

To calculate max_codesize for a standard build using dumprpl

  1. Open a cafe.bat shell.
  2. At the command prompt, change directories to the location of the RPXfile for your application. Using the helloworld demo as our example, type the following.
    cd "$CAFE_ROOT/system/bin/ghs/cafe/demo/helloworld/DEBUG"
  3. We must account for the RPX and the RPLs that are not in the shared area by including them in the dumprpl command. At a command prompt, type the following command:
    dumprpl -loadsize <RPXName.rpx> <RPLName.rpl> ... [RPLName.rpl]
    When passing in RPLs to dumprpl, do not include shared RPLs. To determine if an RPL is shared, the steps detailed in how to calculate max_codesize using make run may be used. The output from step 5 contains a list of all RPLs loaded in the application. On each line are pairs of TEXT, DATA, and LOAD addresses. Shared RPLs may be found by looking at the LOAD addresses: those starting with 0xf are in the shared area. In our helloworld example, there are 4 RPLs and the RPX that are not in the shared area: helloworld.rpx, proc_ui.rpl nn_save.rpl nn_act.rpl nn_acp.rpl. Include these RPLs and the RPX in the dumprpl command.
    dumprpl -loadsize helloworld.rpx proc_ui.rpl nn_save.rpl nn_act.rpl nn_acp.rpl
    NOTE:
    If the RPLs are not in the same folder as the RPX, locate them, and then copy them into the folder.
  4. Note the output that is printed. For our example, the output is:
    To load helloworld.rpx it requires:
         96384 bytes free in code area
        389772 bytes free in data area
    
    To load proc_ui.rpl it requires:
         15168 bytes free in code area
         25780 bytes free in data area
    
    To load nn_save.rpl it requires:
        198784 bytes free in code area
        161012 bytes free in data area
    
    To load nn_act.rpl it requires:
        237760 bytes free in code area
        240888 bytes free in data area
    
    To load nn_acp.rpl it requires:
        243968 bytes free in code area
        234616 bytes free in data area
    
    
    Summary: To load
      helloworld.rpx
      proc_ui.rpl
      nn_save.rpl
      nn_act.rpl
      nn_acp.rpl
    
    it requires:
    
        792064 bytes free in code area
       1052068 bytes free in data area
    
    Note: 89920 bytes of the 792064 bytes are used from the code area for the loading process
          These bytes are available for use in the next dynamic acquire
    
  5. Calculate the max_codesize in bytes using the following formula:
    max_codesize = bytes-free-in-code-area + heap-management-buffer + decompression-buffer + (shared-area-RPLs * 250)
    1. To account for the loader temp heap, multiply the bytes-free-in-code-area that is listed in the output from the dumprpl command by 1.15. In our example:
      bytes-free-in-code-area = 792064 * 1.15 = 910874
    2. The heap-management-buffer is a fixed 12K for the heap overhead, unless the number of CODE heap blocks used is greater than 768, which is the default. In our example, the number of blocks-used is 58, so we add 12K for the heap overhead.
      max_codesize = 910874 + 12288 + decompression-buffer
    3. The decompression-buffer is a fixed 32K. In our example:
      max_codesize = 910874 + 12288 + 32768 = 955930
    4. Add 250 bytes per shared RPL. In our example, the shared RPLs are nsysccr.rpl, vpadbase.rpl, vpad.rpl, uvc.rpl, tve.rpl, tcl.rpl, dc.rpl,, avm.rpl, gx2.rpl, and coreinit.rpl.
      max_codesize = 955930 + (10 * 250) = 958430
  6. Convert the max_codesize to a hex number. In our example:
    958430 converts to 0xE9FDE
  7. Rounding up to the next 128KB, we enter 0x100000 in the max_codesize field in cos.xml.

In the following instructions, we use the helloworld demo and the DEBUG with Multi configuration to determine the amount of memory that the application uses. Repeat the instructions for the NDEBUG with Multi configuration.

To calculate max_codesize for a Multi build using dumprpl

  1. Open a cafe.bat shell.
  2. At the command prompt, change directories to the location of the RPXfile for your application. Using the helloworld demo as our example, type the following.
    cd "$CAFE_ROOT/system/bin/ghs/cafe/demo/helloworld/NDEBUG"
  3. At a command prompt, type the following command:
    $ dumprpl -loadsize <ApplicationName.rpx> [RPLName.rpl] ... [RPLName.rpl]
    
    When passing in RPLs to dumprpl, do not include shared RPLs. To determine if an RPL is shared the steps detailed in how to calculate max_codesize using make multirun may be used. The output from step 5 contains a list of all RPLs loaded in the application. On each line are pairs of TEXT, DATA, and LOAD addresses. Shared RPLs can be found by looking at the LOAD addresses: those starting with 0xf are in the shared area. Include all RPLs listed in the dumprpl command, along with the RPX file. For our example, type the following.
    dumprpl -loadsize helloworld.rpx nn_act.rpl nn_acp.rpl nn_save.rpl nsysccr.rpl vpadbase.rpl vpad.rpl uvc.rpl tve.rpl tcl.rpl dc.rpl avm.rpl gx2.rpl proc_ui.rpl coreinit.rpl
    
    NOTE:
    If the RPLs are not in the same folder as the RPX, locate them, and then copy them into the folder.
  4. Note the output that is printed. For our example, the output is:
    To load helloworld.rpx it requires:
         96384 bytes free in code area
        389772 bytes free in data area
    
    To load nn_act.rpl it requires:
        237760 bytes free in code area
        240888 bytes free in data area
    
    To load nn_acp.rpl it requires:
        243968 bytes free in code area
        234616 bytes free in data area
    
    To load nn_save.rpl it requires:
        198784 bytes free in code area
        161012 bytes free in data area
    
    To load nsysccr.rpl it requires:
         45376 bytes free in code area
         55696 bytes free in data area
    
    To load vpadbase.rpl it requires:
         21248 bytes free in code area
         30096 bytes free in data area
    
    To load vpad.rpl it requires:
         56256 bytes free in code area
         53748 bytes free in data area
    
    To load uvc.rpl it requires:
         11776 bytes free in code area
        290800 bytes free in data area
    
    To load tve.rpl it requires:
        167616 bytes free in code area
         64172 bytes free in data area
    
    To load tcl.rpl it requires:
        116544 bytes free in code area
        268236 bytes free in data area
    
    To load dc.rpl it requires:
         81600 bytes free in code area
         68564 bytes free in data area
    
    To load avm.rpl it requires:
         80000 bytes free in code area
         70256 bytes free in data area
    
    To load gx2.rpl it requires:
        743744 bytes free in code area
        598908 bytes free in data area
    
    To load proc_ui.rpl it requires:
         15168 bytes free in code area
         25780 bytes free in data area
    
    To load coreinit.rpl it requires:
        487808 bytes free in code area
       2272376 bytes free in data area
    
    
    Summary: To load
      helloworld.rpx
      nn_act.rpl
      nn_acp.rpl
      nn_save.rpl
      nsysccr.rpl
      vpadbase.rpl
      vpad.rpl
      uvc.rpl
      tve.rpl
      tcl.rpl
      dc.rpl
      avm.rpl
      gx2.rpl
      proc_ui.rpl
      coreinit.rpl
    
    it requires:
    
       2604032 bytes free in code area
       4824920 bytes free in data area
    
    Note: 303616 bytes of the 2604032 bytes are used from the code area for the loading process
          These bytes are available for use in the next dynamic acquire
    
  5. Calculate the max_codesize in bytes using the following formula:
    max_codesize = bytes-free-in-code-area + heap-management-buffer + decompression-buffer
    1. Multiply the bytes-free-in-code-area that is listed in the output from the dumprpl command by 1.15. In our example:
      bytes-free-in-code-area = 2604032 * 1.15 = 2994637
    2. The heap-management-buffer is a fixed 12K for the heap overhead, unless blocks-used is greater than 768. In our example, the number of blocks-used is 137, so we add 12K for the heap overhead.
      max_codesize = 2994637 + 12288 + decompression-buffer
    3. The decompression-buffer is a fixed 32K. In our example:
      max_codesize = 2994637 + 12288 + 32768 = 3039693
    4. Add 250 bytes per shared RPL. In our example, all of the RPLs are accounted for in the dumprplcommand.
      max_codesize = 3039693 + 0 = 3039693
  6. Convert the max_codesize to a hex number. In our example:
    3039693 converts to 0x2E61CD
  7. Rounding up to the next 128KB, we enter 0x300000 in the max_codesize field in cos.xml.

Calculating Maximum Code Memory (Release Phase)

Specify the amount of total memory allocated to the application to use for the executable code. The specified amount of memory is allocated as executable memory starting from the lower limit of the memory space.

Specify 224 MB in most cases.

If you need to allocate a size smaller than 224 MB, specify a size larger than the maximum value of the combined code execution areas for RPX and the RPL used simultaneously. Also include any RPLs provided by the system in this total, such as the software keyboard. The size of the code execution area for the system-provided RPLs may change in a future system update. Add some margin for this to your calculation. Specify this value in 128 KB increments.

NOTE:
If you set the maximum memory size for code to a value other than 224 MB, Nintendo requires that you add 15 MB to the size of the RPX and RPL for the application itself. This ensures stable operation regardless of the number or types of system-provided RPLs used.

The code execution area is the "code area" shown when running the following command on an RPX or RPL file.

dumprpl -loadsize <rpl_name>.{rpl|rpx}

For more information, see the Wii U Master ROM Creation and Submission Procedures documentation available from your local Nintendo developer support group.

Specifying the Amount of Heap Blocks

The default amount of heap blocks to track memory allocations in the loader is 768 blocks. You can adjust the default amount of heap blocks by modifying the following fields in the applications cos.xml file.

NOTE:
For legacy purposes, there are 2 available heap block fields. The loader adds these two fields together and uses their sum for allocation tracking.

The default integer value for the two fields in the default_cos.xml file is 0. A 0 integer value indicates the following.

<num_codearea_heap_blocks type="unsignedInt" length="4">0</num_codearea_heap_blocks> Indicates 256 heap blocks.
<num_workarea_heap_blocks type="unsignedInt" length="4">0</num_workarea_heap_blocks> Indicates 512 heap blocks.

Added together, the sum of the two values is 768 heap blocks. Therefore, 768 heap blocks is the default amount of blocks created by using the default integer value of 0. When either of these two field values is a nonzero integer value, the value will represent the number of heap blocks that are created.

Example of Using Nonzero Integer Values

<num_codearea_heap_blocks type="unsignedInt" length="4">64</num_codearea_heap_blocks> Indicates 64 heap blocks.
<num_workarea_heap_blocks type="unsignedInt" length="4">32</num_workarea_heap_blocks> Indicates 32 heap blocks.

For a total amount of 96 heap blocks created.

NOTE:
Decreasing the number of blocks increases loader heap memory that can be used for other purposes.

Cafe Console Log Errors

In the Cafe console log, you may be presented with an allocation error similar to the following.

***LiCacheLineCorrectAlloc(32772) failed; (needed 32896).
***heap blocks used 767:792768, free 1:234087168, unused 0
***used all of 768 available blocks. No unused blocks available to split a free
block.
***please increase num_codearea heap_blocks in cos.xml. To increase by 25% try:
  <num_codearea_heap_blocks type="unsignedInt" length="4">448</num_codearea_heap_blocks>
***nn_acp DATA 3 Decompression (12305->50896) failure.
***LiSetupOneRPL(nn_acp) failed with err=-4.
***Loader failure -4.
__OSDynLoad_InitFromCoreInit() - main program load failed (err=0xBAD10021).
OSPanic in "OSDynLoad_DynInit.c" at line 271 on thread = Default Core 1.

In this example, 512 heap blocks and 448 heap blocks equaled a sum of 960 blocks. 960 blocks is 25% greater than the default amount of 768 blocks.

This error could indicate that numerous RPLs are being loaded with each RPL having numerous allocations. As previously shown, you can increase or decrease the number of heap blocks that are required in the application's cos.xml file.

The value in the above console log of 448 is merely a suggestion. You can make changes to the fields and rerun the process to discover a suitable amount. More accurate recommendations are obtained from the error handler if you set the num_workarea_heap_blocks integer value to 0, or to greater than 512.

See Also

Application Concepts
app.xml
meta.xml

Revision History

2015/01/29 Clarify the setting of CAFE_CODE_DIR.
2014/04/01 Added heap block info.
2013/05/08 Automated cleanup pass.
2011/02/21 Initial version.


CONFIDENTIAL