//////////////////////////////////////////////////////////////////////// // // boot.c: pico2 booter (coff/elf version) // version 1.2 (May 6, 2010) // // (c) Hideki Kozima (xkozima@myu.ac.jp), subject to GPLv2 // #include "sh7046f.h" // // __main: dummy function void __main (void) {} //////////////////////////////////////////////////////////////////////// // // operators for interrupt control // // set_vbr: set vector base register void set_vbr (void *vbr) { asm(" ldc %0,vbr "::"r"(vbr)); } // // get_vbr: get vector base register uint *get_vbr () { uint *vbr; asm(" stc vbr,%0 ":"=r"(vbr):); return vbr; } // // set_imask: enable interrupts // Call once right after having get interrupt handlers ready. void set_imask (ushort mask) { uint value; mask <<= 4; mask &= 0x00f0; asm(" stc sr,%0 ":"=r"(value):); value &= 0xffffff0f; value = value | mask; asm(" ldc %0,sr "::"r"(value)); } // // definterrupt: associate interrupt and handler function // ex. definterrupt(173, (void *) SCI_receive_byte); // #pragma interrupt // void SCI_receive_byte (void) { // ... // } void definterrupt (ushort intno, void *handler(void)) { uint *vbr; vbr = get_vbr(); vbr += intno; *vbr = (uint) handler; } //////////////////////////////////////////////////////////////////////// // // boot: pico2 first initialization // (just in order to avoid hardware collision) extern char svbase; void boot (void) { void section_init(void); int main(void); // PortA initialization // PA7-0: in (tentative) // PA8: RxD, PA9: TxD, // PA10: out=0 (TE) // PA15-11: in (tentative) PFC.PACRL1.WORD = 0x0005; PFC.PACRL2.WORD = 0x0000; PFC.PACRL3.WORD = 0x0300; PFC.PAIORL.WORD = 0x0400; PA.DR.WORD = 0x0000; // TE off // PortB initialization // PB5-2: in (tentative) PFC.PBCR1.WORD = 0x0000; PFC.PBCR2.WORD = 0x0000; PFC.PBIOR.WORD = 0x0000; // PB2-5 in // PortE initialization // PE21-17: in (SWs) // PE16-12: out (LEDs) // PE11-0 : out (with zero) PFC.PECRH.WORD = 0x0000; PFC.PECRL1.WORD = 0x0000; PFC.PECRL2.WORD = 0x0000; PFC.PEIORH.WORD = 0x0001; PFC.PEIORL.WORD = 0xffff; PE.DRH.WORD = 0x0000; // LED5 on PE.DRL.WORD = 0x0000; // LED4-0 on // initialize memory section_init(); // set VBR set_vbr(&svbase); // start main program main(); } // // memory initialization (cf. rom.x) // .text [_stext, _etext) for code // .rodata [ ... ) for readonly data // initvar [_mdata, ... ) for initvar for .data // .data [_sdata, _edata) for variables with init // .bss [_sbss, _ebss ) for variables without init // note: .data has to be copied from the end of .text area. extern char mdata, sdata, edata, sbss, ebss; void section_init (void) { char *src; char *dst; // initialize .data area // initvar is located in [_mdata, ...), // so copy to .data = [_sdata, _edata) src = &mdata; dst = &sdata; while (dst < &edata) *dst++ = *src++; // clear .bss area for ( dst = &sbss; dst < &ebss; dst++ ) *dst = 0; } ////////////////////////////////////////////////////////////////////////