source: rtems/cpukit/score/cpu/lm32/include/rtems/score/cpu.h

Last change on this file was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 22.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief LM32 CPU Department Source
5 *
6 * This include file contains information pertaining to the LM32
7 * processor.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2008.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_CPU_H
20#define _RTEMS_SCORE_CPU_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#include <rtems/score/basedefs.h>
27#include <rtems/score/lm32.h>
28
29/* conditional compilation parameters */
30
31/**
32 * Does the CPU follow the simple vectored interrupt model?
33 *
34 * If TRUE, then RTEMS allocates the vector table it internally manages.
35 * If FALSE, then the BSP is assumed to allocate and manage the vector
36 * table
37 *
38 * Port Specific Information:
39 *
40 * XXX document implementation including references if appropriate
41 */
42#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
43
44/**
45 * Does the RTEMS invoke the user's ISR with the vector number and
46 * a pointer to the saved interrupt frame (1) or just the vector
47 * number (0)?
48 *
49 * Port Specific Information:
50 *
51 * XXX document implementation including references if appropriate
52 */
53#define CPU_ISR_PASSES_FRAME_POINTER TRUE
54
55#define CPU_HARDWARE_FP FALSE
56
57#define CPU_SOFTWARE_FP FALSE
58
59/**
60 * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
61 *
62 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
63 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
64 *
65 * So far, the only CPUs in which this option has been used are the
66 * HP PA-RISC and PowerPC.  On the PA-RISC, The HP C compiler and
67 * gcc both implicitly used the floating point registers to perform
68 * integer multiplies.  Similarly, the PowerPC port of gcc has been
69 * seen to allocate floating point local variables and touch the FPU
70 * even when the flow through a subroutine (like vfprintf()) might
71 * not use floating point formats.
72 *
73 * If a function which you would not think utilize the FP unit DOES,
74 * then one can not easily predict which tasks will use the FP hardware.
75 * In this case, this option should be TRUE.
76 *
77 * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
78 *
79 * Port Specific Information:
80 *
81 * XXX document implementation including references if appropriate
82 */
83#define CPU_ALL_TASKS_ARE_FP     FALSE
84
85/**
86 * Should the IDLE task have a floating point context?
87 *
88 * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
89 * and it has a floating point context which is switched in and out.
90 * If FALSE, then the IDLE task does not have a floating point context.
91 *
92 * Setting this to TRUE negatively impacts the time required to preempt
93 * the IDLE task from an interrupt because the floating point context
94 * must be saved as part of the preemption.
95 *
96 * Port Specific Information:
97 *
98 * XXX document implementation including references if appropriate
99 */
100#define CPU_IDLE_TASK_IS_FP      FALSE
101
102/**
103 * Should the saving of the floating point registers be deferred
104 * until a context switch is made to another different floating point
105 * task?
106 *
107 * If TRUE, then the floating point context will not be stored until
108 * necessary.  It will remain in the floating point registers and not
109 * disturned until another floating point task is switched to.
110 *
111 * If FALSE, then the floating point context is saved when a floating
112 * point task is switched out and restored when the next floating point
113 * task is restored.  The state of the floating point registers between
114 * those two operations is not specified.
115 *
116 * If the floating point context does NOT have to be saved as part of
117 * interrupt dispatching, then it should be safe to set this to TRUE.
118 *
119 * Setting this flag to TRUE results in using a different algorithm
120 * for deciding when to save and restore the floating point context.
121 * The deferred FP switch algorithm minimizes the number of times
122 * the FP context is saved and restored.  The FP context is not saved
123 * until a context switch is made to another, different FP task.
124 * Thus in a system with only one FP task, the FP context will never
125 * be saved or restored.
126 *
127 * Port Specific Information:
128 *
129 * XXX document implementation including references if appropriate
130 */
131#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
132
133#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
134
135/**
136 * Does the stack grow up (toward higher addresses) or down
137 * (toward lower addresses)?
138 *
139 * If TRUE, then the grows upward.
140 * If FALSE, then the grows toward smaller addresses.
141 *
142 * Port Specific Information:
143 *
144 * XXX document implementation including references if appropriate
145 */
146#define CPU_STACK_GROWS_UP               FALSE
147
148/* L2 cache lines are 32 bytes in Milkymist SoC */
149#define CPU_CACHE_LINE_BYTES 32
150
151#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
152
153/**
154 * @addtogroup RTEMSScoreCPUlm32Interrupt
155 * The following defines the number of bits actually used in the
156 * interrupt field of the task mode.  How those bits map to the
157 * CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
158 *
159 * Port Specific Information:
160 *
161 * XXX document implementation including references if appropriate
162 */
163#define CPU_MODES_INTERRUPT_MASK   0x00000001
164
165#define CPU_MAXIMUM_PROCESSORS 32
166
167/*
168 *  Processor defined structures required for cpukit/score.
169 *
170 *  Port Specific Information:
171 *
172 *  XXX document implementation including references if appropriate
173 */
174
175/* may need to put some structures here.  */
176
177/**
178 * @defgroup RTEMSScoreCPUlm32Context Processor Dependent Context Management
179 *
180 * @ingroup RTEMSScoreCPUlm32
181 *
182 * From the highest level viewpoint, there are 2 types of context to save.
183 *
184 *    -# Interrupt registers to save
185 *    -# Task level registers to save
186 *
187 * Since RTEMS handles integer and floating point contexts separately, this
188 * means we have the following 3 context items:
189 *
190 *    -# task level context stuff::  Context_Control
191 *    -# floating point task stuff:: Context_Control_fp
192 *    -# special interrupt level context :: CPU_Interrupt_frame
193 *
194 * On some processors, it is cost-effective to save only the callee
195 * preserved registers during a task context switch.  This means
196 * that the ISR code needs to save those registers which do not
197 * persist across function calls.  It is not mandatory to make this
198 * distinctions between the caller/callee saves registers for the
199 * purpose of minimizing context saved during task switch and on interrupts.
200 * If the cost of saving extra registers is minimal, simplicity is the
201 * choice.  Save the same context on interrupt entry as for tasks in
202 * this case.
203 *
204 * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
205 * care should be used in designing the context area.
206 *
207 * On some CPUs with hardware floating point support, the Context_Control_fp
208 * structure will not be used or it simply consist of an array of a
209 * fixed number of bytes.   This is done when the floating point context
210 * is dumped by a "FP save context" type instruction and the format
211 * is not really defined by the CPU.  In this case, there is no need
212 * to figure out the exact format -- only the size.  Of course, although
213 * this is enough information for RTEMS, it is probably not enough for
214 * a debugger such as gdb.  But that is another problem.
215 *
216 * Port Specific Information:
217 *
218 * XXX document implementation including references if appropriate
219 */
220/**@{**/
221
222/**
223 * This defines the minimal set of integer and processor state registers
224 * that must be saved during a voluntary context switch from one thread
225 * to another.
226 */
227typedef struct {
228  uint32_t r11;
229  uint32_t r12;
230  uint32_t r13;
231  uint32_t r14;
232  uint32_t r15;
233  uint32_t r16;
234  uint32_t r17;
235  uint32_t r18;
236  uint32_t r19;
237  uint32_t r20;
238  uint32_t r21;
239  uint32_t r22;
240  uint32_t r23;
241  uint32_t r24;
242  uint32_t r25;
243  uint32_t gp;
244  uint32_t fp;
245  uint32_t sp;
246  uint32_t ra;
247  uint32_t ie;
248  uint32_t epc;
249} Context_Control;
250
251/**
252 *
253 * This macro returns the stack pointer associated with @a _context.
254 *
255 * @param[in] _context is the thread context area to access
256 *
257 * @return This method returns the stack pointer.
258 */
259#define _CPU_Context_Get_SP( _context ) \
260  (_context)->sp
261
262/**
263 * This defines the set of integer and processor state registers that must
264 * be saved during an interrupt.  This set does not include any which are
265 * in @ref Context_Control.
266 */
267typedef struct {
268  uint32_t r1;
269  uint32_t r2;
270  uint32_t r3;
271  uint32_t r4;
272  uint32_t r5;
273  uint32_t r6;
274  uint32_t r7;
275  uint32_t r8;
276  uint32_t r9;
277  uint32_t r10;
278  uint32_t ra;
279  uint32_t ba;
280  uint32_t ea;
281} CPU_Interrupt_frame;
282
283/**
284 * This variable is optional.  It is used on CPUs on which it is difficult
285 * to generate an "uninitialized" FP context.  It is filled in by
286 * @ref _CPU_Initialize and copied into the task's FP context area during
287 * @ref _CPU_Context_Initialize.
288 *
289 * Port Specific Information:
290 *
291 * XXX document implementation including references if appropriate
292 */
293#if 0
294extern Context_Control_fp _CPU_Null_fp_context;
295#endif
296
297/** @} */
298
299/**
300 * @defgroup RTEMSScoreCPUlm32Interrupt Processor Dependent Interrupt Management
301 *
302 * @ingroup RTEMSScoreCPUlm32
303 */
304/** @{ **/
305/** @} **/
306
307/*
308 * Nothing prevents the porter from declaring more CPU specific variables.
309 *
310 * Port Specific Information:
311 *
312 * XXX document implementation including references if appropriate
313 */
314
315/* XXX: if needed, put more variables here */
316
317/**
318 * @addtogroup RTEMSScoreCPUlm32Interrupt
319 * Amount of extra stack (above minimum stack size) required by
320 * MPCI receive server thread.  Remember that in a multiprocessor
321 * system this thread must exist and be able to process all directives.
322 *
323 * Port Specific Information:
324 *
325 * XXX document implementation including references if appropriate
326 */
327#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
328
329/**
330 * @addtogroup RTEMSScoreCPUlm32Interrupt
331 * This defines the number of entries in the @ref _ISR_Vector_table managed
332 * by RTEMS.
333 *
334 * Port Specific Information:
335 *
336 * XXX document implementation including references if appropriate
337 */
338#define CPU_INTERRUPT_NUMBER_OF_VECTORS      32
339
340/**
341 * @addtogroup RTEMSScoreCPUlm32Interrupt
342 * This defines the highest interrupt vector number for this port.
343 */
344#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
345
346/**
347 * @addtogroup RTEMSScoreCPUlm32Interrupt
348 * This is defined if the port has a special way to report the ISR nesting
349 * level.  Most ports maintain the variable @a _ISR_Nest_level.
350 */
351#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
352
353
354/**
355 * @addtogroup RTEMSScoreCPUlm32Context
356 * Should be large enough to run all RTEMS tests.  This ensures
357 * that a "reasonable" small application should not have any problems.
358 *
359 * Port Specific Information:
360 *
361 * XXX document implementation including references if appropriate
362 */
363#define CPU_STACK_MINIMUM_SIZE          (1024*4)
364
365#define CPU_SIZEOF_POINTER 4
366
367/**
368 * CPU's worst alignment requirement for data types on a byte boundary.  This
369 * alignment does not take into account the requirements for the stack.
370 *
371 * Port Specific Information:
372 * The LM32 architecture manual simply states: "All memory accesses must be
373 * aligned to the size of the access", and there is no hardware support
374 * whatsoever for 64-bit numbers.
375 * (lm32_archman.pdf, July 2009, p. 15)
376 */
377#define CPU_ALIGNMENT              4
378
379/**
380 * This number corresponds to the byte alignment requirement for the
381 * heap handler.  This alignment requirement may be stricter than that
382 * for the data types alignment specified by @ref CPU_ALIGNMENT.  It is
383 * common for the heap to follow the same alignment requirement as
384 * @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is strict enough for
385 * the heap, then this should be set to @ref CPU_ALIGNMENT.
386 *
387 * NOTE:  This does not have to be a power of 2 although it should be
388 *        a multiple of 2 greater than or equal to 2.  The requirement
389 *        to be a multiple of 2 is because the heap uses the least
390 *        significant field of the front and back flags to indicate
391 *        that a block is in use or free.  So you do not want any odd
392 *        length blocks really putting length data in that bit.
393 *
394 *        On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
395 *        have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
396 *        elements allocated from the heap meet all restrictions.
397 *
398 * Port Specific Information:
399 *
400 * XXX document implementation including references if appropriate
401 */
402#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
403
404#define CPU_STACK_ALIGNMENT        CPU_ALIGNMENT
405
406#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
407
408/*
409 *  ISR handler macros
410 */
411
412/**
413 * @addtogroup RTEMSScoreCPUlm32Interrupt
414 */
415/**@{**/
416
417/**
418 * Disable all interrupts for an RTEMS critical section.  The previous
419 * level is returned in @a _isr_cookie.
420 *
421 * @param[out] _isr_cookie will contain the previous level cookie
422 *
423 * Port Specific Information:
424 *
425 * XXX document implementation including references if appropriate
426 */
427#define _CPU_ISR_Disable( _isr_cookie ) \
428  lm32_disable_interrupts( _isr_cookie );
429
430/**
431 * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
432 * This indicates the end of an RTEMS critical section.  The parameter
433 * @a _isr_cookie is not modified.
434 *
435 * @param[in] _isr_cookie contain the previous level cookie
436 *
437 * Port Specific Information:
438 *
439 * XXX document implementation including references if appropriate
440 */
441#define _CPU_ISR_Enable( _isr_cookie ) \
442  lm32_enable_interrupts( _isr_cookie );
443
444/**
445 * This temporarily restores the interrupt to @a _isr_cookie before immediately
446 * disabling them again.  This is used to divide long RTEMS critical
447 * sections into two or more parts.  The parameter @a _isr_cookie is not
448 * modified.
449 *
450 * @param[in] _isr_cookie contain the previous level cookie
451 *
452 * Port Specific Information:
453 *
454 * XXX document implementation including references if appropriate
455 */
456#define _CPU_ISR_Flash( _isr_cookie ) \
457  lm32_flash_interrupts( _isr_cookie );
458
459static inline bool _CPU_ISR_Is_enabled( uint32_t level )
460{
461  return ( level & 0x0001 ) != 0;
462}
463
464/**
465 * This routine and @ref _CPU_ISR_Get_level
466 * Map the interrupt level in task mode onto the hardware that the CPU
467 * actually provides.  Currently, interrupt levels which do not
468 * map onto the CPU in a generic fashion are undefined.  Someday,
469 * it would be nice if these were "mapped" by the application
470 * via a callout.  For example, m68k has 8 levels 0 - 7, levels
471 * 8 - 255 would be available for bsp/application specific meaning.
472 * This could be used to manage a programmable interrupt controller
473 * via the rtems_task_mode directive.
474 *
475 * Port Specific Information:
476 *
477 * XXX document implementation including references if appropriate
478 */
479#define _CPU_ISR_Set_level( new_level ) \
480  { \
481    _CPU_ISR_Enable( ( new_level==0 ) ? 1 : 0 ); \
482  }
483
484/**
485 * Return the current interrupt disable level for this task in
486 * the format used by the interrupt level portion of the task mode.
487 *
488 * NOTE: This routine usually must be implemented as a subroutine.
489 *
490 * Port Specific Information:
491 *
492 * XXX document implementation including references if appropriate
493 */
494uint32_t   _CPU_ISR_Get_level( void );
495
496/* end of ISR handler macros */
497
498/** @} */
499
500/* Context handler macros */
501
502/**
503 * @addtogroup RTEMSScoreCPUlm32Context
504 * Initialize the context to a state suitable for starting a
505 * task after a context restore operation.  Generally, this
506 * involves:
507 *
508 *    - setting a starting address
509 *    - preparing the stack
510 *    - preparing the stack and frame pointers
511 *    - setting the proper interrupt level in the context
512 *    - initializing the floating point context
513 *
514 * This routine generally does not set any unnecessary register
515 * in the context.  The state of the "general data" registers is
516 * undefined at task start time.
517 *
518 * @param[in] _the_context is the context structure to be initialized
519 * @param[in] _stack_base is the lowest physical address of this task's stack
520 * @param[in] _size is the size of this task's stack
521 * @param[in] _isr is the interrupt disable level
522 * @param[in] _entry_point is the thread's entry point.  This is
523 *        always @a _Thread_Handler
524 * @param[in] _is_fp is TRUE if the thread is to be a floating
525 *       point thread.  This is typically only used on CPUs where the
526 *       FPU may be easily disabled by software such as on the SPARC
527 *       where the PSR contains an enable FPU bit.
528 *
529 * Port Specific Information:
530 *
531 * XXX document implementation including references if appropriate
532 */
533extern char _gp[];
534
535#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
536                                 _isr, _entry_point, _is_fp, _tls_area ) \
537   do { \
538     uint32_t _stack = (uint32_t)(_stack_base) + (_size) - 4; \
539     \
540     (void) _is_fp; /* avoid warning for being unused */ \
541     (void) _isr;  /* avoid warning for being unused */ \
542     (_the_context)->gp = (uint32_t)_gp; \
543     (_the_context)->fp = (uint32_t)_stack; \
544     (_the_context)->sp = (uint32_t)_stack; \
545     (_the_context)->ra = (uint32_t)(_entry_point); \
546   } while ( 0 )
547
548/**
549 * This routine is responsible for somehow restarting the currently
550 * executing task.  If you are lucky, then all that is necessary
551 * is restoring the context.  Otherwise, there will need to be
552 * a special assembly routine which does something special in this
553 * case.  For many ports, simply adding a label to the restore path
554 * of @ref _CPU_Context_switch will work.  On other ports, it may be
555 * possibly to load a few arguments and jump to the restore path. It will
556 * not work if restarting self conflicts with the stack frame
557 * assumptions of restoring a context.
558 *
559 * Port Specific Information:
560 *
561 * XXX document implementation including references if appropriate
562 */
563#define _CPU_Context_Restart_self( _the_context ) \
564   _CPU_Context_restore( (_the_context) );
565
566/**
567 * This routine initializes the FP context area passed to it to.
568 * There are a few standard ways in which to initialize the
569 * floating point context.  The code included for this macro assumes
570 * that this is a CPU in which a "initial" FP context was saved into
571 * @a _CPU_Null_fp_context and it simply copies it to the destination
572 * context passed to it.
573 *
574 * Other floating point context save/restore models include:
575 *   -# not doing anything, and
576 *   -# putting a "null FP status word" in the correct place in the FP context.
577 *
578 * @param[in] _destination is the floating point context area
579 *
580 * Port Specific Information:
581 *
582 * XXX document implementation including references if appropriate
583 */
584#define _CPU_Context_Initialize_fp( _destination )
585#if 0
586  { \
587   *(*(_destination)) = _CPU_Null_fp_context; \
588  }
589#endif
590
591/* end of Context handler macros */
592
593#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
594
595#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE
596
597/* functions */
598
599/**
600 * This routine performs CPU dependent initialization.
601 *
602 * Port Specific Information:
603 *
604 * XXX document implementation including references if appropriate
605 */
606void _CPU_Initialize(void);
607
608/**
609 * @addtogroup RTEMSScoreCPUlm32Interrupt
610 */
611/**@{**/
612
613typedef void ( *CPU_ISR_raw_handler )( void );
614
615static inline void _CPU_ISR_install_raw_handler(
616  uint32_t             vector,
617  CPU_ISR_raw_handler  new_handler,
618  CPU_ISR_raw_handler *old_handler
619)
620{
621  /* TODO */
622}
623
624typedef void ( *CPU_ISR_handler )( uint32_t );
625
626void _CPU_ISR_install_vector(
627  uint32_t         vector,
628  CPU_ISR_handler  new_handler,
629  CPU_ISR_handler *old_handler
630);
631
632/** @} */
633
634void *_CPU_Thread_Idle_body( uintptr_t ignored );
635
636/**
637 * @addtogroup RTEMSScoreCPUlm32Context
638 * This routine switches from the run context to the heir context.
639 *
640 * @param[in] run points to the context of the currently executing task
641 * @param[in] heir points to the context of the heir task
642 *
643 * Port Specific Information:
644 *
645 * XXX document implementation including references if appropriate
646 */
647void _CPU_Context_switch(
648  Context_Control  *run,
649  Context_Control  *heir
650);
651
652/**
653 * @addtogroup RTEMSScoreCPUlm32Context
654 */
655/**@{**/
656
657/**
658 * This routine is generally used only to restart self in an
659 * efficient manner.  It may simply be a label in @ref _CPU_Context_switch.
660 *
661 * @param[in] new_context points to the context to be restored.
662 *
663 * NOTE: May be unnecessary to reload some registers.
664 *
665 * Port Specific Information:
666 *
667 * XXX document implementation including references if appropriate
668 */
669RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
670
671/** @} */
672
673/* FIXME */
674typedef CPU_Interrupt_frame CPU_Exception_frame;
675
676void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
677
678/**
679 * @defgroup RTEMSScoreCPUlm32CPUEndian CPUEndian
680 *
681 * @ingroup RTEMSScoreCPUlm32
682 *
683 * @brief CPUEndian
684 */
685/** @{ */
686
687/**
688 * The following routine swaps the endian format of an unsigned int.
689 * It must be static because it is referenced indirectly.
690 *
691 * This version will work on any processor, but if there is a better
692 * way for your CPU PLEASE use it.  The most common way to do this is to:
693 *
694 *    swap least significant two bytes with 16-bit rotate
695 *    swap upper and lower 16-bits
696 *    swap most significant two bytes with 16-bit rotate
697 *
698 * Some CPUs have special instructions which swap a 32-bit quantity in
699 * a single instruction (e.g. i486).  It is probably best to avoid
700 * an "endian swapping control bit" in the CPU.  One good reason is
701 * that interrupts would probably have to be disabled to ensure that
702 * an interrupt does not try to access the same "chunk" with the wrong
703 * endian.  Another good reason is that on some CPUs, the endian bit
704 * endianness for ALL fetches -- both code and data -- so the code
705 * will be fetched incorrectly.
706 *
707 * @param[in] value is the value to be swapped
708 * @return the value after being endian swapped
709 *
710 * Port Specific Information:
711 *
712 * XXX document implementation including references if appropriate
713 */
714static inline uint32_t CPU_swap_u32(
715  uint32_t value
716)
717{
718  uint32_t byte1, byte2, byte3, byte4, swapped;
719
720  byte4 = (value >> 24) & 0xff;
721  byte3 = (value >> 16) & 0xff;
722  byte2 = (value >> 8)  & 0xff;
723  byte1 =  value        & 0xff;
724
725  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
726  return swapped;
727}
728
729/**
730 * This routine swaps a 16 bir quantity.
731 *
732 * @param[in] value is the value to be swapped
733 * @return the value after being endian swapped
734 */
735static inline uint16_t CPU_swap_u16(uint16_t v)
736{
737    return v << 8 | v >> 8;
738}
739
740/** @} */
741
742typedef uint32_t CPU_Counter_ticks;
743
744uint32_t _CPU_Counter_frequency( void );
745
746CPU_Counter_ticks _CPU_Counter_read( void );
747
748/** Type that can store a 32-bit integer or a pointer. */
749typedef uintptr_t CPU_Uint32ptr;
750
751#ifdef __cplusplus
752}
753#endif
754
755#endif
Note: See TracBrowser for help on using the repository browser.