* [PATCH 0/3] Support BE8 kernel modules relocation
@ 2011-01-17 8:42 ` Stanley.Miao
0 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-arm-kernel
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] 24+ messages in thread
* [PATCH 0/3] Support BE8 kernel modules relocation
@ 2011-01-17 8:42 ` Stanley.Miao
0 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw)
To: linux-arm-kernel
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] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-17 8:42 ` Stanley.Miao
@ 2011-01-17 8:42 ` Stanley.Miao
-1 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw)
To: linux-kernel; +Cc: 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
need to be inverted before writing to memory and after reading from memory.
Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
arch/arm/Makefile | 1 +
arch/arm/include/asm/io.h | 12 ++++++++++
arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++--------------------
3 files changed, 41 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/include/asm/io.h b/arch/arm/include/asm/io.h
index 815efa2..2f088c5 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
#endif /* __mem_pci */
+#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
+
/*
* ioremap and friends.
*
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d9bd786..9c58a0d 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -14,6 +14,7 @@
#include <linux/moduleloader.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/io.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
@@ -148,7 +149,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 +166,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 +175,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 +186,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 +194,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 +243,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 +276,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] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
@ 2011-01-17 8:42 ` Stanley.Miao
0 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 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
need to be inverted before writing to memory and after reading from memory.
Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
---
arch/arm/Makefile | 1 +
arch/arm/include/asm/io.h | 12 ++++++++++
arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++--------------------
3 files changed, 41 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/include/asm/io.h b/arch/arm/include/asm/io.h
index 815efa2..2f088c5 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
#endif /* __mem_pci */
+#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
+
/*
* ioremap and friends.
*
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d9bd786..9c58a0d 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -14,6 +14,7 @@
#include <linux/moduleloader.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/io.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
@@ -148,7 +149,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 +166,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 +175,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 +186,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 +194,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 +243,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 +276,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] 24+ messages in thread
* [PATCH 2/3] support ARM BE8 mode on a little endian machine
2011-01-17 8:42 ` Stanley.Miao
@ 2011-01-17 8:42 ` Stanley.Miao
-1 siblings, 0 replies; 24+ 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] 24+ 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; 24+ 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] 24+ messages in thread
* [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly
2011-01-17 8:42 ` Stanley.Miao
@ 2011-01-17 8:42 ` Stanley.Miao
-1 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw)
To: linux-kernel; +Cc: 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] 24+ messages in thread
* [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly
@ 2011-01-17 8:42 ` Stanley.Miao
0 siblings, 0 replies; 24+ messages in thread
From: Stanley.Miao @ 2011-01-17 8:42 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] 24+ messages in thread
* Re: [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-17 8:42 ` Stanley.Miao
@ 2011-01-17 8:52 ` Russell King - ARM Linux
-1 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2011-01-17 8:52 UTC (permalink / raw)
To: Stanley.Miao; +Cc: linux-kernel, linux-arm-kernel
On Mon, Jan 17, 2011 at 04:42:07PM +0800, Stanley.Miao wrote:
> 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
> need to be inverted before writing to memory and after reading from memory.
>
> Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
> ---
> arch/arm/Makefile | 1 +
> arch/arm/include/asm/io.h | 12 ++++++++++
> arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++--------------------
> 3 files changed, 41 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/include/asm/io.h b/arch/arm/include/asm/io.h
> index 815efa2..2f088c5 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>
> #endif /* __mem_pci */
>
> +#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
> +
It makes no sense to put these in asm/io.h
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
@ 2011-01-17 8:52 ` Russell King - ARM Linux
0 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2011-01-17 8:52 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Jan 17, 2011 at 04:42:07PM +0800, Stanley.Miao wrote:
> 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
> need to be inverted before writing to memory and after reading from memory.
>
> Signed-off-by: Stanley.Miao <stanley.miao@windriver.com>
> ---
> arch/arm/Makefile | 1 +
> arch/arm/include/asm/io.h | 12 ++++++++++
> arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++--------------------
> 3 files changed, 41 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/include/asm/io.h b/arch/arm/include/asm/io.h
> index 815efa2..2f088c5 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>
> #endif /* __mem_pci */
>
> +#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
> +
It makes no sense to put these in asm/io.h
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-17 8:42 ` Stanley.Miao
@ 2011-01-17 9:56 ` Catalin Marinas
-1 siblings, 0 replies; 24+ messages in thread
From: Catalin Marinas @ 2011-01-17 9:56 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:
> 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
> need to be inverted before writing to memory and after reading from memory.
[...]
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>
> #endif /* __mem_pci */
>
> +#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
Can we not use cpu_to_le32 etc in here (and as Russell said, they are
not really IO)?
--
Catalin
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
@ 2011-01-17 9:56 ` Catalin Marinas
0 siblings, 0 replies; 24+ messages in thread
From: Catalin Marinas @ 2011-01-17 9:56 UTC (permalink / raw)
To: linux-arm-kernel
On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
> 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
> need to be inverted before writing to memory and after reading from memory.
[...]
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>
> ?#endif /* __mem_pci */
>
> +#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
Can we not use cpu_to_le32 etc in here (and as Russell said, they are
not really IO)?
--
Catalin
^ permalink raw reply [flat|nested] 24+ 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; 24+ 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] 24+ 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; 24+ 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] 24+ 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; 24+ 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] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-17 9:56 ` Catalin Marinas
(?)
@ 2011-01-18 1:22 ` Stanley.Miao
2011-01-18 15:23 ` Catalin Marinas
-1 siblings, 1 reply; 24+ messages in thread
From: Stanley.Miao @ 2011-01-18 1:22 UTC (permalink / raw)
To: linux-arm-kernel
2011/1/17 Catalin Marinas <catalin.marinas@arm.com>:
> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
>> 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
>> need to be inverted before writing to memory and after reading from memory.
> [...]
>> --- a/arch/arm/include/asm/io.h
>> +++ b/arch/arm/include/asm/io.h
>> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>>
>> ?#endif /* __mem_pci */
>>
>> +#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
>
> Can we not use cpu_to_le32 etc in here (and as Russell said, they are
> not really IO)?
Except moving these definition to arch/arm/kernel/module.c, do I need
to do other modifications ?
Stanley.
>
> --
> 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] 24+ 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; 24+ 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] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-18 1:22 ` Stanley.Miao
@ 2011-01-18 15:23 ` Catalin Marinas
2011-01-19 6:21 ` Stanley.Miao
0 siblings, 1 reply; 24+ messages in thread
From: Catalin Marinas @ 2011-01-18 15:23 UTC (permalink / raw)
To: linux-arm-kernel
On 18 January 2011 01:22, Stanley.Miao <stanleymiao@gmail.com> wrote:
> 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>:
>> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
>>> 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
>>> need to be inverted before writing to memory and after reading from memory.
>> [...]
>>> --- a/arch/arm/include/asm/io.h
>>> +++ b/arch/arm/include/asm/io.h
>>> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>>>
>>> ?#endif /* __mem_pci */
>>>
>>> +#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
>>
>> Can we not use cpu_to_le32 etc in here (and as Russell said, they are
>> not really IO)?
>
> Except moving these definition to arch/arm/kernel/module.c, do I need
> to do other modifications ?
Just personal preference (not important), I'd rather have a "u32
instr" variable set by read_instr32() than this kind of functional
style (in C code, I'm fine with it otherwise):
> + write_instr32((read_instr32(loc) & 0xff000000) |
> + (offset & 0x00ffffff), loc);
BTW (not related to modules, but since you are looking at this), when
we copy the sigreturn_codes to the vectors page in early_trap_init(),
do they get there in little endian form (as required by BE8)?
--
Catalin
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-18 15:23 ` Catalin Marinas
@ 2011-01-19 6:21 ` Stanley.Miao
2011-01-19 17:32 ` Catalin Marinas
0 siblings, 1 reply; 24+ messages in thread
From: Stanley.Miao @ 2011-01-19 6:21 UTC (permalink / raw)
To: linux-arm-kernel
2011/1/18 Catalin Marinas <catalin.marinas@arm.com>:
> On 18 January 2011 01:22, Stanley.Miao <stanleymiao@gmail.com> wrote:
>> 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>:
>>> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote:
>>>> 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
>>>> need to be inverted before writing to memory and after reading from memory.
>>> [...]
>>>> --- a/arch/arm/include/asm/io.h
>>>> +++ b/arch/arm/include/asm/io.h
>>>> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
>>>>
>>>> ?#endif /* __mem_pci */
>>>>
>>>> +#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
>>>
>>> Can we not use cpu_to_le32 etc in here (and as Russell said, they are
>>> not really IO)?
>>
>> Except moving these definition to arch/arm/kernel/module.c, do I need
>> to do other modifications ?
>
> Just personal preference (not important), I'd rather have a "u32
> instr" variable set by read_instr32() than this kind of functional
> style (in C code, I'm fine with it otherwise):
upper, lower and offset are used. It looks we don't need another "instr".
>
>> + ? ? ? ? ? ? ? ? ? ? ? write_instr32((read_instr32(loc) & 0xff000000) |
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (offset & 0x00ffffff), loc);
>
> BTW (not related to modules, but since you are looking at this), when
> we copy the sigreturn_codes to the vectors page in early_trap_init(),
> do they get there in little endian form (as required by BE8)?
No, they get there in big endian.They are read as data in the function
setup_return().
retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
Stanley.
>
> --
> Catalin
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-19 6:21 ` Stanley.Miao
@ 2011-01-19 17:32 ` Catalin Marinas
2011-01-21 9:39 ` stanley.miao
0 siblings, 1 reply; 24+ messages in thread
From: Catalin Marinas @ 2011-01-19 17:32 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 2011-01-19 at 06:21 +0000, Stanley.Miao wrote:
> 2011/1/18 Catalin Marinas <catalin.marinas@arm.com>:
> > BTW (not related to modules, but since you are looking at this), when
> > we copy the sigreturn_codes to the vectors page in early_trap_init(),
> > do they get there in little endian form (as required by BE8)?
>
> No, they get there in big endian.They are read as data in the function
> setup_return().
>
> retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
This retcode here is an address in the vectors page which is set to LR
when invoking the signal handler. All fine here.
But the sigreturn_codes array contains instructions which get copied to
the vectors page in the early_trap_init() function. This array has this
instructions in big endian format but they should be converted to little
endian when copied to the vectors page.
--
Catalin
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation
2011-01-19 17:32 ` Catalin Marinas
@ 2011-01-21 9:39 ` stanley.miao
0 siblings, 0 replies; 24+ messages in thread
From: stanley.miao @ 2011-01-21 9:39 UTC (permalink / raw)
To: linux-arm-kernel
Catalin Marinas wrote:
> On Wed, 2011-01-19 at 06:21 +0000, Stanley.Miao wrote:
>
>> 2011/1/18 Catalin Marinas <catalin.marinas@arm.com>:
>>
>>> BTW (not related to modules, but since you are looking at this), when
>>> we copy the sigreturn_codes to the vectors page in early_trap_init(),
>>> do they get there in little endian form (as required by BE8)?
>>>
>> No, they get there in big endian.They are read as data in the function
>> setup_return().
>>
>> retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
>>
>
> This retcode here is an address in the vectors page which is set to LR
> when invoking the signal handler. All fine here.
>
> But the sigreturn_codes array contains instructions which get copied to
> the vectors page in the early_trap_init() function. This array has this
> instructions in big endian format but they should be converted to little
> endian when copied to the vectors page.
>
>
I don't have a board in hand for now. When I get a board, I will test it.
Stanley.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110121/c05712b2/attachment-0001.html>
^ permalink raw reply [flat|nested] 24+ 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; 24+ 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] 24+ 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; 24+ 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] 24+ 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 ` Stanley.Miao
2011-01-21 9:46 ` Russell King - ARM Linux
0 siblings, 1 reply; 24+ 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] 24+ messages in thread
end of thread, other threads:[~2011-01-21 10:51 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-17 8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao
2011-01-17 8:42 ` Stanley.Miao
2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao
2011-01-17 8:42 ` Stanley.Miao
2011-01-17 8:52 ` Russell King - ARM Linux
2011-01-17 8:52 ` Russell King - ARM Linux
2011-01-17 9:56 ` Catalin Marinas
2011-01-17 9:56 ` Catalin Marinas
2011-01-18 1:22 ` Stanley.Miao
2011-01-18 15:23 ` Catalin Marinas
2011-01-19 6:21 ` Stanley.Miao
2011-01-19 17:32 ` Catalin Marinas
2011-01-21 9:39 ` 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
2011-01-17 8:42 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao
2011-01-17 8:42 ` Stanley.Miao
2011-01-19 6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao
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
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.