Êíèãà: Embedded Linux Primer: A Practical, Real-World Approach

7.4.3. EP405 Processor Initialization

7.4.3. EP405 Processor Initialization

The first task that your new U-Boot port must do correctly is to initialize the processor and the memory (DRAM) subsystems. After reset, the 405GP processor core is designed to fetch instructions starting from 0xFFFF_FFFC. The core attempts to execute the instructions found here. Because this is the top of the memory range, the instruction found here must be an unconditional branch instruction.

This processor core is also hard-coded to configure the upper 2MB memory region so that it is accessible without programming the external bus controller, to which Flash memory is usually attached. This forces the requirement to branch to a location within this address space because the processor is incapable of addressing memory anywhere else until our bootloader code initializes additional memory regions. We must branch to somewhere at or above 0xFFE0_0000. How did we know all this? Because we read the 405GP user's manual!

The behavior of the 405GP processor core, as described in the previous paragraph, places requirements on the hardware designer to ensure that, on power-up, nonvolatile memory (Flash) is mapped to the required upper 2MB memory region. Certain attributes of this initial memory region assume default values on reset. For example, this upper 2MB region will be configured for 256 wait states, three cycles of address-to-chip select delay, three cycles of chip select to output enable delay, and seven cycles of hold time.[58] This allows maximum freedom for the hardware designer to select appropriate devices or methods of getting instruction code to the processor directly after reset.

We've already seen how the reset vector is installed to the top of Flash in Listing 7-2. When configured for the 405GP, our first lines of code will be found in the file .../cpu/ppc4xx/start.S. The U-Boot developers intended this code to be processor generic. In theory, there should be no need for board-specific code in this file. You will see how this is accomplished.

We don't need to understand PowerPC assembly language in any depth to understand the logical flow in start.S. Many frequently asked questions (FAQs) have been posted to the U-Boot mailing list about modifying low-level assembly code. In nearly all cases, it is not necessary to modify this code if you are porting to one of the many supported processors. It is mature code, with many successful ports running on it. You need to modify the board-specific code (at a bare minimum) for your port. If you find yourself troubleshooting or modifying the early startup assembler code for a processor that has been around for a while, you are most likely heading down the wrong road.

Listing 7-6 reproduces a portion of start.S for the 4 xx architecture.

Listing 7-6. U-Boot 4xx startup code

...
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) ||
defined(CONFIG_405) || defined(CONFIG_405EP)
     /*--------------------------------- */
/* Clear and set up some registers.  */
/*--------------------------------- */
addi    r4,r0,0x0000
mtspr   sgr,r4
mtspr   dcwr,r4
mtesr   r4              /* clear Exception Syndrome Reg */
mttcr   r4              /* clear Timer Control Reg */
mtxer   r4              /* clear Fixed-Point Exception Reg */
mtevpr  r4            /* clear Exception Vector Prefix Reg */
addi    r4,r0,0x1000   /* set ME bit (Machine Exceptions) */
oris    r4,r4,0x0002             /* set CE bit (Critical Exceptions) */
mtmsr   r4                        /* change MSR */
addi    r4,r0,(0xFFFF-0x10000)  /* set r4 to 0xFFFFFFFF (status in the */
                             /* dbsr is cleared by setting bits to 1) */
mtdbsr  r4                        /* clear/reset the dbsr */
/*---------------------------------- */
/* Invalidate I and D caches. Enable I cache for defined memory regions */
/* to speed things up. Leave the D cache disabled for now. It will be  */
/* enabled/left disabled later based on user selected menu options. */
/* Be aware that the I cache may be disabled later based on the menu */
/* options as well. See miscLib/main.c.  */
/*------------------------------------- */
bl      invalidate_icache
bl      invalidate_dcache
/*-------------------------------------- */
/* Enable two 128MB cachable regions.     */
/*-----------------------------------    */
addis   r4,r0,0x8000
addi    r4,r4,0x0001
mticcr  r4                        /* instruction cache */
isync
addis   r4,r0,0x0000
addi    r4,r4,0x0000
mtdccr  r4                        /* data cache */

The first code to execute in start.S for the 405GP processor starts about a third of the way into the source file, where a handful of processor registers are cleared or set to sane initial values. The instruction and data caches are then invalidated, and the instruction cache is enabled to speed up the initial load. Two 128MB cacheable regions are set up, one at the high end of memory (the Flash region) and the other at the bottom (normally the start of system DRAM). U-Boot eventually is copied to RAM in this region and executed from there. The reason for this is performance: Raw reads from RAM are an order of magnitude (or more) faster than reads from Flash. However, for the 4 xx CPU, there is another subtle reason for enabling the instruction cache, as we shall soon discover.

Îãëàâëåíèå êíèãè


Ãåíåðàöèÿ: 0.571. Çàïðîñîâ Ê ÁÄ/Cache: 3 / 0
ïîäåëèòüñÿ
Ââåðõ Âíèç