在arch/powerpc/cpu/mpc85xx 下有两个.S文件 release.S start.S 在release.S中代码只有两行.section .resetvec,"ax" b _start_e500 跳转到start.S中执行 .section .bootpg,"ax" .globl _start_e500 _start_e500: /* clear registers/arrays not reset by hardware */ /* L1 */ li r0,2 mtspr L1CSR0,r0 /* invalidate d-cache */ mtspr L1CSR1,r0 /* invalidate i-cache */ mfspr r1,DBSR mtspr DBSR,r1 /* Clear all valid bits */ /* * Enable L1 Caches early * */ 。。。。。。 435 bl cpu_init_early_f 436 437 /* switch back to AS = 0 */ 438 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h 439 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l 440 mtmsr r3 441 isync 442 443 bl cpu_init_f 444 bl board_init_f 445 isync 446 ***************** #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
[/code]
大概的意思是声明一个指向gd_t结构体变量的指针gd,并固定使用寄存器r8来存放该指针。而对gd_t结构体的定义从上面的第36行开始:
cpu_init_early_f在arch/powerpc/cpu/mpc85xx/ cpu_init_early.c /* We run cpu_init_early_f in AS = 1 */ 73 void cpu_init_early_f(void)//设置tlb /* We run cpu_init_early_f in AS = 1 */ 73 void cpu_init_early_f(void) 74 { 75 u32 mas0, mas1, mas2, mas3, mas7; 76 int i; 77 78 /* Pointer is writable since we allocated a register for it */ 79 gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); 80 81 /* 82 * Clear initial global data 83 * we don't use memset so we can share this code with NAND_SPL 84 */ 85 for (i = 0; i < sizeof(gd_t); i++) 86 ((char *)gd)[i] = 0; 87 88 mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0); 89 mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); 90 mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G); 91 mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR); 92 mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_PHYS); 93 94 write_tlb(mas0, mas1, mas2, mas3, mas7); 95 96 /* set up CCSR if we want it moved */ 97 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) 98 mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(1); 99 /* mas1 is the same as above */ 100 mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G); 101 mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, MAS3_SW|MAS3_SR); 102 mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_DEFAULT); 103 104 write_tlb(mas0, mas1, mas2, mas3, mas7); 105 106 setup_ccsrbar(); 107 #endif 108 109 init_laws(); 110 invalidate_tlb(0); 111 init_tlbs(); 112 } ******************************* cpu_init_f() 在cpu_init.c中 203 void cpu_init_f (void) 204 { 205 extern void m8560_cpm_reset (void); 206 #ifdef CONFIG_MPC8548 207 ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); 208 uint svr = get_svr(); 209 210 /* 211 * CPU2 errata workaround: A core hang possible while executing 212 * a msync instruction and a snoopable transaction from an I/O 213 * master tagged to make quick forward progress is present. 214 * Fixed in silicon rev 2.1. 215 */ 216 if ((SVR_MAJ(svr) == 1) || ((SVR_MAJ(svr) == 2 && SVR_MIN(svr) == 0x0))) 217 out_be32(&ecm->eebpcr, in_be32(&ecm->eebpcr) | (1 << 16)); 218 #endif 219 220 disable_tlb(14); 221 disable_tlb(15); 222 223 #ifdef CONFIG_CPM2 224 config_8560_ioports((ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR); 225 #endif 226 227 init_early_memctl_regs(); 228 229 #if defined(CONFIG_CPM2) 230 m8560_cpm_reset(); 231 #endif 232 #ifdef CONFIG_QE 233 /* Config QE ioports */ 234 config_qe_ioports(); 235 #endif 236 #if defined(CONFIG_FSL_DMA) 237 dma_init(); 238 #endif 239 #ifdef CONFIG_FSL_CORENET 240 corenet_tb_init(); 241 #endif 242 init_used_tlb_cams(); 243 244 /* Invalidate the CPC before DDR gets enabled */ 245 invalidate_cpc(); 246 } void board_init_f在arch/powerpc/cpu/lib/borad.c中定义 258 /************************************************************************ 259 * Initialization sequence * 260 ************************************************************************ 261 */ 262 263 init_fnc_t *init_sequence[] = { 264 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) 265 probecpu, 266 #endif 267 #if defined(CONFIG_BOARD_EARLY_INIT_F) 268 board_early_init_f, 269 #endif 270 #if !defined(CONFIG_8xx_CPUCLK_DEFAULT) 271 get_clocks, /* get CPU and bus clocks (etc.) */ 272 #if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \ 273 && !defined(CONFIG_TQM885D) 274 adjust_sdram_tbs_8xx, 275 #endif 276 init_timebase, 277 #endif 278 #ifdef CONFIG_SYS_ALLOC_DPRAM 279 #if !defined(CONFIG_CPM2) 280 dpram_init, 281 #endif 282 #endif 283 #if defined(CONFIG_BOARD_POSTCLK_INIT) 284 board_postclk_init, 285 #endif 286 env_init, 287 #if defined(CONFIG_8xx_CPUCLK_DEFAULT) 288 get_clocks_866, /* get CPU and bus clocks according to the environment variable */ 289 sdram_adjust_866, /* adjust sdram refresh rate according to the new clock */ 290 init_timebase, 291 #endif 292 init_baudrate, 293 serial_init, 294 console_init_f, 295 display_options, 296 #if defined(CONFIG_8260) 297 prt_8260_rsr, 298 prt_8260_clks, 299 #endif /* CONFIG_8260 */ 300 #if defined(CONFIG_MPC83xx) 301 prt_83xx_rsr, 302 #endif 303 checkcpu, 304 #if defined(CONFIG_MPC5xxx) 305 prt_mpc5xxx_clks, 306 #endif /* CONFIG_MPC5xxx */ 307 #if defined(CONFIG_MPC8220) 308 prt_mpc8220_clks, 309 #endif 310 checkboard, 311 INIT_FUNC_WATCHDOG_INIT 312 #if defined(CONFIG_MISC_INIT_F) 313 misc_init_f, 314 #endif 315 INIT_FUNC_WATCHDOG_RESET 316 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) 317 init_func_i2c, 318 #endif 319 #if defined(CONFIG_HARD_SPI) 320 init_func_spi, 321 #endif 322 #ifdef CONFIG_POST 323 post_init_f, 324 #endif 325 INIT_FUNC_WATCHDOG_RESET 326 init_func_ram, //初始化DDR内存 -->initdram()-->fixed_sdram() 327 #if defined(CONFIG_SYS_DRAM_TEST) 328 testdram, 329 #endif /* CONFIG_SYS_DRAM_TEST */ 330 INIT_FUNC_WATCHDOG_RESET 331 332 NULL, /* Terminate this list */ 333 }; 369 void board_init_f (ulong bootflag) 370 { 371 bd_t *bd; 372 ulong len, addr, addr_sp; 373 ulong *s; 374 gd_t *id; 375 init_fnc_t **init_fnc_ptr; 376 #ifdef CONFIG_PRAM 377 int i; 378 ulong reg; 379 uchar tmp[64]; /* long enough for environment variables */ 380 #endif 381 382 /* Pointer is writable since we allocated a register for it */ 383 gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); 384 /* compiler optimization barrier needed for GCC >= 3.4 */ 385 __asm__ __volatile__("": : :"memory"); 386 387 #if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \ 388 !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \ 389 !defined(CONFIG_MPC86xx) 390 /* Clear initial global data */ 391 memset ((void *) gd, 0, sizeof (gd_t)); 392 #endif 393 394 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {//调用初始化函数 395 if ((*init_fnc_ptr) () != 0) { 396 hang (); 397 } 398 } 399 400 /* 401 * Now that we have DRAM mapped and working, we can 402 * relocate the code and continue running from DRAM. 403 * 404 * Reserve memory at end of RAM for (top down in that order): 405 * - area that won't get touched by U-Boot and Linux (optional) 406 * - kernel log buffer 407 * - protected RAM * - LCD framebuffer 409 * - monitor code 410 * - board info struct 411 */ 412 len = (ulong)&_end - CONFIG_SYS_MONITOR_BASE; 413 414 /* 415 * Subtract specified amount of memory to hide so that it won't 416 * get "touched" at all by U-Boot. By fixing up gd->ram_size 417 * the Linux kernel should now get passed the now "corrected" 418 * memory size and won't touch it either. This should work 419 * for arch/ppc and arch/powerpc. Only Linux board ports in 420 * arch/powerpc with bootwrapper support, that recalculate the 421 * memory size from the SDRAM controller setup will have to 422 * get fixed. 423 */ 424 gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; 425 426 addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize(); 427 428 #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) 429 /* 430 * We need to make sure the location we intend to put secondary core 431 * boot code is reserved and not used by any part of u-boot 432 */ 433 if (addr > determine_mp_bootpg()) { 434 addr = determine_mp_bootpg(); 435 debug ("Reserving MP boot page to %08lx\n", addr); 436 } 437 #endif 438 439 #ifdef CONFIG_LOGBUFFER 440 #ifndef CONFIG_ALT_LB_ADDR 441 /* reserve kernel log buffer */ 442 addr -= (LOGBUFF_RESERVE); 443 debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); 444 #endif 445 #endif 446 447 #ifdef CONFIG_PRAM /* 449 * reserve protected RAM 450 */ 451 i = getenv_f("pram", (char *)tmp, sizeof (tmp)); 452 reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM; 453 addr -= (reg << 10); /* size is in kB */ 454 debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); 455 #endif /* CONFIG_PRAM */ 456 457 /* round down to next 4 kB limit */ 458 addr &= ~(4096 - 1); 459 debug ("Top of RAM usable for U-Boot at: %08lx\n", addr); 460 461 #ifdef CONFIG_LCD 462 /* reserve memory for LCD display (always full pages) */ 463 addr = lcd_setmem (addr); 464 gd->fb_base = addr; 465 #endif /* CONFIG_LCD */ 466 467 #if defined(CONFIG_VIDEO) && defined(CONFIG_8xx) 468 /* reserve memory for video display (always full pages) */ 469 addr = video_setmem (addr); 470 gd->fb_base = addr; 471 #endif /* CONFIG_VIDEO */ 472 473 /* 474 * reserve memory for U-Boot code, data & bss 475 * round down to next 4 kB limit 476 */ 477 addr -= len; 478 addr &= ~(4096 - 1); 479 #ifdef CONFIG_E500 480 /* round down to next 64 kB limit so that IVPR stays aligned */ 481 addr &= ~(65536 - 1); 482 #endif 483 484 debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr); 485 486 /* 487 * reserve memory for malloc() arena 488 */ 489 addr_sp = addr - TOTAL_MALLOC_LEN; 490 debug ("Reserving %dk for malloc() at: %08lx\n", 491 TOTAL_MALLOC_LEN >> 10, addr_sp); 492 493 /* 494 * (permanently) allocate a Board Info struct 495 * and a permanent copy of the "global" data 496 */ 497 addr_sp -= sizeof (bd_t); 498 bd = (bd_t *) addr_sp; 499 memset(bd, 0, sizeof(bd_t)); 500 gd->bd = bd; 501 debug ("Reserving %zu Bytes for Board Info at: %08lx\n", 502 sizeof (bd_t), addr_sp); 503 addr_sp -= sizeof (gd_t); 504 id = (gd_t *) addr_sp; 505 debug ("Reserving %zu Bytes for Global Data at: %08lx\n", 506 sizeof (gd_t), addr_sp); 507 508 /* 509 * Finally, we set up a new (bigger) stack. 510 * 511 * Leave some safety gap for SP, force alignment on 16 byte boundary 512 * Clear initial stack frame 513 */ 514 addr_sp -= 16; 515 addr_sp &= ~0xF; 516 s = (ulong *)addr_sp; 517 *s-- = 0; 518 *s-- = 0; 519 addr_sp = (ulong)s; 520 debug ("Stack Pointer at: %08lx\n", addr_sp); 521 522 /* 523 * Save local variables to board info struct 524 */ 525 526 bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of DRAM memory */ 527 bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */ 528 529 #ifdef CONFIG_SYS_SRAM_BASE 530 bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM memory */ 531 bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM memory */ 532 #endif 533 534 #if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \ 535 defined(CONFIG_E500) || defined(CONFIG_MPC86xx) 536 bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */ 537 #endif 538 #if defined(CONFIG_MPC5xxx) 539 bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ 540 #endif 541 #if defined(CONFIG_MPC83xx) 542 bd->bi_immrbar = CONFIG_SYS_IMMR; 543 #endif 544 #if defined(CONFIG_MPC8220) 545 bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ 546 bd->bi_inpfreq = gd->inp_clk; 547 bd->bi_pcifreq = gd->pci_clk; 548 bd->bi_vcofreq = gd->vco_clk; 549 bd->bi_pevfreq = gd->pev_clk; 550 bd->bi_flbfreq = gd->flb_clk; 551 552 /* store bootparam to sram (backward compatible), here? */ 553 { 554 u32 *sram = (u32 *)CONFIG_SYS_SRAM_BASE; 555 *sram++ = gd->ram_size; 556 *sram++ = gd->bus_clk; 557 *sram++ = gd->inp_clk; 558 *sram++ = gd->cpu_clk; 559 *sram++ = gd->vco_clk; 560 *sram++ = gd->flb_clk; 561 *sram++ = 0xb8c3ba11; /* boot signature */ 562 } 563 #endif 564 565 WATCHDOG_RESET (); 566 bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ 567 bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */ 568 #if defined(CONFIG_CPM2) 569 bd->bi_cpmfreq = gd->cpm_clk; 570 bd->bi_brgfreq = gd->brg_clk; 571 bd->bi_sccfreq = gd->scc_clk; 572 bd->bi_vco = gd->vco_out; 573 #endif /* CONFIG_CPM2 */ 574 #if defined(CONFIG_MPC512X) 575 bd->bi_ipsfreq = gd->ips_clk; 576 #endif /* CONFIG_MPC512X */ 577 #if defined(CONFIG_MPC5xxx) 578 bd->bi_ipbfreq = gd->ipb_clk; 579 bd->bi_pcifreq = gd->pci_clk; 580 #endif /* CONFIG_MPC5xxx */ 581 bd->bi_baudrate = gd->baudrate; /* Console Baudrate */ 582 583 #ifdef CONFIG_SYS_EXTBDINFO 584 strncpy ((char *)bd->bi_s_version, "1.2", sizeof (bd->bi_s_version)); 585 strncpy ((char *)bd->bi_r_version, U_BOOT_VERSION, sizeof (bd->bi_r_version)); 586 587 bd->bi_procfreq = gd->cpu_clk; /* Processor Speed, In Hz */ 588 bd->bi_plb_busfreq = gd->bus_clk; 589 #if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \ 590 defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ 591 defined(CONFIG_440EPX) || defined(CONFIG_440GRX) 592 bd->bi_pci_busfreq = get_PCI_freq (); 593 bd->bi_opbfreq = get_OPB_freq (); 594 #elif defined(CONFIG_XILINX_405) 595 bd->bi_pci_busfreq = get_PCI_freq (); 596 #endif 597 #endif 598 599 debug ("New Stack Pointer is: %08lx\n", addr_sp); 600 601 WATCHDOG_RESET (); 602 603 #ifdef CONFIG_POST 604 post_bootmode_init(); 605 post_run (NULL, POST_ROM | post_bootmode_get(0)); 606 #endif 607 608 WATCHDOG_RESET(); 609 610 gd->relocaddr = addr; /* Record relocation address, useful for debug */ 611 612 memcpy (id, (void *)gd, sizeof (gd_t)); 613 614 relocate_code (addr_sp, id, addr); 615 616 /* NOTREACHED - relocate_code() does not return */ 617 } 614relocate_code (addr_sp, id, addr); } relocate_code 在start.S中定义 .globl relocate_code 929 relocate_code 。。。 1085 bl board_init_r//在board.c中定义 void board_init_r (gd_t *id, ulong dest_addr) 629 { 630 char *s; 631 bd_t *bd; 632 ulong malloc_start; 633 634 #ifndef CONFIG_SYS_NO_FLASH 635 ulong flash_size; 636 #endif 637 638 gd = id; /* initialize RAM version of global data */ 639 bd = gd->bd; 640 641 gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ 642 643 /* The Malloc area is immediately below the monitor copy in DRAM */ 644 malloc_start = dest_addr - TOTAL_MALLOC_LEN; 645 646 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) 647 /* 648 * The gd->cpu pointer is set to an address in flash before relocat ion. 649 * We need to update it to point to the same CPU entry in RAM. 650 */ 651 gd->cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; 652 #endif 653 654 #ifdef CONFIG_SYS_EXTRA_ENV_RELOC 。。。。。。。。。。。。 1067 for (;;) { 1068 WATCHDOG_RESET (); 1069 main_loop (); 1070 } main_loop()在common/main.c中 至此uboot启动完成 |
|
来自: langhuayipian > 《bootloader》