source: rtems-docs/porting/miscellanous.rst @ f916fca

4.115
Last change on this file since f916fca was d389819, checked in by Amar Takhar <amar@…>, on 01/18/16 at 05:37:40

Convert all Unicode to ASCII(128)

  • Property mode set to 100644
File size: 6.6 KB
Line 
1Miscellaneous
2#############
3
4Fatal Error Default Handler
5===========================
6
7The ``_CPU_Fatal_halt`` routine is the default fatal error handler. This
8routine copies _error into a known place - typically a stack location or
9a register, optionally disables interrupts, and halts/stops the CPU.  It
10is prototyped as follows and is often implemented as a macro:
11.. code:: c
12
13    void _CPU_Fatal_halt(
14    unsigned32 _error
15    );
16
17CPU Context Validation
18======================
19
20The test case ``sptests/spcontext01`` ensures that the context switching and
21interrupt processing works.  This test uses two support functions provided by
22the CPU port.  These two functions are only used for this test and have no
23other purpose.
24.. code:: c
25
26    void _CPU_Context_volatile_clobber( uintptr_t pattern );
27    void _CPU_Context_validate( uintptr_t pattern );
28
29The ``_CPU_Context_volatile_clobber()`` function clobbers all volatile
30registers with values derived from the pattern parameter.  This makes sure that
31the interrupt prologue code restores all volatile registers of the interrupted
32context.
33
34The ``_CPU_Context_validate()`` function initializes and validates the CPU
35context with values derived from the pattern parameter.  This function will not
36return if the CPU context remains consistent.  In case this function returns
37the CPU port is broken.  The test uses two threads which concurrently validate
38the CPU context with a different patterns for each thread.  This ensures that
39the context switching code works.
40
41Processor Endianness
42====================
43
44Endianness refers to the order in which numeric values are stored in
45memory by the microprocessor.  Big endian architectures store the most
46significant byte of a multi-byte numeric value in the byte with the lowest
47address.  This results in the hexadecimal value 0x12345678 being stored as
480x12345678 with 0x12 in the byte at offset zero, 0x34 in the byte at
49offset one, etc..  The Motorola M68K and numerous RISC processor families
50is big endian.  Conversely, little endian architectures store the least
51significant byte of a multi-byte numeric value in the byte with the lowest
52address.  This results in the hexadecimal value 0x12345678 being stored as
530x78563412 with 0x78 in the byte at offset zero, 0x56 in the byte at
54offset one, etc..  The Intel ix86 family is little endian.
55Interestingly, some CPU models within the PowerPC and MIPS architectures
56can be switched between big and little endian modes.  Most embedded
57systems use these families strictly in big endian mode.
58
59RTEMS must be informed of the byte ordering for this microprocessor family
60and, optionally, endian conversion routines may be provided as part of the
61port.  Conversion between endian formats is often necessary in
62multiprocessor environments and sometimes needed when interfacing with
63peripheral controllers.
64
65Specifying Processor Endianness
66-------------------------------
67
68The ``CPU_BIG_ENDIAN`` and ``CPU_LITTLE_ENDIAN`` are
69set to specify the endian
70format used by this microprocessor.  These macros should not be set to the
71same value.  The following example illustrates how these macros should be
72set on a processor family that is big endian.
73.. code:: c
74
75    #define CPU_BIG_ENDIAN                           TRUE
76    #define CPU_LITTLE_ENDIAN                        FALSE
77
78The ``CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK`` macro is set to the amount of
79stack space above the minimum thread stack space required by the MPCI
80Receive Server Thread.  This macro is needed because in a multiprocessor
81system the MPCI Receive Server Thread must be able to process all
82directives.
83.. code:: c
84
85    #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
86
87Endian Swap Unsigned Integers
88-----------------------------
89
90The port should provide routines to swap sixteen (``CPU_swap_u16``) and
91thirty-bit (``CPU_swap_u32``) unsigned integers.  These are primarily used in
92two areas of RTEMS - multiprocessing support and the network endian swap
93routines.  The ``CPU_swap_u32`` routine must be implemented as a static
94routine rather than a macro because its address is taken and used
95indirectly.  On the other hand, the ``CPU_swap_u16`` routine may be
96implemented as a macro.
97
98Some CPUs have special instructions that swap a 32-bit quantity in a
99single instruction (e.g. i486).  It is probably best to avoid an "endian
100swapping control bit" in the CPU.  One good reason is that interrupts
101would probably have to be disabled to insure that an interrupt does not
102try to access the same "chunk" with the wrong endian.  Another good reason
103is that on some CPUs, the endian bit endianness for ALL fetches - both
104code and data - so the code will be fetched incorrectly.
105
106The following is an implementation of the ``CPU_swap_u32`` routine that will
107work on any CPU.  It operates by breaking the unsigned thirty-two bit
108integer into four byte-wide quantities and reassemblying them.
109.. code:: c
110
111    static inline unsigned int CPU_swap_u32(
112    unsigned int value
113    )
114    {
115    unsigned32 byte1, byte2, byte3, byte4, swapped;
116    byte4 = (value >> 24) & 0xff;
117    byte3 = (value >> 16) & 0xff;
118    byte2 = (value >> 8)  & 0xff;
119    byte1 =  value        & 0xff;
120    swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
121    return( swapped );
122    }
123
124Although the above implementation is portable, it is not particularly
125efficient.  So if there is a better way to implement this on a particular
126CPU family or model, please do so.  The efficiency of this routine has
127significant impact on the efficiency of the multiprocessing support code
128in the shared memory driver and in network applications using the ntohl()
129family of routines.
130
131Most microprocessor families have rotate instructions which can be used to
132greatly improve the ``CPU_swap_u32`` routine.  The most common
133way to do this is to:
134.. code:: c
135
136    swap least significant two bytes with 16-bit rotate
137    swap upper and lower 16-bits
138    swap most significant two bytes with 16-bit rotate
139
140Some CPUs have special instructions that swap a 32-bit quantity in a
141single instruction (e.g. i486).  It is probably best to avoid an "endian
142swapping control bit" in the CPU.  One good reason is that interrupts
143would probably have to be disabled to insure that an interrupt does not
144try to access the same "chunk" with the wrong endian.  Another good reason
145is that on some CPUs, the endian bit endianness for ALL fetches - both
146code and data - so the code will be fetched incorrectly.
147
148Similarly, here is a portable implementation of the ``CPU_swap_u16``
149routine.  Just as with the ``CPU_swap_u32`` routine, the porter
150should provide a better implementation if possible.
151.. code:: c
152
153    #define CPU_swap_u16( value ) \\
154    (((value&0xff) << 8) | ((value >> 8)&0xff))
155
Note: See TracBrowser for help on using the repository browser.