【嵌入式Linux学习七步曲之第三篇 Linux系统bootlaoder移植】Guidelines for Porting PPCBOOT on PowerPC

 

Guidelines for Porting PPCBOOT on PowerPC

Sailor_forever  sailing_9806#163.com 转载请注明

http://blog.csdn.net/sailor_8318/archive/2009/10/30/4745793.aspx


1    Introduction    4
1.1    Purpose    4
1.2    Revision Information    4
1.3    Reference    4
1.4    Abbreviations    4
2    Basic of Boot loader    4
2.1    Why to port    4
2.2    How to download    5
2.3    Where to download    5
2.4    Operation mode    5
2.5    Transmission protocol    6
2.6    General boot flow    6
3    General about PPCBOOT    6
3.1    Functions supported    6
3.2    Commands supported    7
3.3    Environment variables    8
3.4    Development environment and tools    9
3.5    Boot flow    9
4    Porting on MPC8270    11
4.1    Related files    11
4.2    Link script    12
4.3    Memory map    14
4.3.1    Base Address    14
4.3.2    FLASH    15
4.3.3    SDRAM    16
4.4    Cfg header file    18
4.5    Porting steps    18
4.6    Hard Reset Configuration Word    21
4.7    HIMEM and LOMEM boot mode    22
4.8    Flash program    22
4.8.1    nRSTCONF high    23
4.8.2    nRSTCONF low    25
4.8.3    Programming steps    26
4.9    Debug with GDB    28
4.9.1    BDI configuration file for debug    28
4.9.2    Debugging of U-Boot before relocation    29
4.9.3    Debugging of U-Boot after relocation    31
4.9.4    Debugging with GUI    35
4.9.5    GDB script    35
4.10    Flash loading    37
4.10.1    IMMR    37
4.10.2    Stored address    37
4.10.3    Link address    37
4.10.4    Watchdog    37
4.10.5    Critical code    38
4.10.6    Entry point    38
4.11    RAM loading    39
4.11.1    IMMR    39
4.11.2    Stored address    39
4.11.3    Load address    39
4.11.4    Link address    40
4.11.5    Watchdog    40
4.11.6    Critical code    40
4.11.7    Entry point    42
5    Add user defined commands    43

 

 

1    Introduction
1.1    Purpose
This article gives a brief introduction to PPCBOOT and provides a detailed guideline for porting PPCBOOT to MPC8270. It covers the whole development stages including porting, Flash programming, debugging and even dynamically loading.
1.2    Revision Information            
1.3    Reference
MPC8270 reference manual
Ppcboot2.0 source code
http://www.denx.de/
1.4    Abbreviations

2    Basic of Boot loader

2.1    Why to port
Boot loader is the first piece of code to be run on reset, and it is mainly responsible for initializing memory, console, other major peripherals and then loading kernel. Generally there are different boot loaders for different CPU architectures and OS, but some boot loader support several CPU architectures and OS. For example, VIVI is just for Samsung ARM series, BLOB just for Intel PXA series, PPCBOOT or PPCBOOTfor ARM, PPC, MIPS, and several different OS like VxWorks, Linux, PSOS and so on, Redboot for MIPS, M68k and ARM.
Boot loader is highly dependent on CPU architecture, CPU type and board configuration. Embedded system is a highly configurable system, so boot loader should be modified to adapt to different requirements.
These kinds of universal boot loader is highly portable and configurable, so adopting these boot loaders instead of proprietary ones can greatly decrease the difficulty and thus shorten development periods.

 

2.2    How to download
For a completely new board, how we download the program to memory device? Generally during development stage, program is loaded to RAM to execute by emulator in order to decrease programming frequency since programming is a little time consuming. After program is stable, it will be downloaded to nonvolatile memory like Flash.
Typically there are three ways to download program:
1) JTAG. External emulator makes use of JTAG to control CPU, and then download program to Flash or RAM;
2) Internal ROM loader. For this situation, CPU is selected to boot from internal ROM, and receive program from host through x-modem protocol by UART. Usually the first downloaded program is saved in internal RAM, and it then severs as a loader to continue to receive the actual bootloader, and eventually the bootloader itself save it to Flash. After reset, CPU should be selected to from Flash.
3) External main controller. Some CPU can boot directly from RAM or EEPROM, and main controller send program to CPU every time on reset.
Once boot loader is downloaded to nonvolatile memory, then there is no more need to use any other tool because boot loader can upgrade itself.

 

2.3    Where to download
Where program should be downloaded to is up to the boot mode. Internal ROM, RAM, Flash and EEPROM all can be booting device. No matter what boot mode is, program should be saved where the first instruction is fetched according to the boot mode. This reset address is quite different from CPU to CPU. For example, 0x00000000 always for ARM, 0xFFF0 0000 or 0x00000000 or 0xFFFF FFFC for PPC, and 0x1FC0 0000 for MIPS. For detailed reset address, refer to the specific chip manual.

 

2.4    Operation mode
Target board and host are usually connected by UART, and target use UART as a standard output and input device. Boot loader usually includes two operation modes: boot loading and downloading.
1) Boot loading: boot loader loads kernel and file system to RAM automatically and then jumps to kernel entry point without any user interference. It's the default mode for eventual products.
2) Downloading: after boot loader initializes the hardware, it provides a user interface through UART to wait any user command input. It's usually for downloading kernel and file system for the first time or upgrading during development stage. Usually boot loader receives files from host through UART/Ethernet/USB, saves it in RAM and eventually programs it into Flash.
Boot loader works in boot loading mode on reset, and will switch to downloading mode if any key is pressed to interrupt the booting procedure.

 

2.5    Transmission protocol
The transmission protocol between the target and host is usually kermit / x-modem / y-modem for UART, and host tool is any terminal software like DNW, hyper terminal, minicom, or kermit. But UART speed is limited, and is of very low efficiency for transmitting big files. So another option is TFTP, and this protocol needs a working Ethernet. Its speed is much greater than UART. Of course USB can be used, but it's much more complicated and besides not all CPU have USB port.

 

2.6    General boot flow
Because boot loader is greatly dependent on CPU architecture, typically boot loader is divided into two stages. Stage 1 usually runs in Flash, and it is usually assembly code and position independent. It's mainly responsible for initializing core registers, configuring and checking SDRAM, setup stack, code relocation, and last jumping to entry point of stage 2.
Stage 2 runs in RAM and is C code, so it's CPU independent and highly portable. It's responsible for initializing other major peripheral and resources, offering user interface, loading kernel and file system from Flash to RAM, and jumping to kernel entry point if there is no user interrupt.

 

3    General about PPCBOOT
3.1    Functions supported
PPCBOOT or PPCBOOTis a universal boot loader applicable for hardware like PPC, ARM, MIPS, x86 and m68k, and OS like Linux, VxWorks and PSOS.
Its main functions are listed below:
"    Support NFS or Ramdisk root file system;
"    Support compressed and non compressed Linux kernel;
"    Support Flash and RAM booting;
"    Multiple parameters to kernel;
"    Support script, environment variables in FLASH, NVRAM and EEPROM;
"    UART and TFTP download;
"    CRC check;
"    All kinds of drivers for UART, Flash, SDRAM, NVRAM, IIC EEPROM, USB, PCI, SPI, LED, RTC and so on;
"    SDRAM and Flash auto check at reset;
"    User defined commands;
"    Memory reading, writing and modify

 

3.2    Commands supported
PPCBOOT support many commands, but it's highly configurable to achieve a smaller code size and higher reliability, so not all commands are supported on one board.

Information Commands
bdinfo - print Board Info structure
flinfo - print FLASH memory information
iminfo - print header information for application image
help - print online help
Memory Commands
cmp - memory compare
cp - memory copy
md - memory display
mm - memory modify (auto-incrementing)
mtest - simple RAM test
mw - memory write (fill)
nm - memory modify (constant address)
Flash Memory Commands
cp - memory copy (program flash)
flinfo - print FLASH memory information
erase - erase FLASH memory
protect - enable or disable FLASH write protection
Execution Control Commands
bootm - boot application image from memory
go - start application at address 'addr'
Network Commands
bootp - boot image via network using BOOTP/TFTP protocol
dhcp - invoke DHCP client to obtain IP/boot params
loadb - load binary file over serial line (kermit mode)
nfs - boot image via network using NFS protocol
ping - send ICMP ECHO_REQUEST to network host
rarppcboot- boot image via network using RARP/TFTP protocol
tftppcboot- boot image via network using TFTP protocol
Environment Variables Commands
printenv- print environment variables
saveenv - save environment variables to persistent storage
askenv - get environment variables from stdin
setenv - set environment variables
run - run commands in an environment variable
bootd - boot default, i.e., run 'bootcmd'
Special Commands
i2c - I2C sub-system
kgdb - enter gdb remote debug mode
icache - enable or disable instruction cache
dcache - enable or disable data cache
pci - list and access PCI Configuraton Space
regdump - register dump commands
usb - USB sub-system
Miscellaneous Commands
date - get/set/reset date & time
echo - echo args to console
exit - exit script
reset - Perform RESET of the CPU
version - print monitor version
wd - check and set watchdog
? - alias for 'help'

 

3.3    Environment variables
Environment Variables can be used to configure the system and to store parameters for commands, and even commands and sequences of commands (simple scripts).
There are four big classes of commands:
Board Configuration
baudrate, ethaddr
Startup Behaviour
bootdelay, bootcmd
Network Parameters
ipaddr, serverip, gatewayip, dnsip, netmask, hostname, rootpath, bootfile
Misc
loadaddr
User Defined
User defined variables offer great flexibility for user defined commands and scripts
Environment variables may be stored in any of FLASH, NVRAM and EEPROM. For a completely new board, since CRC check will fail, the default variables will be used.
=> saveenv, to save variables to non volatile memory configured.

 

3.4    Development environment and tools
PPCBOOT is Linux based system, and all compilers, linkers and debuggers should work on Linux platform. For ARM, compile tool is cross-tool(arm-linux-gcc), while for PPC, it is ELDK(The Embedded Linux Development Kit) which includes the GNU cross development tools, such as the compilers, binutils, gdb, etc., and a number of pre-built target tools and libraries necessary to provide some functionality on the target system.
Other tools include UART terminal like DNW, hyper terminal, putty on windows, and kermit, minicom on Linux.
Besides TFTP server is needed to download kernel and file system, and NFS server is needed to download application and kernel module after Linux kernel boots.

 

3.5    Boot flow
For MPC8270, The reset vector is vectored at 0xFFF0 0100 or 0x0000 0100 according to high or low memory space, and the first instruction will be fetched here. The memory space and reset vector offset are both decided by HRCW. The reset code is 0x100 offset from the image, since the first 0x100 bytes are HRCW. There is 0x100 bytes' space for each exception handler.
Boot flow includes two stages with stage 1 running in Flash and stage 2 in SDRAM. The detailed function for each stage for PPC is quite different from that for ARM.
Stage 1 for PPC is not PIC(position independent code)which means that there must a copy of code at the address where PPCBOOT is linked at, so special attention should be paid to absolute jump instruction. And before relocation to SDRAM, data section is read-only and bss section can not be accessed, so a data structure called gd_t is created in DPRAM to pass some information in stage 1 to stage 2.
Stage 1 is responsible:
Initialise the MPC8260 processor core(enable machine check interrupt, disable MMU, disable other interrupts, disable instruction and data cache, disable watchdog if needed, initialize BAT and TLB);
Clear OR0 to jump to absolute Flash link address;
Set up stack in internal DPRAM and then run C code in Flash;
Initialize the global data pointer;
Initialize all GPIO;
Set up the memory map;
Initialize a bunch of registers like SCCR, RMR, BCR, SIUMCR, TMCNTSC and PISCR;
Initialize the UPM's;
Initialize UART and console;
Initialize SDRAM and check it;
Calculate relocation position and new stack pointer in SDRAM;
Relocate code to SDRAM, flush the cache and jump to RAM entry;

Stage 2:
Now PPCBOOT is running in RAM, but before accessing any global data or bss section, GOT(Global offset table)  have to be fixed due to relocation. And then jump to main C entry in stage 2.
Fix any referenced global pointer including command table and environment variable pointer and so on;
Relocate trap handler to corresponding exception vectors and fix any exception handler pointer;
Initialize Flash;
Initialize Ethernet;
Enable interrupt;
Initialize any board related drivers;
Enter main loop to receive any command through CLI;
Boot OS if there is no interrupt;

 
4    Porting on MPC8270

4.1    Related files
PPCBOOT is a highly configurable and portable system, so porting to a new board is quite easy, but porting to a new CPU type is relatively difficult, and porting to a new CPU architecture is almost impossible with just you hand.
PPCBOOT version is 2.0 and major files are listed as below:
File or directory    Function Description
Board/board_name    All specific board related files
Cpu/cpu_name    All specific CPU related files
common    All command files and some CPU and board independent drivers
drivers    CPU and board dependent drivers
Include    All header files
Include/configs    board specific configuration files
lib_ppc    CPU architecture related files
Net    Network related drivers
post    Some test program
Tools    Tools to pack image and others
Makefile    The highest level make file
Config.mk    Specific compile options like debug and optimization

 

4.2    Link script
Link script is in the directory of Board/board_name.
Section option divides the code into different sectors, and then maps them into different memory segment, and all this will decide the link address of all symbols.
Some compilers support user defined section which offers great convenience for designers to fully control the code arrangement.
Usually the compiler defined sections include:
.text, .data, .bss, .init, .sdata
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
   __DYNAMIC = 0;    */
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  . = + SIZEOF_HEADERS;
  .interp : { *(.interp) }
  .hash          : { *(.hash)        }
  .dynsym        : { *(.dynsym)        }
  .dynstr        : { *(.dynstr)        }
  .rel.text      : { *(.rel.text)        }
  .rela.text     : { *(.rela.text)     }
  .rel.data      : { *(.rel.data)        }
  .rela.data     : { *(.rela.data)     }
  .rel.rodata    : { *(.rel.rodata)     }
  .rela.rodata   : { *(.rela.rodata)     }
  .rel.got       : { *(.rel.got)        }
  .rela.got      : { *(.rela.got)        }
  .rel.ctors     : { *(.rel.ctors)    }
  .rela.ctors    : { *(.rela.ctors)    }
  .rel.dtors     : { *(.rel.dtors)    }
  .rela.dtors    : { *(.rela.dtors)    }
  .rel.bss       : { *(.rel.bss)        }
  .rela.bss      : { *(.rela.bss)        }
  .rel.plt       : { *(.rel.plt)        }
  .rela.plt      : { *(.rela.plt)        }
  .init          : { *(.init)    }
  .plt : { *(.plt) }
  .text      :
  {
    cpu/mpc8270/start.o    (.text)
    *(.text)
    common/environment.o(.text)
    *(.fixup)
    *(.got1)
    . = ALIGN(16);
    *(.rodata)
    *(.rodata1)
  }
  .fini      : { *(.fini)    } =0
  .ctors     : { *(.ctors)   }
  .dtors     : { *(.dtors)   }

  /* Read-write section, merged into data segment: */
  . = (. + 0x0FFF) & 0xFFFFF000;
  _erotext = .;
  PROVIDE (erotext = .);
  .reloc   :
  {
    *(.got)
    _GOT2_TABLE_ = .;
    *(.got2)
    _FIXUP_TABLE_ = .;
    *(.fixup)
  }
  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;

  .data    :
  {
    *(.data)
    *(.data1)
    *(.sdata)
    *(.sdata2)
    *(.dynamic)
    CONSTRUCTORS
  }
  _edata  =  .;
  PROVIDE (edata = .);

  __start___ex_table = .;
  __ex_table : { *(__ex_table) }
  __stop___ex_table = .;

  . = ALIGN(4096);
  __init_begin = .;
  .text.init : { *(.text.init) }
  .data.init : { *(.data.init) }
  . = ALIGN(4096);
  __init_end = .;

  __bss_start = .;
  .bss       :
  {
   *(.sbss) *(.scommon)
   *(.dynbss)
   *(.bss)
   *(COMMON)
  }
  _end = . ;
  PROVIDE (end = .);
}

There is no MEMORY option, so all the text, bss, data and other sections will be based on the same flash link address defined in config.mk in the same directory. Before relocation to RAM, all global data is read-only and bss section is not cleared. After code is relocated into SDRAM, any reference to all global data, bss and pointer should be fixed. This characteristic is quite different from that of ARM. This method for PPC will reduce the difficulty of porting, otherwise complicated MEMORY option is needed to map code into different memory segment, mainly flash and RAM part. So this is a universal method for all PPC CPU.

 

4.3    Memory map
4.3.1    Base Address
The memory structure is very essential for BSP development. All the memory items are as follows:

Function    CS    Bus    MemSize    Portsize    MemCntrl
Flash    0    60x    16MByte    16bit    GPCM
SDRAM    1    60x    64MByte    64bit    SDRAM
MPC8270 Internal Memory Map    -    -    128KBytes    -    -
Table 1 memory characteristic
At reset, flash is mapped at 0x00000000 for low memory boot mode, code is running in flash, and change Flash base to actual design value. And then initialize SDRAM base to 0x00000000, copy it self to SDRAM. After this, it jumps to high memory of SDRAM.

Function    Start address
Flash    0x00000000/0x4000 0000
MPC8270 Internal Memory Map    0xFFF00000
SDRAM    0x00000000

Table 2 Memory base address

 

4.3.2    FLASH
Following a reset the processor reads the reset configuration words from the device connected to nCS0 using 8 bit wide accesses when nRSTCONF pin is low. These words hold among other information the width of the Flash, which is used subsequently. Therefore the Flash device is connected to nCS0.
Register    Field    Value    Pattern
BR0        0x40001001    
    BA    0x40000000    0x0400
    PS    16-bit port size    10
    MS    GPCM-60x bus    000
    V    valid    1
OR0        0xFF001846    
    AM    16 Mbytes    0xFF00
    BCTLD    RnW not asserted    1
    CSNT    nCS negated earlier    1
    ACS    nCS same time as address    00
    SCY    4 wait states    0100
    SETA    No external termination    0
    TRLX    Timing relaxed    1
    EHTR    Extended Hold Time On Read Accesses    1
Table 3 Flash reg config
Function    offset
Jiffs file system for configuration data    0x00D00000
File system for ramdisk    0x00500000
OS    0x00100000
PPCBOOT    0x00000000





Table 4 Flash layout

 

4.3.3    SDRAM
The main system memory resides on the 60x Bus. The module operates without ECC using a 64-bit wide interface. Four devices with a 16-bit interface are used. Four devices with 128Mbit each, give a total capacity of 64MB.

Register    Field    Value    Pattern
BR1        0x00000041    
    BA    0x00000000    0
    PS    64-bit port size    00
    MS    SDRAM-60x bus    010
    V    valid    1
OR1        0xFC002CC0    
    SDAM    64 Mbytes    0xFC0
    LSDAM    0x0    0x0
    BPD    4 internal banks    01
    ROWST    A6 PSDMR[PBI]=1    0110
    NUMR    12 row addr lines    011
    PMSEL    back-to-back mode (normal)    0
    IBID    0    0
PSDMR    PBI    Page-based interleaving (normal)    1
    RFEN    Refresh services are required    1
    OP    Normal operation    000
    SDAM    Multiplex A[5:17] to A[16:28]    011
    BSMA    Bank select is A12-A14    000
    SDA10    AP alternates with A7, PSDMR[PBI] = 1    011
    RFRC    Refresh recovery 66ns => 6Clk    100
    PRETOACT    Precharge to activate 20ns => 2Clk    010
    ACTTORW    Activate to read/write 20ns => 2Clk    010
    BL    Burst length is 4    0
    LDOTOPRE    Last data out to precharge 1 Clk    01
    WRC    Write recovery 1Clk + 7.5ns => 2 Clk    10
    EAMUX    No external address multiplexing    0
    BUFCMD    Normal timing on control lines (no external buffers)    0
    CL    CAS latency 2 Clk    10
MPTPR    PTP    31    0x1F
PSRT    PSRT    15    0x0F
Table 5 SDRAM reg config
When PPCBOOT is running, the layout for SDRAM is as follows:
Function    Offset range
PPCBOOT    0x03F80000-0x03FFFFFF
Stack     0x03E00000-0x03E7FFFF
Download area    0x00003000-0x03DFFFFF
Exception vectors    0x00000000-0x00002FFF
Table 6 PPCBOOT SDRAM layout

 

4.4    Cfg header file
For a supported CPU type, the most difficult part for porting is configuration header file for each specific board under directory of Include/configs.
Before configuring, you need a thorough knowledge about HW configuration of the target board.
Item     configuration
CPU series    CONFIG_MPC8260
Location for environment variables    EEPROM offset 0x1D00
IIC driver    Soft
IIC EEPROM device addr    0x56
IIC EEPROM addr length    2 bytes
UART    SMC2
Baud rate    19200 8N1
Ethernet     FCC1, external clock
clock rate    66666666
Flash base    0x4000 0000
Flash size    16M
Flash bit width    16bit
Number of Flash bank    1
IMMR    0xFFF0 0000
High or low boot mode    Low
SDRAM base     0x00000000
SDRAM size    64M
Monitor base    Link address
Max monitor length    512k
Watch dog    Disabled
Other core registers    Refer to manual
Detailed configuration is attached.
 
4.5    Porting steps
1) Create a mpc8270 directory under "./cpu". Since mpc8270 architecture is the same as mpc8260, just make a copy of mpc8260 dir.
2) Create a board_name directory under "./board". Just copy a 8260 board.
There are at least four files.
Item     Description
Config.mk    TEXT_BASE is link address
Flash.c    Flash driver
board_name.c    SDRAM driver and GPIO configuration
Ppcboot.lds    Link script. Not need to be changed
Makefile    To compile any file under this dir
Flash driver, SDRAM and GPIO should be ported to adapt to board configuration. Any other board dependent drivers can be put in this directory. When doing so, Makefile should be changed so that new file will be compiled.
3) Create a board configuration header file under "./include/configs"
Principe to configure the header file, refer to 4.4.
4) Add a configuration item in Makefile under root directory of the project, for example:
eric8270_config:        unconfig
    @./mkconfig $(@:_config=) ppc mpc8270 board_name
Ppc is the CPU architecture, mpc8270 is CPU type in step 1 and board_name is the name of board in step 2.
5) Clean all previous rubbish
make distclean
6) Configure the board
Make eric8270_config
7) Compile the project
Make depend
Make all
This will build BIN image and map file under root directory of the project.
After this, you can get a downloadable image to debug. Here is an interesting guide.
int main (int argc, char *argv[])
{
sighandler_t no_more_time;
signal (SIGALRM, no_more_time);
alarm (PROJECT_DEADLINE - toSec (3 * WEEK));
if (available_money > available_manpower) {
pay consultant to port U-Boot;
return 0;
}
Download latest PPCBOOTsource;
Subscribe to u-boot-users mailing list;
if (clueless) {
email ("Hi, I am new to U-Boot, how do I get started?");
}
while (learning) {
Read the README file in the top level directory;
Read http://www.denx.de/re/DPLG.html
Read the source, Luke;
}
if (available_money > toLocalCurrency ($2500)) {
Buy a BDI2000;
} else {
Add a lot of aggravation and time;
}
Create your own board support subdirectory;
Create your own board config file;
while (!running) {
do {
Add / modify source code;
} until (compiles);
Debug;
if (clueless)
email ("Hi, I am having problems...");
}
Send patch file to Wolfgang;
return 0;
}
void no_more_time (int sig)
{
hire_a_guru();
}


4.6    Hard Reset Configuration Word
Hard Reset Configuration Word(HRCW) is defined in cpu/mpc8270/start.S and it occupies the first 256 bytes of code segment. There are four values that make up one Hard Reset Configuration Word.
This sequence contains all zero values for the first 256 bytes up to the reset vector with the exception of the Hard Reset Configuration Word at offset (0x00, 0x08, 0x10, and 0x18). The most significant byte is at 0x00 and the least is at 0x18.
The Hard Reset Configuration Word (HRCW) sets a number of useful things such as whether there is an external memory controller, whether the PowerPC core is disabled (i.e. only the communications processor is active, accessed by another CPU on the bus), whether using external arbitration, external bus mode, boot port size, core initial prefix, internal space base, boot memory space, etc.
These things dictate where the processor begins execution, where the boot ROM appears in memory, the memory controller setup when accessing boot ROM, etc. The HRCW is *extremely* important.
The reset configuration sequence is designed to support a system that uses up to eight MPC8270 chips, each configured differently. The HRCW is read from the bus during reset when nRSTCONF pin is pulled low, otherwise it is 0x00000000 on default. One CPU on the bus will be a hard reset configuration master; any others will be hard reset configuration slaves. The master reads eight HRCWs from flash during reset - the first it uses for itself, the other 7 it communicates to up to 7 configuration slaves by some complicated mechanism, which is not really important here.
The configuration master performs 32 successive reads starting at address 0 and incrementing by 8 each read (i.e. on 64 bit boundaries) but only 8 bits is read, and always from byte lane D[0-7] (so that port size of the boot device does not matter). The first four reads form the 32 bit HRCW for the master itself. The second four reads form the HRCW for the first slave, and so on, up to seven slaves.

 
Element    Function Description
CIP    Core initial prefix. Defines the initial value of MSR[IP]. Exception prefix. The setting of this bit specifies whether an exception vector offset is prepended with Fs or 0s. In the following description, nnnnn is the offset of the exception vector.
0 MSR[IP] = 1 (default). Exceptions are vectored to the physical address 0xFFFn_nnnn
1 MSR[IP] = 0 Exceptions are vectored to the physical address 0x000n_nnnn.
BPS    Boot port size. Defines the initial value of BR0[PS], the port size for memory controller bank 0.
ISB    Initial internal space base select. Defines the initial value of IMMR[0-14] and determines the base address of the internal memory space
BMS    Boot memory space. Defines the initial value for BR0[BA]. There are two possible boot memory regions: HIMEM and LOMEM.
0 0xFE00_0000-0xFFFF_FFFF
1 0x0000_0000-0x01FF_FFFF

4.7    HIMEM and LOMEM boot mode
The base address of bank 0 for MPC8270 is not fixed but decided by BR0, so before software set up BR0, there should be a default value for BR0. Generally there are two boot memory spaces for BR0, HIMEM and LOMEM.
High: 0xFE00_0000-0xFFFF_FFFF
Low: 0x0000_0000-0x01FF_FFFF
On reset, the first instruction will be fetched from address 0xFFF00100 or 0x00000100 which is decided by CIP of HRCW.
Any address access will be matched by each ORx and BRx pair. Since OR0[AM] on reset is 1111_1110_0000_0000_0, upper seven bits of address buses will be compared. So the combination of OR0 and BR0 should ensure that reset vector will be mapped into Flash space.
Here are some typical combinations:
CIP = 1 and BMS = 1;
CIP = 0 and BMS = 0;

 

4.8    Flash program
The programming can be done via jtag by boundary scan (Goepel) or debugger(BDI3000).
The BDI3000 is a jtag programmer distributed by ABATRON:
http://www.abatron.ch/fileadmin/user_upload/products/pdf/BDI3000-Brochure.pdf
When using BDI3000, hardware dog on board should be disabled.
4.8.1    nRSTCONF high
For a completely new flash, which means there is no any valid program in base address, nRSTCONF pin should be pulled high.
Configuration file for nRSTCONF high is as follows:


; bdiGDB configuration file for PUC8270/80 Board and PPCBoot and MirrorBit-Flash
; Hard Reset Configuration Word = 0x00000000 (RSTCONF=HIGH)
; ---------------------------------------------------------
;
[INIT]
; init core register
WREG    MSR             0x00000000
;      ;clear MSR

;; init IMMR when RSTCONF=HIGH
WM32    0x000101A8    0x00000000    ;IMMR : internal space @ 0x00000000 decided by ISB of Hard Reset Configuration Word
WM32    0x00010004    0xFFFFFFC3    ;SYPCR: disable watchdog
WM32    0x00010C80    0x00000001    ;SCCR : normal operation
WM32    0x00010024    0x00040000    ;BCR init
WM32    0x00010000    0x00000000    ;SIUMCR init
WM32    0x00010C94    0x00000000      ;RMR init

; init memory controller
; Flash S29GL128M10, 16MB, 100ns
WM32    0x00010104    0xFF001846    ;OR0: Data buffer dis., 6 w.s., ext.hold on read, tc=8*15ns=120ns
WM32    0x00010100    0x40001001    ;BR0: Flash @0x40000000, 16bit, no parity

[TARGET]
CPUTYPE     8270        ;the CPU type (603EV,750,8240,8260)
JTAGCLOCK   0          ;use 16.6 MHz JTAG clock
BOOTADDR    0xFFF00100  ;boot address used for start-up break, decided by CIP of Hard Reset Configuration Word
BDIMODE     AGENT         ;the BDI working mode (LOADONLY | AGENT | GATEWAY)
BREAKMODE   HARD          ;SOFT or HARD, HARD uses PPC hardware breakpoints
STEPMODE    HWBP       ;TRACE or HWBP, HWPB uses a hardware breakpoint
;MMU         XLAT

;VECTOR      NOCATCH      ;catch unhandled exceptions
;DCACHE      NOFLUSH    ;data cache flushing (FLUSH | NOFLUSH)
POWERUP     3000        ;start delay after power-up detected in ms
REGLIST     ALL         ;select registers needed init to transfer to CPU
STARTUP         RESET  ;for programming
;STARTUP        RUN    ;for gdb debug
WAKEUP            1000
;MEMDELAY        2000


[HOST]
IP          147.128.21.52   ;tftp sever ip where to get download image
LOAD        MANUAL      ;load code MANUAL or AUTO after reset
DEBUGPORT   2001        ;network port for gdb debug
PROMPT      PUC8270>    ;new prompt for Telnet
DUMP        E:/temp/dump.bin

[FLASH]
CHIPTYPE    MIRRORX16   ;Flash type: AMD MirrorBit
CHIPSIZE    0x1000000   ;The size of one flash chip in bytes (e.g. S29GL128M10 = 0x1000000)
BUSWIDTH    16          ;The width of the flash memory bus in bits (8 | 16 | 32 | 64)
FILE        ppcboot.bin   ;default file to program, here is TMN PPCBOOT
FORMAT      BIN
;WORKSPACE   0x00000000    ;workspace in int. target RAM for fast download; download is stable without this, but fast with it.

;default for erase command, total size should be larger the size of download image
ERASE       0x40000000  ;erase sector (128K) of flash
ERASE       0x40020000  ;erase sector (128K) of flash
ERASE       0x40040000  ;erase sector (128K) of flash
ERASE       0x40060000  ;erase sector (128K) of flash
ERASE       0x40080000  ;erase sector (128K) of flash
ERASE       0x400a0000  ;erase sector (128K) of flash

[REGS]
DMM1        0x00000000  ;IMMR base
FILE        $reg8280.def


4.8.2    nRSTCONF low

When there is a valid HRCW at Flash base, then nRSTCONF pin can be pulled high or low. When nRSTCONF  is low, CPU will fetch HRCW first, then BDI run initialisation script. All registers' address should be based on ISB of HRCW.

Configuration file for nRSTCONF low is as follows:

; bdiGDB configuration file for PUC8270/80 Board and PPCBoot and MirrorBit-Flash
; Hard Reset Configuration Word = 0x0A07B000 (RSTCONF=LOW)
; ---------------------------------------------------------
;
[INIT]
; init core register
WREG    MSR             0x00000000
;      ;clear MSR

;IMMR : internal space @ 0xFFF00000 decided by ISB of Hard Reset Configuration Word
WM32    0xFFF10004    0xFFFFFFC3    ;SYPCR: disable watchdog
WM32    0xFFF10C80    0x00000001    ;SCCR : normal operation
WM32    0xFFF10024    0x00040000    ;BCR init
WM32    0xFFF10000    0x00000000    ;SIUMCR init
WM32    0xFFF10C94    0x00000000      ;RMR init

; init memory controller
; Flash S29GL128M10, 16MB, 100ns
WM32    0xFFF10104    0xFF001846    ;OR0: Data buffer dis., 6 w.s., ext.hold on read, tc=8*15ns=120ns
WM32    0xFFF10100    0x00001001    ;BR0: Flash @0x00000000, 16bit, no parity,default value for low boot memory mode instead of the eventual value

[TARGET]
CPUTYPE     8270        ;the CPU type (603EV,750,8240,8260)
JTAGCLOCK   0          ;use 16.6 MHz JTAG clock
BOOTADDR    0x00000100  ;boot address used for start-up break, decided by CIP of Hard Reset Configuration Word
BDIMODE     AGENT         ;the BDI working mode (LOADONLY | AGENT | GATEWAY)
BREAKMODE   HARD          ;SOFT or HARD, HARD uses PPC hardware breakpoints
STEPMODE    HWBP       ;TRACE or HWBP, HWPB uses a hardware breakpoint
;MMU         XLAT

;VECTOR      NOCATCH      ;catch unhandled exceptions
;DCACHE      NOFLUSH    ;data cache flushing (FLUSH | NOFLUSH)
POWERUP     3000        ;start delay after power-up detected in ms
REGLIST     ALL         ;select registers needed init to transfer to CPU
STARTUP         RESET  ;for programming
;STARTUP        RUN    ;for gdb debug
WAKEUP            1000
;MEMDELAY        2000


[HOST]
IP          147.128.21.52   ;tftp sever ip where to get download image
LOAD        MANUAL      ;load code MANUAL or AUTO after reset
DEBUGPORT   2001        ;network port for gdb debug
PROMPT      PUC8270>    ;new prompt for Telnet
DUMP        E:/temp/dump.bin

[FLASH]
CHIPTYPE    MIRRORX16   ;Flash type: AMD MirrorBit
CHIPSIZE    0x1000000   ;The size of one flash chip in bytes (e.g. S29GL128M10 = 0x1000000)
BUSWIDTH    16          ;The width of the flash memory bus in bits (8 | 16 | 32 | 64)
FILE        ppcboot.bin   ;default file to program, here is TMN PPCBOOT
FORMAT      BIN
;WORKSPACE   0xFFF00000    ;workspace in int. target RAM for fast download; download is stable without this, but fast with it.

;default for erase command, total size should be larger the size of download image
ERASE       0x00000000  ;erase sector (128K) of flash
ERASE       0x00020000  ;erase sector (128K) of flash
ERASE       0x00040000  ;erase sector (128K) of flash
ERASE       0x00060000  ;erase sector (128K) of flash
ERASE       0x00080000  ;erase sector (128K) of flash
ERASE       0x000a0000  ;erase sector (128K) of flash

[REGS]
DMM1        0xFFF00000  ;IMMR base
FILE        $reg8280.def

 

4.8.3    Programming steps
1) Configure an tftp server (e.g. tftppcboot/bkt003......) where to put the BDI3000 configuration file and the PPC8270 register configuration files
2) Configure in the BDI3000 via rs232 interface the ip address of the debugger and the tftp server in the configuration file under the HOST section, also the ip of the tftp server where to get the binary file to download into the flash.
When doing this, be sure to disconnect BDI3000 with the board, otherwise configuration may fail.
 
3) connect BDI3000 with target board, and start a telnet session on the BDI3000: from the BDI3000 menu is possible to erase the flash and to reprogram it.
The erase command will execute the ERASE sections of the config file
PUC8270>erase
Erasing flash at 0x00000000
Erasing flash at 0x00010000
Erasing flash at 0x00020000
Erasing flash at 0x00030000
Erasing flash passed
Then program bin file to flash
PUC8270>prog 0x00000000 ppcboot.bin BIN
0x00000000 is the base address of flash defined in the cfg file.
PUC8270>md 0x00000000
00000000 : 0a0a0a0a 0a0a0a0a 07070707 07070707  ................
00000010 : b0b0b0b0 b0b0b0b0 00000000 00000000  ................
00000020 : 00000000 00000000 00000000 00000000  ................
We can see that Flash is successfully programmed.

 

4.9    Debug with GDB
In order to debug program with GDB in step mode,"-g" compile option is needed to build some symbol and compile optimization should be deleted for single step otherwise code will not run line by line.
This is configured in config.mk in root directory of the project
Add "DBGFLAGS= -g #-DDEBUG"
Delete "OPTFLAGS= -Os #-fomit-frame-pointer"
When PPCBOOT starts it is running from ROM space. Running from flash would make it nearly impossible to read from flash while executing code from flash not to speak of updating the PPCBOOT image in flash itself. To be able to do just that, PPCBOOT relocates itself to RAM. We therefore have two phases with different program addresses.
When directly booting from flash, the symbol table can be used directly, but when PPCBOOT relocate itself to RAM, the BDI3000 debugger can not identify the symbol any longer. So debugging is divided into two stages.

 

4.9.1    BDI configuration file for debug
After program PPCBOOT into Flash, nRSTCONF pin should be pulled low so that CPU can boot normally. Since now BDI configures BR0 and OR0 according to configuration file, but reset vector is decided by HRCW, the combination of BR0 and OR0 should ensure that instruction at reset vector can be fetched from Flash.
HRCW is 0x0A07B000 which means that reset vector is 0x00000100, and boot memory space is 0--0x01FF_FFFF. So BR0 should be 0x00000000 instead of the eventual designed value 0x40000000.
Otherwise PC should be changed to a 0x100 offset from the Flash base address(0x40000100) manually by:
PUC8270>ti 0x40000100
    Target CPU        : MPC8280/8220/5200 (Zeppo)
    Target state      : debug mode
    Debug entry cause : instruction address breakpoint
    Current PC        : 0x40000104
    Current CR        : 0x00000000
    Current MSR       : 0x00000000
Current LR        : 0x00000000
PUC8270>md 0x40000100
40000100 : 3aa00001 48000014 00000000 00000000  :...H...........
40000110 : 3aa00002 48000004 7ca000a6 4800305d  :...H...|...H.0]
40000120 : 3c60fff1 80830104 38a07fff 7c842838  <`......8...|.(8
We can see that CPU can fetch right instructions from 0x40000100.

 

4.9.2    Debugging of U-Boot before relocation
Some commands used are listed here.
Command    Function Description
target remote 150.236.68.212:2001    Connect board BDI serverip:portnum. Portnum is configured in the BDI cfg file
ppc_82xx-gdb ppcboot    ppc_82xx-gdb is cross debug tool, and ppcboot is elf image
d b(delete breakpoint)    Delete all breakpoints
b _start_warm    Set a breakpoint at function _start_warm
c    Continue to run
detach    Reset board and terminate debug
symbol-file    Delete loaded symbol file
Add-symbol-file elfimage startaddr    Add new symbol file of elfimage at startaddr
l board_init_r    List codes near function board_init_r
p    print
After PC points to the entry point _start in Flash, then connect board.
cnbjc0052 ppcboot-2.0.0_dev/ppcboot-2.0.0> ppc_82xx-gdb ppcboot
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux"...
(gdb) target remote 150.236.68.212:2001
Remote debugging using 150.236.68.212:2001
0x00000100 in ?? ()
Since on reset, now the PC is 0x00000100, but the symbol table base address is 0x40000000, so GDB can not map 0x00000100 to any code.
(gdb) d b
(gdb) b _start_warm
Breakpoint 1 at 0x40000110: file /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S, line 226.
(gdb) c
Continuing.
If PC becomes 0x40000110 as program is going on, the GDB will stop CPU, but when CPU come to  _start_warm, PC is 0x00000110, so CPU will not stop at _start_warm.
After label in_flash, PC will point to over 0x40000000 range area. Since MPC8270 only supports one hardware breakpoint, we have to give another try. Reset board and reconnect.
(gdb) detach
(gdb) target remote 150.236.68.212:2001
After connecting board,
(gdb) b board_init_f
Breakpoint 1 at 0x400058cc: file board.c, line 342.
(gdb) c
Continuing.
Breakpoint 1, board_init_f (bootflag=0) at board.c:342
342     {
(gdb) l
337      *
338      ************************************************************************
339      */
340
341     void board_init_f (ulong bootflag)
342     {
343             DECLARE_GLOBAL_DATA_PTR;
344
345             bd_t *bd;
346             ulong len, addr, addr_sp;
(gdb)
Since when CPU comes to board_init_f, PC is 0x400058cc, so CPU stopped.
(gdb) d b
 (gdb) b board_init_r
Breakpoint 2 at 0x40005bb4: file board.c, line 572.
(gdb) c
Continuing.
CPU did not stop at board_init_r as expected. So we must add new map table before CPU comes to board_init_r.

 

4.9.3    Debugging of U-Boot after relocation
For debugging U-Boot after relocation we need to know the address to which U-Boot relocates itself to. When no exotic features like PRAM are used, this address usually is CFG_SDRAM_BASE + SDRAM_MAX_SIZE - CFG_MONITOR_LEN. In our example with 64MB RAM based at 0 and CFG_MONITOR_LEN = 512KB this yields the address 0x04000000 - 0x80000 = 0x3F80000.
In other cases, check the source code, and apply some common sense. For example, on PPC we use "r29" to hold a pointer to the "global data" structure ("struct global_data"); this structure contains a field
unsigned long   reloc_off;      /* Relocation Offset */
which is the offset between the image addresses in flash and in RAM. You can easily print this value in gdb like that:
(gdb) print/x ((gd_t *)$r29)->reloc_off
$2 = 0xc3f80000
Then add this value to the value of TEXT_BASE as defined in your board's config.mk file, and you get the start address of the U-Boot image in RAM.
Or just add -DDEBUG in config.mk
DBGFLAGS= -g -DDEBUG
And this print out the address where PPCBOOT is relocated in board.c
#ifdef DEBUG
    printf ("Top of RAM usable for PPCBoot at: %08lx/n", addr);
#endif
Top of RAM usable for PPCBoot at 0x03f80000

(gdb) target remote 150.236.68.212:2001
Remote debugging using 150.236.68.212:2001
0x00000100 in ?? ()
(gdb) d b
Delete all breakpoints? (y or n) y
(gdb) b relocate_code
Breakpoint 5 at 0x40003314: file /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S, line 906.
(gdb) c
Continuing.
Breakpoint 5, relocate_code ()
    at /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S:906
906             mr      r1,  r3         /* Set new stack pointer  
Before jumping to board_init_r, we can instruct gdb to forget the old symbol table and reload the symbols at new location in SDRAM:
(gdb) d b
Delete all breakpoints? (y or n) y
(gdb) symbol-file
Discard symbol table from `/home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/ppcboot'? (y or n) y
No symbol file now.
(gdb) add-symbol-file ppcboot 0x3f80000
add symbol table from file "ppcboot" at
        .text_addr = 0x3f80000
(y or n) y
Reading symbols from ppcboot...done.
(gdb) l board_init_r
551      *
552      ************************************************************************
553      */
554
555     void board_init_r (gd_t *id, ulong dest_addr)
556     {
557             DECLARE_GLOBAL_DATA_PTR;
558
559             cmd_tbl_t *cmdtp;
560             char *s, *e;
 (gdb) b board_init_r
Breakpoint 2 at 0x3f85b78: file board.c, line 556.
board_init_r is the first C routine running in the newly relocated C friendly RAM environment.

(gdb) c
Continuing.

Breakpoint 2, board_init_r (id=0x0, dest_addr=60490649) at board.c:556
556     {
CPU stopped at board_init_r as expected.
(gdb) p &mem_malloc_end
$1 = (ulong *) 0x3fcdcc0
Global data mem_malloc_end's address has been relocated.
(gdb) p init_sequence
$2 = 0x40045d90
But array init_sequence's address is still the link address. So any reference to global pointer has to been fixed.
(gdb) p get_clocks
$3 = {int ()} 0x3fc1d28
(gdb) p mem_malloc_end
$4 = 0
(gdb) d b
Delete all breakpoints? (y or n) y
(gdb) b env_relocate
Breakpoint 3 at 0x3f8e930: file env_common.c, line 199.
(gdb) c
Continuing.
Breakpoint 3, env_relocate () at env_common.c:199
199             env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
Now mem_malloc_end has been inited, and the value is right.
 (gdb) p/x mem_malloc_end
$6 = 0x3f80000

 

4.9.4    Debugging with GUI
DDD is a GUI debugger for GDB on Linux. It allows to define and execute frequently used commands via buttons. You can start DDD with the command:
ddd --debugger ppc_82xx-gdb -gdb ppcboot &

 

4.9.5    GDB script
When GDB is started, it can automatically call startup file .gdbinit in the root directory of current project. Startup file supports some MICRO which offers great convenience for debugging.
An example of .gdbinit is below:
target remote 150.236.68.212:2001

define reset
        detach
        target remote 150.236.68.212:2001
        d b
        symbol-file
        add-symbol-file ppcboot $arg0
        b relocate_code
end

define add-symbol
        d b
        symbol-file
        add-symbol-file ppcboot $arg0
        b board_init_r
end

document add-symbol
        Usage: add-symbol
        Do add-symbol-file for .text section of elf module ppcboot automatically.
end

document reset
        Usage: reset
        Do add-symbol-file for .text section of elf module ppcboot automatically.
end
 
All commands except micros will be executed automatically when script .gdbinit is called. So BDI server will be connected by "target remote 150.236.68.212:2001". Micro reset will terminate current debugging, reset board, re-connect BDI server, add symbols at link address and set a breakpoint before jumping to RAM. Micro add-symbol will delete former breakpoints, delete old symbols, add new symbol at the relocated address, and set a new breakpoint at the entry of c code in RAM.
Micro reset is for debugging before relocation and add-symbol is for debugging after relocation. Below is a test log.
cnbjc0052 ppcboot-2.0.0_dev/ppcboot-2.0.0> ppc_82xx-gdb ppcboot
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux"...
0x00000100 in ?? ()
(gdb) reset 0x40000000
0x00000100 in ?? ()
add symbol table from file "ppcboot" at
        .text_addr = 0x40000000
Breakpoint 1 at 0x40003314: file /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S, line 906.
(gdb) c
Continuing.

Breakpoint 1, relocate_code ()
    at /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S:906
906             mr      r1,  r3         /* Set new stack pointer               */
(gdb) add-symbol 0x3f80000
add symbol table from file "ppcboot" at
        .text_addr = 0x3f80000
Breakpoint 2 at 0x3f85b78: file board.c, line 556.
(gdb) c
Continuing.

Breakpoint 2, board_init_r (id=0x0, dest_addr=60490649) at board.c:556
556     {
Now PPCBOOT is running in RAM after relocation.
If we want to debug from the very beginning now, we can reset the board again.
(gdb) reset 0x40000000
0x00000100 in ?? ()
add symbol table from file "ppcboot" at
        .text_addr = 0x40000000
Breakpoint 3 at 0x40003314: file /home/sailing/ppcboot-2.0.0_dev/ppcboot-2.0.0/cpu/mpc8270/start.S, line 906.
(gdb)


4.10    Flash loading
Generally PPCBOOT is used as the first boot loader on reset, but sometimes PPCBOOT is just used as the second boot loader to boot OS. For this situation, PPCBOOT is saved in Flash and loaded by the first boot loader, so there are several differences to boot PPCBOOT successfully.
4.10.1    IMMR
The working environment is already setup by the first boot loader, while it is configured by HRCW when PPCBOOT is used as the first boot loader. So IMMR should be the same as that when PPCBOOT is loaded by the first boot loader.
4.10.2    Stored address
Just the same as IMMR, Flash base address(FLASH_BASE) now is decided by the first boot loader. Because code is copied from CFG_MONITOR_BASE when PPCBOOT relocates itself to RAM, CFG_MONITOR_BASE should be equal to FLASH_BASE + offset.
4.10.3    Link address
Since when PPCBOOT runs in stage 1, it's not always PIC(position independent code), so the link address(TEXT_BASE) should be the same as CFG_MONITOR_BASE, which means that link address is equal to the address where PPCBOOT is stored.
4.10.4    Watchdog
SYPCR controls the software watchdog, and SYPCR can be written only once on reset, otherwise another write will cause reset if the new value is different from that setup by the first boot loader.
4.10.5    Critical code
Some code should not be executed when PPCBOOT used as the second boot loader.
The following code in start.S is under the target CPU directory.
#ifndef CFG_SECOND_BOOTLOADER
    /* When booting from ROM (Flash or EPROM), clear the        */
    /* Address Mask in OR0 so ROM appears everywhere        */
    /*--------------------------------------------------------------*/

    lis    r3, (CFG_IMMR+IM_REGBASE)@h
    lwz    r4, IM_OR0@l(r3)
    li    r5, 0x7fff
    and    r4, r4, r5
    stw    r4, IM_OR0@l(r3)

    /* Calculate absolute address in FLASH and jump there        */

    lis    r3, CFG_MONITOR_BASE@h
    ori    r3, r3, CFG_MONITOR_BASE@l
    addi    r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
    mtlr    r3
    blr

in_flash:
#endif    /* CFG_SECOND_BOOTLOADER */

When the address mask OR0 is cleared, only the first 32k in Flash can be accessed, so CPU will jump to the first boot loader instead of PPCBOOT.
4.10.6    Entry point
When PPCBOOT directly boot from Flash, PC will be automatically set as the reset vector which is a 256bytes offset from the image base. So the first boot loader should jump to a 256bytes offset from where PPCBOOT is stored in Flash. If first boot loader must jump to the image base, since the first 256bytes' HRCW are no longer used, they can be changed as follows:
#ifndef CFG_SECOND_BOOTLOADER
    ….HRCW
#else
    .globl     second_boot_entry
second_boot_entry:
        or      r5, r5, r5       /* NOP */
        or      r5, r5, r5       /* NOP */
        b       _start      /* jumping over the following invalid code */
……
#endif    /* CFG_SECOND_BOOTLOADER */
    . = EXC_OFF_SYS_RESET
    .globl    _start
_start:

 

4.11    RAM loading
When PPCBOOT is loaded by the first boot loader to RAM to be executed, there are several advantages over Flash loading as follows:
1) When PPCBOOT has to be stored in some non-volatile memory, the address can be any address in Flash or EEPROM, and this offers great convenience.
2) The first boot loader can receive PPCBOOT image for other CPU or host dynamically, save it to RAM, and then jump there. This method is quite convenient when debugging PPCBOOT, because there is no need to save PPCBOOT into Flash which is quite time consuming.
4.11.1    IMMR
The principle is the as that of Flash loading.
4.11.2    Stored address
Anywhere you like.
4.11.3    Load address
Since the first boot loader does not directly jump to where PPCBOOT is stored, it copy PPCBOOT to a used RAM area. No matter where PPCBOOT boot from, it will relocate itself to a higher RAM area. So these two areas can not overlap. Because code is copied from CFG_MONITOR_BASE when PPCBOOT relocates itself to RAM, CFG_MONITOR_BASE should be equal to the load address because there must be a copy of PPCBOOT here.
4.11.4    Link address
Since when PPCBOOT runs in stage 1, it's not always PIC(position independent code), so the link address(TEXT_BASE) should be equal to the address where PPCBOOT is loaded in RAM. So actually link address, load address and CFG_MONITOR_BASE are the same address in RAM.
4.11.5    Watchdog
The principle is the as that of Flash loading.
4.11.6    Critical code
Some code should not be executed when PPCBOOT used as the second boot loader.
The following code in start.S is under the target CPU directory.
#ifndef CFG_SECOND_BOOTLOADER
    /* When booting from ROM (Flash or EPROM), clear the        */
    /* Address Mask in OR0 so ROM appears everywhere        */
    /*--------------------------------------------------------------*/

    lis    r3, (CFG_IMMR+IM_REGBASE)@h
    lwz    r4, IM_OR0@l(r3)
    li    r5, 0x7fff
    and    r4, r4, r5
    stw    r4, IM_OR0@l(r3)

    /* Calculate absolute address in FLASH and jump there        */

    lis    r3, CFG_MONITOR_BASE@h
    ori    r3, r3, CFG_MONITOR_BASE@l
    addi    r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
    mtlr    r3
    blr

in_flash:
#endif    /* CFG_SECOND_BOOTLOADER */

When the address mask OR0 is cleared, only the first 32k in Flash can be accessed, so CPU will jump to the first boot loader instead of PPCBOOT in RAM.
Besides, since now PPCBOOT is already running in RAM, any RAM initialization and test should be cancelled which is different from Flash loading.
RAM initialization exists in function initdram of board_name.c under board/board_name directory.
long int initdram(int board_type)
{
/*    long psize = (64 * 1024 * 1024); */
    long psize = SDRAM_MAX_SIZE;
    volatile immap_t *immap = (immap_t *)CFG_IMMR;
    volatile memctl8260_t *memctl = &immap->im_memctl;
    volatile uchar *base;
    int i;

#ifndef CFG_RAMBOOT
    base = (uchar *)CFG_SDRAM_BASE;
   
    memctl->memc_psrt               = CFG_PSRT;       /* Periodic timer */
    memctl->memc_mptpr              = CFG_MPTPR;
   
    /* configure CS for SDRAM */
    immap->im_memctl.memc_or1       = CFG_OR1; /* 0xFC002CC0 64MByte, 4 banks, A12, 12 row addr,*/
    immap->im_memctl.memc_br1       = CFG_BR1; /* 0x00000041 Base=0x0, SDRAM on 60x-Bus, Valid */
   
    /* Precharge all banks */
    memctl->memc_psdmr              = CFG_PSDMR_PRE; /* 0xAB0E2462 Precharge */
    *base = 0xFF;
   
    /* CBR refresh */
    memctl->memc_psdmr              = CFG_PSDMR_CBR; /* 0x8B0E2462 CBR refresh */
    for (i = 0; i < 8; i++)
            *base = 0xFF;
   
    /* Mode set command */
    memctl->memc_psdmr              = CFG_PSDMR_MRW; /* 0x9B0E2462 Mode register write */
    *(base + CFG_MRS_OFFS) = 0xFF;
   
    /* Normal operation command */
    memctl->memc_psdmr              = CFG_PSDMR_NORM; /* 0xC30E2462 Normal operation with refresh*/
    *base = 0xFF;
#endif


    /* return total ram size */
    return (psize);
}
Just return SDRAM size is OK.
RAM initialization exists in file board.c under lib_ppc.
init_fnc_t *init_sequence[] = {
…………..
    INIT_FUNC_WATCHDOG_RESET
    init_func_ram,
    /*sailing add #ifndef CFG_RAMBOOT to avoid init again 20090826 */
#ifndef CFG_RAMBOOT
#if defined(CFG_DRAM_TEST)
    testdram,
#endif /* CFG_DRAM_TEST */
#endif /* CFG_RAMBOOT */
    INIT_FUNC_WATCHDOG_RESET

    NULL,            /* Terminate this list */
};
4.11.7    Entry point
The first boot loader should jump to a 256bytes offset from where PPCBOOT is loaded in RAM. If first boot loader must jump to the image base, since the first 256bytes' HRCW are no longer used, they can be changed as follows:
#ifndef CFG_SECOND_BOOTLOADER
    ….HRCW
#else
    .globl     second_boot_entry
second_boot_entry:
        or      r5, r5, r5       /* NOP */
        or      r5, r5, r5       /* NOP */
        b       _start      /* jumping over the following invalid code */
……
#endif    /* CFG_SECOND_BOOTLOADER */
    . = EXC_OFF_SYS_RESET
    .globl    _start
_start:


5    Add user defined commands
TBD
 

 

你可能感兴趣的:(嵌入式Linux,Power,PC)