1 | .. comment SPDX-License-Identifier: CC-BY-SA-4.0 |
---|
2 | |
---|
3 | .. COMMENT: Copyright (c) 2014 embedded brains GmbH. All rights reserved. |
---|
4 | |
---|
5 | M68xxx and Coldfire Specific Information |
---|
6 | ######################################## |
---|
7 | |
---|
8 | This chapter discusses the Freescale (formerly Motorola) MC68xxx and Coldfire |
---|
9 | architectural dependencies. The MC68xxx family has a wide variety of CPU |
---|
10 | models within it based upon different CPU core implementations. Ignoring the |
---|
11 | Coldfire parts, the part numbers for these models are generally divided into |
---|
12 | MC680xx and MC683xx. The MC680xx models are more general purpose processors |
---|
13 | with no integrated peripherals. The MC683xx models, on the other hand, are |
---|
14 | more specialized and have a variety of peripherals on chip including |
---|
15 | sophisticated timers and serial communications controllers. |
---|
16 | |
---|
17 | **Architecture Documents** |
---|
18 | |
---|
19 | For information on the MC68xxx and Coldfire architecture, refer to the |
---|
20 | following documents available from Freescale website |
---|
21 | (http//www.freescale.com/): |
---|
22 | |
---|
23 | - *M68000 Family Reference, Motorola, FR68K/D*. |
---|
24 | |
---|
25 | - *MC68020 User's Manual, Motorola, MC68020UM/AD*. |
---|
26 | |
---|
27 | - *MC68881/MC68882 Floating-Point Coprocessor User's Manual, |
---|
28 | Motorola, MC68881UM/AD*. |
---|
29 | |
---|
30 | CPU Model Dependent Features |
---|
31 | ============================ |
---|
32 | |
---|
33 | This section presents the set of features which vary across m68k/Coldfire |
---|
34 | implementations that are of importance to RTEMS. The set of CPU model feature |
---|
35 | macros are defined in the file :file:`cpukit/score/cpu/m68k/m68k.h` based upon |
---|
36 | the particular CPU model selected on the compilation command line. |
---|
37 | |
---|
38 | BFFFO Instruction |
---|
39 | ----------------- |
---|
40 | |
---|
41 | The macro ``M68K_HAS_BFFFO`` is set to 1 to indicate that this CPU model has |
---|
42 | the bfffo instruction. |
---|
43 | |
---|
44 | Vector Base Register |
---|
45 | -------------------- |
---|
46 | |
---|
47 | The macro ``M68K_HAS_VBR`` is set to 1 to indicate that this CPU model has a |
---|
48 | vector base register (vbr). |
---|
49 | |
---|
50 | Separate Stacks |
---|
51 | --------------- |
---|
52 | |
---|
53 | The macro ``M68K_HAS_SEPARATE_STACKS`` is set to 1 to indicate that this CPU |
---|
54 | model has separate interrupt, user, and supervisor mode stacks. |
---|
55 | |
---|
56 | Pre-Indexing Address Mode |
---|
57 | ------------------------- |
---|
58 | |
---|
59 | The macro ``M68K_HAS_PREINDEXING`` is set to 1 to indicate that this CPU model |
---|
60 | has the pre-indexing address mode. |
---|
61 | |
---|
62 | Extend Byte to Long Instruction |
---|
63 | ------------------------------- |
---|
64 | |
---|
65 | The macro ``M68K_HAS_EXTB_L`` is set to 1 to indicate that this CPU model has |
---|
66 | the extb.l instruction. This instruction is supposed to be available in all |
---|
67 | models based on the cpu32 core as well as mc68020 and up models. |
---|
68 | |
---|
69 | Calling Conventions |
---|
70 | =================== |
---|
71 | |
---|
72 | The MC68xxx architecture supports a simple yet effective call and return |
---|
73 | mechanism. A subroutine is invoked via the branch to subroutine (``bsr``) or |
---|
74 | the jump to subroutine (``jsr``) instructions. These instructions push the |
---|
75 | return address on the current stack. The return from subroutine (``rts``) |
---|
76 | instruction pops the return address off the current stack and transfers control |
---|
77 | to that instruction. It is is important to note that the MC68xxx call and |
---|
78 | return mechanism does not automatically save or restore any registers. It is |
---|
79 | the responsibility of the high-level language compiler to define the register |
---|
80 | preservation and usage convention. |
---|
81 | |
---|
82 | Calling Mechanism |
---|
83 | ----------------- |
---|
84 | |
---|
85 | All RTEMS directives are invoked using either a ``bsr`` or ``jsr`` instruction |
---|
86 | and return to the user application via the rts instruction. |
---|
87 | |
---|
88 | Register Usage |
---|
89 | -------------- |
---|
90 | |
---|
91 | As discussed above, the ``bsr`` and ``jsr`` instructions do not automatically |
---|
92 | save any registers. RTEMS uses the registers D0, D1, A0, and A1 as scratch |
---|
93 | registers. These registers are not preserved by RTEMS directives therefore, |
---|
94 | the contents of these registers should not be assumed upon return from any |
---|
95 | RTEMS directive. |
---|
96 | |
---|
97 | Parameter Passing |
---|
98 | ----------------- |
---|
99 | |
---|
100 | RTEMS assumes that arguments are placed on the current stack before the |
---|
101 | directive is invoked via the bsr or jsr instruction. The first argument is |
---|
102 | assumed to be closest to the return address on the stack. This means that the |
---|
103 | first argument of the C calling sequence is pushed last. The following |
---|
104 | pseudo-code illustrates the typical sequence used to call a RTEMS directive |
---|
105 | with three (3) arguments: |
---|
106 | |
---|
107 | .. code-block:: c |
---|
108 | |
---|
109 | push third argument |
---|
110 | push second argument |
---|
111 | push first argument |
---|
112 | invoke directive |
---|
113 | remove arguments from the stack |
---|
114 | |
---|
115 | The arguments to RTEMS are typically pushed onto the stack using a move |
---|
116 | instruction with a pre-decremented stack pointer as the destination. These |
---|
117 | arguments must be removed from the stack after control is returned to the |
---|
118 | caller. This removal is typically accomplished by adding the size of the |
---|
119 | argument list in bytes to the current stack pointer. |
---|
120 | |
---|
121 | Memory Model |
---|
122 | ============ |
---|
123 | |
---|
124 | The MC68xxx family supports a flat 32-bit address space with addresses ranging |
---|
125 | from 0x00000000 to 0xFFFFFFFF (4 gigabytes). Each address is represented by a |
---|
126 | 32-bit value and is byte addressable. The address may be used to reference a |
---|
127 | single byte, word (2-bytes), or long word (4 bytes). Memory accesses within |
---|
128 | this address space are performed in big endian fashion by the processors in |
---|
129 | this family. |
---|
130 | |
---|
131 | Some of the MC68xxx family members such as the MC68020, MC68030, and MC68040 |
---|
132 | support virtual memory and segmentation. The MC68020 requires external |
---|
133 | hardware support such as the MC68851 Paged Memory Management Unit coprocessor |
---|
134 | which is typically used to perform address translations for these systems. |
---|
135 | RTEMS does not support virtual memory or segmentation on any of the MC68xxx |
---|
136 | family members. |
---|
137 | |
---|
138 | Interrupt Processing |
---|
139 | ==================== |
---|
140 | |
---|
141 | Discussed in this section are the MC68xxx's interrupt response and control |
---|
142 | mechanisms as they pertain to RTEMS. |
---|
143 | |
---|
144 | Vectoring of an Interrupt Handler |
---|
145 | --------------------------------- |
---|
146 | |
---|
147 | Depending on whether or not the particular CPU supports a separate interrupt |
---|
148 | stack, the MC68xxx family has two different interrupt handling models. |
---|
149 | |
---|
150 | Models Without Separate Interrupt Stacks |
---|
151 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
152 | |
---|
153 | Upon receipt of an interrupt the MC68xxx family members without separate |
---|
154 | interrupt stacks automatically use software to switch stacks. |
---|
155 | |
---|
156 | Models With Separate Interrupt Stacks |
---|
157 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
158 | |
---|
159 | Upon receipt of an interrupt the MC68xxx family members with separate interrupt |
---|
160 | stacks automatically perform the following actions: |
---|
161 | |
---|
162 | - saves the current status register (SR), |
---|
163 | |
---|
164 | - clears the master/interrupt (M) bit of the SR to indicate the switch from |
---|
165 | master state to interrupt state, |
---|
166 | |
---|
167 | - sets the privilege mode to supervisor, |
---|
168 | |
---|
169 | - suppresses tracing, |
---|
170 | |
---|
171 | - sets the interrupt mask level equal to the level of the interrupt being |
---|
172 | serviced, |
---|
173 | |
---|
174 | - pushes an interrupt stack frame (ISF), which includes the program counter |
---|
175 | (PC), the status register (SR), and the format/exception vector offset (FVO) |
---|
176 | word, onto the supervisor and interrupt stacks, |
---|
177 | |
---|
178 | - switches the current stack to the interrupt stack and vectors to an interrupt |
---|
179 | service routine (ISR). If the ISR was installed with the interrupt_catch |
---|
180 | directive, then the RTEMS interrupt handler will begin execution. The RTEMS |
---|
181 | interrupt handler saves all registers which are not preserved according to |
---|
182 | the calling conventions and invokes the application's ISR. |
---|
183 | |
---|
184 | A nested interrupt is processed similarly by these CPU models with the |
---|
185 | exception that only a single ISF is placed on the interrupt stack and the |
---|
186 | current stack need not be switched. |
---|
187 | |
---|
188 | The FVO word in the Interrupt Stack Frame is examined by RTEMS to determine |
---|
189 | when an outer most interrupt is being exited. Since the FVO is used by RTEMS |
---|
190 | for this purpose, the user application code MUST NOT modify this field. |
---|
191 | |
---|
192 | The following shows the Interrupt Stack Frame for MC68xxx CPU models with |
---|
193 | separate interrupt stacks: |
---|
194 | |
---|
195 | +----------------------+-----+ |
---|
196 | | Status Register | 0x0 | |
---|
197 | +----------------------+-----+ |
---|
198 | | Program Counter High | 0x2 | |
---|
199 | +----------------------+-----+ |
---|
200 | | Program Counter Low | 0x4 | |
---|
201 | +----------------------+-----+ |
---|
202 | | Format/Vector Offset | 0x6 | |
---|
203 | +----------------------+-----+ |
---|
204 | |
---|
205 | |
---|
206 | CPU Models Without VBR and RAM at 0 |
---|
207 | ----------------------------------- |
---|
208 | |
---|
209 | This is from a post by Zoltan Kocsi <zoltan@bendor.com.au> and is a nice trick |
---|
210 | in certain situations. In his words: |
---|
211 | |
---|
212 | I think somebody on this list asked about the interupt vector handling w/o VBR |
---|
213 | and RAM at 0. The usual trick is to initialise the vector table (except the |
---|
214 | first 2 two entries, of course) to point to the same location BUT you also add |
---|
215 | the vector number times 0x1000000 to them. That is, bits 31-24 contain the |
---|
216 | vector number and 23-0 the address of the common handler. Since the PC is 32 |
---|
217 | bit wide but the actual address bus is only 24, the top byte will be in the PC |
---|
218 | but will be ignored when jumping onto your routine. |
---|
219 | |
---|
220 | Then your common interrupt routine gets this info by loading the PC into some |
---|
221 | register and based on that info, you can jump to a vector in a vector table |
---|
222 | pointed by a virtual VBR: |
---|
223 | |
---|
224 | .. code-block:: c |
---|
225 | |
---|
226 | // |
---|
227 | // Real vector table at 0 |
---|
228 | // |
---|
229 | .long initial_sp |
---|
230 | .long initial_pc |
---|
231 | .long myhandler+0x02000000 |
---|
232 | .long myhandler+0x03000000 |
---|
233 | .long myhandler+0x04000000 |
---|
234 | ... |
---|
235 | .long myhandler+0xff000000 |
---|
236 | // |
---|
237 | // This handler will jump to the interrupt routine of which |
---|
238 | // the address is stored at VBR[ vector_no ] |
---|
239 | // The registers and stackframe will be intact, the interrupt |
---|
240 | // routine will see exactly what it would see if it was called |
---|
241 | // directly from the HW vector table at 0. |
---|
242 | // |
---|
243 | .comm VBR,4,2 // This defines the 'virtual' VBR |
---|
244 | // From C: extern void *VBR; |
---|
245 | myhandler: // At entry, PC contains the full vector |
---|
246 | move.l %d0,-(%sp) // Save d0 |
---|
247 | move.l %a0,-(%sp) // Save a0 |
---|
248 | lea 0(%pc),%a0 // Get the value of the PC |
---|
249 | move.l %a0,%d0 // Copy it to a data reg, d0 is VV?????? |
---|
250 | swap %d0 // Now d0 is ????VV?? |
---|
251 | and.w #0xff00,%d0 // Now d0 is ????VV00 (1) |
---|
252 | lsr.w #6,%d0 // Now d0.w contains the VBR table offset |
---|
253 | move.l VBR,%a0 // Get the address from VBR to a0 |
---|
254 | move.l (%a0,%d0.w),%a0 // Fetch the vector |
---|
255 | move.l 4(%sp),%d0 // Restore d0 |
---|
256 | move.l %a0,4(%sp) // Place target address to the stack |
---|
257 | move.l (%sp)+,%a0 // Restore a0, target address is on TOS |
---|
258 | ret // This will jump to the handler and |
---|
259 | // restore the stack |
---|
260 | |
---|
261 | (1) If 'myhandler' is guaranteed to be in the first 64K, e.g. just |
---|
262 | after the vector table then that insn is not needed. |
---|
263 | |
---|
264 | There are probably shorter ways to do this, but it I believe is enough to |
---|
265 | illustrate the trick. Optimisation is left as an exercise to the reader :-) |
---|
266 | |
---|
267 | Interrupt Levels |
---|
268 | ---------------- |
---|
269 | |
---|
270 | Eight levels (0-7) of interrupt priorities are supported by MC68xxx family |
---|
271 | members with level seven (7) being the highest priority. Level zero (0) |
---|
272 | indicates that interrupts are fully enabled. Interrupt requests for interrupts |
---|
273 | with priorities less than or equal to the current interrupt mask level are |
---|
274 | ignored. |
---|
275 | |
---|
276 | Although RTEMS supports 256 interrupt levels, the MC68xxx family only supports |
---|
277 | eight. RTEMS interrupt levels 0 through 7 directly correspond to MC68xxx |
---|
278 | interrupt levels. All other RTEMS interrupt levels are undefined and their |
---|
279 | behavior is unpredictable. |
---|
280 | |
---|
281 | Default Fatal Error Processing |
---|
282 | ============================== |
---|
283 | |
---|
284 | The default fatal error handler for this architecture disables processor |
---|
285 | interrupts to level 7, places the error code in D0, and executes a ``stop`` |
---|
286 | instruction to simulate a halt processor instruction. |
---|
287 | |
---|
288 | Symmetric Multiprocessing |
---|
289 | ========================= |
---|
290 | |
---|
291 | SMP is not supported. |
---|
292 | |
---|
293 | Thread-Local Storage |
---|
294 | ==================== |
---|
295 | |
---|
296 | Thread-local storage is supported. |
---|
297 | |
---|
298 | Board Support Packages |
---|
299 | ====================== |
---|
300 | |
---|
301 | System Reset |
---|
302 | ------------ |
---|
303 | |
---|
304 | An RTEMS based application is initiated or re-initiated when the MC68020 |
---|
305 | processor is reset. When the MC68020 is reset, the processor performs the |
---|
306 | following actions: |
---|
307 | |
---|
308 | - The tracing bits of the status register are cleared to disable tracing. |
---|
309 | |
---|
310 | - The supervisor interrupt state is entered by setting the supervisor (S) bit |
---|
311 | and clearing the master/interrupt (M) bit of the status register. |
---|
312 | |
---|
313 | - The interrupt mask of the status register is set to level 7 to effectively |
---|
314 | disable all maskable interrupts. |
---|
315 | |
---|
316 | - The vector base register (VBR) is set to zero. |
---|
317 | |
---|
318 | - The cache control register (CACR) is set to zero to disable and freeze the |
---|
319 | processor cache. |
---|
320 | |
---|
321 | - The interrupt stack pointer (ISP) is set to the value stored at vector 0 |
---|
322 | (bytes 0-3) of the exception vector table (EVT). |
---|
323 | |
---|
324 | - The program counter (PC) is set to the value stored at vector 1 (bytes 4-7) |
---|
325 | of the EVT. |
---|
326 | |
---|
327 | - The processor begins execution at the address stored in the PC. |
---|
328 | |
---|
329 | Processor Initialization |
---|
330 | ------------------------ |
---|
331 | |
---|
332 | The address of the application's initialization code should be stored in the |
---|
333 | first vector of the EVT which will allow the immediate vectoring to the |
---|
334 | application code. If the application requires that the VBR be some value |
---|
335 | besides zero, then it should be set to the required value at this point. All |
---|
336 | tasks share the same MC68020's VBR value. Because interrupts are enabled |
---|
337 | automatically by RTEMS as part of the context switch to the first task, the VBR |
---|
338 | MUST be set by either RTEMS of the BSP before this occurs ensure correct |
---|
339 | interrupt vectoring. If processor caching is to be utilized, then it should be |
---|
340 | enabled during the reset application initialization code. |
---|
341 | |
---|
342 | In addition to the requirements described in the Board Support Packages chapter |
---|
343 | of the Applications User's Manual for the reset code which is executed before |
---|
344 | the call to initialize executive, the MC68020 version has the following |
---|
345 | specific requirements: |
---|
346 | |
---|
347 | - Must leave the S bit of the status register set so that the MC68020 remains |
---|
348 | in the supervisor state. |
---|
349 | |
---|
350 | - Must set the M bit of the status register to remove the MC68020 from the |
---|
351 | interrupt state. |
---|
352 | |
---|
353 | - Must set the master stack pointer (MSP) such that a minimum stack size of |
---|
354 | MINIMUM_STACK_SIZE bytes is provided for the initialize executive directive. |
---|
355 | |
---|
356 | - Must initialize the MC68020's vector table. |
---|