source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h @ 1869bb7

4.11
Last change on this file since 1869bb7 was 1869bb7, checked in by Sebastian Huber <sebastian.huber@…>, on May 18, 2012 at 1:47:23 PM

powerpc: Simplify context switch

PowerPC cores with the SPE (Signal Processing Extension) have 64-bit
general-purpose registers. The SPE context switch code has been merged
with the standard context switch code. The context switch may use cache
operations to increase the performance. It will be ensured that the
context is 32-byte aligned (PPC_DEFAULT_CACHE_LINE_SIZE). This
increases the overall memory size of the context area in the thread
control block slightly. The general-purpose registers GPR2 and GPR13
are no longer part of the context. The BSP must initialize these
registers during startup (usually initialized by the eabi() function).

The new BSP option BSP_USE_DATA_CACHE_BLOCK_TOUCH can be used to enable
the dcbt instruction in the context switch.

The new BSP option BSP_USE_SYNC_IN_CONTEXT_SWITCH can be used to enable
sync and isync instructions in the context switch. This should be not
necessary in most cases.

  • Property mode set to 100644
File size: 16.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ppc_exc
5 * @ingroup ppc_exc_frame
6 *
7 * @brief PowerPC Exceptions API.
8 */
9
10/*
11 * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
12 *                    Canon Centre Recherche France.
13 *
14 * Copyright (C) 2007 Till Straumann <strauman@slac.stanford.edu>
15 *
16 * Copyright (C) 2009 embedded brains GmbH.
17 *
18 * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
19 * to support 603, 603e, 604, 604e exceptions
20 *
21 * Moved to "libcpu/powerpc/new-exceptions" and consolidated
22 * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
23 * to be common for all PPCs with new exceptions.
24 *
25 * Derived from file "libcpu/powerpc/new-exceptions/raw_exception.h".
26 * Derived from file "libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_bspsupp.h".
27 *
28 * The license and distribution terms for this file may be
29 * found in the file LICENSE in this distribution or at
30 * http://www.rtems.com/license/LICENSE.
31 */
32
33/* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */
34
35#ifndef LIBCPU_VECTORS_H
36#define LIBCPU_VECTORS_H
37
38#include <libcpu/powerpc-utility.h>
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44/**
45 * @defgroup ppc_exc PowerPC Exceptions
46 *
47 * @brief XXX
48 *
49 * @{
50 */
51
52#define ASM_RESET_VECTOR                     0x01
53#define ASM_MACH_VECTOR                      0x02
54#define ASM_PROT_VECTOR                      0x03
55#define ASM_ISI_VECTOR                       0x04
56#define ASM_EXT_VECTOR                       0x05
57#define ASM_ALIGN_VECTOR                     0x06
58#define ASM_PROG_VECTOR                      0x07
59#define ASM_FLOAT_VECTOR                     0x08
60#define ASM_DEC_VECTOR                       0x09
61#define ASM_SYS_VECTOR                       0x0C
62#define ASM_TRACE_VECTOR                     0x0D
63
64#define ASM_PPC405_APU_UNAVAIL_VECTOR        ASM_60X_VEC_ASSIST_VECTOR
65
66#define ASM_8XX_FLOATASSIST_VECTOR           0x0E
67#define ASM_8XX_SOFTEMUL_VECTOR              0x10
68#define ASM_8XX_ITLBMISS_VECTOR              0x11
69#define ASM_8XX_DTLBMISS_VECTOR              0x12
70#define ASM_8XX_ITLBERROR_VECTOR             0x13
71#define ASM_8XX_DTLBERROR_VECTOR             0x14
72#define ASM_8XX_DBREAK_VECTOR                0x1C
73#define ASM_8XX_IBREAK_VECTOR                0x1D
74#define ASM_8XX_PERIFBREAK_VECTOR            0x1E
75#define ASM_8XX_DEVPORT_VECTOR               0x1F
76
77#define ASM_5XX_FLOATASSIST_VECTOR           0x0E
78#define ASM_5XX_SOFTEMUL_VECTOR              0x10
79#define ASM_5XX_IPROT_VECTOR                 0x13
80#define ASM_5XX_DPROT_VECTOR                 0x14
81#define ASM_5XX_DBREAK_VECTOR                0x1C
82#define ASM_5XX_IBREAK_VECTOR                0x1D
83#define ASM_5XX_MEBREAK_VECTOR               0x1E
84#define ASM_5XX_NMEBREAK_VECTOR              0x1F
85
86#define ASM_60X_VEC_VECTOR                   0x0A
87#define ASM_60X_PERFMON_VECTOR               0x0F
88#define ASM_60X_IMISS_VECTOR                 0x10
89#define ASM_60X_DLMISS_VECTOR                0x11
90#define ASM_60X_DSMISS_VECTOR                0x12
91#define ASM_60X_ADDR_VECTOR                  0x13
92#define ASM_60X_SYSMGMT_VECTOR               0x14
93#define ASM_60X_VEC_ASSIST_VECTOR            0x16
94#define ASM_60X_ITM_VECTOR                   0x17
95
96/* Book E */
97#define ASM_BOOKE_CRIT_VECTOR                0x01
98/* We could use the std. decrementer vector # on bookE, too,
99 * but the bookE decrementer has slightly different semantics
100 * so we use a different vector (which happens to be
101 * the PIT vector on the 405 which is like the booke decrementer)
102 */
103#define ASM_BOOKE_DEC_VECTOR                 0x10
104#define ASM_BOOKE_ITLBMISS_VECTOR            0x11
105#define ASM_BOOKE_DTLBMISS_VECTOR            0x12
106#define ASM_BOOKE_FIT_VECTOR                 0x13
107#define ASM_BOOKE_WDOG_VECTOR                0x14
108#define ASM_BOOKE_APU_VECTOR                 0x18
109#define ASM_BOOKE_DEBUG_VECTOR               ASM_TRACE_VECTOR
110
111/* e200 and e500 */
112#define ASM_E500_SPE_UNAVAILABLE_VECTOR      ASM_60X_VEC_VECTOR
113#define ASM_E500_EMB_FP_DATA_VECTOR          0x19
114#define ASM_E500_EMB_FP_ROUND_VECTOR         0x1A
115#define ASM_E500_PERFMON_VECTOR              ASM_60X_PERFMON_VECTOR
116
117/* e300 */
118#define ASM_E300_CRIT_VECTOR                 0x0A
119#define ASM_E300_PERFMON_VECTOR              ASM_60X_PERFMON_VECTOR
120#define ASM_E300_IMISS_VECTOR                ASM_60X_IMISS_VECTOR  /* Special case: Shadowed GPRs */
121#define ASM_E300_DLMISS_VECTOR               ASM_60X_DLMISS_VECTOR /* Special case: Shadowed GPRs */
122#define ASM_E300_DSMISS_VECTOR               ASM_60X_DSMISS_VECTOR /* Special case: Shadowed GPRs */
123#define ASM_E300_ADDR_VECTOR                 ASM_60X_ADDR_VECTOR
124#define ASM_E300_SYSMGMT_VECTOR              ASM_60X_SYSMGMT_VECTOR
125
126/*
127 * If you change that number make sure to adjust the wrapper code in ppc_exc.S
128 * and that ppc_exc_handler_table will be correctly initialized.
129 */
130#define LAST_VALID_EXC                       0x1F
131
132/* DO NOT USE -- this symbol is DEPRECATED
133 * (only used by libbsp/shared/vectors/vectors.S
134 * which should not be used by new BSPs).
135 */
136#define ASM_60X_VEC_VECTOR_OFFSET            0xf20
137
138#define ASM_PPC405_FIT_VECTOR_OFFSET         0x1010
139#define ASM_PPC405_WDOG_VECTOR_OFFSET        0x1020
140#define ASM_PPC405_TRACE_VECTOR_OFFSET       0x2000
141
142/** @} */
143
144#ifndef __SPE__
145  #define PPC_EXC_GPR_OFFSET(gpr) ((gpr) * PPC_GPR_SIZE + 36)
146  #define PPC_EXC_VECTOR_PROLOGUE_OFFSET PPC_EXC_GPR_OFFSET(4)
147  #define PPC_EXC_MINIMAL_FRAME_SIZE 96
148  #define PPC_EXC_FRAME_SIZE 176
149#else
150  #define PPC_EXC_SPEFSCR_OFFSET 36
151  #define PPC_EXC_ACC_OFFSET 40
152  #define PPC_EXC_GPR_OFFSET(gpr) ((gpr) * PPC_GPR_SIZE + 48)
153  #define PPC_EXC_VECTOR_PROLOGUE_OFFSET (PPC_EXC_GPR_OFFSET(4) + 4)
154  #define PPC_EXC_MINIMAL_FRAME_SIZE 160
155  #define PPC_EXC_FRAME_SIZE 320
156#endif
157
158/**
159 * @defgroup ppc_exc_frame PowerPC Exception Frame
160 *
161 * @brief XXX
162 *
163 * @{
164 */
165
166/*
167 * The callee (high level exception code written in C)
168 * will store the Link Registers (return address) at entry r1 + 4 !!!.
169 * So let room for it!!!.
170 */
171#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
172
173#define SRR0_FRAME_OFFSET 8
174#define SRR1_FRAME_OFFSET 12
175#define EXCEPTION_NUMBER_OFFSET 16
176#define EXC_CR_OFFSET 20
177#define EXC_CTR_OFFSET 24
178#define EXC_XER_OFFSET 28
179#define EXC_LR_OFFSET 32
180#define GPR0_OFFSET PPC_EXC_GPR_OFFSET(0)
181#define GPR1_OFFSET PPC_EXC_GPR_OFFSET(1)
182#define GPR2_OFFSET PPC_EXC_GPR_OFFSET(2)
183#define GPR3_OFFSET PPC_EXC_GPR_OFFSET(3)
184#define GPR4_OFFSET PPC_EXC_GPR_OFFSET(4)
185#define GPR5_OFFSET PPC_EXC_GPR_OFFSET(5)
186#define GPR6_OFFSET PPC_EXC_GPR_OFFSET(6)
187#define GPR7_OFFSET PPC_EXC_GPR_OFFSET(7)
188#define GPR8_OFFSET PPC_EXC_GPR_OFFSET(8)
189#define GPR9_OFFSET PPC_EXC_GPR_OFFSET(9)
190#define GPR10_OFFSET PPC_EXC_GPR_OFFSET(10)
191#define GPR11_OFFSET PPC_EXC_GPR_OFFSET(11)
192#define GPR12_OFFSET PPC_EXC_GPR_OFFSET(12)
193#define GPR13_OFFSET PPC_EXC_GPR_OFFSET(13)
194#define GPR14_OFFSET PPC_EXC_GPR_OFFSET(14)
195#define GPR15_OFFSET PPC_EXC_GPR_OFFSET(15)
196#define GPR16_OFFSET PPC_EXC_GPR_OFFSET(16)
197#define GPR17_OFFSET PPC_EXC_GPR_OFFSET(17)
198#define GPR18_OFFSET PPC_EXC_GPR_OFFSET(18)
199#define GPR19_OFFSET PPC_EXC_GPR_OFFSET(19)
200#define GPR20_OFFSET PPC_EXC_GPR_OFFSET(20)
201#define GPR21_OFFSET PPC_EXC_GPR_OFFSET(21)
202#define GPR22_OFFSET PPC_EXC_GPR_OFFSET(22)
203#define GPR23_OFFSET PPC_EXC_GPR_OFFSET(23)
204#define GPR24_OFFSET PPC_EXC_GPR_OFFSET(24)
205#define GPR25_OFFSET PPC_EXC_GPR_OFFSET(25)
206#define GPR26_OFFSET PPC_EXC_GPR_OFFSET(26)
207#define GPR27_OFFSET PPC_EXC_GPR_OFFSET(27)
208#define GPR28_OFFSET PPC_EXC_GPR_OFFSET(28)
209#define GPR29_OFFSET PPC_EXC_GPR_OFFSET(29)
210#define GPR30_OFFSET PPC_EXC_GPR_OFFSET(30)
211#define GPR31_OFFSET PPC_EXC_GPR_OFFSET(31)
212#define EXC_MSR_OFFSET PPC_EXC_GPR_OFFSET(32)
213#define EXC_DAR_OFFSET (4 + EXC_MSR_OFFSET)
214
215#define EXC_GENERIC_SIZE PPC_EXC_FRAME_SIZE
216
217#ifdef __ALTIVEC__
218#define EXC_VEC_OFFSET EXC_GENERIC_SIZE
219#ifndef PPC_CACHE_ALIGNMENT
220#error "Missing include file!"
221#endif
222/*   20 volatile registers
223 * + cache-aligned area for vcsr, vrsave
224 * + area for alignment
225 */
226#define EXC_VEC_SIZE   (16*20 + 2*PPC_CACHE_ALIGNMENT)
227#else
228#define EXC_VEC_SIZE   (0)
229#endif
230
231/* Exception stack frame -> BSP_Exception_frame */
232#define FRAME_LINK_SPACE 8
233
234/*
235 * maintain the EABI requested 8 bytes aligment
236 * As SVR4 ABI requires 16, make it 16 (as some
237 * exception may need more registers to be processed...)
238 */
239#define EXCEPTION_FRAME_END (EXC_GENERIC_SIZE + EXC_VEC_SIZE)
240
241/** @} */
242
243#ifndef ASM
244
245/**
246 * @ingroup ppc_exc_frame
247 *
248 * @{
249 */
250
251typedef struct {
252  unsigned EXC_SRR0;
253  unsigned EXC_SRR1;
254  unsigned _EXC_number;
255  unsigned EXC_CR;
256  unsigned EXC_CTR;
257  unsigned EXC_XER;
258  unsigned EXC_LR;
259  #ifdef __SPE__
260    uint32_t EXC_SPEFSCR;
261    uint64_t EXC_ACC;
262  #endif
263  PPC_GPR_TYPE GPR0;
264  PPC_GPR_TYPE GPR1;
265  PPC_GPR_TYPE GPR2;
266  PPC_GPR_TYPE GPR3;
267  PPC_GPR_TYPE GPR4;
268  PPC_GPR_TYPE GPR5;
269  PPC_GPR_TYPE GPR6;
270  PPC_GPR_TYPE GPR7;
271  PPC_GPR_TYPE GPR8;
272  PPC_GPR_TYPE GPR9;
273  PPC_GPR_TYPE GPR10;
274  PPC_GPR_TYPE GPR11;
275  PPC_GPR_TYPE GPR12;
276  PPC_GPR_TYPE GPR13;
277  PPC_GPR_TYPE GPR14;
278  PPC_GPR_TYPE GPR15;
279  PPC_GPR_TYPE GPR16;
280  PPC_GPR_TYPE GPR17;
281  PPC_GPR_TYPE GPR18;
282  PPC_GPR_TYPE GPR19;
283  PPC_GPR_TYPE GPR20;
284  PPC_GPR_TYPE GPR21;
285  PPC_GPR_TYPE GPR22;
286  PPC_GPR_TYPE GPR23;
287  PPC_GPR_TYPE GPR24;
288  PPC_GPR_TYPE GPR25;
289  PPC_GPR_TYPE GPR26;
290  PPC_GPR_TYPE GPR27;
291  PPC_GPR_TYPE GPR28;
292  PPC_GPR_TYPE GPR29;
293  PPC_GPR_TYPE GPR30;
294  PPC_GPR_TYPE GPR31;
295  unsigned EXC_MSR;
296  unsigned EXC_DAR;
297} BSP_Exception_frame;
298
299/** @} */
300
301/**
302 * @ingroup ppc_exc
303 *
304 * @{
305 */
306
307/**
308 * @brief Global exception handler type.
309 */
310typedef void (*exception_handler_t)(BSP_Exception_frame*);
311
312/**
313 * @brief Global exception handler.
314 */
315extern exception_handler_t globalExceptHdl;
316
317/**
318 * @brief Default global exception handler.
319 */
320void C_exception_handler(BSP_Exception_frame* excPtr);
321
322void BSP_printStackTrace(BSP_Exception_frame *excPtr);
323
324/**
325 * @brief Exception categories.
326 *
327 * Exceptions of different categories use different SRR registers to save the
328 * machine state and do different things in the prologue and epilogue.
329 *
330 * For now, the CPU descriptions assume this fits into 8 bits.
331 */
332typedef enum {
333  PPC_EXC_INVALID = 0,
334  PPC_EXC_ASYNC = 1,
335  PPC_EXC_CLASSIC = 2,
336  PPC_EXC_CLASSIC_ASYNC = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
337  PPC_EXC_405_CRITICAL = 4,
338  PPC_EXC_405_CRITICAL_ASYNC = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
339  PPC_EXC_BOOKE_CRITICAL = 6,
340  PPC_EXC_BOOKE_CRITICAL_ASYNC = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
341  PPC_EXC_E500_MACHCHK  = 8,
342  PPC_EXC_E500_MACHCHK_ASYNC = PPC_EXC_E500_MACHCHK | PPC_EXC_ASYNC,
343  PPC_EXC_NAKED = 10
344} ppc_exc_category;
345
346/**
347 * @brief Categorie set type.
348 */
349typedef uint8_t ppc_exc_categories [LAST_VALID_EXC + 1];
350
351static inline bool ppc_exc_is_valid_category(ppc_exc_category category)
352{
353  return (unsigned) category <= (unsigned) PPC_EXC_NAKED;
354}
355
356/**
357 * @brief Indicates if exception entry table resides in a writable memory.
358 *
359 * This variable is initialized to 'TRUE' by default;
360 * BSPs which have their vectors in ROM should set it
361 * to FALSE prior to initializing raw exceptions.
362 *
363 * I suspect the only candidate is the simulator.
364 * After all, the value of this variable is used to
365 * determine where to install the prologue code and
366 * installing to ROM on anyting that's real ROM
367 * will fail anyways.
368 *
369 * This should probably go away... (T.S. 2007/11/30)
370 */
371extern bool bsp_exceptions_in_RAM;
372
373/**
374 * @brief Vector base address for CPUs (for example e200 and e500) with IVPR
375 * and IVOR registers.
376 */
377extern uint32_t ppc_exc_vector_base;
378
379/**
380 * @brief Returns the entry address of the vector @a vector.
381 */
382void *ppc_exc_vector_address(unsigned vector);
383
384/**
385 * @brief Returns the category set for a CPU of type @a cpu, or @c NULL if
386 * there is no category set available for this CPU.
387 */
388const ppc_exc_categories *ppc_exc_categories_for_cpu(ppc_cpu_id_t cpu);
389
390/**
391 * @brief Returns the category set for the current CPU, or @c NULL if there is
392 * no category set available for this CPU.
393 */
394static inline const ppc_exc_categories *ppc_exc_current_categories(void)
395{
396  return ppc_exc_categories_for_cpu(ppc_cpu_current());
397}
398
399/**
400 * @brief Returns the category for the vector @a vector using the category set
401 * @a categories.
402 */
403ppc_exc_category ppc_exc_category_for_vector(
404  const ppc_exc_categories *categories,
405  unsigned vector
406);
407
408/**
409 * @brief Makes a minimal prologue for the vector @a vector with the category
410 * @a category.
411 *
412 * The minimal prologue will be copied to @a prologue.  Not more than @a
413 * prologue_size bytes will be copied.  Returns the actual minimal prologue
414 * size in bytes in @a prologue_size.
415 *
416 * @retval RTEMS_SUCCESSFUL Minimal prologue successfully made.
417 * @retval RTEMS_INVALID_ID Invalid vector number.
418 * @retval RTEMS_INVALID_NUMBER Invalid category.
419 * @retval RTEMS_INVALID_SIZE Prologue size to small.
420 */
421rtems_status_code ppc_exc_make_prologue(
422  unsigned vector,
423  ppc_exc_category category,
424  uint32_t *prologue,
425  size_t *prologue_size
426);
427
428/**
429 * @brief Initializes the exception handling.
430 *
431 * @retval RTEMS_SUCCESSFUL Successful initialization.
432 * @retval RTEMS_NOT_IMPLEMENTED No category set available for the current CPU.
433 * @retval RTEMS_NOT_CONFIGURED Register r13 does not point to the small data
434 * area anchor required by SVR4/EABI.
435 * @retval RTEMS_INTERNAL_ERROR Minimal prologue creation failed.
436 */
437rtems_status_code ppc_exc_initialize(
438  uint32_t interrupt_disable_mask,
439  uintptr_t interrupt_stack_begin,
440  uintptr_t interrupt_stack_size
441);
442
443/**
444 * @brief High-level exception handler type.
445 *
446 * Exception handlers should return zero if the exception was handled and
447 * normal execution may resume.
448 *
449 * They should return minus one to reject the exception resulting in the
450 * globalExcHdl() being called.
451 *
452 * Other return values are reserved.
453 */
454typedef int (*ppc_exc_handler_t)(BSP_Exception_frame *f, unsigned vector);
455
456/**
457 * @brief Bits for MSR update.
458 *
459 * Bits in MSR that are enabled during execution of exception handlers / ISRs
460 * (on classic PPC these are DR/IR/RI [default], on bookE-style CPUs they should
461 * be set to 0 during initialization)
462 *
463 * By default, the setting of these bits that is in effect when exception
464 * handling is initialized is used.
465 */
466extern uint32_t ppc_exc_msr_bits;
467
468/**
469 * @brief Cache write back check flag.
470 *
471 * (See README under CAVEATS). During initialization
472 * a check is performed to assert that write-back
473 * caching is enabled for memory accesses. If a BSP
474 * runs entirely without any caching then it should
475 * set this variable to zero prior to initializing
476 * exceptions in order to skip the test.
477 * NOTE: The code does NOT support mapping memory
478 *       with cache-attributes other than write-back
479 *       (unless the entire cache is physically disabled)
480 */
481extern uint32_t ppc_exc_cache_wb_check;
482
483/**
484 * @brief Set high-level exception handler.
485 *
486 * Hook C exception handlers.
487 *  - handlers for asynchronous exceptions run on the ISR stack
488 *    with thread-dispatching disabled.
489 *  - handlers for synchronous exceptions run on the task stack
490 *    with thread-dispatching enabled.
491 *
492 * If a particular slot is NULL then the traditional 'globalExcHdl' is used.
493 *
494 * ppc_exc_set_handler() registers a handler (returning 0 on success,
495 * -1 if the vector argument is too big).
496 *
497 * It is legal to set a NULL handler. This leads to the globalExcHdl
498 * being called if an exception for 'vector' occurs.
499 */
500rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t hdl);
501
502/**
503 * @brief Returns the currently active high-level exception handler.
504 */
505ppc_exc_handler_t ppc_exc_get_handler(unsigned vector);
506
507/**
508 * @brief Function for DAR access.
509 *
510 * CPU support may store the address of a function here
511 * that can be used by the default exception handler to
512 * obtain fault-address info which is helpful. Unfortunately,
513 * the SPR holding this information is not uniform
514 * across PPC families so we need assistance from
515 * CPU support
516 */
517extern uint32_t (*ppc_exc_get_DAR)(void);
518
519void
520ppc_exc_wrapup(BSP_Exception_frame *f);
521
522/**
523 * @brief Standard aligment handler.
524 *
525 * @retval 0 Performed a dcbz instruction.
526 * @retval -1 Otherwise.
527 */
528int ppc_exc_alignment_handler(BSP_Exception_frame *frame, unsigned excNum);
529
530/** @} */
531
532/*
533 * Compatibility with pc386
534 */
535typedef BSP_Exception_frame CPU_Exception_frame;
536typedef exception_handler_t cpuExcHandlerType;
537
538#endif /* ASM */
539
540#ifdef __cplusplus
541}
542#endif
543
544#endif /* LIBCPU_VECTORS_H */
Note: See TracBrowser for help on using the repository browser.