Print this page
_locore_start needs to set up an 8-byte aligned stack
Sadly, during removal of special early-boot stacks
(027eb01d0ff8f66be55208b58ecd7cb2b7b27714) the stack passed into mlsetup
lost its 8-byte aligned-ness.
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/armv6/ml/glocore.s
+++ new/usr/src/uts/armv6/ml/glocore.s
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2013 (c) Joyent, Inc. All rights reserved.
14 14 */
15 15
16 16 #include <sys/asm_linkage.h>
17 17 #include <sys/machparam.h>
18 18 #include <sys/cpu_asm.h>
19 19
20 20 #include "assym.h"
21 21
22 22 #if defined(__lint)
23 23
24 24 #endif
25 25
26 26 /*
27 27 * Each of the different machines has its own locore.s to take care of getting
28 28 * us into fakebop for the first time. After that, they all return here to a
29 29 * generic locore to take us into mlsetup and then to main forever more.
30 30 */
31 31
32 32 /*
33 33 * External globals
34 34 */
35 35 .globl _locore_start
36 36 .globl mlsetup
37 37 .globl sysp
38 38 .globl bootops
39 39 .globl bootopsp
40 40 .globl t0
41 41
42 42 .data
43 43 .comm t0stack, DEFAULTSTKSZ, 32
44 44 .comm t0, 4094, 32
45 45
46 46 #if defined(__lint)
47 47
48 48 /* ARGSUSED */
49 49 void
50 50 _locore_start(struct boot_syscalls *sysp, struct bootops *bop)
51 51 {}
52 52
53 53 #else /* __lint */
54 54
55 55 /*
56 56 * We got here from _kobj_init() via exitto(). We have a few different
57 57 * tasks that we need to take care of before we hop into mlsetup and
58 58 * then main. We're never going back so we shouldn't feel compelled to
59 59 * preserve any registers.
60 60 *
61 61 * o Enable unaligned access
62 62 * o Enable our I/D-caches
63 63 * o Save the boot syscalls and bootops for later
64 64 * o Set up our stack to be the real stack of t0stack.
65 65 * o Save t0 as curthread
66 66 * o Set up a struct REGS for mlsetup
67 67 * o Make sure that we're 8 byte aligned for the call
68 68 */
69 69
70 70 ENTRY(_locore_start)
71 71
72 72
73 73 /*
74 74 * We've been running in t0stack anyway, up to this point, but
75 75 * _locore_start represents what is in effect a fresh start in the
76 76 * real kernel -- We'll never return back through here.
77 77 *
78 78 * So reclaim those few bytes
79 79 */
80 80 ldr sp, =t0stack
81 81 ldr r4, =(DEFAULTSTKSZ - REGSIZE)
82 82 add sp, r4
83 83 bic sp, sp, #0xff
84 84
85 85 /*
86 86 * Save flags and arguments for potential debugging
87 87 */
88 88 str r0, [sp, #REGOFF_R0]
89 89 str r1, [sp, #REGOFF_R1]
90 90 str r2, [sp, #REGOFF_R2]
91 91 str r3, [sp, #REGOFF_R3]
92 92 mrs r4, CPSR
93 93 str r4, [sp, #REGOFF_CPSR]
94 94
95 95 /*
96 96 * Save back the bootops and boot_syscalls.
97 97 */
98 98 ldr r2, =sysp
99 99 str r0, [r2]
100 100 ldr r2, =bootops
101 101 str r1, [r2]
102 102 ldr r2, =bootopsp
103 103 ldr r2, [r2]
104 104 str r1, [r2]
105 105
106 106 /*
107 107 * Set up our curthread pointer
108 108 */
109 109 ldr r0, =t0
110 110 mcr p15, 0, r0, c13, c0, 4
111 111
112 112 /*
113 113 * Go ahead now and enable unaligned access, the L1 I/D caches.
114 114 *
115 115 * Bit 2 is for the D cache
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
116 116 * Bit 12 is for the I cache
117 117 * Bit 22 is for unaligned access
118 118 */
119 119 mrc p15, 0, r0, c1, c0, 0
120 120 orr r0, #0x02
121 121 orr r0, #0x1000
122 122 orr r0, #0x400000
123 123 mcr p15, 0, r0, c1, c0, 0
124 124
125 125 /*
126 - * mlsetup() takes the struct regs as an argument. main doesn't take any
127 - * and should never return. After the push below, we should have a
128 - * 8-byte aligned stack pointer. This is why we subtracted four earlier
129 - * on if we were 8-byte aligned.
126 + * mlsetup() takes the struct regs as an argument. main doesn't take
127 + * any and should never return. Currently, we have an 8-byte aligned
128 + * stack. We want to push a zero frame pointer to terminate any
129 + * stack walking, but that would cause us to end up with only a
130 + * 4-byte aligned stack. So, to keep things nice and correct, we
131 + * push a zero value twice - it's similar to a typical function
132 + * entry:
133 + * push { r9, lr }
130 134 */
131 135 mov r9,#0
132 - push { r9 }
136 + push { r9 } /* link register */
137 + push { r9 } /* frame pointer */
133 138 mov r0, sp
134 139 bl mlsetup
135 140 bl main
136 141 /* NOTREACHED */
137 142 ldr r0,=__return_from_main
138 143 ldr r0,[r0]
139 144 bl panic
140 145 SET_SIZE(_locore_start)
141 146
142 147 __return_from_main:
143 148 .string "main() returned"
144 149 #endif /* __lint */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX