source: rtems-docs/porting/miscellanous.rst @ 9aafb39

4.115
Last change on this file since 9aafb39 was b0f2977, checked in by Joel Sherrill <joel@…>, on 10/28/16 at 01:01:47

porting: Fix code-block markup

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