source: rtems/doc/porting/miscellaneous.t @ 9847d61d

4.115
Last change on this file since 9847d61d was fae9d83, checked in by Ralf Corsepius <ralf.corsepius@…>, on 05/09/07 at 15:34:26

2007-05-09 Ralf Corsépius <ralf.corsepius@…>

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