/*
* Copyright (c) 2006 SigmaTel, Inc.
*
* elftosb boot description file that creates some complicated situations for
* the loader to handle. of course this is also a good test for elftosb itself.
*/

/* testing C style comments */
// testing C++ style comments
# testing shell style comments

constants {
       kProgressReportsImageFlag = 0x1;

       kPlayerDriveTag = 0xa0;
       kHostlinkDriveTag = 0xb0;
}

options {
       productVersion = "5.0.999";
       componentVersion = "5.0.999";

   flags = kProgressReportsImageFlag;  // turn on progress reports

       secinfoClear = "ignore";
}

constants {
   arg = 0xfeedf00d;

   callArg1 = 2;
   callArg2 = 3;

   halfword = 10.h;

//    flag = 1;

       testboolexpr = 1 > 0;

       mainSizeIsDefined = defined(mainSize);
}

sources {
   elffile = extern(0) (toolset="ghs");
   binfile1 = extern(1);
   binfile2 = extern(2);
   foofile = "file.dat";
   anotherfile = "another.dat";
       srecfile = "test_files/sd_player_gcc.srec";
}

options {
       driveTag = kPlayerDriveTag;

       some_option = defined(testboolexpr);
}

constants {
       printMessageAddr = elffile:printMessage;
       printMessageSize = sizeof(elffile:printMessage);

       // create const with address of main() in elffile
       mainAddr = elffile:main;

       mainSize = sizeof(elffile:main);

       halfwordSize = sizeof(halfword);

       elf_startAddr = elffile:_start;

//      poop = exists(nonexistantfile);

       binfile1size = sizeof(binfile1);
}

/*
* test s-record support
*/
section (0)
{
       load dcd {{ 00 11 22 33 }} > 0;
       load srecfile;
       call srecfile;
}

section(1; coalesce=true) {

       info "welcome to section 1!";
       info "elffile path = $(elffile)";
       info "mainSizeIsDefined = $(d:mainSizeIsDefined)";
       info "printMessage = $(x:printMessageAddr)";

       info "size of binfile1 = $(binfile1size)";

       // can use symbol refs inside bool expressions in an if stmt
       if elffile:main == 0
       {
               warning "$(elffile) does not seem to have a main() function";
       }
       else
       {
               info "address of main() of $(elffile) is $(x:mainAddr)";
       }

       if defined(flag) && flag != 0
       {
               load 0x1234.h > 0..10K;
       }
       else
       {
               // print message using both decimal and hex formatting
               warning "loading only halfword = $(d:halfword) [$(x:halfword)]!";
               load halfword > 0..1K;
       }

       info "size of main() in $(elffile) is $(mainSize)";
       info "printMessage() size is $(printMessageSize)";
       info "size of halfword = $(halfwordSize)";

       load 0xff.b > 32K..32K + sizeof(elffile:printMessage);

       from elffile {
       load {{ 00 01 02 03 04 }} > 1K;

               // load all sections except .mytext
               load ~$.mytext;

               // figure out where to go from here
               call :maybeSwitchSections(callArg1);

               // print msg and loop
               load "hi from section 1" > :szMsg;
               call :printMessage(0);

               jump :hello(0);
       }

       // erase a function in memory
       load 0.w > (elffile:endOfLine)..(elffile:endOfLine + sizeof(elffile:endOfLine));
}

section(2; alignment=64K) {
       // cause an error if testConst has not been set
       if !defined(testConst)
       {
               error "testConst is not defined!";
       }

   from elffile {
       load "in section 2" > :szMsg;
       call :printMessage();
   }

   // load the contents of binfile1 into the upper 128KB of ocram
   load binfile1 > 128K..192K;

   from elffile {
       load "loaded binfile1" > :szMsg;
       call :printMessage(0);

       call :maybeSwitchSections(callArg2);

       jump :endOfLine(2);
   }
}

// non-bootable section between two bootable sections
section(0xbeef; alignment=32K, cleartext=false) <= binfile2;

section(3; alignment=8K) {
   // load our special section
   load $.mytext from elffile;
   call elffile:countToN(5);

       if (exists(foofile) && exists(anotherfile))
       {
               // a trainload of beef!
               load 0xbeef.h > 128K..192K;
       }
       else if (exists(elffile) && callArg1 == 2)
       {
               // aaaaaaah!
               load 0x12345678.w > 128K..192K;
       }
       else
       {
               from elffile
               {
                       // aaaaaaah!
                       load 0xaaaa.h > 128K..192K;
                       load $.text;
                       load 0xbbbb.h > 128K..192K;
               }
       }

   from elffile {
       load "hold on now, in section 3" > :szMsg;
       call :printMessage(0);

       jump :endOfLine(3);
   }

   from elffile {
       load elffile;
       load elffile > .;
       load elffile[ $.bss ] > elffile:countToN;
//              load [ $.bss ] > (elffile:countToN)..(elffile:countToN + sizeof(elffile:countToN));
       call elffile;
       call elffile(1);
   }

   info "address of _start in $(elffile) is $(elf_startAddr)";
}

section ('four'; alignment=8K, sectionFlags=0x1000) <= binfile1;

section ('five'; alignment=8K, cleartext=1, sectionFlags=0x1000) <= binfile1;

/*
* create a data section out of some sections of an elf file
*/
section (1234) <= ~$.bss, ~$.data from elffile;
section (4321) <= elffile [ $* ];
section (1111) <= elffile;

/* test data sections from various data sources */
section (0xaa) <= 0x12345678.w;
section (0xbb) <= "hi there! this is a data section.";
section (0xcc) <= {{ aa55aa55aa55aa55aa55aa55aa55aa55 }};


section (2345)
{
       load elffile[ $*.text*, ~$.sdram* ];
}


section ('six_')
{
       // load a blob at address 0x1000
       load {{
               00 0a 07 b0 bb ff 03 78
               00 0a 07 b0 bb ff 03 78
               00 0a 07 b0 bb ff 03 78
               00 0a 07 b0 bb ff 03 78
               00 0a 07 b0 bb ff 03 78
       }} > 0x1000;
}

section ('bad_')
{
       // uncomment to test better error reporting for files that failed to open
//      load foofile;
}

//section (2345) <= {{ 00 11 22 33 44 55 }};