summaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/head.S')
-rw-r--r--arch/microblaze/kernel/head.S45
1 files changed, 28 insertions, 17 deletions
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 4243400..77320b8 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -39,7 +39,7 @@
#include <asm/mmu.h>
#include <asm/processor.h>
-.data
+.section .data
.global empty_zero_page
.align 12
empty_zero_page:
@@ -50,6 +50,11 @@ swapper_pg_dir:
#endif /* CONFIG_MMU */
+.section .rodata
+.align 4
+endian_check:
+ .word 1
+
__HEAD
ENTRY(_start)
#if CONFIG_KERNEL_BASE_ADDR == 0
@@ -62,23 +67,29 @@ real_start:
andi r1, r1, ~2
mts rmsr, r1
/*
- * Here is checking mechanism which check if Microblaze has msr instructions
- * We load msr and compare it with previous r1 value - if is the same,
- * msr instructions works if not - cpu don't have them.
+ * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
+ * if the msrclr instruction is not enabled. We use this to detect
+ * if the opcode is available, by issuing msrclr and then testing the result.
+ * r8 == 0 - msr instructions are implemented
+ * r8 != 0 - msr instructions are not implemented
*/
- /* r8=0 - I have msr instr, 1 - I don't have them */
- rsubi r0, r0, 1 /* set the carry bit */
- msrclr r0, 0x4 /* try to clear it */
- /* read the carry bit, r8 will be '0' if msrclr exists */
- addik r8, r0, 0
+ msrclr r8, 0 /* clear nothing - just read msr for test */
+ cmpu r8, r8, r1 /* r1 must contain msr reg content */
/* r7 may point to an FDT, or there may be one linked in.
if it's in r7, we've got to save it away ASAP.
We ensure r7 points to a valid FDT, just in case the bootloader
is broken or non-existent */
beqi r7, no_fdt_arg /* NULL pointer? don't copy */
- lw r11, r0, r7 /* Does r7 point to a */
- rsubi r11, r11, OF_DT_HEADER /* valid FDT? */
+/* Does r7 point to a valid FDT? Load HEADER magic number */
+ /* Run time Big/Little endian platform */
+ /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */
+ lbui r11, r0, TOPHYS(endian_check)
+ beqid r11, big_endian /* DO NOT break delay stop dependency */
+ lw r11, r0, r7 /* Big endian load in delay slot */
+ lwr r11, r0, r7 /* Little endian load */
+big_endian:
+ rsubi r11, r11, OF_DT_HEADER /* Check FDT header */
beqi r11, _prepare_copy_fdt
or r7, r0, r0 /* clear R7 when not valid DTB */
bnei r11, no_fdt_arg /* No - get out of here */
@@ -213,26 +224,26 @@ start_here:
#endif /* CONFIG_MMU */
/* Initialize small data anchors */
- la r13, r0, _KERNEL_SDA_BASE_
- la r2, r0, _KERNEL_SDA2_BASE_
+ addik r13, r0, _KERNEL_SDA_BASE_
+ addik r2, r0, _KERNEL_SDA2_BASE_
/* Initialize stack pointer */
- la r1, r0, init_thread_union + THREAD_SIZE - 4
+ addik r1, r0, init_thread_union + THREAD_SIZE - 4
/* Initialize r31 with current task address */
- la r31, r0, init_task
+ addik r31, r0, init_task
/*
* Call platform dependent initialize function.
* Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
* the function.
*/
- la r9, r0, machine_early_init
+ addik r9, r0, machine_early_init
brald r15, r9
nop
#ifndef CONFIG_MMU
- la r15, r0, machine_halt
+ addik r15, r0, machine_halt
braid start_kernel
nop
#else
OpenPOWER on IntegriCloud