Commit | Line | Data |
---|---|---|
fdabf525 JH |
1 | ========================== |
2 | KERNEL ABIS FOR METAG ARCH | |
3 | ========================== | |
4 | ||
5 | This document describes the Linux ABIs for the metag architecture, and has the | |
6 | following sections: | |
7 | ||
8 | (*) Outline of registers | |
9 | (*) Userland registers | |
10 | (*) Kernel registers | |
11 | (*) System call ABI | |
12 | (*) Calling conventions | |
13 | ||
14 | ||
15 | ==================== | |
16 | OUTLINE OF REGISTERS | |
17 | ==================== | |
18 | ||
19 | The main Meta core registers are arranged in units: | |
20 | ||
21 | UNIT Type DESCRIPTION GP EXT PRIV GLOBAL | |
22 | ======= ======= =============== ======= ======= ======= ======= | |
23 | CT Special Control unit | |
24 | D0 General Data unit 0 0-7 8-15 16-31 16-31 | |
25 | D1 General Data unit 1 0-7 8-15 16-31 16-31 | |
26 | A0 General Address unit 0 0-3 4-7 8-15 8-15 | |
27 | A1 General Address unit 1 0-3 4-7 8-15 8-15 | |
28 | PC Special PC unit 0 1 | |
29 | PORT Special Ports | |
30 | TR Special Trigger unit 0-7 | |
31 | TT Special Trace unit 0-5 | |
32 | FX General FP unit 0-15 | |
33 | ||
34 | GP registers form part of the main context. | |
35 | ||
36 | Extended context registers (EXT) may not be present on all hardware threads and | |
37 | can be context switched if support is enabled and the appropriate bits are set | |
38 | in e.g. the D0.8 register to indicate what extended state to preserve. | |
39 | ||
40 | Global registers are shared between threads and are privilege protected. | |
41 | ||
42 | See arch/metag/include/asm/metag_regs.h for definitions relating to core | |
43 | registers and the fields and bits they contain. See the TRMs for further details | |
44 | about special registers. | |
45 | ||
46 | Several special registers are preserved in the main context, these are the | |
47 | interesting ones: | |
48 | ||
49 | REG (ALIAS) PURPOSE | |
50 | ======================= =============================================== | |
51 | CT.1 (TXMODE) Processor mode bits (particularly for DSP) | |
52 | CT.2 (TXSTATUS) Condition flags and LSM_STEP (MGET/MSET step) | |
53 | CT.3 (TXRPT) Branch repeat counter | |
54 | PC.0 (PC) Program counter | |
55 | ||
56 | Some of the general registers have special purposes in the ABI and therefore | |
57 | have aliases: | |
58 | ||
59 | D0 REG (ALIAS) PURPOSE D1 REG (ALIAS) PURPOSE | |
60 | =============== =============== =============== ======================= | |
61 | D0.0 (D0Re0) 32bit result D1.0 (D1Re0) Top half of 64bit result | |
62 | D0.1 (D0Ar6) Argument 6 D1.1 (D1Ar5) Argument 5 | |
63 | D0.2 (D0Ar4) Argument 4 D1.2 (D1Ar3) Argument 3 | |
64 | D0.3 (D0Ar2) Argument 2 D1.3 (D1Ar1) Argument 1 | |
65 | D0.4 (D0FrT) Frame temp D1.4 (D1RtP) Return pointer | |
66 | D0.5 Call preserved D1.5 Call preserved | |
67 | D0.6 Call preserved D1.6 Call preserved | |
68 | D0.7 Call preserved D1.7 Call preserved | |
69 | ||
70 | A0 REG (ALIAS) PURPOSE A1 REG (ALIAS) PURPOSE | |
71 | =============== =============== =============== ======================= | |
72 | A0.0 (A0StP) Stack pointer A1.0 (A1GbP) Global base pointer | |
73 | A0.1 (A0FrP) Frame pointer A1.1 (A1LbP) Local base pointer | |
74 | A0.2 A1.2 | |
75 | A0.3 A1.3 | |
76 | ||
77 | ||
78 | ================== | |
79 | USERLAND REGISTERS | |
80 | ================== | |
81 | ||
82 | All the general purpose D0, D1, A0, A1 registers are preserved when entering the | |
83 | kernel (including asynchronous events such as interrupts and timer ticks) except | |
84 | the following which have special purposes in the ABI: | |
85 | ||
86 | REGISTERS WHEN STATUS PURPOSE | |
87 | =============== ======= =============== =============================== | |
88 | D0.8 DSP Preserved ECH, determines what extended | |
89 | DSP state to preserve. | |
90 | A0.0 (A0StP) ALWAYS Preserved Stack >= A0StP may be clobbered | |
91 | at any time by the creation of a | |
92 | signal frame. | |
93 | A1.0 (A1GbP) SMP Clobbered Used as temporary for loading | |
94 | kernel stack pointer and saving | |
95 | core context. | |
96 | A0.15 !SMP Protected Stores kernel stack pointer. | |
97 | A1.15 ALWAYS Protected Stores kernel base pointer. | |
98 | ||
99 | On UP A0.15 is used to store the kernel stack pointer for storing the userland | |
100 | context. A0.15 is global between hardware threads though which means it cannot | |
101 | be used on SMP for this purpose. Since no protected local registers are | |
102 | available A1GbP is reserved for use as a temporary to allow a percpu stack | |
103 | pointer to be loaded for storing the rest of the context. | |
104 | ||
105 | ||
106 | ================ | |
107 | KERNEL REGISTERS | |
108 | ================ | |
109 | ||
110 | When in the kernel the following registers have special purposes in the ABI: | |
111 | ||
112 | REGISTERS WHEN STATUS PURPOSE | |
113 | =============== ======= =============== =============================== | |
114 | A0.0 (A0StP) ALWAYS Preserved Stack >= A0StP may be clobbered | |
115 | at any time by the creation of | |
116 | an irq signal frame. | |
117 | A1.0 (A1GbP) ALWAYS Preserved Reserved (kernel base pointer). | |
118 | ||
119 | ||
120 | =============== | |
121 | SYSTEM CALL ABI | |
122 | =============== | |
123 | ||
124 | When a system call is made, the following registers are effective: | |
125 | ||
126 | REGISTERS CALL RETURN | |
127 | =============== ======================= =============================== | |
128 | D0.0 (D0Re0) Return value (or -errno) | |
129 | D1.0 (D1Re0) System call number Clobbered | |
130 | D0.1 (D0Ar6) Syscall arg #6 Preserved | |
131 | D1.1 (D1Ar5) Syscall arg #5 Preserved | |
132 | D0.2 (D0Ar4) Syscall arg #4 Preserved | |
133 | D1.2 (D1Ar3) Syscall arg #3 Preserved | |
134 | D0.3 (D0Ar2) Syscall arg #2 Preserved | |
135 | D1.3 (D1Ar1) Syscall arg #1 Preserved | |
136 | ||
137 | Due to the limited number of argument registers and some system calls with badly | |
138 | aligned 64-bit arguments, 64-bit values are always packed in consecutive | |
139 | arguments, even if this is contrary to the normal calling conventions (where the | |
140 | two halves would go in a matching pair of data registers). | |
141 | ||
142 | For example fadvise64_64 usually has the signature: | |
143 | ||
144 | long sys_fadvise64_64(i32 fd, i64 offs, i64 len, i32 advice); | |
145 | ||
146 | But for metag fadvise64_64 is wrapped so that the 64-bit arguments are packed: | |
147 | ||
148 | long sys_fadvise64_64_metag(i32 fd, i32 offs_lo, | |
149 | i32 offs_hi, i32 len_lo, | |
150 | i32 len_hi, i32 advice) | |
151 | ||
152 | So the arguments are packed in the registers like this: | |
153 | ||
154 | D0 REG (ALIAS) VALUE D1 REG (ALIAS) VALUE | |
155 | =============== =============== =============== ======================= | |
156 | D0.1 (D0Ar6) advice D1.1 (D1Ar5) hi(len) | |
157 | D0.2 (D0Ar4) lo(len) D1.2 (D1Ar3) hi(offs) | |
158 | D0.3 (D0Ar2) lo(offs) D1.3 (D1Ar1) fd | |
159 | ||
160 | ||
161 | =================== | |
162 | CALLING CONVENTIONS | |
163 | =================== | |
164 | ||
165 | These calling conventions apply to both user and kernel code. The stack grows | |
166 | from low addresses to high addresses in the metag ABI. The stack pointer (A0StP) | |
167 | should always point to the next free address on the stack and should at all | |
168 | times be 64-bit aligned. The following registers are effective at the point of a | |
169 | call: | |
170 | ||
171 | REGISTERS CALL RETURN | |
172 | =============== ======================= =============================== | |
173 | D0.0 (D0Re0) 32bit return value | |
174 | D1.0 (D1Re0) Upper half of 64bit return value | |
175 | D0.1 (D0Ar6) 32bit argument #6 Clobbered | |
176 | D1.1 (D1Ar5) 32bit argument #5 Clobbered | |
177 | D0.2 (D0Ar4) 32bit argument #4 Clobbered | |
178 | D1.2 (D1Ar3) 32bit argument #3 Clobbered | |
179 | D0.3 (D0Ar2) 32bit argument #2 Clobbered | |
180 | D1.3 (D1Ar1) 32bit argument #1 Clobbered | |
181 | D0.4 (D0FrT) Clobbered | |
182 | D1.4 (D1RtP) Return pointer Clobbered | |
183 | D{0-1}.{5-7} Preserved | |
184 | A0.0 (A0StP) Stack pointer Preserved | |
185 | A1.0 (A0GbP) Preserved | |
186 | A0.1 (A0FrP) Frame pointer Preserved | |
187 | A1.1 (A0LbP) Preserved | |
188 | A{0-1},{2-3} Clobbered | |
189 | ||
190 | 64-bit arguments are placed in matching pairs of registers (i.e. the same | |
191 | register number in both D0 and D1 units), with the least significant half in D0 | |
f884ab15 | 192 | and the most significant half in D1, leaving a gap where necessary. Further |
fdabf525 JH |
193 | arguments are stored on the stack in reverse order (earlier arguments at higher |
194 | addresses): | |
195 | ||
196 | ADDRESS 0 1 2 3 4 5 6 7 | |
197 | =============== ===== ===== ===== ===== ===== ===== ===== ===== | |
198 | A0StP --> | |
199 | A0StP-0x08 32bit argument #8 32bit argument #7 | |
200 | A0StP-0x10 32bit argument #10 32bit argument #9 | |
201 | ||
202 | Function prologues tend to look a bit like this: | |
203 | ||
204 | /* If frame pointer in use, move it to frame temp register so it can be | |
205 | easily pushed onto stack */ | |
206 | MOV D0FrT,A0FrP | |
207 | ||
208 | /* If frame pointer in use, set it to stack pointer */ | |
209 | ADD A0FrP,A0StP,#0 | |
210 | ||
211 | /* Preserve D0FrT, D1RtP, D{0-1}.{5-7} on stack, incrementing A0StP */ | |
212 | MSETL [A0StP++],D0FrT,D0.5,D0.6,D0.7 | |
213 | ||
214 | /* Allocate some stack space for local variables */ | |
215 | ADD A0StP,A0StP,#0x10 | |
216 | ||
217 | At this point the stack would look like this: | |
218 | ||
219 | ADDRESS 0 1 2 3 4 5 6 7 | |
220 | =============== ===== ===== ===== ===== ===== ===== ===== ===== | |
221 | A0StP --> | |
222 | A0StP-0x08 | |
223 | A0StP-0x10 | |
224 | A0StP-0x18 Old D0.7 Old D1.7 | |
225 | A0StP-0x20 Old D0.6 Old D1.6 | |
226 | A0StP-0x28 Old D0.5 Old D1.5 | |
227 | A0FrP --> Old A0FrP (frame ptr) Old D1RtP (return ptr) | |
228 | A0FrP-0x08 32bit argument #8 32bit argument #7 | |
229 | A0FrP-0x10 32bit argument #10 32bit argument #9 | |
230 | ||
231 | Function epilogues tend to differ depending on the use of a frame pointer. An | |
232 | example of a frame pointer epilogue: | |
233 | ||
234 | /* Restore D0FrT, D1RtP, D{0-1}.{5-7} from stack, incrementing A0FrP */ | |
235 | MGETL D0FrT,D0.5,D0.6,D0.7,[A0FrP++] | |
236 | /* Restore stack pointer to where frame pointer was before increment */ | |
237 | SUB A0StP,A0FrP,#0x20 | |
238 | /* Restore frame pointer from frame temp */ | |
239 | MOV A0FrP,D0FrT | |
240 | /* Return to caller via restored return pointer */ | |
241 | MOV PC,D1RtP | |
242 | ||
243 | If the function hasn't touched the frame pointer, MGETL cannot be safely used | |
244 | with A0StP as it always increments and that would expose the stack to clobbering | |
245 | by interrupts (kernel) or signals (user). Therefore it's common to see the MGETL | |
246 | split into separate GETL instructions: | |
247 | ||
248 | /* Restore D0FrT, D1RtP, D{0-1}.{5-7} from stack */ | |
249 | GETL D0FrT,D1RtP,[A0StP+#-0x30] | |
250 | GETL D0.5,D1.5,[A0StP+#-0x28] | |
251 | GETL D0.6,D1.6,[A0StP+#-0x20] | |
252 | GETL D0.7,D1.7,[A0StP+#-0x18] | |
253 | /* Restore stack pointer */ | |
254 | SUB A0StP,A0StP,#0x30 | |
255 | /* Return to caller via restored return pointer */ | |
256 | MOV PC,D1RtP |