123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732 |
- Power-On-Self-Test support in U-Boot
- ------------------------------------
- This project is to support Power-On-Self-Test (POST) in U-Boot.
- 1. High-level requirements
- The key rquirements for this project are as follows:
- 1) The project shall develop a flexible framework for implementing
- and running Power-On-Self-Test in U-Boot. This framework shall
- possess the following features:
- o) Extensibility
- The framework shall allow adding/removing/replacing POST tests.
- Also, standalone POST tests shall be supported.
- o) Configurability
- The framework shall allow run-time configuration of the lists
- of tests running on normal/power-fail booting.
- o) Controllability
- The framework shall support manual running of the POST tests.
- 2) The results of tests shall be saved so that it will be possible to
- retrieve them from Linux.
- 3) The following POST tests shall be developed for MPC823E-based
- boards:
- o) CPU test
- o) Cache test
- o) Memory test
- o) Ethernet test
- o) Serial channels test
- o) Watchdog timer test
- o) RTC test
- o) I2C test
- o) SPI test
- o) USB test
- 4) The LWMON board shall be used for reference.
- 2. Design
- This section details the key points of the design for the project.
- The whole project can be divided into two independent tasks:
- enhancing U-Boot/Linux to provide a common framework for running POST
- tests and developing such tests for particular hardware.
- 2.1. Hardware-independent POST layer
- A new optional module will be added to U-Boot, which will run POST
- tests and collect their results at boot time. Also, U-Boot will
- support running POST tests manually at any time by executing a
- special command from the system console.
- The list of available POST tests will be configured at U-Boot build
- time. The POST layer will allow the developer to add any custom POST
- tests. All POST tests will be divided into the following groups:
- 1) Tests running on power-on booting only
- This group will contain those tests that run only once on
- power-on reset (e.g. watchdog test)
- 2) Tests running on normal booting only
- This group will contain those tests that do not take much
- time and can be run on the regular basis (e.g. CPU test)
- 3) Tests running on power-fail booting only
- This group will contain POST tests that consume much time
- and cannot be run regularly (e.g. I2C test)
- 4) Manually executed tests
- This group will contain those tests that can be run manually.
- If necessary, some tests may belong to several groups simultaneously.
- For example, SDRAM test may run on both noarmal and power-fail
- booting. On normal booting, SDRAM test may perform a fast superficial
- memory test only, while running on power-fail booting it may perform
- a full memory check-up.
- Also, all tests will be discriminated by the moment they run at.
- Specifically, the following groups will be singled out:
- 1) Tests running before relocating to RAM
- These tests will run immediatelly after initializing RAM
- as to enable modifying it without taking care of its
- contents. Basically, this group will contain memory tests
- only.
- 2) Tests running after relocating to RAM
- These tests will run immediately before entering the main
- loop as to guarantee full hardware initialization.
- The POST layer will also distinguish a special group of tests that
- may cause system rebooting (e.g. watchdog test). For such tests, the
- layer will automatically detect rebooting and will notify the test
- about it.
- 2.1.1. POST layer interfaces
- This section details the interfaces between the POST layer and the
- rest of U-Boot.
- The following flags will be defined:
- #define POST_ROM 0x01 /* test runs in ROM */
- #define POST_RAM 0x02 /* test runs in RAM */
- #define POST_POWERON 0x04 /* test runs on power-on booting */
- #define POST_NORMAL 0x08 /* test runs on normal booting */
- #define POST_SHUTDOWN 0x10 /* test runs on power-fail booting */
- #define POST_MANUAL 0x20 /* test can be executed manually */
- #define POST_REBOOT 0x80 /* test may cause rebooting */
- The POST layer will export the following interface routines:
- o) int post_run(bd_t *bd, char *name, int flags);
- This routine will run the test (or the group of tests) specified
- by the name and flag arguments. More specifically, if the name
- argument is not NULL, the test with this name will be performed,
- otherwise all tests running in ROM/RAM (depending on the flag
- argument) will be executed. This routine will be called at least
- twice with name set to NULL, once from board_init_f() and once
- from board_init_r(). The flags argument will also specify the
- mode the test is executed in (power-on, normal, power-fail,
- manual).
- o) void post_reloc(ulong offset);
- This routine will be called from board_init_r() and will
- relocate the POST test table.
- o) int post_info(char *name);
- This routine will print the list of all POST tests that can be
- executed manually if name is NULL, and the description of a
- particular test if name is not NULL.
- o) int post_log(char *format, ...);
- This routine will be called from POST tests to log their
- results. Basically, this routine will print the results to
- stderr. The format of the arguments and the return value
- will be identical to the printf() routine.
- Also, the following board-specific routines will be called from the
- U-Boot common code:
- o) int board_power_mode(void)
- This routine will return the mode the system is running in
- (POST_POWERON, POST_NORMAL or POST_SHUTDOWN).
- o) void board_poweroff(void)
- This routine will turn off the power supply of the board. It
- will be called on power-fail booting after running all POST
- tests.
- The list of available POST tests be kept in the post_tests array
- filled at U-Boot build time. The format of entry in this array will
- be as follows:
- struct post_test {
- char *name;
- char *cmd;
- char *desc;
- int flags;
- int (*test)(bd_t *bd, int flags);
- };
- o) name
- This field will contain a short name of the test, which will be
- used in logs and on listing POST tests (e.g. CPU test).
- o) cmd
- This field will keep a name for identifying the test on manual
- testing (e.g. cpu). For more information, refer to section
- "Command line interface".
- o) desc
- This field will contain a detailed description of the test,
- which will be printed on user request. For more information, see
- section "Command line interface".
- o) flags
- This field will contain a combination of the bit flags described
- above, which will specify the mode the test is running in
- (power-on, normal, power-fail or manual mode), the moment it
- should be run at (before or after relocating to RAM), whether it
- can cause system rebooting or not.
- o) test
- This field will contain a pointer to the routine that will
- perform the test, which will take 2 arguments. The first
- argument will be a pointer to the board info structure, while
- the second will be a combination of bit flags specifying the
- mode the test is running in (POST_POWERON, POST_NORMAL,
- POST_SLOWTEST, POST_MANUAL) and whether the last execution of
- the test caused system rebooting (POST_REBOOT). The routine will
- return 0 on successful execution of the test, and 1 if the test
- failed.
- The lists of the POST tests that should be run at power-on/normal/
- power-fail booting will be kept in the environment. Namely, the
- following environment variables will be used: post_poweron,
- powet_normal, post_slowtest.
- 2.1.2. Test results
- The results of tests will be collected by the POST layer. The POST
- log will have the following format:
- ...
- --------------------------------------------
- START <name>
- <test-specific output>
- [PASSED|FAILED]
- --------------------------------------------
- ...
- Basically, the results of tests will be printed to stderr. This
- feature may be enhanced in future to spool the log to a serial line,
- save it in non-volatile RAM (NVRAM), transfer it to a dedicated
- storage server and etc.
- 2.1.3. Integration issues
- All POST-related code will be #ifdef'ed with the CONFIG_POST macro.
- This macro will be defined in the config_<board>.h file for those
- boards that need POST. The CONFIG_POST macro will contain the list of
- POST tests for the board. The macro will have the format of array
- composed of post_test structures:
- #define CONFIG_POST \
- {
- "On-board peripherals test", "board", \
- " This test performs full check-up of the " \
- "on-board hardware.", \
- POST_RAM | POST_SLOWTEST, \
- &board_post_test \
- }
- A new file, post.h, will be created in the include/ directory. This
- file will contain common POST declarations and will define a set of
- macros that will be reused for defining CONFIG_POST. As an example,
- the following macro may be defined:
- #define POST_CACHE \
- {
- "Cache test", "cache", \
- " This test verifies the CPU cache operation.", \
- POST_RAM | POST_NORMAL, \
- &cache_post_test \
- }
- A new subdirectory will be created in the U-Boot root directory. It
- will contain the source code of the POST layer and most of POST
- tests. Each POST test in this directory will be placed into a
- separate file (it will be needed for building standalone tests). Some
- POST tests (mainly those for testing peripheral devices) will be
- located in the source files of the drivers for those devices. This
- way will be used only if the test subtantially uses the driver.
- 2.1.4. Standalone tests
- The POST framework will allow to develop and run standalone tests. A
- user-space library will be developed to provide the POST interface
- functions to standalone tests.
- 2.1.5. Command line interface
- A new command, diag, will be added to U-Boot. This command will be
- used for listing all available hardware tests, getting detailed
- descriptions of them and running these tests.
- More specifically, being run without any arguments, this command will
- print the list of all available hardware tests:
- => diag
- Available hardware tests:
- cache - cache test
- cpu - CPU test
- enet - SCC/FCC ethernet test
- Use 'diag [<test1> [<test2>]] ... ' to get more info.
- Use 'diag run [<test1> [<test2>]] ... ' to run tests.
- =>
- If the first argument to the diag command is not 'run', detailed
- descriptions of the specified tests will be printed:
- => diag cpu cache
- cpu - CPU test
- This test verifies the arithmetic logic unit of CPU.
- cache - cache test
- This test verifies the CPU cache operation.
- =>
- If the first argument to diag is 'run', the specified tests will be
- executed. If no tests are specified, all available tests will be
- executed.
- It will be prohibited to execute tests running in ROM manually. The
- 'diag' command will not display such tests and/or run them.
- 2.1.6. Power failure handling
- The Linux kernel will be modified to detect power failures and
- automatically reboot the system in such cases. It will be assumed
- that the power failure causes a system interrupt.
- To perform correct system shutdown, the kernel will register a
- handler of the power-fail IRQ on booting. Being called, the handler
- will run /sbin/reboot using the call_usermodehelper() routine.
- /sbin/reboot will automatically bring the system down in a secure
- way. This feature will be configured in/out from the kernel
- configuration file.
- The POST layer of U-Boot will check whether the system runs in
- power-fail mode. If it does, the system will be powered off after
- executing all hardware tests.
- 2.1.7. Hazardous tests
- Some tests may cause system rebooting during their execution. For
- some tests, this will indicate a failure, while for the Watchdog
- test, this means successful operation of the timer.
- In order to support such tests, the following scheme will be
- implemented. All the tests that may cause system rebooting will have
- the POST_REBOOT bit flag set in the flag field of the correspondent
- post_test structure. Before starting tests marked with this bit flag,
- the POST layer will store an identification number of the test in a
- location in IMMR. On booting, the POST layer will check the value of
- this variable and if it is set will skip over the tests preceding the
- failed one. On second execution of the failed test, the POST_REBOOT
- bit flag will be set in the flag argument to the test routine. This
- will allow to detect system rebooting on the previous iteration. For
- example, the watchdog timer test may have the following
- declaration/body:
- ...
- #define POST_WATCHDOG \
- {
- "Watchdog timer test", "watchdog", \
- " This test checks the watchdog timer.", \
- POST_RAM | POST_POWERON | POST_REBOOT, \
- &watchdog_post_test \
- }
- ...
- ...
- int watchdog_post_test(bd_t *bd, int flags)
- {
- unsigned long start_time;
- if (flags & POST_REBOOT) {
- /* Test passed */
- return 0;
- } else {
- /* disable interrupts */
- disable_interrupts();
- /* 10-second delay */
- ...
- /* if we've reached this, the watchdog timer does not work */
- enable_interrupts();
- return 1;
- }
- }
- ...
- 2.2. Hardware-specific details
- This project will also develop a set of POST tests for MPC8xx- based
- systems. This section provides technical details of how it will be
- done.
- 2.2.1. Generic PPC tests
- The following generic POST tests will be developed:
- o) CPU test
- This test will check the arithmetic logic unit (ALU) of CPU. The
- test will take several milliseconds and will run on normal
- booting.
- o) Cache test
- This test will verify the CPU cache (L1 cache). The test will
- run on normal booting.
- o) Memory test
- This test will examine RAM and check it for errors. The test
- will always run on booting. On normal booting, only a limited
- amount of RAM will be checked. On power-fail booting a fool
- memory check-up will be performed.
- 2.2.1.1. CPU test
- This test will verify the following ALU instructions:
- o) Condition register istructions
- This group will contain: mtcrf, mfcr, mcrxr, crand, crandc,
- cror, crorc, crxor, crnand, crnor, creqv, mcrf.
- The mtcrf/mfcr instructions will be tested by loading different
- values into the condition register (mtcrf), moving its value to
- a general-purpose register (mfcr) and comparing this value with
- the expected one. The mcrxr instruction will be tested by
- loading a fixed value into the XER register (mtspr), moving XER
- value to the condition register (mcrxr), moving it to a
- general-purpose register (mfcr) and comparing the value of this
- register with the expected one. The rest of instructions will be
- tested by loading a fixed value into the condition register
- (mtcrf), executing each instruction several times to modify all
- 4-bit condition fields, moving the value of the conditional
- register to a general-purpose register (mfcr) and comparing it
- with the expected one.
- o) Integer compare instructions
- This group will contain: cmp, cmpi, cmpl, cmpli.
- To verify these instructions the test will run them with
- different combinations of operands, read the condition register
- value and compare it with the expected one. More specifically,
- the test will contain a pre-built table containing the
- description of each test case: the instruction, the values of
- the operands, the condition field to save the result in and the
- expected result.
- o) Arithmetic instructions
- This group will contain: add, addc, adde, addme, addze, subf,
- subfc, subfe, subme, subze, mullw, mulhw, mulhwu, divw, divwu,
- extsb, extsh.
- The test will contain a pre-built table of instructions,
- operands, expected results and expected states of the condition
- register. For each table entry, the test will cyclically use
- different sets of operand registers and result registers. For
- example, for instructions that use 3 registers on the first
- iteration r0/r1 will be used as operands and r2 for result. On
- the second iteration, r1/r2 will be used as operands and r3 as
- for result and so on. This will enable to verify all
- general-purpose registers.
- o) Logic instructions
- This group will contain: and, andc, andi, andis, or, orc, ori,
- oris, xor, xori, xoris, nand, nor, neg, eqv, cntlzw.
- The test scheme will be identical to that from the previous
- point.
- o) Shift instructions
- This group will contain: slw, srw, sraw, srawi, rlwinm, rlwnm,
- rlwimi
- The test scheme will be identical to that from the previous
- point.
- o) Branch instructions
- This group will contain: b, bl, bc.
- The first 2 instructions (b, bl) will be verified by jumping to
- a fixed address and checking whether control was transfered to
- that very point. For the bl instruction the value of the link
- register will be checked as well (using mfspr). To verify the bc
- instruction various combinations of the BI/BO fields, the CTR
- and the condition register values will be checked. The list of
- such combinations will be pre-built and linked in U-Boot at
- build time.
- o) Load/store instructions
- This group will contain: lbz(x)(u), lhz(x)(u), lha(x)(u),
- lwz(x)(u), stb(x)(u), sth(x)(u), stw(x)(u).
- All operations will be performed on a 16-byte array. The array
- will be 4-byte aligned. The base register will point to offset
- 8. The immediate offset (index register) will range in [-8 ...
- +7]. The test cases will be composed so that they will not cause
- alignment exceptions. The test will contain a pre-built table
- describing all test cases. For store instructions, the table
- entry will contain: the instruction opcode, the value of the
- index register and the value of the source register. After
- executing the instruction, the test will verify the contents of
- the array and the value of the base register (it must change for
- "store with update" instructions). For load instructions, the
- table entry will contain: the instruction opcode, the array
- contents, the value of the index register and the expected value
- of the destination register. After executing the instruction,
- the test will verify the value of the destination register and
- the value of the base register (it must change for "load with
- update" instructions).
- o) Load/store multiple/string instructions
- The CPU test will run in RAM in order to allow run-time modification
- of the code to reduce the memory footprint.
- 2.2.1.2 Special-Purpose Registers Tests
- TBD.
- 2.2.1.3. Cache test
- To verify the data cache operation the following test scenarios will
- be used:
- 1) Basic test #1
- - turn on the data cache
- - switch the data cache to write-back or write-through mode
- - invalidate the data cache
- - write the negative pattern to a cached area
- - read the area
- The negative pattern must be read at the last step
- 2) Basic test #2
- - turn on the data cache
- - switch the data cache to write-back or write-through mode
- - invalidate the data cache
- - write the zero pattern to a cached area
- - turn off the data cache
- - write the negative pattern to the area
- - turn on the data cache
- - read the area
- The negative pattern must be read at the last step
- 3) Write-through mode test
- - turn on the data cache
- - switch the data cache to write-through mode
- - invalidate the data cache
- - write the zero pattern to a cached area
- - flush the data cache
- - write the negative pattern to the area
- - turn off the data cache
- - read the area
- The negative pattern must be read at the last step
- 4) Write-back mode test
- - turn on the data cache
- - switch the data cache to write-back mode
- - invalidate the data cache
- - write the negative pattern to a cached area
- - flush the data cache
- - write the zero pattern to the area
- - invalidate the data cache
- - read the area
- The negative pattern must be read at the last step
- To verify the instruction cache operation the following test
- scenarios will be used:
- 1) Basic test #1
- - turn on the instruction cache
- - unlock the entire instruction cache
- - invalidate the instruction cache
- - lock a branch instruction in the instruction cache
- - replace the branch instruction with "nop"
- - jump to the branch instruction
- - check that the branch instruction was executed
- 2) Basic test #2
- - turn on the instruction cache
- - unlock the entire instruction cache
- - invalidate the instruction cache
- - jump to a branch instruction
- - check that the branch instruction was executed
- - replace the branch instruction with "nop"
- - invalidate the instruction cache
- - jump to the branch instruction
- - check that the "nop" instruction was executed
- The CPU test will run in RAM in order to allow run-time modification
- of the code.
- 2.2.1.4. Memory test
- The memory test will verify RAM using sequential writes and reads
- to/from RAM. Specifically, there will be several test cases that will
- use different patterns to verify RAM. Each test case will first fill
- a region of RAM with one pattern and then read the region back and
- compare its contents with the pattern. The following patterns will be
- used:
- 1) zero pattern (0x00000000)
- 2) negative pattern (0xffffffff)
- 3) checkerboard pattern (0x55555555, 0xaaaaaaaa)
- 4) bit-flip pattern ((1 << (offset % 32)), ~(1 << (offset % 32)))
- 5) address pattern (offset, ~offset)
- Patterns #1, #2 will help to find unstable bits. Patterns #3, #4 will
- be used to detect adherent bits, i.e. bits whose state may randomly
- change if adjacent bits are modified. The last pattern will be used
- to detect far-located errors, i.e. situations when writing to one
- location modifies an area located far from it. Also, usage of the
- last pattern will help to detect memory controller misconfigurations
- when RAM represents a cyclically repeated portion of a smaller size.
- Being run in normal mode, the test will verify only small 4Kb regions
- of RAM around each 1Mb boundary. For example, for 64Mb RAM the
- following areas will be verified: 0x00000000-0x00000800,
- 0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
- 0x04000000. If the test is run in power-fail mode, it will verify the
- whole RAM.
- The memory test will run in ROM before relocating U-Boot to RAM in
- order to allow RAM modification without saving its contents.
- 2.2.2. Common tests
- This section describes tests that are not based on any hardware
- peculiarities and use common U-Boot interfaces only. These tests do
- not need any modifications for porting them to another board/CPU.
- 2.2.2.1. I2C test
- For verifying the I2C bus, a full I2C bus scanning will be performed
- using the i2c_probe() routine. If any I2C device is found, the test
- will be considered as passed, otherwise failed. This particular way
- will be used because it provides the most common method of testing.
- For example, using the internal loopback mode of the CPM I2C
- controller for testing would not work on boards where the software
- I2C driver (also known as bit-banged driver) is used.
- 2.2.2.2. Watchdog timer test
- To test the watchdog timer the scheme mentioned above (refer to
- section "Hazardous tests") will be used. Namely, this test will be
- marked with the POST_REBOOT bit flag. On the first iteration, the
- test routine will make a 10-second delay. If the system does not
- reboot during this delay, the watchdog timer is not operational and
- the test fails. If the system reboots, on the second iteration the
- POST_REBOOT bit will be set in the flag argument to the test routine.
- The test routine will check this bit and report a success if it is
- set.
- 2.2.2.3. RTC test
- The RTC test will use the rtc_get()/rtc_set() routines. The following
- features will be verified:
- o) Time uniformity
- This will be verified by reading RTC in polling within a short
- period of time (5-10 seconds).
- o) Passing month boundaries
- This will be checked by setting RTC to a second before a month
- boundary and reading it after its passing the boundary. The test
- will be performed for both leap- and nonleap-years.
- 2.2.3. MPC8xx peripherals tests
- This project will develop a set of tests verifying the peripheral
- units of MPC8xx processors. Namely, the following controllers of the
- MPC8xx communication processor module (CPM) will be tested:
- o) Serial Management Controllers (SMC)
- o) Serial Communication Controllers (SCC)
- 2.2.3.1. Ethernet tests (SCC)
- The internal (local) loopback mode will be used to test SCC. To do
- that the controllers will be configured accordingly and several
- packets will be transmitted. These tests may be enhanced in future to
- use external loopback for testing. That will need appropriate
- reconfiguration of the physical interface chip.
- The test routines for the SCC ethernet tests will be located in
- cpu/mpc8xx/scc.c.
- 2.2.3.2. UART tests (SMC/SCC)
- To perform these tests the internal (local) loopback mode will be
- used. The SMC/SCC controllers will be configured to connect the
- transmitter output to the receiver input. After that, several bytes
- will be transmitted. These tests may be enhanced to make to perform
- "external" loopback test using a loopback cable. In this case, the
- test will be executed manually.
- The test routine for the SMC/SCC UART tests will be located in
- cpu/mpc8xx/serial.c.
- 2.2.3.3. USB test
- TBD
- 2.2.3.4. SPI test
- TBD
- 2.3. Design notes
- Currently it is unknown how we will power off the board after running
- all power-fail POST tests. This point needs further clarification.
|