/*
 * 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 }};




