[U-Boot] [PATCH V2 08/21] mx6: add plugin file for use with imximage.cfg

Troy Kisky troy.kisky at boundarydevices.com
Mon Sep 24 22:46:42 CEST 2012


On 9/23/2012 3:17 AM, Stefano Babic wrote:
> On 22/09/2012 04:39, Troy Kisky wrote:
>> The "plugin" command of mkimage can take this
>> file as an argument.
>>
>> Signed-off-by: Troy Kisky <troy.kisky at boundarydevices.com>
>> ---
> Hi Troy,
>
> I agree with Vikram that a better explanation of what a plugin is can
> help to understand without reading deeply into the i.MX6 manual.
>
> So a "plugin" is a chunk of code that can be called directly by the
> BootROM of i.MX processors supporting V2 version of the i.MX header.
> In my understanding, this is supported by i.MX53, too. After the plugin
> run, the control is returned to the BootROM.
>
> Now that we have some basis, why do we need this mechanism to boot this
> board ? Is it not possible to make the same initialization directly in
> u-boot ?
>
> In principle, this adds stil some code that is not so easy to maintain.

I can add to README.imximage. But I'm beginning to doubt if plugins are 
going
to be accepted at all.

>
>>   arch/arm/cpu/armv7/mx6/Makefile          |    5 +-
>>   arch/arm/cpu/armv7/mx6/plugin.S          |  164 ++++++++++++++++++++++++++++++
>>   arch/arm/include/asm/arch-mx6/imx-regs.h |    1 +
>>   3 files changed, 169 insertions(+), 1 deletion(-)
>>   create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S
>>
>> diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile
>> index cbce411..b1fce4e 100644
>> --- a/arch/arm/cpu/armv7/mx6/Makefile
>> +++ b/arch/arm/cpu/armv7/mx6/Makefile
>> @@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
>>   SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
>>   OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
>>   
>> -all:	$(obj).depend $(LIB)
>> +all:	$(obj).depend $(LIB) plugin.bin
>>   
>>   $(LIB):	$(OBJS)
>>   	$(call cmd_link_o_target, $(OBJS))
>>   
>> +plugin.bin: plugin.o
>> +	$(OBJCOPY) -O binary --gap-fill 0xff $< $@
> If we add a plugin mechanism, we can have several plugins (booting
> directly from Net, maybe ?). We should then have a general mechanism. A
> directory "plugins" here can contain the code, and it is compiled only
> if a CONFIG_ is set or better if required from imximage.cfg

CONFIG_xx I understand, but can you describe an implementation from 
imximage.cfg?


>
>
>> +
>>   #########################################################################
>>   
>>   # defines $(obj).depend target
>> diff --git a/arch/arm/cpu/armv7/mx6/plugin.S b/arch/arm/cpu/armv7/mx6/plugin.S
>> new file mode 100644
>> index 0000000..99c6b20
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/mx6/plugin.S
>> @@ -0,0 +1,164 @@
>> +/*
>> + * Copyright (C) 2012 Boundary Devices Inc.
>> + *
>> + * Licensed under the GPL-2 or later.
>> + */
>> +#include <config.h>
>> +#include <asm/arch/imx-regs.h>
>> +
>> +#define HAB_RVT_ENTRY		0x98
>> +#define HAB_RVT_FAIL_SAFE_VECT	0xbc
>> +#define HAB_RVT_LOAD_DATA	0xc8
>> +
>> +#define HDR_SELF_PTR	0x14
>> +#define HDR_BOOT_DATA	0x20
>> +#define HDR_IMAGE_LEN	0x24
>> +
>> +#define L2X0_CTRL	0x100
>> +#define SCU_CONFIG	0x004
>> +
>> +/*
>> + * Disable L2 cache because ROM will turn it on when a plugin is used.
>> + * There are cache coherence problems if cache is on when Linux kernel
>> + * expects it to be off.
>> + */
>> +.macro disable_l2_cache
>> +	ldr	r1, =L2_BASE_ADDR
>> +	mov	r0, #0x0
>> +	str	r0, [r1, #L2X0_CTRL]
>> +.endm
>> +
>> +
>> +/*
>> + * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
>> + */
>> +plugin_start:
>> +/* Save the return address and the function arguments */
>> +	push	{r0-r8, lr}
>> +
>> +/* r0-r2 must be  >= 0x100 and must be 4 byte aligned */
>> +	cmp	r0, #0x100
>> +	cmphs	r1, #0x100
>> +	cmphs	r2, #0x100
>> +
>> +/* rCPU: 22 - mx6q, 12 - mx6dl, 12|0x100 - solo, 2 - sololite */
>> +#define rCPU	r2
>> +#define rIomux	r3
>> +#define rVal0	r4	/* mx6q value */
>> +#define rVal1	r5	/* mx6dl value */
>> +#define rVal2	r6	/* mx6solo value */
>> +#define rVal3	r7	/* mx6sololite value */
>> +#define rFlag	lr
>> +#define rTable	r8
>> +
>> +	orr	rFlag, r0, r1
>> +	orr	rFlag, rFlag, r2
>> +	orrlo	rFlag, rFlag, #1
>> +
>> +	mov	rCPU, #22		/* mx6q */
>> +	mov	r1, #SCU_BASE_ADDR
>> +	ldr	r0, [r1, #SCU_CONFIG]
>> +	and	r0, r0, #3
>> +	cmp	r0, #3			/* is mx6q? */
>> +	movne	rCPU, #12		/* mx6dl */
>> +	cmpne	r0, #1			/* is mx6dl? */
>> +	movne	rCPU, #2		/* mx6 sololite */
>> +
>> +	ldrne	r1, =ANATOP_BASE_ADDR
>> +	ldrne	r0, [r1, #0x280]
>> +	movne	r0, r0, LSR #16
>> +	cmpne	r0, #0x60		/* is mx6 Sololite? */
>> +	movne	rCPU, #12 | 0x100	/* Solo */
> Ok - until here you have checked which processor is running. Now the
> more obscure code:
>
>> +
>> +	mov	rVal0, #0
>> +	mov	rVal1, #0
>> +	mov	rVal2, #0
>> +	mov	rVal3, #0
>> +	ldr	rIomux, =IOMUXC_BASE_ADDR
>> +	adr	rTable, mx6_table
>> +	b	3f
>
>
>> +
>> +1:	movs	r0, r1, LSR #30
>> +	beq	2f
>> +	mov	r1, r1, LSL rCPU
>> +	movs	r1, r1, LSR #32-10
>> +	addne	r1, rIomux, r1, LSL #2
>> +	cmp	r0, #3
>> +	subne	r0, r0, #1
>> +	orr	r1, r1, r0
>> +
> The reason is to write GPR12 ? But why do we need a plugin for that ? I
> do not understand why we cannot do it in the initialization code of the
> SOC, as we usually do.

This is not GPR12.  The address value from the cfg file is actually 3 
addresses. One for
mx6q, one for mx6 duallite/solo, one for mx6 sololite. Each is specified 
as a 10 bit
field which we use as a 12 bit offset within IOMUXC_BASE_ADDR (A0/A1 
forced to 0).


>
>> +2:	ands	r0, r1, #3
>> +	bic	r1, r1, #3
>> +	ldrne	rVal0, [rTable], #4
>> +	movne	rVal1, rVal0
>> +	movne	rVal2, rVal0
>> +	movne	rVal3, rVal0
>> +	subnes	r0, r0, #1
>> +	ldrne	rVal1, [rTable], #4
>> +	movne	rVal2, rVal1
>> +	movne	rVal3, rVal1
>> +	subnes	r0, r0, #1
>> +	ldrne	rVal2, [rTable], #4
>> +	ldrne	rVal3, [rTable], #4
>> +
>> +	mov	r0, rVal0
>> +	cmp	rCPU, #22
>> +	movne	r0, rVal1
>> +	cmpne	rCPU, #12
>> +	movne	r0, rVal2
>> +	cmpne	rCPU, #12|0x100
>> +	movne	r0, rVal3
>> +	cmp	r1, #0
>> +	strne	r0, [r1]
>> +3:	ldr	r1, [rTable], #4
>> +	cmp	r1, #0
>> +	bne	1b
>> +
>> +	tst	rFlag, #3
>> +	bne	4f		/* Branch if not called as plugin */
>> +/* Align end of table to 64 byte boundary */
>> +	sub	rTable, rTable, #1
>> +	orr	rTable, rTable, #0x3f
>> +	add	rTable, rTable, #1
>> +	ldr	r2, [rTable, #HDR_SELF_PTR]
>> +	ldr	r0, [rTable, #HDR_BOOT_DATA]
>> +	ldr	r1, [rTable, #HDR_IMAGE_LEN]
>> +	sub	rTable, r2, r0
>> +	mov	r2, r0
>> +	mov	r3, r1
>> +	mov	r4, #0
>> +	push	{r0-r4}
>> +	mov	r0, #HAB_RVT_LOAD_DATA
>> +	ldr	r4, [r0]
>> +	mov	r0, sp
>> +	add	r1, sp, #4
>> +	add	r2, sp, #8
>> +	blx	r4
> Sorry, I need help to understand this code

Now that DDR is initialized, this is calling back into the ROM code
so that it can finish loading u-boot.

>
>> +
>> +	disable_l2_cache
>> +	pop	{r4, r5}
>> +	add	sp, sp, #12
>> +	pop	{r0-r3}
>> +/*
>> + * Before returning to ROM, we need to fill the return values arguments
>> + * to our function.
>> + * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
> As the i.MX and the API suggest, it should be possible to write C code
> for a plugin. Or am I wrong ?


I don't see why not. But this code is currently position independent. It 
would be nice to maintain that.

>
>
>> diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
>> index 8834c59..5c133b2 100644
>> --- a/arch/arm/include/asm/arch-mx6/imx-regs.h
>> +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
>> @@ -48,6 +48,7 @@
>>   #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
>>   #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
>>   #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
>> +#define L2_BASE_ADDR                    0x00A02000
>>   #define GPV0_BASE_ADDR                  0x00B00000
>>   #define GPV1_BASE_ADDR                  0x00C00000
>>   #define PCIE_ARB_BASE_ADDR              0x01000000
>>
> This is useful in any case. I suggest you put this define in a separate
> patch, that can flow independently into mainline.
>
> Best regards,
> Stefano Babic
>

Hmm, do you suggest moving the L2 disable code to another spot as well ?




More information about the U-Boot mailing list