分享

powerpc uboot启动流程分析

 langhuayipian 2011-04-14
在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启动完成





    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多