diff options
Diffstat (limited to 'arch/microblaze/kernel/head.S')
-rw-r--r-- | arch/microblaze/kernel/head.S | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index 42434008209e..77320b8fc16a 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/mmu.h> | 39 | #include <asm/mmu.h> |
40 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
41 | 41 | ||
42 | .data | 42 | .section .data |
43 | .global empty_zero_page | 43 | .global empty_zero_page |
44 | .align 12 | 44 | .align 12 |
45 | empty_zero_page: | 45 | empty_zero_page: |
@@ -50,6 +50,11 @@ swapper_pg_dir: | |||
50 | 50 | ||
51 | #endif /* CONFIG_MMU */ | 51 | #endif /* CONFIG_MMU */ |
52 | 52 | ||
53 | .section .rodata | ||
54 | .align 4 | ||
55 | endian_check: | ||
56 | .word 1 | ||
57 | |||
53 | __HEAD | 58 | __HEAD |
54 | ENTRY(_start) | 59 | ENTRY(_start) |
55 | #if CONFIG_KERNEL_BASE_ADDR == 0 | 60 | #if CONFIG_KERNEL_BASE_ADDR == 0 |
@@ -62,23 +67,29 @@ real_start: | |||
62 | andi r1, r1, ~2 | 67 | andi r1, r1, ~2 |
63 | mts rmsr, r1 | 68 | mts rmsr, r1 |
64 | /* | 69 | /* |
65 | * Here is checking mechanism which check if Microblaze has msr instructions | 70 | * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc' |
66 | * We load msr and compare it with previous r1 value - if is the same, | 71 | * if the msrclr instruction is not enabled. We use this to detect |
67 | * msr instructions works if not - cpu don't have them. | 72 | * if the opcode is available, by issuing msrclr and then testing the result. |
73 | * r8 == 0 - msr instructions are implemented | ||
74 | * r8 != 0 - msr instructions are not implemented | ||
68 | */ | 75 | */ |
69 | /* r8=0 - I have msr instr, 1 - I don't have them */ | 76 | msrclr r8, 0 /* clear nothing - just read msr for test */ |
70 | rsubi r0, r0, 1 /* set the carry bit */ | 77 | cmpu r8, r8, r1 /* r1 must contain msr reg content */ |
71 | msrclr r0, 0x4 /* try to clear it */ | ||
72 | /* read the carry bit, r8 will be '0' if msrclr exists */ | ||
73 | addik r8, r0, 0 | ||
74 | 78 | ||
75 | /* r7 may point to an FDT, or there may be one linked in. | 79 | /* r7 may point to an FDT, or there may be one linked in. |
76 | if it's in r7, we've got to save it away ASAP. | 80 | if it's in r7, we've got to save it away ASAP. |
77 | We ensure r7 points to a valid FDT, just in case the bootloader | 81 | We ensure r7 points to a valid FDT, just in case the bootloader |
78 | is broken or non-existent */ | 82 | is broken or non-existent */ |
79 | beqi r7, no_fdt_arg /* NULL pointer? don't copy */ | 83 | beqi r7, no_fdt_arg /* NULL pointer? don't copy */ |
80 | lw r11, r0, r7 /* Does r7 point to a */ | 84 | /* Does r7 point to a valid FDT? Load HEADER magic number */ |
81 | rsubi r11, r11, OF_DT_HEADER /* valid FDT? */ | 85 | /* Run time Big/Little endian platform */ |
86 | /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */ | ||
87 | lbui r11, r0, TOPHYS(endian_check) | ||
88 | beqid r11, big_endian /* DO NOT break delay stop dependency */ | ||
89 | lw r11, r0, r7 /* Big endian load in delay slot */ | ||
90 | lwr r11, r0, r7 /* Little endian load */ | ||
91 | big_endian: | ||
92 | rsubi r11, r11, OF_DT_HEADER /* Check FDT header */ | ||
82 | beqi r11, _prepare_copy_fdt | 93 | beqi r11, _prepare_copy_fdt |
83 | or r7, r0, r0 /* clear R7 when not valid DTB */ | 94 | or r7, r0, r0 /* clear R7 when not valid DTB */ |
84 | bnei r11, no_fdt_arg /* No - get out of here */ | 95 | bnei r11, no_fdt_arg /* No - get out of here */ |
@@ -213,26 +224,26 @@ start_here: | |||
213 | #endif /* CONFIG_MMU */ | 224 | #endif /* CONFIG_MMU */ |
214 | 225 | ||
215 | /* Initialize small data anchors */ | 226 | /* Initialize small data anchors */ |
216 | la r13, r0, _KERNEL_SDA_BASE_ | 227 | addik r13, r0, _KERNEL_SDA_BASE_ |
217 | la r2, r0, _KERNEL_SDA2_BASE_ | 228 | addik r2, r0, _KERNEL_SDA2_BASE_ |
218 | 229 | ||
219 | /* Initialize stack pointer */ | 230 | /* Initialize stack pointer */ |
220 | la r1, r0, init_thread_union + THREAD_SIZE - 4 | 231 | addik r1, r0, init_thread_union + THREAD_SIZE - 4 |
221 | 232 | ||
222 | /* Initialize r31 with current task address */ | 233 | /* Initialize r31 with current task address */ |
223 | la r31, r0, init_task | 234 | addik r31, r0, init_task |
224 | 235 | ||
225 | /* | 236 | /* |
226 | * Call platform dependent initialize function. | 237 | * Call platform dependent initialize function. |
227 | * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for | 238 | * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for |
228 | * the function. | 239 | * the function. |
229 | */ | 240 | */ |
230 | la r9, r0, machine_early_init | 241 | addik r9, r0, machine_early_init |
231 | brald r15, r9 | 242 | brald r15, r9 |
232 | nop | 243 | nop |
233 | 244 | ||
234 | #ifndef CONFIG_MMU | 245 | #ifndef CONFIG_MMU |
235 | la r15, r0, machine_halt | 246 | addik r15, r0, machine_halt |
236 | braid start_kernel | 247 | braid start_kernel |
237 | nop | 248 | nop |
238 | #else | 249 | #else |