[PATCH 1/3 v3] Add MIPS arch support to barebox

antonynpavlov antonynpavlov at gmail.com
Fri Jul 1 11:29:09 EDT 2011

On Fri, 1 Jul 2011 02:28:15 +0200
Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> wrote:

> > +
> > +	.set noreorder
> > +        .text
> > +	.section ".text_bare_init"
> > +        .globl _start
> > +	.align 4
> > +
> > +_start:
> here the EXPORT

EXPORT(_start)? Ok.

> IIRC we will need to preserve ra for NMI case

How this preserved value can be used?

We have no need to preserve ra because we have no full-grown exception handlers.

> > +	/* Compute _start load address */
> > +	bal	compute_load_address
> > +	 nop
> > +
> > +compute_load_address:
> why don't you use the relocate from Shinya-san?

Because my memory usage is differ.
I will try to explain my view on the memory usage in a separate letter.

Shinya-san's memory usage:

  _start link address = CONFIG_TEXT_BASE

Let's use 32-bit CPU, CONFIG_64BIT is not set.

The MIPS cpu reset entry point is 0xbfc00000 (KSEG1, unmapped and
uncached region).
So code after _start label run from 0xbfc00000.

Let's see Shinya-san's code
---- Shinya-san's code start (arch/mips/cpu/start.S) ----

	 * Config: K0 should be set to the desired Cache Coherency
	 * Algorithm (CCA) prior to accessing Kseg0.
	mfc0	t0, CP0_CONFIG
	/* T.B.D. */
	mtc0	t0, CP0_CONFIG

	 * Config: (4KEm and 4KEp cores only) KU and K23 should be set to
	 * the desired CCA for USeg/KUSeg and KSeg2/3 respectively prior to
	 * accessing those regions.
	mfc0	t0, CP0_CONFIG
	/* T.B.D. */
	mtc0	t0, CP0_CONFIG
---- Shinya-san's code end ----

does this code initialise KSEG0 cache mode?
does this code change CP0_CONFIG at all?
My answer is "no".

But bellow, you can see switching to KSEG0 (label 1f linked to 0x9fc00xxx) ...

---- Shinya-san's code start (arch/mips/cpu/start.S) ----
	/* Switch to CKSEG0 segment */
	la	t0, 1f
	/* T.B.D. -- Convert an addree of the label '1f' into CKSEG0 */
	jr	t0

---- Shinya-san's code end ----

Let's see relocate code:
---- Shinya-san's code start (arch/mips/cpu/start.S) ----
	ADR	t0, _start, t1			# t0 <- current position of code
	beq	t0, t1, stack_setup
---- Shinya-san's code end ----

This code try to check if relocation needs. It try to compute _start <<current>>

  * _start link address is KSEG0 address 0x9fc00000;
  * we have already switched to KSEG0, so _start <<current>> address
is 0x9fc00000 too.

So we __always__ skip copy_loop and go to stack_setup.

But ...
imagine that t0 != t1.

9fc00000 may be KSEG0 address for boot ROM (flash chip) how we can
relocate to ROM?

Running from 0x9fc00000 (even with cache) may be bad idea, because flash may be
connected via narrow and slow bus. barebox must run from cached RAM.

For simplification I use uncached KSEG1 region for barebox, so
I can skip all cache business. But it is temporary measure.

Let's see the copy_loop:
---- Shinya-san's code start (arch/mips/cpu/start.S) ----
	LONG_L		t4, LONGSIZE*0(t0)	# copy from source address [t0]
	LONG_L		t5, LONGSIZE*1(t0)
	LONG_L		t6, LONGSIZE*2(t0)
	LONG_L		t7, LONGSIZE*3(t0)
	LONG_S		t4, LONGSIZE*0(t1)	# copy fo target address [t1]
	LONG_S		t5, LONGSIZE*1(t1)
	LONG_S		t6, LONGSIZE*2(t1)
	LONG_S		t7, LONGSIZE*3(t1)
	PTR_SUBU	t3, t0, t2
	blez		t3, copy_loop
---- Shinya-san's code end ----
Shinya-san use effective unrolled loop. Very good for pipelined CPU.

Every loop this code copy 4 portions of memory.
The size of a portion may be 4 or 8 bytes (depends on cpu type).

But, look here:

This will increase the source address counter (t0) by size of
the only one portion, but __we copy 4 portions__!

Shinya-san's code is very unified code based on Linux macros.
The Linux macros make possible to write code for running
on very different MIPS CPU (e.g. 32-bit or 64-bit).
The macros code has a long history. It was tested many times
in very many different situations. It is proven.
The macros has need of tricky and complex header files.

But today barebox run on only one 32bit emulated CPU.
It has no need of hairy header files.

On the other hand, I can unroll my loop.
I can use Shinya-san's ADR macro instruction.
ADR macro is valuable. My code use assumption about 64K-alignment of
barebox image in ROM. It's true in most cases. Many flash chips
used to store boot code have 64K sector size (or even more).
But ADR macro is more flexible solution.

> > +clear_bss:
> > +	la	t0, __bss_start
> > +	sw	zero, (t0)
> > +	la	t1, _end - 4
> > +1:
> > +	addiu	t0, 4
> > +	sw	zero, (t0)
> > +	bne	t0, t1, 1b
> > +	 nop
> > +
> > +stack_setup:
> his stack setup is more clean
> > +	la	sp, STACK_BASE + STACK_SIZE
> > +	addiu	sp, -32			# init stack pointer
> > +
> > +	la	v0, start_barebox
> > +        jal     v0
> > +	 nop
> > +
> > +	/* No return */
> > +

But I have already used Shinya-san's code!

Here is Shinya-san's code.

---- Shinya-san's code start (arch/mips/cpu/start.) ----
	PTR_LA		t0, __bss_start		# clear .bss
	LONG_S		zero, (t0)
	PTR_LA		t1, _end - LONGSIZE
	LONG_S		zero, (t0)
	bne		t0, t1, 1b

	/* Set the SP */
	PTR_SUB		sp, 4 * SZREG		# init stack pointer

	j		start_barebox
---- Shinya-san's code end ----

Shinya-san uses macros. This is the main difference.

I think that where is no place for such macros in the initial mips support
because there is no need of them.

We can add 64bit CPU support and add macros in the future.

Best regards,
  Antony Pavlov

More information about the barebox mailing list