* [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.