2014/12/11

ARM Vector Table Location

Vector table could be controlled by ARM co-processor's System Control Register Bit 13


[13] V Vectors bit

This bit selects the base address of the exception vectors:

- 0 Normal exception vectors, base address 0x00000000. Software can remap this base address using the VBAR.

- 1 High exception vectors, base address 0xFFFF0000. This base address is never remapped.


Example


MRC     p15, 0, r1, c1, c0, 0      ; c1 Sys Ctrl Reg.
BIC     r1, r1, #0x2000            ; vector base to 0x00000000 or VBAR
MCR     p15, 0, r1, c1, c0, 0

LDR     r0, =Vectors               ; set VBAR, vector base to "Vector"
MCR     p15, 0, r0, c12, c0, 0



MRC     p15, 0, r1, c1, c0, 0      ; c1 Sys Ctrl Reg.
ORR     r1, r1, #0x2000            ; vector base to 0xFFFF0000
MCR     p15, 0, r1, c1, c0, 0


Reference
Cortex-A7 TRM, section 4.3.27
http://lists.denx.de/pipermail/u-boot/2014-November/195139.html

2014/12/04

Example, Volatile in GCC

Below shows how GCC optimized the code with a non-volatile variable, (which caused a bug ).
Lesson: do not forget put volatile to your hardware register variables.

// In below code "stat" and "tbr" are registers could be updated by hardware
static void helx_serial_putc(const char c)
{
 int done = 0;

 if ( c == 0xFF ) {
  return;
 }

 while ( done == 0 ) {                           
  if ( stat->bits.txEmpty ) {
   tbr->bits.data = c;            
   done = 1;
  }
 }
}


// When "stat" is defined as volatile
volatile union uart_stat *stat = (void *)rUART_STAT;

00000000 :
   0: e35000ff  cmp r0, #255 ; 0xff
   4: 012fff1e  bxeq lr
   8: e59f3024  ldr r3, [pc, #36] ; 34 
   c: e5931000  ldr r1, [r3]
  10: e59f3020  ldr r3, [pc, #32] ; 38 
  14: e5933000  ldr r3, [r3]
  18: e5d12000  ldrb r2, [r1]
  1c: e3120040  tst r2, #64 ; 0x40
  20: 0afffffc  beq 18 
  24: e5d32000  ldrb r2, [r3]
  28: e7c72010  bfi r2, r0, #0, #8
  2c: e5c32000  strb r2, [r3]
  30: e12fff1e  bx lr


// When "stat" is defined as none volatile, 
// dead loop assembly code is generated, see offset 0x28
union uart_stat *stat = (void *)rUART_STAT;

00000000 :
   0: e35000ff  cmp r0, #255 ; 0xff
   4: 012fff1e  bxeq lr
   8: e59f201c  ldr r2, [pc, #28] ; 2c 
   c: e59f301c  ldr r3, [pc, #28] ; 30 
  10: e5922000  ldr r2, [r2]
  14: e5933000  ldr r3, [r3]
  18: e5d22000  ldrb r2, [r2]
  1c: e3120040  tst r2, #64 ; 0x40
  20: 15c30000  strbne r0, [r3]
  24: 112fff1e  bxne lr
  28: eafffffe  b 28 

2014/11/28

ARM Code Sections

In source code
#pragma arm section [section_type_list]

Valid section types are:
code
rodata
rwdata
zidata

Example
#pragma arm section rwdata = "foo", rodata = "bar"


In scatter file 
RO
Constants (ex: const TEMP, etc.) and Code 

RW
Expressed initialized global variables 

ZI
Uninitialized global variables, and the variable is initialized to 0


GCC world
.text
program code

.rodata
read-only data;

.data
read-write initialized data;

.bss
read-write zero initialized data.


Reference
http://www.cprogramdevelop.com/912436/
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491g/BCFJBABB.html
https://sourceware.org/binutils/docs/ld/REGION_005fALIAS.html#REGION_005fALIAS

2014/11/27

VIM tips

:vim foo * | cw
Find the "foo" in files in current folder

:vim foo **/*.js | cw
Search for foo in every JavaScript file in the current directory recursively

gt
Switch between tabs

Ctrl+ww
Switch between windows

Ctrl+ws
Split window

Ctrl+r "
Paste yanked text to VIM command prompt

ma, mb
Make a marker "a" , "b"

`a, `b
Got to marker "a", "b"


Reference:
http://stackoverflow.com/questions/12526274/vim-search-text-in-folder

2014/11/04

NCQ Error Info

Host gets NCQ commands error information by issuing command ATA_CMD_READ_LOG_EXT(0x2F), page 10h.

Implementation in Linux: function ata_eh_read_log_10h().
called by ata_eh_analyze_ncq_error()/

2014/10/06

U-Boot boot image


Command "bootm" will boot the image. 

// entry point to handle bootm command
do_bootm() 
  // get the boot image meta data information
  // image header info are in structure image_header
  bootm_start
    // entry point address
    images.ep = image_get_ep(&images.legacy_hdr_os_copy);
    // os load address, after unzip
    images.os.load = image_get_load(os_hdr);
  // load os image
  bootm_load_os
    // un-compress image to os.load address
    gunzip
  // when booting linux, boot_fn points to do_bootm_linux, 
  // for ARM, function implemented in arch/arm/lib/boom.c
  boot_fn
    // jump to the linux kernel
    boot_jump_linux
      kernel_entry = (void (*)(int, int, uint))images->ep;
      kernel_entry(0, machid, r2);

2014/10/02

U-Boot SPL

What is SPL?

SPL: Secondary Program Loader

Unlike NOR flash, many boot sources are not directly memory mapped.

On-chip ROM or other mechanism loads a binary into an SRAM.
  – This SRAM is often very small, sometimes 4 KiB or less.
  – The ROM can't load us into main system RAM yet, since initialization is too complex and must be handled by U-Boot.

SPL (Secondary Program Loader) is a small binary, generated from U-Boot source, that fits in the SRAM and loads the main U-Boot into system RAM.

Configured by a parallel set of makefile config symbols
  –  CONFIG_SPL_I2C_SUPPORT, CONFIG_SPL_NAND_SUPPORT, etc.
  – Normal CONFIG symbols also used, but not to control the differences between the SPL and the main U-Boot.
  – SPL also relies heavily on toolchain garbage collection.

Reference
http://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2013/tpl-presentation.pdf

Post Code on Blogger

Simplest way to post code to blogger for me: <pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black;overflow-x:...