All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/3] Support BE8 kernel modules relocation
@ 2011-01-19  6:44 Stanley.Miao
  2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-19  6:44 UTC (permalink / raw)
  To: linux-arm-kernel

Changes from V1:
1, move the defintion of read_instr32/write_instr32 from arm/include/asm/io.h to arm/kernel/module.c


The first patch is to solve the BE8 kernel modules relocation problems.

The second patch is to support BE8 kernel on a little-endian machine.

The third patch is to add some debug macros to help the developer to location the boot problems.

In order to test the first patch, I am sure some people will need the other two patches, so I send them together.

Stanley.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] Support BE8 mode kernel modules relocation
  2011-01-19  6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao
@ 2011-01-19  6:44 ` Stanley.Miao
  2011-01-21  9:40   ` Stanley.Miao
  2011-01-21  9:44   ` Russell King - ARM Linux
  2011-01-19  6:44 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao
  2011-01-19  6:44 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao
  2 siblings, 2 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-19  6:44 UTC (permalink / raw)
  To: linux-arm-kernel

The code section in BE8 kernel modules is in little-endian while data
section is in big-endian. When reading code from memory in the relocation
procedure, these instructions are read according to big-endian, so they are
needed to be inverted.

Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
 arch/arm/Makefile        |    1 +
 arch/arm/kernel/module.c |   62 +++++++++++++++++++++++++++++-----------------
 2 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3eec793..03e7761 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -13,6 +13,7 @@
 LDFLAGS_vmlinux	:=-p --no-undefined -X
 ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
 LDFLAGS_vmlinux	+= --be8
+LDFLAGS_MODULE	+= --be8
 endif
 
 OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d9bd786..c5e5bb1 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -99,6 +99,18 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
 	return 0;
 }
 
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define read_instr32(c)			__swab32(*(u32 *)c)
+#define read_instr16(c)			__swab16(*(u16 *)c)
+#define write_instr32(v,a)		(*(u32 *)(a) = __swab32((__force __u32)(v)))
+#define write_instr16(v,a)		(*(u16 *)(a) = __swab16((__force __u16)(v)))
+#else
+#define read_instr32(c)			(*(u32 *)c)
+#define read_instr16(c)			(*(u16 *)c)
+#define write_instr32(v,a)		(*(u32 *)(a) = (v))
+#define write_instr16(v,a)		(*(u16 *)(a) = (v))
+#endif
+
 int
 apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 	       unsigned int relindex, struct module *module)
@@ -148,7 +160,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 		case R_ARM_PC24:
 		case R_ARM_CALL:
 		case R_ARM_JUMP24:
-			offset = (*(u32 *)loc & 0x00ffffff) << 2;
+			offset = (read_instr32(loc) & 0x00ffffff) << 2;
 			if (offset & 0x02000000)
 				offset -= 0x04000000;
 
@@ -165,8 +177,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 
 			offset >>= 2;
 
-			*(u32 *)loc &= 0xff000000;
-			*(u32 *)loc |= offset & 0x00ffffff;
+			write_instr32((read_instr32(loc) & 0xff000000) |
+						(offset & 0x00ffffff), loc);
 			break;
 
 	       case R_ARM_V4BX:
@@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			* other bits to re-code instruction as
 			* MOV PC,Rm.
 			*/
-		       *(u32 *)loc &= 0xf000000f;
-		       *(u32 *)loc |= 0x01a0f000;
-		       break;
+			write_instr32((read_instr32(loc) & 0xf000000f) |
+							0x01a0f000, loc);
+			break;
 
 		case R_ARM_PREL31:
 			offset = *(u32 *)loc + sym->st_value - loc;
@@ -185,7 +197,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 
 		case R_ARM_MOVW_ABS_NC:
 		case R_ARM_MOVT_ABS:
-			offset = *(u32 *)loc;
+			offset = read_instr32(loc);
 			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
 			offset = (offset ^ 0x8000) - 0x8000;
 
@@ -193,16 +205,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
 				offset >>= 16;
 
-			*(u32 *)loc &= 0xfff0f000;
-			*(u32 *)loc |= ((offset & 0xf000) << 4) |
-					(offset & 0x0fff);
+			write_instr32((read_instr32(loc) & 0xfff0f000) |
+					((offset & 0xf000) << 4) |
+					(offset & 0x0fff), loc);
 			break;
 
 #ifdef CONFIG_THUMB2_KERNEL
 		case R_ARM_THM_CALL:
 		case R_ARM_THM_JUMP24:
-			upper = *(u16 *)loc;
-			lower = *(u16 *)(loc + 2);
+			upper = read_instr16(loc);
+			lower = read_instr16(loc + 2);
 
 			/*
 			 * 25 bit signed address range (Thumb-2 BL and B.W
@@ -242,17 +254,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			sign = (offset >> 24) & 1;
 			j1 = sign ^ (~(offset >> 23) & 1);
 			j2 = sign ^ (~(offset >> 22) & 1);
-			*(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
-					    ((offset >> 12) & 0x03ff));
-			*(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
-						  (j1 << 13) | (j2 << 11) |
-						  ((offset >> 1) & 0x07ff));
+			write_instr16((u16)((upper & 0xf800) | (sign << 10) |
+						((offset >> 12) & 0x03ff)),
+					loc);
+			write_instr16((u16)((lower & 0xd000) |
+						(j1 << 13) | (j2 << 11) |
+						((offset >> 1) & 0x07ff)),
+					loc + 2);
 			break;
 
 		case R_ARM_THM_MOVW_ABS_NC:
 		case R_ARM_THM_MOVT_ABS:
-			upper = *(u16 *)loc;
-			lower = *(u16 *)(loc + 2);
+			upper = read_instr16(loc);
+			lower = read_instr16(loc + 2);
 
 			/*
 			 * MOVT/MOVW instructions encoding in Thumb-2:
@@ -273,12 +287,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
 				offset >>= 16;
 
-			*(u16 *)loc = (u16)((upper & 0xfbf0) |
+			write_instr16((u16)((upper & 0xfbf0) |
 					    ((offset & 0xf000) >> 12) |
-					    ((offset & 0x0800) >> 1));
-			*(u16 *)(loc + 2) = (u16)((lower & 0x8f00) |
+					    ((offset & 0x0800) >> 1)),
+					doc);
+			write_instr16((u16)((lower & 0x8f00) |
 						  ((offset & 0x0700) << 4) |
-						  (offset & 0x00ff));
+						  (offset & 0x00ff)),
+					doc + 2);
 			break;
 #endif
 
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-19  6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao
  2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
@ 2011-01-19  6:44 ` Stanley.Miao
  2011-01-21  9:46   ` Russell King - ARM Linux
  2011-01-19  6:44 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao
  2 siblings, 1 reply; 16+ messages in thread
From: Stanley.Miao @ 2011-01-19  6:44 UTC (permalink / raw)
  To: linux-arm-kernel

When BE8 kernel is running on a little endian machine, the kernel endian
mode need to be converted at the begining of the startup procedure with
the instruction "setend be".

Besides, the tags that the bootloader passed to the kernel are in
little-endian mode and they need to be inverted.

Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
 arch/arm/boot/compressed/head.S |    3 +++
 arch/arm/include/asm/setup.h    |   13 +++++++++----
 arch/arm/kernel/head-common.S   |    6 ++++++
 arch/arm/kernel/setup.c         |   22 +++++++++++-----------
 arch/arm/mm/Kconfig             |    7 +++++++
 5 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index a00055d..a33075b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -131,6 +131,9 @@ start:
 		mov	r0, r0
 		.endr
 
+#ifdef CONFIG_BE8_ON_LE
+		setend	be
+#endif
 		b	1f
 		.word	0x016f2818		@ Magic numbers to help the loader
 		.word	start			@ absolute load/run zImage address
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9b..1504d09 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -173,15 +173,20 @@ struct tagtable {
 	int (*parse)(const struct tag *);
 };
 
+#ifdef CONFIG_BE8_ON_LE
+#define read_tag(a)	le32_to_cpu(a)
+#else
+#define read_tag(a)	a
+#endif
+
 #define tag_member_present(tag,member)				\
 	((unsigned long)(&((struct tag *)0L)->member + 1)	\
-		<= (tag)->hdr.size * 4)
-
-#define tag_next(t)	((struct tag *)((__u32 *)(t) + (t)->hdr.size))
+		<= read_tag((tag)->hdr.size) * 4)
+#define tag_next(t)	((struct tag *)((__u32 *)(t) + read_tag((t)->hdr.size)))
 #define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
 
 #define for_each_tag(t,base)		\
-	for (t = base; t->hdr.size; t = tag_next(t))
+	for (t = base; read_tag((t)->hdr.size); t = tag_next(t))
 
 #ifdef __KERNEL__
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index bbecaac..37cfa88 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -118,10 +118,16 @@ __vet_atags:
 	bne	1f
 
 	ldr	r5, [r2, #0]			@ is first tag ATAG_CORE?
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	cmp	r5, #ATAG_CORE_SIZE
 	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
 	bne	1f
 	ldr	r5, [r2, #4]
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	ldr	r6, =ATAG_CORE
 	cmp	r5, r6
 	bne	1f
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 3cadb46..9098aa5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -578,10 +578,10 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
  */
 static int __init parse_tag_core(const struct tag *tag)
 {
-	if (tag->hdr.size > 2) {
-		if ((tag->u.core.flags & 1) == 0)
+	if (read_tag(tag->hdr.size) > 2) {
+		if ((read_tag(tag->u.core.flags) & 1) == 0)
 			root_mountflags &= ~MS_RDONLY;
-		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+		ROOT_DEV = old_decode_dev(read_tag(tag->u.core.rootdev));
 	}
 	return 0;
 }
@@ -590,7 +590,7 @@ __tagtable(ATAG_CORE, parse_tag_core);
 
 static int __init parse_tag_mem32(const struct tag *tag)
 {
-	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
+	return arm_add_memory(read_tag(tag->u.mem.start), read_tag(tag->u.mem.size));
 }
 
 __tagtable(ATAG_MEM, parse_tag_mem32);
@@ -643,7 +643,7 @@ __tagtable(ATAG_SERIAL, parse_tag_serialnr);
 
 static int __init parse_tag_revision(const struct tag *tag)
 {
-	system_rev = tag->u.revision.rev;
+	system_rev = read_tag(tag->u.revision.rev);
 	return 0;
 }
 
@@ -670,7 +670,7 @@ static int __init parse_tag(const struct tag *tag)
 	struct tagtable *t;
 
 	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
-		if (tag->hdr.tag == t->tag) {
+		if ((read_tag(tag->hdr.tag) == t->tag)) {
 			t->parse(tag);
 			break;
 		}
@@ -684,9 +684,9 @@ static int __init parse_tag(const struct tag *tag)
  */
 static void __init parse_tags(const struct tag *t)
 {
-	for (; t->hdr.size; t = tag_next(t))
+	for (; read_tag(t->hdr.size); t = tag_next(t))
 		if (!parse_tag(t))
-			printk(KERN_WARNING
+			early_printk(KERN_WARNING
 				"Ignoring unrecognised tag 0x%08x\n",
 				t->hdr.tag);
 }
@@ -824,16 +824,16 @@ void __init setup_arch(char **cmdline_p)
 	 * If we have the old style parameters, convert them to
 	 * a tag list.
 	 */
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		convert_to_tag_list(tags);
 #endif
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		tags = (struct tag *)&init_tags;
 
 	if (mdesc->fixup)
 		mdesc->fixup(mdesc, tags, &from, &meminfo);
 
-	if (tags->hdr.tag == ATAG_CORE) {
+	if (read_tag(tags->hdr.tag) == ATAG_CORE) {
 		if (meminfo.nr_banks != 0)
 			squash_mem_tags(tags);
 		save_atags(tags);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c16ae86..eb74e6b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -686,6 +686,13 @@ config CPU_ENDIAN_BE32
 	help
 	  Support for the BE-32 (big-endian) mode on pre-ARMv6 processors.
 
+config BE8_ON_LE
+	bool "Run BE8 kernel on a little endian machine"
+	depends on CPU_V6 || CPU_V7
+	select CPU_BIG_ENDIAN
+	help
+	  Run BE8 kernel on a little endian machine.
+
 config CPU_HIGH_VECTOR
 	depends on !MMU && CPU_CP15 && !CPU_ARM740T
 	bool "Select the High exception vector"
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly
  2011-01-19  6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao
  2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
  2011-01-19  6:44 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao
@ 2011-01-19  6:44 ` Stanley.Miao
  2 siblings, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-19  6:44 UTC (permalink / raw)
  To: linux-arm-kernel

When we are porting Linux to a new board, we ofter encounter the problems
that the board can't boot up and there is no any messages output in
console. These debug macros can help the developers print registers' value
or messages easily and locate the root cause quickly.

All these debug macros are under CONFIG_DEBUG_LL. When CONFIG_DEBUG_LL is
enabled, the following messages will be printed in the boot procedure.

Uncompressing Linux... done, booting the kernel.
r13:005454ec
stext enter.
__lookup_processor_type enter.
__lookup_machine_type enter.
__vet_atags enter.
__create_page_tables enter.
__enable_mmu enter.
__mmap_switched enter.
__lookup_processor_type enter.
__lookup_machine_type enter.
secondary_startup enter.
__lookup_processor_type enter.
__enable_mmu enter.
__secondary_switched enter.
Linux version 2.6.38.rc1 ...

Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
 arch/arm/kernel/debug_macro.S |   88 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/head-common.S |    8 ++++
 arch/arm/kernel/head.S        |   19 +++++++--
 arch/arm/kernel/vmlinux.lds.S |    7 +++
 4 files changed, 118 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/kernel/debug_macro.S

diff --git a/arch/arm/kernel/debug_macro.S b/arch/arm/kernel/debug_macro.S
new file mode 100644
index 0000000..033acf3
--- /dev/null
+++ b/arch/arm/kernel/debug_macro.S
@@ -0,0 +1,88 @@
+/*
+ *  linux/arch/arm/kernel/debug_macro.S
+ *
+ *  Copyright (c) 2011 Wind River Systems, Inc.
+ *  Stanley.Miao <stanley.miao@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  32-bit debugging code
+ */
+
+#ifdef CONFIG_DEBUG_LL
+
+	.macro  kputc,val
+	mov     r0, \val
+	bl      printch
+	.endm
+
+	.macro	dbgmsg, str
+	stmfd   sp!, {r0-r3, lr}
+	adr	r0, \str
+	bl	printascii
+	ldmfd   sp!, {r0-r3, lr}
+	.endm
+
+	.macro  read_reg reg, num
+	stmfd	sp!, {r0-r4, lr}
+	kputc	#'r'
+	mov	r4, #\num
+	cmp	r4, #10
+	blt	901f
+	sub	r4, r4, #10
+	kputc	#'1'
+901:	add	r0, r4, #'0'
+	bl	printch
+	kputc   #':'
+	ldmfd	sp, {r0-r4, lr}
+	mov     r0, \reg
+	bl      printhex8
+	kputc   #'\n'
+	ldmfd   sp!, {r0-r4, lr}
+	.endm
+
+	.macro	PRINT_SCTLR
+	stmfd	sp!, {r0-r4, lr}
+	kputc	#'S'
+	kputc	#'C'
+	kputc	#'T'
+	kputc	#'L'
+	kputc	#'R'
+	kputc	#':'
+	mrc	p15, 0, r0, c1, c0, 0
+	bl	printhex8
+	kputc	#'\n'
+	ldmfd   sp!, {r0-r4, lr}
+	.endm
+
+	.macro	PRINT_CPSR
+	stmfd	sp!, {r0-r4, lr}
+	kputc	#'C'
+	kputc	#'P'
+	kputc	#'S'
+	kputc	#'R'
+	kputc	#':'
+	mrs	r0, cpsr
+	bl	printhex8
+	kputc	#'\n'
+	ldmfd   sp!, {r0-r4, lr}
+	.endm
+
+#define DBG_MSG(x)	dbgmsg dbg_##x
+#define PRINT_REG(x)	read_reg r##x, x
+
+#undef ENDPROC
+#define ENDPROC(name) \
+	.type name, %function; \
+		END(name); \
+	dbg_##name:; \
+	.ascii #name; \
+	.asciz " enter.\n"; \
+	.align 2
+
+#else
+#define DBG_MSG(x)
+#define PRINT_REG(x)
+#endif
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 37cfa88..f916bb8 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -74,6 +74,7 @@ str_a3:	.asciz	"\nPlease check your kernel config and/or bootloader.\n"
  *  r5 = mach_info pointer in physical address space
  */
 __lookup_machine_type:
+	DBG_MSG(__lookup_machine_type)
 	adr	r3, __lookup_machine_type_data
 	ldmia	r3, {r4, r5, r6}
 	sub	r3, r3, r4			@ get offset between virt&phys
@@ -114,6 +115,7 @@ __lookup_machine_type_data:
  *  r5, r6 corrupted
  */
 __vet_atags:
+	DBG_MSG(__vet_atags)
 	tst	r2, #0x3			@ aligned?
 	bne	1f
 
@@ -149,6 +151,7 @@ ENDPROC(__vet_atags)
  */
 	__INIT
 __mmap_switched:
+	DBG_MSG(__mmap_switched)
 	adr	r3, __mmap_switched_data
 
 	ldmia	r3!, {r4, r5, r6, r7}
@@ -225,6 +228,7 @@ ENDPROC(lookup_processor_type)
  */
 	__CPUINIT
 __lookup_processor_type:
+	DBG_MSG(__lookup_processor_type)
 	adr	r3, __lookup_processor_type_data
 	ldmia	r3, {r4 - r6}
 	sub	r3, r3, r4			@ get offset between virt&phys
@@ -284,3 +288,7 @@ __error:
 1:	mov	r0, r0
 	b	1b
 ENDPROC(__error)
+
+		.align
+		.section ".boot.stack", "aw"
+boot_stack:	.space 512
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index dd6b369..bde50cd 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -33,6 +33,7 @@
 #define KERNEL_RAM_VADDR	(PAGE_OFFSET + TEXT_OFFSET)
 #define KERNEL_RAM_PADDR	(PHYS_OFFSET + TEXT_OFFSET)
 
+#include "debug_macro.S"
 
 /*
  * swapper_pg_dir is the virtual address of the initial page table.
@@ -82,6 +83,9 @@
 ENTRY(stext)
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
+	ldr	r13, =(__stack_end - PAGE_OFFSET + PHYS_OFFSET)
+	PRINT_REG(13)
+	DBG_MSG(stext)
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
@@ -102,8 +106,8 @@ ENTRY(stext)
 	 * above.  On return, the CPU will be ready for the MMU to be
 	 * turned on, and r0 will hold the CPU control register value.
 	 */
-	ldr	r13, =__mmap_switched		@ address to jump to after
-						@ mmu has been enabled
+	ldr	r0, =__mmap_switched		@ address to jump to after
+	str	r0, [r13, #-4]!			@ mmu has been enabled
 	adr	lr, BSYM(1f)			@ return (PIC) address
  ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
@@ -126,6 +130,7 @@ ENDPROC(stext)
  *  r4 = physical page table address
  */
 __create_page_tables:
+	DBG_MSG(__create_page_tables)
 	pgtbl	r4				@ page table address
 
 	/*
@@ -278,6 +283,8 @@ ENTRY(secondary_startup)
 	 * as it has already been validated by the primary processor.
 	 */
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+	ldr	r13, =(__stack_end - PAGE_OFFSET + PHYS_OFFSET)
+	DBG_MSG(secondary_startup)
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type
 	movs	r10, r5				@ invalid processor?
@@ -292,7 +299,7 @@ ENTRY(secondary_startup)
 	sub	r4, r4, r5			@ mmu has been enabled
 	ldr	r4, [r7, r4]			@ get secondary_data.pgdir
 	adr	lr, BSYM(__enable_mmu)		@ return address
-	mov	r13, r12			@ __secondary_switched address
+	str	r12, [r13, #-4]!		@ __secondary_switched address
  ARM(	add	pc, r10, #PROCINFO_INITFUNC	) @ initialise processor
 						  @ (return control reg)
  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
@@ -303,6 +310,7 @@ ENDPROC(secondary_startup)
 	 * r6  = &secondary_data
 	 */
 ENTRY(__secondary_switched)
+	DBG_MSG(__secondary_switched)
 	ldr	sp, [r7, #4]			@ get secondary_data.stack
 	mov	fp, #0
 	b	secondary_start_kernel
@@ -330,6 +338,7 @@ __secondary_data:
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
+	DBG_MSG(__enable_mmu)
 #ifdef CONFIG_ALIGNMENT_TRAP
 	orr	r0, r0, #CR_A
 #else
@@ -373,7 +382,9 @@ __turn_mmu_on:
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
 	mov	r3, r3
-	mov	r3, r13
+	sub	r13, r13, #PHYS_OFFSET
+	add	r13, r13, #PAGE_OFFSET
+	ldr	r3, [r13], #4
 	mov	pc, r3
 __enable_mmu_end:
 ENDPROC(__turn_mmu_on)
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index cead889..5030bc0 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -246,6 +246,13 @@ SECTIONS
 #endif
 
 	BSS_SECTION(0, 0, 0)
+	.stack : {
+		. = ALIGN(4);
+		__stack_start = .;
+		*(.boot.stack)
+		. = ALIGN(4);
+		__stack_end = .;
+	}
 	_end = .;
 
 	STABS_DEBUG
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 1/3] Support BE8 mode kernel modules relocation
  2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
@ 2011-01-21  9:40   ` Stanley.Miao
  2011-01-21  9:44   ` Russell King - ARM Linux
  1 sibling, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-21  9:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Russell,

It looks no other comments. I uploaded these patches to you patches
tracking system.

Stanley.


2011/1/19, Stanley.Miao <stanley.miao@windriver.com>:
> The code section in BE8 kernel modules is in little-endian while data
> section is in big-endian. When reading code from memory in the relocation
> procedure, these instructions are read according to big-endian, so they are
> needed to be inverted.
>
> Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
> ---
>  arch/arm/Makefile        |    1 +
>  arch/arm/kernel/module.c |   62
> +++++++++++++++++++++++++++++-----------------
>  2 files changed, 40 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 3eec793..03e7761 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -13,6 +13,7 @@
>  LDFLAGS_vmlinux	:=-p --no-undefined -X
>  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
>  LDFLAGS_vmlinux	+= --be8
> +LDFLAGS_MODULE	+= --be8
>  endif
>
>  OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index d9bd786..c5e5bb1 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -99,6 +99,18 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
>  	return 0;
>  }
>
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +#define read_instr32(c)			__swab32(*(u32 *)c)
> +#define read_instr16(c)			__swab16(*(u16 *)c)
> +#define write_instr32(v,a)		(*(u32 *)(a) = __swab32((__force __u32)(v)))
> +#define write_instr16(v,a)		(*(u16 *)(a) = __swab16((__force __u16)(v)))
> +#else
> +#define read_instr32(c)			(*(u32 *)c)
> +#define read_instr16(c)			(*(u16 *)c)
> +#define write_instr32(v,a)		(*(u32 *)(a) = (v))
> +#define write_instr16(v,a)		(*(u16 *)(a) = (v))
> +#endif
> +
>  int
>  apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int
> symindex,
>  	       unsigned int relindex, struct module *module)
> @@ -148,7 +160,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
> unsigned int symindex,
>  		case R_ARM_PC24:
>  		case R_ARM_CALL:
>  		case R_ARM_JUMP24:
> -			offset = (*(u32 *)loc & 0x00ffffff) << 2;
> +			offset = (read_instr32(loc) & 0x00ffffff) << 2;
>  			if (offset & 0x02000000)
>  				offset -= 0x04000000;
>
> @@ -165,8 +177,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
> unsigned int symindex,
>
>  			offset >>= 2;
>
> -			*(u32 *)loc &= 0xff000000;
> -			*(u32 *)loc |= offset & 0x00ffffff;
> +			write_instr32((read_instr32(loc) & 0xff000000) |
> +						(offset & 0x00ffffff), loc);
>  			break;
>
>  	       case R_ARM_V4BX:
> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
> unsigned int symindex,
>  			* other bits to re-code instruction as
>  			* MOV PC,Rm.
>  			*/
> -		       *(u32 *)loc &= 0xf000000f;
> -		       *(u32 *)loc |= 0x01a0f000;
> -		       break;
> +			write_instr32((read_instr32(loc) & 0xf000000f) |
> +							0x01a0f000, loc);
> +			break;
>
>  		case R_ARM_PREL31:
>  			offset = *(u32 *)loc + sym->st_value - loc;
> @@ -185,7 +197,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
> unsigned int symindex,
>
>  		case R_ARM_MOVW_ABS_NC:
>  		case R_ARM_MOVT_ABS:
> -			offset = *(u32 *)loc;
> +			offset = read_instr32(loc);
>  			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
>  			offset = (offset ^ 0x8000) - 0x8000;
>
> @@ -193,16 +205,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char
> *strtab, unsigned int symindex,
>  			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
>  				offset >>= 16;
>
> -			*(u32 *)loc &= 0xfff0f000;
> -			*(u32 *)loc |= ((offset & 0xf000) << 4) |
> -					(offset & 0x0fff);
> +			write_instr32((read_instr32(loc) & 0xfff0f000) |
> +					((offset & 0xf000) << 4) |
> +					(offset & 0x0fff), loc);
>  			break;
>
>  #ifdef CONFIG_THUMB2_KERNEL
>  		case R_ARM_THM_CALL:
>  		case R_ARM_THM_JUMP24:
> -			upper = *(u16 *)loc;
> -			lower = *(u16 *)(loc + 2);
> +			upper = read_instr16(loc);
> +			lower = read_instr16(loc + 2);
>
>  			/*
>  			 * 25 bit signed address range (Thumb-2 BL and B.W
> @@ -242,17 +254,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char
> *strtab, unsigned int symindex,
>  			sign = (offset >> 24) & 1;
>  			j1 = sign ^ (~(offset >> 23) & 1);
>  			j2 = sign ^ (~(offset >> 22) & 1);
> -			*(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
> -					    ((offset >> 12) & 0x03ff));
> -			*(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
> -						  (j1 << 13) | (j2 << 11) |
> -						  ((offset >> 1) & 0x07ff));
> +			write_instr16((u16)((upper & 0xf800) | (sign << 10) |
> +						((offset >> 12) & 0x03ff)),
> +					loc);
> +			write_instr16((u16)((lower & 0xd000) |
> +						(j1 << 13) | (j2 << 11) |
> +						((offset >> 1) & 0x07ff)),
> +					loc + 2);
>  			break;
>
>  		case R_ARM_THM_MOVW_ABS_NC:
>  		case R_ARM_THM_MOVT_ABS:
> -			upper = *(u16 *)loc;
> -			lower = *(u16 *)(loc + 2);
> +			upper = read_instr16(loc);
> +			lower = read_instr16(loc + 2);
>
>  			/*
>  			 * MOVT/MOVW instructions encoding in Thumb-2:
> @@ -273,12 +287,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char
> *strtab, unsigned int symindex,
>  			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
>  				offset >>= 16;
>
> -			*(u16 *)loc = (u16)((upper & 0xfbf0) |
> +			write_instr16((u16)((upper & 0xfbf0) |
>  					    ((offset & 0xf000) >> 12) |
> -					    ((offset & 0x0800) >> 1));
> -			*(u16 *)(loc + 2) = (u16)((lower & 0x8f00) |
> +					    ((offset & 0x0800) >> 1)),
> +					doc);
> +			write_instr16((u16)((lower & 0x8f00) |
>  						  ((offset & 0x0700) << 4) |
> -						  (offset & 0x00ff));
> +						  (offset & 0x00ff)),
> +					doc + 2);
>  			break;
>  #endif
>
> --
> 1.5.4.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] Support BE8 mode kernel modules relocation
  2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
  2011-01-21  9:40   ` Stanley.Miao
@ 2011-01-21  9:44   ` Russell King - ARM Linux
  2011-01-21 10:11     ` stanley.miao
  1 sibling, 1 reply; 16+ messages in thread
From: Russell King - ARM Linux @ 2011-01-21  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote:
> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>  			* other bits to re-code instruction as
>  			* MOV PC,Rm.
>  			*/
> -		       *(u32 *)loc &= 0xf000000f;
> -		       *(u32 *)loc |= 0x01a0f000;
> -		       break;
> +			write_instr32((read_instr32(loc) & 0xf000000f) |
> +							0x01a0f000, loc);
> +			break;

Indentation error.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-19  6:44 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao
@ 2011-01-21  9:46   ` Russell King - ARM Linux
  2011-01-21 10:51     ` Stanley.Miao
  0 siblings, 1 reply; 16+ messages in thread
From: Russell King - ARM Linux @ 2011-01-21  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 19, 2011 at 02:44:46PM +0800, Stanley.Miao wrote:
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index a00055d..a33075b 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -131,6 +131,9 @@ start:
>  		mov	r0, r0
>  		.endr
>  
> +#ifdef CONFIG_BE8_ON_LE
> +		setend	be
> +#endif

This should not be before the magic numbers.

>  		b	1f
>  		.word	0x016f2818		@ Magic numbers to help the loader
>  		.word	start			@ absolute load/run zImage address
> diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
> index f1e5a9b..1504d09 100644
> --- a/arch/arm/include/asm/setup.h
> +++ b/arch/arm/include/asm/setup.h
> @@ -173,15 +173,20 @@ struct tagtable {
>  	int (*parse)(const struct tag *);
>  };
>  
> +#ifdef CONFIG_BE8_ON_LE
> +#define read_tag(a)	le32_to_cpu(a)
> +#else
> +#define read_tag(a)	a
> +#endif

I think this is going to cause sparse errors.  Has it been checked with
sparse?

What about those structures which contain u8's and u16's ?  These can't
be dealt with a le32_to_cpu().

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] Support BE8 mode kernel modules relocation
  2011-01-21  9:44   ` Russell King - ARM Linux
@ 2011-01-21 10:11     ` stanley.miao
  2011-01-22 17:00       ` Russell King - ARM Linux
  0 siblings, 1 reply; 16+ messages in thread
From: stanley.miao @ 2011-01-21 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote:
>   
>> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>>  			* other bits to re-code instruction as
>>  			* MOV PC,Rm.
>>  			*/
>> -		       *(u32 *)loc &= 0xf000000f;
>> -		       *(u32 *)loc |= 0x01a0f000;
>> -		       break;
>> +			write_instr32((read_instr32(loc) & 0xf000000f) |
>> +							0x01a0f000, loc);
>> +			break;
>>     
>
> Indentation error.
>
>   
Actually, The indentation of my code is right, and the original code is 
wrong.

Stanley.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110121/aaf41cba/attachment-0001.html>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-21  9:46   ` Russell King - ARM Linux
@ 2011-01-21 10:51     ` Stanley.Miao
  0 siblings, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-21 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

2011/1/21 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> On Wed, Jan 19, 2011 at 02:44:46PM +0800, Stanley.Miao wrote:
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index a00055d..a33075b 100644
>> --- a/arch/arm/boot/compressed/head.S
>> +++ b/arch/arm/boot/compressed/head.S
>> @@ -131,6 +131,9 @@ start:
>> ? ? ? ? ? ? ? mov ? ? r0, r0
>> ? ? ? ? ? ? ? .endr
>>
>> +#ifdef CONFIG_BE8_ON_LE
>> + ? ? ? ? ? ? setend ?be
>> +#endif
>
> This should not be before the magic numbers.

I will move it downward in V3.

--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -131,9 +131,6 @@ start:
                mov     r0, r0
                .endr

-#ifdef CONFIG_BE8_ON_LE
-               setend  be
-#endif
                b       1f
                .word   0x016f2818              @ Magic numbers to
help the loader
                .word   start                   @ absolute load/run
zImage address
@@ -141,6 +138,10 @@ start:
 1:             mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer

+#ifdef CONFIG_BE8_ON_LE
+               setend  be
+#endif
+
 #ifndef __ARM_ARCH_2__

>
>> ? ? ? ? ? ? ? b ? ? ? 1f
>> ? ? ? ? ? ? ? .word ? 0x016f2818 ? ? ? ? ? ? ?@ Magic numbers to help the loader
>> ? ? ? ? ? ? ? .word ? start ? ? ? ? ? ? ? ? ? @ absolute load/run zImage address
>> diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
>> index f1e5a9b..1504d09 100644
>> --- a/arch/arm/include/asm/setup.h
>> +++ b/arch/arm/include/asm/setup.h
>> @@ -173,15 +173,20 @@ struct tagtable {
>> ? ? ? int (*parse)(const struct tag *);
>> ?};
>>
>> +#ifdef CONFIG_BE8_ON_LE
>> +#define read_tag(a) ?le32_to_cpu(a)
>> +#else
>> +#define read_tag(a) ?a
>> +#endif
>
> I think this is going to cause sparse errors. ?Has it been checked with
> sparse?

Yes, no sparse error.

>
> What about those structures which contain u8's and u16's ? ?These can't
> be dealt with a le32_to_cpu().

I will add read_tag32 and read_tag16 in V3.  u8 is not needed.

Stanley.

>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] Support BE8 mode kernel modules relocation
  2011-01-21 10:11     ` stanley.miao
@ 2011-01-22 17:00       ` Russell King - ARM Linux
  0 siblings, 0 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2011-01-22 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 21, 2011 at 06:11:45PM +0800, stanley.miao wrote:
> Russell King - ARM Linux wrote:
>> On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote:
>>   
>>> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>>>  			* other bits to re-code instruction as
>>>  			* MOV PC,Rm.
>>>  			*/
>>> -		       *(u32 *)loc &= 0xf000000f;
>>> -		       *(u32 *)loc |= 0x01a0f000;
>>> -		       break;
>>> +			write_instr32((read_instr32(loc) & 0xf000000f) |
>>> +							0x01a0f000, loc);
>>> +			break;
>>>     
>>
>> Indentation error.
>>
>>   
> Actually, The indentation of my code is right, and the original code is  
> wrong.

Yes, you're right.  Please precede your patch which a patch which _just_
corrects the formatting of the old code.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-17 10:01     ` Catalin Marinas
  (?)
  (?)
@ 2011-01-18  1:24     ` Stanley.Miao
  -1 siblings, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-18  1:24 UTC (permalink / raw)
  To: linux-arm-kernel

Yes, the bootloader can also do this. However, it is dangerous to modify the
bootloader. If the new boot loader can't work, it is difficult to update the
bootloader again. So, I choose to modify Linux kernel.

Stanley.

2011/1/17 Catalin Marinas <catalin.marinas@arm.com>:
> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
>> When BE8 kernel is running on a little endian machine, the kernel endian
>> mode need to be converted at the begining of the startup procedure with
>> the instruction "setend be".
>
> Can we not let the boot loader do this? It could also prepare the tags
> as big endian.
>
> --
> Catalin
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-17 10:01     ` Catalin Marinas
  (?)
@ 2011-01-17 10:23     ` stanley.miao
  -1 siblings, 0 replies; 16+ messages in thread
From: stanley.miao @ 2011-01-17 10:23 UTC (permalink / raw)
  To: linux-arm-kernel

Catalin Marinas wrote:
> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
>   
>> When BE8 kernel is running on a little endian machine, the kernel endian
>> mode need to be converted at the begining of the startup procedure with
>> the instruction "setend be".
>>     
>
> Can we not let the boot loader do this? It could also prepare the tags
> as big endian.
>
>   
Yes, the bootloader can also do this. However, it is dangerous to modify 
the
bootloader. If the new boot loader can't work, it is difficult to update 
the
bootloader again. So, I choose to modify Linux kernel.

Stanley.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110117/ce66b171/attachment-0001.html>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-17  8:42   ` Stanley.Miao
@ 2011-01-17 10:01     ` Catalin Marinas
  -1 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2011-01-17 10:01 UTC (permalink / raw)
  To: Stanley.Miao; +Cc: linux-kernel, linux-arm-kernel

On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
> When BE8 kernel is running on a little endian machine, the kernel endian
> mode need to be converted at the begining of the startup procedure with
> the instruction "setend be".

Can we not let the boot loader do this? It could also prepare the tags
as big endian.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
@ 2011-01-17 10:01     ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2011-01-17 10:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
> When BE8 kernel is running on a little endian machine, the kernel endian
> mode need to be converted at the begining of the startup procedure with
> the instruction "setend be".

Can we not let the boot loader do this? It could also prepare the tags
as big endian.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
  2011-01-17  8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao
@ 2011-01-17  8:42   ` Stanley.Miao
  0 siblings, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-17  8:42 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-arm-kernel

When BE8 kernel is running on a little endian machine, the kernel endian
mode need to be converted at the begining of the startup procedure with
the instruction "setend be".

Besides, the tags that the bootloader passed to the kernel are in
little-endian mode and they need to be inverted.

Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
 arch/arm/boot/compressed/head.S |    3 +++
 arch/arm/include/asm/setup.h    |   13 +++++++++----
 arch/arm/kernel/head-common.S   |    6 ++++++
 arch/arm/kernel/setup.c         |   22 +++++++++++-----------
 arch/arm/mm/Kconfig             |    7 +++++++
 5 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index a00055d..a33075b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -131,6 +131,9 @@ start:
 		mov	r0, r0
 		.endr
 
+#ifdef CONFIG_BE8_ON_LE
+		setend	be
+#endif
 		b	1f
 		.word	0x016f2818		@ Magic numbers to help the loader
 		.word	start			@ absolute load/run zImage address
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9b..1504d09 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -173,15 +173,20 @@ struct tagtable {
 	int (*parse)(const struct tag *);
 };
 
+#ifdef CONFIG_BE8_ON_LE
+#define read_tag(a)	le32_to_cpu(a)
+#else
+#define read_tag(a)	a
+#endif
+
 #define tag_member_present(tag,member)				\
 	((unsigned long)(&((struct tag *)0L)->member + 1)	\
-		<= (tag)->hdr.size * 4)
-
-#define tag_next(t)	((struct tag *)((__u32 *)(t) + (t)->hdr.size))
+		<= read_tag((tag)->hdr.size) * 4)
+#define tag_next(t)	((struct tag *)((__u32 *)(t) + read_tag((t)->hdr.size)))
 #define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
 
 #define for_each_tag(t,base)		\
-	for (t = base; t->hdr.size; t = tag_next(t))
+	for (t = base; read_tag((t)->hdr.size); t = tag_next(t))
 
 #ifdef __KERNEL__
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index bbecaac..37cfa88 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -118,10 +118,16 @@ __vet_atags:
 	bne	1f
 
 	ldr	r5, [r2, #0]			@ is first tag ATAG_CORE?
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	cmp	r5, #ATAG_CORE_SIZE
 	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
 	bne	1f
 	ldr	r5, [r2, #4]
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	ldr	r6, =ATAG_CORE
 	cmp	r5, r6
 	bne	1f
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 3cadb46..9098aa5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -578,10 +578,10 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
  */
 static int __init parse_tag_core(const struct tag *tag)
 {
-	if (tag->hdr.size > 2) {
-		if ((tag->u.core.flags & 1) == 0)
+	if (read_tag(tag->hdr.size) > 2) {
+		if ((read_tag(tag->u.core.flags) & 1) == 0)
 			root_mountflags &= ~MS_RDONLY;
-		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+		ROOT_DEV = old_decode_dev(read_tag(tag->u.core.rootdev));
 	}
 	return 0;
 }
@@ -590,7 +590,7 @@ __tagtable(ATAG_CORE, parse_tag_core);
 
 static int __init parse_tag_mem32(const struct tag *tag)
 {
-	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
+	return arm_add_memory(read_tag(tag->u.mem.start), read_tag(tag->u.mem.size));
 }
 
 __tagtable(ATAG_MEM, parse_tag_mem32);
@@ -643,7 +643,7 @@ __tagtable(ATAG_SERIAL, parse_tag_serialnr);
 
 static int __init parse_tag_revision(const struct tag *tag)
 {
-	system_rev = tag->u.revision.rev;
+	system_rev = read_tag(tag->u.revision.rev);
 	return 0;
 }
 
@@ -670,7 +670,7 @@ static int __init parse_tag(const struct tag *tag)
 	struct tagtable *t;
 
 	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
-		if (tag->hdr.tag == t->tag) {
+		if ((read_tag(tag->hdr.tag) == t->tag)) {
 			t->parse(tag);
 			break;
 		}
@@ -684,9 +684,9 @@ static int __init parse_tag(const struct tag *tag)
  */
 static void __init parse_tags(const struct tag *t)
 {
-	for (; t->hdr.size; t = tag_next(t))
+	for (; read_tag(t->hdr.size); t = tag_next(t))
 		if (!parse_tag(t))
-			printk(KERN_WARNING
+			early_printk(KERN_WARNING
 				"Ignoring unrecognised tag 0x%08x\n",
 				t->hdr.tag);
 }
@@ -824,16 +824,16 @@ void __init setup_arch(char **cmdline_p)
 	 * If we have the old style parameters, convert them to
 	 * a tag list.
 	 */
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		convert_to_tag_list(tags);
 #endif
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		tags = (struct tag *)&init_tags;
 
 	if (mdesc->fixup)
 		mdesc->fixup(mdesc, tags, &from, &meminfo);
 
-	if (tags->hdr.tag == ATAG_CORE) {
+	if (read_tag(tags->hdr.tag) == ATAG_CORE) {
 		if (meminfo.nr_banks != 0)
 			squash_mem_tags(tags);
 		save_atags(tags);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c16ae86..eb74e6b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -686,6 +686,13 @@ config CPU_ENDIAN_BE32
 	help
 	  Support for the BE-32 (big-endian) mode on pre-ARMv6 processors.
 
+config BE8_ON_LE
+	bool "Run BE8 kernel on a little endian machine"
+	depends on CPU_V6 || CPU_V7
+	select CPU_BIG_ENDIAN
+	help
+	  Run BE8 kernel on a little endian machine.
+
 config CPU_HIGH_VECTOR
 	depends on !MMU && CPU_CP15 && !CPU_ARM740T
 	bool "Select the High exception vector"
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/3] support ARM BE8 mode on a little endian machine
@ 2011-01-17  8:42   ` Stanley.Miao
  0 siblings, 0 replies; 16+ messages in thread
From: Stanley.Miao @ 2011-01-17  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

When BE8 kernel is running on a little endian machine, the kernel endian
mode need to be converted at the begining of the startup procedure with
the instruction "setend be".

Besides, the tags that the bootloader passed to the kernel are in
little-endian mode and they need to be inverted.

Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
 arch/arm/boot/compressed/head.S |    3 +++
 arch/arm/include/asm/setup.h    |   13 +++++++++----
 arch/arm/kernel/head-common.S   |    6 ++++++
 arch/arm/kernel/setup.c         |   22 +++++++++++-----------
 arch/arm/mm/Kconfig             |    7 +++++++
 5 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index a00055d..a33075b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -131,6 +131,9 @@ start:
 		mov	r0, r0
 		.endr
 
+#ifdef CONFIG_BE8_ON_LE
+		setend	be
+#endif
 		b	1f
 		.word	0x016f2818		@ Magic numbers to help the loader
 		.word	start			@ absolute load/run zImage address
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9b..1504d09 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -173,15 +173,20 @@ struct tagtable {
 	int (*parse)(const struct tag *);
 };
 
+#ifdef CONFIG_BE8_ON_LE
+#define read_tag(a)	le32_to_cpu(a)
+#else
+#define read_tag(a)	a
+#endif
+
 #define tag_member_present(tag,member)				\
 	((unsigned long)(&((struct tag *)0L)->member + 1)	\
-		<= (tag)->hdr.size * 4)
-
-#define tag_next(t)	((struct tag *)((__u32 *)(t) + (t)->hdr.size))
+		<= read_tag((tag)->hdr.size) * 4)
+#define tag_next(t)	((struct tag *)((__u32 *)(t) + read_tag((t)->hdr.size)))
 #define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
 
 #define for_each_tag(t,base)		\
-	for (t = base; t->hdr.size; t = tag_next(t))
+	for (t = base; read_tag((t)->hdr.size); t = tag_next(t))
 
 #ifdef __KERNEL__
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index bbecaac..37cfa88 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -118,10 +118,16 @@ __vet_atags:
 	bne	1f
 
 	ldr	r5, [r2, #0]			@ is first tag ATAG_CORE?
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	cmp	r5, #ATAG_CORE_SIZE
 	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
 	bne	1f
 	ldr	r5, [r2, #4]
+#ifdef CONFIG_BE8_ON_LE
+	rev	r5, r5
+#endif
 	ldr	r6, =ATAG_CORE
 	cmp	r5, r6
 	bne	1f
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 3cadb46..9098aa5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -578,10 +578,10 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
  */
 static int __init parse_tag_core(const struct tag *tag)
 {
-	if (tag->hdr.size > 2) {
-		if ((tag->u.core.flags & 1) == 0)
+	if (read_tag(tag->hdr.size) > 2) {
+		if ((read_tag(tag->u.core.flags) & 1) == 0)
 			root_mountflags &= ~MS_RDONLY;
-		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+		ROOT_DEV = old_decode_dev(read_tag(tag->u.core.rootdev));
 	}
 	return 0;
 }
@@ -590,7 +590,7 @@ __tagtable(ATAG_CORE, parse_tag_core);
 
 static int __init parse_tag_mem32(const struct tag *tag)
 {
-	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
+	return arm_add_memory(read_tag(tag->u.mem.start), read_tag(tag->u.mem.size));
 }
 
 __tagtable(ATAG_MEM, parse_tag_mem32);
@@ -643,7 +643,7 @@ __tagtable(ATAG_SERIAL, parse_tag_serialnr);
 
 static int __init parse_tag_revision(const struct tag *tag)
 {
-	system_rev = tag->u.revision.rev;
+	system_rev = read_tag(tag->u.revision.rev);
 	return 0;
 }
 
@@ -670,7 +670,7 @@ static int __init parse_tag(const struct tag *tag)
 	struct tagtable *t;
 
 	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
-		if (tag->hdr.tag == t->tag) {
+		if ((read_tag(tag->hdr.tag) == t->tag)) {
 			t->parse(tag);
 			break;
 		}
@@ -684,9 +684,9 @@ static int __init parse_tag(const struct tag *tag)
  */
 static void __init parse_tags(const struct tag *t)
 {
-	for (; t->hdr.size; t = tag_next(t))
+	for (; read_tag(t->hdr.size); t = tag_next(t))
 		if (!parse_tag(t))
-			printk(KERN_WARNING
+			early_printk(KERN_WARNING
 				"Ignoring unrecognised tag 0x%08x\n",
 				t->hdr.tag);
 }
@@ -824,16 +824,16 @@ void __init setup_arch(char **cmdline_p)
 	 * If we have the old style parameters, convert them to
 	 * a tag list.
 	 */
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		convert_to_tag_list(tags);
 #endif
-	if (tags->hdr.tag != ATAG_CORE)
+	if (read_tag(tags->hdr.tag) != ATAG_CORE)
 		tags = (struct tag *)&init_tags;
 
 	if (mdesc->fixup)
 		mdesc->fixup(mdesc, tags, &from, &meminfo);
 
-	if (tags->hdr.tag == ATAG_CORE) {
+	if (read_tag(tags->hdr.tag) == ATAG_CORE) {
 		if (meminfo.nr_banks != 0)
 			squash_mem_tags(tags);
 		save_atags(tags);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c16ae86..eb74e6b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -686,6 +686,13 @@ config CPU_ENDIAN_BE32
 	help
 	  Support for the BE-32 (big-endian) mode on pre-ARMv6 processors.
 
+config BE8_ON_LE
+	bool "Run BE8 kernel on a little endian machine"
+	depends on CPU_V6 || CPU_V7
+	select CPU_BIG_ENDIAN
+	help
+	  Run BE8 kernel on a little endian machine.
+
 config CPU_HIGH_VECTOR
 	depends on !MMU && CPU_CP15 && !CPU_ARM740T
 	bool "Select the High exception vector"
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-01-22 17:00 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-19  6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao
2011-01-19  6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
2011-01-21  9:40   ` Stanley.Miao
2011-01-21  9:44   ` Russell King - ARM Linux
2011-01-21 10:11     ` stanley.miao
2011-01-22 17:00       ` Russell King - ARM Linux
2011-01-19  6:44 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao
2011-01-21  9:46   ` Russell King - ARM Linux
2011-01-21 10:51     ` Stanley.Miao
2011-01-19  6:44 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao
  -- strict thread matches above, loose matches on Subject: below --
2011-01-17  8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao
2011-01-17  8:42 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao
2011-01-17  8:42   ` Stanley.Miao
2011-01-17 10:01   ` Catalin Marinas
2011-01-17 10:01     ` Catalin Marinas
2011-01-17 10:23     ` stanley.miao
2011-01-18  1:24     ` Stanley.Miao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.