Hi, I need urgently help!! I'm beginning using gcc-ppc (powerpc-elf) as a Cross-Compiler to develop Software for a Motorola Eximer Board. At the moment i'm collecting a set of files to compile C-Programs and run them on a MPC603e on this Evaluation Board. I'm able to initialize the PPC and bring a C-Program to run, but when i start to use some Functions, i get trouble with managing strings. The problem is the following: when i declared a global string, i can access it inside the main-function without some problems. But when i try to access the string outside the main-function, the system crashes at startup. I don't know why. What do i wrong? Please look at the following example: This is a c-code wich runs without some problems: /*************************************************************************** ****************************/ /*begin of file */ /*char_test.c*/ #include "duart.h" void outstr(); char Teststring[20] = "Dies ist ein Test."; char testreturn() { return 0x32; } int main () { unsigned long count; char input; com1_init(); while (1) { input = com1_getchar(); com1_putchar(Teststring[0]); com1_putchar(input); com1_putchar(testreturn()); } return 0; } /* end of file */ /*************************************************************************** ***********************************/ If i modyfy the code this way, the system crashes at startup: /*************************************************************************** ****************************/ /*begin of file */ /*char_test.c*/ #include "duart.h" void outstr(); char Teststring[20] = "Dies ist ein Test."; char testreturn() { return Teststring[0]; } int main () { unsigned long count; char input; com1_init(); while (1) { input = com1_getchar(); com1_putchar(Teststring[0]); com1_putchar(input); com1_putchar(testreturn()); } return 0; } /* end of file */ /*************************************************************************** ***********************************/ I don't know why this crashs, maybee anyone of you can help me. for better understand i attach the other files inclusive the liker script and the makefile. Maybee anyone has an idea? The Files are the folliowing: /*Makefile*/ /*ppcinit.h*/ /*ppcinit.S*/ /* reg_defs.h */ /*duart.h*/ /*script.ld*/ /*************************************************************************** ****************************/ /*begin of file */ /*Makefile*/ Makefile PREFIX = TARGET = powerpc-elf CC = $(TARGET)-g++ LD = $(TARGET)-gcc OBJCOPY = $(TARGET)-objcopy OBJDUMP = $(TARGET)-objdump # # Define locations for the text and data code sections. The bss # gets tacked on to the end of the data by the linker script, # don't worry about it. # # define this to move from the default of 0xFFF00000 #IMAGE_TEXT_START = 0xFFC00000 # where do you want the text to execute? Define this to move # from 0x00000000 #TEXT_START = 0x00000000 # the data section location defaults to the end of the text section, # so define these only if you want it in a specific place # ex. If you're using a real ROM, you need to specify a DATA_START # that is in RAM so you can actually write to the data space. # # IMAGE_DATA_START = 0xFFF40000 # DATA_START = 0x00050000 # define options for compilation # add -gdwarf for debug # CFLAGS = -gdwarf # define options for linkage. Prevent the inclusion of standard start # code and libraries. LDFLAGS = -fno-builtin -nostartfiles -nodefaultlibs -T script.ld ifdef IMAGE_TEXT_START LDFLAGS += -Wl,--defsym,TEXT_START=$(TEXT_START) \ -Wl,--defsym,IMAGE_TEXT_START=$(IMAGE_TEXT_START) endif ifdef IMAGE_DATA_START LDFLAGS += -Wl,--defsym,DATA_START=$(DATA_START) \ -Wl,--defsym,IMAGE_DATA_START=$(IMAGE_DATA_START) endif # define options for the objdump DUMPFLAGS = --syms --disassemble-all # list C modules to link with the init code here C_SRC = char_test.c C_OBJS = $(C_SRC:.c=.o) # use variables to refer to init code in case it changes PPCINIT = ppcinit.o PPCINIT_DEP = reg_defs.h ppcinit.h ppcinit.S # # define build targets # all: go.srec clean: rm *.o *.elf *.srec *.dump *.i *.bin # build s-record with init code and c files linked together go.srec: $(C_OBJS) $(PPCINIT) $(LD) $(LDFLAGS) -o go.elf $(PPCINIT) $(C_OBJS) $(OBJDUMP) $(DUMPFLAGS) go.elf > go.dump $(OBJCOPY) -O srec -R .comment go.elf go.srec $(OBJCOPY) -O binary go.elf go.bin # compile init code $(PPCINIT): $(PPCINIT_DEP) $(CC) $(CFLAGS) -c -x assembler-with-cpp $*.S # handle compilation of C files %.o:%.c $(CC) $(CFLAGS) -c $< /* end of file */ /*************************************************************************** ***********************************/ /*************************************************************************** ****************************/ /*begin of file */ /*ppcinit.h*/ /* ppcinit.h */ #include "reg_defs.h" /* contains bit defines and register names */ /* Set the entry point into the user code. Normally, this should be defined as main. If a function other than main is used, the user MUST insert a call to __eabi() in the function before any other executable code. */ #define USER_ENTRY main /* define ONE appropriate processor type for your system */ #define MPC603e //#define MPC750 //#define MPC7400 /* Max has VMX; other processors don?t yet. Define as necessary. May be set to zero also to disallow use of vmx on Max.*/ #ifdef MPC7400 #define VMX_AVAIL 1 /* 1 = vma avail, 0 = no vmx */ #else #define VMX_AVAIL 0 #endif /* L2 cache enablement */ #ifdef MPC603e #define L2CACHE_ENABLE 0 /* just note that there?s no L2 on 603e */ #else /* 750 or 7400 */ #define L2CACHE_ENABLE 1 /* default - L2 on for Max and Arthur */ /* * L2_INIT is used to set up the L2 cache as follows: * size = .5 MB * clock ratio = div 2 * RAM type = burst SRAM * Output Hold = 0.5ns * * These may need to be changed for your board. Refer to your board specs and your * processor manual for more information on setting up the L2 cache */ #define L2_INIT (L2CR_L2SIZ_HM|L2CR_L2CLK_2|L2CR_L2RAM_BURST| L2CR_L2OH_5) #define L2_ENABLE (L2_INIT | L2CR_L2E) #endif /* L1 Instruction and data caches on or off? */ #define ICACHE_ON 0 #define DCACHE_ON 0 /* Where should I put the stack? Upper and lower address bits This number should be 16-byte aligned (PPC ABI) or 8-byte aligned (PPC EABI) */ #define STACK_LOC 0x00070000 /* Do we want to use the MMU?s address translation ability? */ #define MMU_ON 0 /* If we?re using the MMU we need to set up the BAT registers. Since we don?t have a nice operating system handling page table entries and the like for us, the BATs provide the easiest translation mechanism. The User must define the bat mappings here. For unused BATs, specify the BAT as INVALID and having NO_ACCESS as shown for bats 2 and 3 below. This code maps everything, including the ROM and instruction space as read-write because we?re in a simulator and might want to do something that you wouldn?t be able to do on real HW. In a real system, ROM and instruction space is typically mapped Read-only. The defines used here are found in reg_defs.h. */ /* first, set address ranges for the devices I?m mapping with the BATs. The memory model for my board has ROM at fffc00000 and RAM at 0x00000000. */ #define PROM_BASE 0xffc00000 #define PRAM_BASE 0x00000000 #define VROM_BASE PROM_BASE #define VRAM_BASE PRAM_BASE #define IBAT0L_VAL (PROM_BASE | BAT_CACHE_INHIBITED | BAT_READ_WRITE) #define IBAT0U_VAL (VROM_BASE|BAT_VALID_SUPERVISOR|BAT_VALID_USER|BAT_BL_4M) #define DBAT0L_VAL IBAT0L_VAL #define DBAT0U_VAL IBAT0U_VAL #define IBAT1L_VAL (PRAM_BASE | BAT_READ_WRITE) #define IBAT1U_VAL (VRAM_BASE|BAT_BL_32M|BAT_VALID_SUPERVISOR| BAT_VALID_USER) #define DBAT1L_VAL IBAT1L_VAL #define DBAT1U_VAL IBAT1U_VAL #define IBAT2L_VAL (BAT_NO_ACCESS) #define IBAT2U_VAL (BAT_INVALID) #define DBAT2L_VAL (BAT_NO_ACCESS) #define DBAT2U_VAL (BAT_INVALID) #define IBAT3L_VAL (BAT_NO_ACCESS) #define IBAT3U_VAL (BAT_INVALID) #define DBAT3L_VAL (BAT_NO_ACCESS) #define DBAT3U_VAL (BAT_INVALID) /* end of file */ /*************************************************************************** ***********************************/ /*************************************************************************** ****************************/ /*begin of file */ /*ppcinit.S*/ /* ppcinit.S // This file contains generic boot init code designed to be run on // processor simulations that just need minimal setup. // // This code has also successfully been used to run processor-intensive // benchmarks (written in C) from power-up on minimal hardware boards such as // Excimer. // // This code is designed to be run from Power-up or hard reset; running from // soft reset may require additional operations such as cache invalidation, // that are not supplied here. // // Once the hw init is complete, this code branches into the // USER_ENTRY defined in the user code // // This code has been tested on the mpc603e, mpc750 and mpc7400/ // Architectural differences between processors with respect to cache // types and sizes, cache management instructions, number of TLB // entries, etc, may require changes to be made to this code before it may // be used successfully on other processors. // // WARNING: If this code is run on a MAX! (MPC7400) processor // earlier than rev 2.9, certain bits in HID0, IABR, MSSCR0, and // MSSCR1 have to be set. Please refer to the processor errata if // problems are encountered with this part. */ // NOTE: If you need to define variables, put them at the end! The _start // symbol needs to be at hreset in order for this code to run automatically // on hard reset. #include "ppcinit.h" .text .global __eabi .global _start .space (0x0100) // locate at hreset vector // this should now be located at the reset vector _start: b system_reset .space (0x3000) // space past exception space // here?s the real startup code, located outside the exception vector space system_reset: addis r0,0,0x0000 // from reset, the BATs are in an unknown state on most PPCs. // Invalidate them all to avoid error states mtspr ibat0u,r0 mtspr ibat1u,r0 mtspr ibat2u,r0 mtspr ibat3u,r0 isync mtspr dbat0u,r0 mtspr dbat1u,r0 mtspr dbat2u,r0 mtspr dbat3u,r0 isync // If there?s L2 cache we enable later, set it up and invalidate it. // Don?t turn it on until after the ROM-RAM copy of the image so // we don?t preload the caches (in case we?re going to run a benchmark). #if L2CACHE_ENABLE == 1 addis r3,r0,L2_INIT@h ori r3,r3,L2_INIT@l mtspr l2cr,r3 // This invalidate serves two purposes. // First, it invalidates the L2 cache. // Second, it ensures that when this section of code has completed // execution, the L2 DLL will have stabilized. L2_invalidate: #if defined(MPC7400) && defined(VMX_AVAIL) .long 0x7e00066c // dssall instruction, not all compilers // understand it yet. Actually, as // long as this code is run from hard // reset, before any data stream touch // instructions, this instruction isn?t needed. // I?m putting in for correctness in case // someone cut-and-pastes this code into // another application. #endif sync oris r3,r3,0x0020 mtspr l2cr,r3 sync invalidate: mfspr r3,l2cr andi. r3,r3,0x1 bne invalidate // turn off the L2I global invalidate bit mfspr r3,l2cr rlwinm r3,r3,0,11,9 mtspr l2cr,r3 #endif // L2CACHE_ENABLE // Note MSR state at power-up: // all exceptions disabled, address translation off, // Exception prefix at 0xfff00000, FP disabled #if MMU_ON == 1 // If the code specifies that we?re going to use the MMU, branch to // to the setup function that handles setting up the BATs and // invalidating TLB entries. // // NOTE: We?ve done nothing with the segment registers, so we need to // be sure that all memory accessed by this code and by the user // program is represented in the BATs. Otherwise, we might get // some spurious translations. bl setup_bats sync bl address_translation_on sync #endif // relocate the text, data, and bss segments bl relocate_image // Note: This code is run from reset, so we assume that there is no // data that needs to be flushed from the cache. This code only // invalidates and enables the caches, it does not flush! // // Note: The caches are enabled *after* the relocation in order // to help avoid cache preloading. #if DCACHE_ON == 1 bl invalidate_and_enable_L1_dcache #endif #if ICACHE_ON == 1 bl invalidate_and_enable_L1_icache #endif #if L2CACHE_ENABLE == 1 addis r3,r0,L2_ENABLE@h ori r3,r3,L2_ENABLE@l mtspr l2cr,r3 #endif // get the start address of the main routine of the code we want to run. addis r3,r0,USER_ENTRY@h ori r3,r3,USER_ENTRY@l mtspr srr0,r3 // Set the MSR. // we just move the value into srr1 - it will get copied into // the msr upon the rfi. #if VMX_AVAIL == 1 addis r4,0,0x0200 #else addis r4,0,0x0000 #endif ori r4,r4,0x3900 // turn on fp, // enable fp & machine check exceptions #if MMU_ON == 1 ori r4,r4,0x0030 // turn on I and D translation #endif // See if we relocated the code to an address above 0xffc00000. // If so, put the exception prefix at 0xfff00000. Otherwise, // make it at 0. addis r5,0,0xffc0 ori r5,r5,0x0000 cmp 0,0,r5,r3 blt set_state ori r4,r4,0x0040 // put exception prefix at 0xfff00000 // in our new msr set_state: // Put r4 into srr1 so it gets copied into the msr on rfi mtspr srr1,r4 // let?s put something in the link register - when the user program // starts, it?s going to save the link register, do it?s thing, then // restore the link register and blr. // we?ll put in the address following the rfi so we can save // off the time base once the user code is complete addis r3,0,save_timebase@h ori r3,r3,save_timebase@l mtlr r3 // set up the time base register addis r4,r0,0x0000 mtspr 285,r4 mtspr 284,r4 // Set up stack pointer for the user application addis r1,r0,STACK_LOC@h // STACK_LOC defined in ppcinit.h ori r1,r1,STACK_LOC@l // make sure the word the stack pointer points to is NULL addis r14,r0,0x0000 stw r14,0(r1) /*************************************************** lis r25,0xabcd ori r25,r25,0x1234 test_loop: nop b test_loop *****************************************************/ // go to the C code rfi save_timebase: // read time base, checking for rollover mfspr r3,269 mfspr r4,268 mfspr r5,269 cmpw r5,r3 bne save_timebase // save vals off addis r5,0,TBUSAVE@h ori r5,r5,TBUSAVE@l stw r3,0(r5) addis r5,0,TBLSAVE@h ori r5,r5,TBLSAVE@l stw r4,0(r5) // done, go to an arbitrary address done: addis r3,0,0xfff0 ori r3,r3,0x0700 mtlr r3 blr // // Label: __eabi() // // Replaces standard __eabi(). This is a minimal __eabi, because we don?t // require anything to happen here other than setting up the SDA pointers. // __eabi: // Get small data area locations as per PPC EABI // See http://motorola.com/semiconductors (search on EABI) // for more information. addis r13,r0,_SDA_BASE_@h ori r13,r13,_SDA_BASE_@l addis r2,r0,_SDA2_BASE_@h ori r2,r2,_SDA2_BASE_@l blr //-------------------------------------------------------------------------- - // Label: relocate_image // // copy this image and the user code into RAM space. // Note that the starting locations of text, data, and bss are // defined in the ld.script. Make sure these definitions, // as well as the definition for STACK_LOC in ppcinit.h, give // ample room for your image. //-------------------------------------------------------------------------- - relocate_image: addis r3,0,_img_text_start@h ori r3,r3,_img_text_start@l addis r4,0,_final_text_start@h ori r4,r4,_final_text_start@l // are they the same? No need to relocate if so cmp 0,0,r3,r4 beq relocate_data addis r7,0,_img_text_end@h ori r7,r7,_img_text_end@l cont: lwzx r5,0,r3 stwx r5,0,r4 lwzx r8,0,r4 cmp 0,0,r8,r5 bne error addi r4,r4,4 addi r3,r3,4 cmp 0,0,r3,r7 ble cont relocate_data: addis r3,0,_final_data_start@h ori r3,r3,_final_data_start@l addis r7,0,_final_data_end@h ori r7,r7,_final_data_end@l addis r4,0,_img_data_start@h ori r4,r4,_img_data_start@l cmp 0,0,r3,r4 // is the data not relocated? beq clear_bss // if not, go do the bss cont1: lwzx r5,0,r4 stwx r5,0,r3 lwzx r8,0,r3 cmp 0,0,r8,r5 bne error addi r4,r4,4 addi r3,r3,4 cmp 0,0,r3,r7 ble cont1 // This clear_bss code can be removed if you?re sure you never // depend on uninitialized data being 0. clear_bss: addis r4,0,_bss_start@h ori r4,r4,_bss_start@l addis r7,0,_bss_end@h ori r7,r7,_bss_end@l addis r5,0,0x0000 cont2: stwx r5,0,r4 addi r4,r4,4 cmp 0,0,r4,r7 ble cont2 sync // return from relocate_image blr //-------------------------------------------------------------------------- - // Function: setup_bats // // Here is the code that handles setting up the BAT registers. // IBAT0L and such must be defined in the header file // // The MMU should be turned off before this code is run and // re-enabled afterward //-------------------------------------------------------------------------- - setup_bats: addis r0,r0,0x0000 addis r4,r0,IBAT0L_VAL@h ori r4,r4,IBAT0L_VAL@l addis r3,r0,IBAT0U_VAL@h ori r3,r3,IBAT0U_VAL@l mtspr ibat0l,r4 mtspr ibat0u,r3 isync addis r4,r0,DBAT0L_VAL@h ori r4,r4,DBAT0L_VAL@l addis r3,r0,DBAT0U_VAL@h ori r3,r3,DBAT0U_VAL@l mtspr dbat0l,r4 mtspr dbat0u,r3 isync addis r4,r0,IBAT1L_VAL@h ori r4,r4,IBAT1L_VAL@l addis r3,r0,IBAT1U_VAL@h ori r3,r3,IBAT1U_VAL@l mtspr ibat1l,r4 mtspr ibat1u,r3 isync addis r4,r0,DBAT1L_VAL@h ori r4,r4,DBAT1L_VAL@l addis r3,r0,DBAT1U_VAL@h ori r3,r3,DBAT1U_VAL@l mtspr dbat1l,r4 mtspr dbat1u,r3 isync addis r4,r0,IBAT2L_VAL@h ori r4,r4,IBAT2L_VAL@l addis r3,r0,IBAT2U_VAL@h ori r3,r3,IBAT2U_VAL@l mtspr ibat2l,r4 mtspr ibat2u,r3 isync addis r4,r0,DBAT2L_VAL@h ori r4,r4,DBAT2L_VAL@l addis r3,r0,DBAT2U_VAL@h ori r3,r3,DBAT2U_VAL@l mtspr dbat2l,r4 mtspr dbat2u,r3 isync addis r4,r0,IBAT3L_VAL@h ori r4,r4,IBAT3L_VAL@l addis r3,r0,IBAT3U_VAL@h ori r3,r3,IBAT3U_VAL@l mtspr ibat3l,r4 mtspr ibat3u,r3 isync addis r4,r0,DBAT3L_VAL@h ori r4,r4,DBAT3L_VAL@l addis r3,r0,DBAT3U_VAL@h ori r3,r3,DBAT3U_VAL@l mtspr dbat3l,r4 mtspr dbat3u,r3 isync // BATs are now set up, now invalidate tlb entries addis r3,0,0x0000 #ifdef MPC603e addis r5,0,0x2 // set up high bound of 0x00020000 for 603e #endif #if defined(MPC750) || defined(MPC7400) addis r5,0,0x4 // 750/MAX have 2x as many tlbs as 603e #endif isync // Recall that in order to invalidate TLB entries, the value issued to // tlbie must increase the value in bits 14:19 (750, MAX) or 15:19(603e) // by one each iteration. tlblp: tlbie r3 sync addi r3,r3,0x1000 cmp 0,0,r3,r5 // check if all TLBs invalidated yet blt tlblp blr //----------------------------------------------------------------------- // Function: invalidate_and_enable_L1_dcache // // Flash invalidate and enable the L1 dcache //----------------------------------------------------------------------- invalidate_and_enable_L1_dcache: mfspr r5,hid0 ori r5,r5,0x4400 sync mtspr hid0,r5 #ifdef MPC603e rlwinm r6,r5,0,22,20 mtspr hid0,r6 #endif blr //----------------------------------------------------------------------- // Function: invalidate_and_enable_L1_icache // // Flash invalidate and enable the L1 icache //----------------------------------------------------------------------- invalidate_and_enable_L1_icache: mfspr r5,hid0 ori r5,r5,0x8800 isync mtspr hid0,r5 #ifdef MPC603e rlwinm r6,r5,0,21,19 mtspr hid0,r6 #endif blr //----------------------------------------------------------------------- // Function: address_translation_on // // Enable address translation using the MMU //----------------------------------------------------------------------- address_translation_on: mfmsr r5 ori r5,r5,0x0030 mtmsr r5 isync blr //----------------------------------------------------------------------- // Function: error // // If an error occurs while we?re copying from ROM to RAM, we have nowhere // to go because there?s no OS support. Hang. //----------------------------------------------------------------------- error: b error //--------------------------------------------------------------------- // // Define space for data items needed by this code // //--------------------------------------------------------------------- .data /* save time base to use for benchmarking numbers */ TBUSAVE: .double 0 TBLSAVE: .double 0 /* end of file */ /*************************************************************************** ***********************************/ /*************************************************************************** ****************************/ /*begin of file */ /* reg_defs.h */ /* define names to make the asm easier to read - some compilers don?t have this built in */ #define r0 0 #define r1 1 #define r2 2 #define r3 3 #define r4 4 #define r5 5 #define r6 6 #define r7 7 #define r8 8 #define r9 9 #define r13 13 #define r14 14 #define r15 15 #define r16 16 #define r17 17 #define r18 18 #define r19 19 #define r20 20 #define r21 21 #define r22 22 #define r23 23 #define r24 24 #define r25 25 #define r26 26 #define r27 27 #define r28 28 #define r29 29 #define r30 30 #define r31 31 #define hid0 1008 #define srr1 27 #define srr0 26 #define ibat0u 528 #define ibat0l 529 #define ibat1u 530 #define ibat1l 531 #define ibat2u 532 #define ibat2l 533 #define ibat3u 534 #define ibat3l 535 #define dbat0u 536 #define dbat0l 537 #define dbat1u 538 #define dbat1l 539 #define dbat2u 540 #define dbat2l 541 #define dbat3u 542 #define dbat3l 543 #define pvr 287 #define l2cr 1017 /* general BAT defines for bit settings to compose BAT regs */ /* represent all the different block lengths */ /* The BL field is part of the Upper Bat Register */ #define BAT_BL_128K 0x00000000 #define BAT_BL_256K 0x00000004 #define BAT_BL_512K 0x0000000C #define BAT_BL_1M 0x0000001C #define BAT_BL_2M 0x0000003C #define BAT_BL_4M 0x0000007C #define BAT_BL_8M 0x000000FC #define BAT_BL_16M 0x000001FC #define BAT_BL_32M 0x000003FC #define BAT_BL_64M 0x000007FC #define BAT_BL_128M 0x00000FFC #define BAT_BL_256M 0x00001FFC /* supervisor/user valid mode definitions - Upper BAT*/ #define BAT_VALID_SUPERVISOR 0x00000002 #define BAT_VALID_USER 0x00000001 #define BAT_INVALID 0x00000000 /* WIMG bit settings - Lower BAT */ #define BAT_WRITE_THROUGH 0x00000040 #define BAT_CACHE_INHIBITED 0x00000020 #define BAT_COHERENT 0x00000010 #define BAT_GUARDED 0x00000008 /* Protection bits - Lower BAT */ #define BAT_NO_ACCESS 0x00000000 #define BAT_READ_ONLY 0x00000001 #define BAT_READ_WRITE 0x00000002 /* Bit defines for the L2CR register */ #define L2CR_L2E 0x80000000 /* bit 0 - enable */ #define L2CR_L2PE 0x40000000 /* bit 1 - data parity */ #define L2CR_L2SIZ_2M 0x00000000 /* bits 2-3 2 MB; MPC7400 ONLY! */ #define L2CR_L2SIZ_1M 0x30000000 /* bits 2-3 1MB */ #define L2CR_L2SIZ_HM 0x20000000 /* bits 2-3 512K */ #define L2CR_L2SIZ_QM 0x10000000 /* bits 2-3 256K; MPC750 ONLY */ #define L2CR_L2CLK_1 0x02000000 /* bits 4-6 Clock Ratio div 1 */ #define L2CR_L2CLK_1_5 0x04000000 /* bits 4-6 Clock Ratio div 1.5 */ #define L2CR_L2CLK_2 0x08000000 /* bits 4-6 Clock Ratio div 2 */ #define L2CR_L2CLK_2_5 0x0a000000 /* bits 4-6 Clock Ratio div 2.5 */ #define L2CR_L2CLK_3 0x0c000000 /* bits 4-6 Clock Ratio div 3 */ #define L2CR_L2RAM_BURST 0x01000000 /* bits 7-8 burst SRAM */ #define L2CR_DO 0x00400000 /* bit 9 Enable caching of instr. in L2 */ #define L2CR_L2I 0x00200000 /* bit 10 Global invalidate bit */ #define L2CR_TS 0x00040000 /* bit 13 Test support on */ #define L2CR_TS_OFF ~L2CR_TS /* bit 13 Test support off */ #define L2CR_L2OH_5 0x00000000 /* bits 14-15 Output Hold time = 0.5ns*/ #define L2CR_L2OH_1 0x00010000 /* bits 14-15 Output Hold time = 1.0ns*/ #define L2CR_L2OH_INV 0x00020000 /* bits 14-15 Output Hold time = 1.0ns*/ /* end of file */ /*************************************************************************** ***********************************/ /*************************************************************************** ****************************/ /*begin of file */ /*duart.h*/ void com1_init() /*** DUART COM1 Initialisieren ***/ /*************************************************/ { char new_char; *(char *) (0x40580000) = 0x80; //open DLAB1 *(char *) (0x40480000) = 0x00; // Divisor Latch MSB *(char *) (0x40400000) = 0xA0; // Divisor Latch LSB // 9600 Baud at 24 Mhz *(char *) (0x40580000) = 0x03; // 8 N 1 *(char *) (0x40480000) = 0x00; // disable Interrupt *(char *) (0x40500000) = 0x00; // Disable FIFO *(char *) (0x40600000) = 0x00; // Disable Modem Control new_char = 0; // No new Character acknowledge } char com1_getchar() /*** DUART COM1 getchar***/ /* Warte bis ein neues Zeichen in den Empfangspuffer */ /* geschrieben wird und gebe dies als Rueckgabewert aus. */ /*************************************************/ { char input; char new_char; new_char = 0; while (new_char == 0) { if( (*(char *) (0x40680000) & 0x01) == 0x01) input = *(char *) (0x40400000); switch (input) { case 13: input = 10; break; default: break; } new_char = 1; } } return input; } void com1_putchar(char output) { /* Gebe das Zeichen output über Com1 aus */ /**********************************************/ char char_acknowledge; char_acknowledge = 1; while(char_acknowledge == 1) if( (*(char *) (0x40680000) & 0x20) == 0x20) *(char *) (0x40400000) = output; char_acknowledge = 0; } } } /* end of file */ /*************************************************************************** ***********************************/ /*************************************************************************** ****************************/ /*begin of file */ /*script.ld*/ /* script.ld */ SECTIONS { /* * check to see if we defined section starts in the makefile - if not, * define them here. * * Align everything to a 16-byte boundary if you?re specifying the * addresses here. */ TEXT_START = 0x00000000; IMAGE_TEXT_START = 0xFFF40000; .text TEXT_START : AT (IMAGE_TEXT_START) { /* We?re building a s-record with the .text section located at TEXT_START that we?re going to load into memory at IMAGE_TEXT_START. _img_text_start and _img_text_end indicate the locations of the start and end of the text segment at the loaded location. These values are used by the routine that relocates the text. */ *(.text) *(.rodata) *(.rodata1) *(.got1); } /* Save text location in image and the final location to be used in ppcinit.S */ _img_text_start = LOADADDR(.text); _img_text_end = ( LOADADDR(.text) + SIZEOF(.text) ); _final_text_start = ADDR(.text); /* * Put the data section right after the text in the load image * as well as after the relocation unless else specified * If the user specified an address, assume it?s aligned to a * 32-byte boundary (typical cache block size). If we?re * calculating the address, align it to cache block size ourself. */ DATA_START = DEFINED(DATA_START) ? DATA_START : (((ADDR(.text) + SIZEOF(.text)) & 0xFFFFFFE0) + 0x00000020); IMAGE_DATA_START = DEFINED(IMAGE_DATA_START) ? IMAGE_DATA_START : (((LOADADDR(.text) + SIZEOF(.text)) & 0xFFFFFFE0) + 0x00000020); .data DATA_START : AT (IMAGE_DATA_START) { _final_data_start = .; *(.data) *(.data1) *(.sdata) *(.sdata2) *(.got.plt) *(.got) *(.dynamic) *(.fixup); _final_data_end = .; } /* Now save off the start of the data in the image */ _img_data_start = LOADADDR(.data); /* * Place bss right after the data section. * * We only define one set of location variables for the BSS because * it doesn?t actually exist in the image. All we do is go to the * final location and zero out an appropriate chunk of memory. */ .bss (ADDR(.data) + SIZEOF(.data)) : { _bss_start = .; *(.sbss) *(.scommon) *(.dynbss) *(.bss) *(COMMON) ; _bss_end = . ; } _end = .; /* These debug sections are here for information only - they?re not going to be included in the ROM-RAM copy because it only copies .text, .data, and .bss. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } /* DWARF debug sections */ .debug 0 : {*(.debug)} .debug_srcinfo 0 : {*(.debug_srcinfo)} .debug_aranges 0 : {*(.debug_aranges)} .debug_pubnames 0 : {*(.debug_pubnames)} .debug_sfnames 0 : {*(.debug_sfnames)} .line 0 : {*(.line)} } /* end of file */ /*************************************************************************** ***********************************/ Thanks! cu Oliver Stoerkel