source: rtems/cpukit/score/cpu/or1k/include/rtems/score/cpu.h @ 27bbc05

Last change on this file since 27bbc05 was 27bbc05, checked in by Sebastian Huber <sebastian.huber@…>, on Aug 2, 2018 at 12:49:01 PM

score: Remove CPU_PARTITION_ALIGNMENT

Use the CPU_SIZEOF_POINTER alignment instead. The internal alignment
requirement is defined by the use of Chain_Node (consisting of two
pointers) to manage the free chain of partitions.

It seems that previously the condition

CPU_PARTITION_ALIGNMENT >= sizeof(Chain_Node)

was true on all CPU ports. Now, we need an additional check.

Update #3482.

  • Property mode set to 100644
File size: 21.6 KB
Line 
1/**
2 * @file rtems/score/cpu.h
3 */
4
5/*
6 *  This include file contains macros pertaining to the Opencores
7 *  or1k processor family.
8 *
9 *  COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary@gmail.com>
10 *  COPYRIGHT (c) 1989-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 *
17 *  This file adapted from no_cpu example of the RTEMS distribution.
18 *  The body has been modified for the Opencores OR1k implementation by
19 *  Chris Ziomkowski. <chris@asics.ws>
20 *
21 */
22
23#ifndef _OR1K_CPU_H
24#define _OR1K_CPU_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30
31#include <rtems/score/or1k.h>            /* pick up machine definitions */
32#include <rtems/score/or1k-utility.h>
33#include <rtems/score/basedefs.h>
34#ifndef ASM
35#include <rtems/bspIo.h>
36#include <stdint.h>
37#include <stdio.h> /* for printk */
38#endif
39
40/* conditional compilation parameters */
41
42/*
43 *  Does the RTEMS invoke the user's ISR with the vector number and
44 *  a pointer to the saved interrupt frame (1) or just the vector
45 *  number (0)?
46 *
47 */
48
49#define CPU_ISR_PASSES_FRAME_POINTER TRUE
50
51/*
52 *  Does the CPU have hardware floating point?
53 *
54 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
55 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
56 *
57 *  If there is a FP coprocessor such as the i387 or mc68881, then
58 *  the answer is TRUE.
59 *
60 *  The macro name "OR1K_HAS_FPU" should be made CPU specific.
61 *  It indicates whether or not this CPU model has FP support.  For
62 *  example, it would be possible to have an i386_nofp CPU model
63 *  which set this to false to indicate that you have an i386 without
64 *  an i387 and wish to leave floating point support out of RTEMS.
65 *
66 *  The CPU_SOFTWARE_FP is used to indicate whether or not there
67 *  is software implemented floating point that must be context
68 *  switched.  The determination of whether or not this applies
69 *  is very tool specific and the state saved/restored is also
70 *  compiler specific.
71 *
72 *  Or1k Specific Information:
73 *
74 *  At this time there are no implementations of Or1k that are
75 *  expected to implement floating point. More importantly, the
76 *  floating point architecture is expected to change significantly
77 *  before such chips are fabricated.
78 */
79
80#define CPU_HARDWARE_FP     FALSE
81#define CPU_SOFTWARE_FP     FALSE
82
83/*
84 *  Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
85 *
86 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
87 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
88 *
89 *  If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
90 *
91 */
92
93#define CPU_ALL_TASKS_ARE_FP     FALSE
94
95/*
96 *  Should the IDLE task have a floating point context?
97 *
98 *  If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
99 *  and it has a floating point context which is switched in and out.
100 *  If FALSE, then the IDLE task does not have a floating point context.
101 *
102 *  Setting this to TRUE negatively impacts the time required to preempt
103 *  the IDLE task from an interrupt because the floating point context
104 *  must be saved as part of the preemption.
105 *
106 */
107
108#define CPU_IDLE_TASK_IS_FP      FALSE
109
110/*
111 *  Should the saving of the floating point registers be deferred
112 *  until a context switch is made to another different floating point
113 *  task?
114 *
115 *  If TRUE, then the floating point context will not be stored until
116 *  necessary.  It will remain in the floating point registers and not
117 *  disturned until another floating point task is switched to.
118 *
119 *  If FALSE, then the floating point context is saved when a floating
120 *  point task is switched out and restored when the next floating point
121 *  task is restored.  The state of the floating point registers between
122 *  those two operations is not specified.
123 *
124 *  If the floating point context does NOT have to be saved as part of
125 *  interrupt dispatching, then it should be safe to set this to TRUE.
126 *
127 *  Setting this flag to TRUE results in using a different algorithm
128 *  for deciding when to save and restore the floating point context.
129 *  The deferred FP switch algorithm minimizes the number of times
130 *  the FP context is saved and restored.  The FP context is not saved
131 *  until a context switch is made to another, different FP task.
132 *  Thus in a system with only one FP task, the FP context will never
133 *  be saved or restored.
134 *
135 */
136
137#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
138
139#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
140
141/*
142 *  Does this port provide a CPU dependent IDLE task implementation?
143 *
144 *  If TRUE, then the routine _CPU_Thread_Idle_body
145 *  must be provided and is the default IDLE thread body instead of
146 *  _CPU_Thread_Idle_body.
147 *
148 *  If FALSE, then use the generic IDLE thread body if the BSP does
149 *  not provide one.
150 *
151 *  This is intended to allow for supporting processors which have
152 *  a low power or idle mode.  When the IDLE thread is executed, then
153 *  the CPU can be powered down.
154 *
155 *  The order of precedence for selecting the IDLE thread body is:
156 *
157 *    1.  BSP provided
158 *    2.  CPU dependent (if provided)
159 *    3.  generic (if no BSP and no CPU dependent)
160 *
161 */
162
163#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
164
165/*
166 *  Does the stack grow up (toward higher addresses) or down
167 *  (toward lower addresses)?
168 *
169 *  If TRUE, then the grows upward.
170 *  If FALSE, then the grows toward smaller addresses.
171 *
172 */
173
174#define CPU_STACK_GROWS_UP               FALSE
175
176/* FIXME: Is this the right value? */
177#define CPU_CACHE_LINE_BYTES 32
178
179#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
180
181/*
182 *  The following defines the number of bits actually used in the
183 *  interrupt field of the task mode.  How those bits map to the
184 *  CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
185 *
186 */
187
188#define CPU_MODES_INTERRUPT_MASK   0x00000001
189
190/*
191 *  Processor defined structures required for cpukit/score.
192 */
193
194
195/*
196 * Contexts
197 *
198 *  Generally there are 2 types of context to save.
199 *     1. Interrupt registers to save
200 *     2. Task level registers to save
201 *
202 *  This means we have the following 3 context items:
203 *     1. task level context stuff::  Context_Control
204 *     2. floating point task stuff:: Context_Control_fp
205 *     3. special interrupt level context :: Context_Control_interrupt
206 *
207 *  On some processors, it is cost-effective to save only the callee
208 *  preserved registers during a task context switch.  This means
209 *  that the ISR code needs to save those registers which do not
210 *  persist across function calls.  It is not mandatory to make this
211 *  distinctions between the caller/callee saves registers for the
212 *  purpose of minimizing context saved during task switch and on interrupts.
213 *  If the cost of saving extra registers is minimal, simplicity is the
214 *  choice.  Save the same context on interrupt entry as for tasks in
215 *  this case.
216 *
217 *  Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
218 *  care should be used in designing the context area.
219 *
220 *  On some CPUs with hardware floating point support, the Context_Control_fp
221 *  structure will not be used or it simply consist of an array of a
222 *  fixed number of bytes.   This is done when the floating point context
223 *  is dumped by a "FP save context" type instruction and the format
224 *  is not really defined by the CPU.  In this case, there is no need
225 *  to figure out the exact format -- only the size.  Of course, although
226 *  this is enough information for RTEMS, it is probably not enough for
227 *  a debugger such as gdb.  But that is another problem.
228 *
229 *
230 */
231#ifndef ASM
232#ifdef OR1K_64BIT_ARCH
233#define or1kreg uint64_t
234#else
235#define or1kreg uint32_t
236#endif
237
238typedef struct {
239  uint32_t  r1;     /* Stack pointer */
240  uint32_t  r2;     /* Frame pointer */
241  uint32_t  r3;
242  uint32_t  r4;
243  uint32_t  r5;
244  uint32_t  r6;
245  uint32_t  r7;
246  uint32_t  r8;
247  uint32_t  r9;
248  uint32_t  r10;
249  uint32_t  r11;
250  uint32_t  r12;
251  uint32_t  r13;
252  uint32_t  r14;
253  uint32_t  r15;
254  uint32_t  r16;
255  uint32_t  r17;
256  uint32_t  r18;
257  uint32_t  r19;
258  uint32_t  r20;
259  uint32_t  r21;
260  uint32_t  r22;
261  uint32_t  r23;
262  uint32_t  r24;
263  uint32_t  r25;
264  uint32_t  r26;
265  uint32_t  r27;
266  uint32_t  r28;
267  uint32_t  r29;
268  uint32_t  r30;
269  uint32_t  r31;
270
271  uint32_t  sr;  /* Current supervision register non persistent values */
272  uint32_t  epcr;
273  uint32_t  eear;
274  uint32_t  esr;
275} Context_Control;
276
277#define _CPU_Context_Get_SP( _context ) \
278  (_context)->r1
279
280typedef struct {
281  /** FPU registers are listed here */
282  double      some_float_register;
283} Context_Control_fp;
284
285typedef Context_Control CPU_Interrupt_frame;
286
287/*
288 *  The size of the floating point context area.  On some CPUs this
289 *  will not be a "sizeof" because the format of the floating point
290 *  area is not defined -- only the size is.  This is usually on
291 *  CPUs with a "floating point save context" instruction.
292 *
293 *  Or1k Specific Information:
294 *
295 */
296
297#define CPU_CONTEXT_FP_SIZE  0
298
299/*
300 *  Amount of extra stack (above minimum stack size) required by
301 *  MPCI receive server thread.  Remember that in a multiprocessor
302 *  system this thread must exist and be able to process all directives.
303 *
304 */
305
306#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
307
308/*
309 *  Should be large enough to run all RTEMS tests.  This insures
310 *  that a "reasonable" small application should not have any problems.
311 *
312 */
313
314#define CPU_STACK_MINIMUM_SIZE  4096
315
316/*
317 *  CPU's worst alignment requirement for data types on a byte boundary.  This
318 *  alignment does not take into account the requirements for the stack.
319 *
320 */
321
322#define CPU_ALIGNMENT  8
323
324/*
325 *  This is defined if the port has a special way to report the ISR nesting
326 *  level.  Most ports maintain the variable _ISR_Nest_level.
327 */
328#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
329
330/**
331 * Size of a pointer.
332 *
333 * This must be an integer literal that can be used by the assembler.  This
334 * value will be used to calculate offsets of structure members.  These
335 * offsets will be used in assembler code.
336 */
337#define CPU_SIZEOF_POINTER         4
338
339/*
340 *  This number corresponds to the byte alignment requirement for the
341 *  heap handler.  This alignment requirement may be stricter than that
342 *  for the data types alignment specified by CPU_ALIGNMENT.  It is
343 *  common for the heap to follow the same alignment requirement as
344 *  CPU_ALIGNMENT.  If the CPU_ALIGNMENT is strict enough for the heap,
345 *  then this should be set to CPU_ALIGNMENT.
346 *
347 *  NOTE:  This does not have to be a power of 2 although it should be
348 *         a multiple of 2 greater than or equal to 2.  The requirement
349 *         to be a multiple of 2 is because the heap uses the least
350 *         significant field of the front and back flags to indicate
351 *         that a block is in use or free.  So you do not want any odd
352 *         length blocks really putting length data in that bit.
353 *
354 *         On byte oriented architectures, CPU_HEAP_ALIGNMENT normally will
355 *         have to be greater or equal to than CPU_ALIGNMENT to ensure that
356 *         elements allocated from the heap meet all restrictions.
357 *
358 */
359
360#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
361
362/*
363 *  This number corresponds to the byte alignment requirement for the
364 *  stack.  This alignment requirement may be stricter than that for the
365 *  data types alignment specified by CPU_ALIGNMENT.  If the CPU_ALIGNMENT
366 *  is strict enough for the stack, then this should be set to 0.
367 *
368 *  NOTE:  This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
369 *
370 */
371
372#define CPU_STACK_ALIGNMENT        0
373
374#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
375
376/* ISR handler macros */
377
378/*
379 *  Support routine to initialize the RTEMS vector table after it is allocated.
380 *
381 *  NO_CPU Specific Information:
382 *
383 *  XXX document implementation including references if appropriate
384 */
385
386#define _CPU_Initialize_vectors()
387
388/*
389 *  Disable all interrupts for an RTEMS critical section.  The previous
390 *  level is returned in _level.
391 *
392 */
393
394static inline uint32_t or1k_interrupt_disable( void )
395{
396  uint32_t sr;
397  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
398
399  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE));
400
401  return sr;
402}
403
404static inline void or1k_interrupt_enable(uint32_t level)
405{
406  uint32_t sr;
407
408  /* Enable interrupts and restore rs */
409  sr = level | CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
410  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
411
412}
413
414#define _CPU_ISR_Disable( _level ) \
415    _level = or1k_interrupt_disable()
416
417
418/*
419 *  Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
420 *  This indicates the end of an RTEMS critical section.  The parameter
421 *  _level is not modified.
422 *
423 */
424
425#define _CPU_ISR_Enable( _level )  \
426  or1k_interrupt_enable( _level )
427
428/*
429 *  This temporarily restores the interrupt to _level before immediately
430 *  disabling them again.  This is used to divide long RTEMS critical
431 *  sections into two or more parts.  The parameter _level is not
432 *  modified.
433 *
434 */
435
436#define _CPU_ISR_Flash( _level ) \
437  do{ \
438      _CPU_ISR_Enable( _level ); \
439      _OR1K_mtspr(CPU_OR1K_SPR_SR, (_level & ~CPU_OR1K_SPR_SR_IEE)); \
440    } while(0)
441
442RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
443{
444  return ( level & CPU_OR1K_SPR_SR ) != 0;
445}
446
447/*
448 *  Map interrupt level in task mode onto the hardware that the CPU
449 *  actually provides.  Currently, interrupt levels which do not
450 *  map onto the CPU in a generic fashion are undefined.  Someday,
451 *  it would be nice if these were "mapped" by the application
452 *  via a callout.  For example, m68k has 8 levels 0 - 7, levels
453 *  8 - 255 would be available for bsp/application specific meaning.
454 *  This could be used to manage a programmable interrupt controller
455 *  via the rtems_task_mode directive.
456 *
457 *  The get routine usually must be implemented as a subroutine.
458 *
459 */
460
461void _CPU_ISR_Set_level( uint32_t level );
462
463uint32_t _CPU_ISR_Get_level( void );
464
465/* end of ISR handler macros */
466
467/* Context handler macros */
468
469#define OR1K_FAST_CONTEXT_SWITCH_ENABLED FALSE
470/*
471 *  Initialize the context to a state suitable for starting a
472 *  task after a context restore operation.  Generally, this
473 *  involves:
474 *
475 *     - setting a starting address
476 *     - preparing the stack
477 *     - preparing the stack and frame pointers
478 *     - setting the proper interrupt level in the context
479 *     - initializing the floating point context
480 *
481 *  This routine generally does not set any unnecessary register
482 *  in the context.  The state of the "general data" registers is
483 *  undefined at task start time.
484 *
485 *  NOTE: This is_fp parameter is TRUE if the thread is to be a floating
486 *        point thread.  This is typically only used on CPUs where the
487 *        FPU may be easily disabled by software such as on the SPARC
488 *        where the PSR contains an enable FPU bit.
489 *
490 */
491
492/**
493 * @brief Initializes the CPU context.
494 *
495 * The following steps are performed:
496 *  - setting a starting address
497 *  - preparing the stack
498 *  - preparing the stack and frame pointers
499 *  - setting the proper interrupt level in the context
500 *
501 * @param[in] context points to the context area
502 * @param[in] stack_area_begin is the low address of the allocated stack area
503 * @param[in] stack_area_size is the size of the stack area in bytes
504 * @param[in] new_level is the interrupt level for the task
505 * @param[in] entry_point is the task's entry point
506 * @param[in] is_fp is set to @c true if the task is a floating point task
507 * @param[in] tls_area is the thread-local storage (TLS) area
508 */
509void _CPU_Context_Initialize(
510  Context_Control *context,
511  void *stack_area_begin,
512  size_t stack_area_size,
513  uint32_t new_level,
514  void (*entry_point)( void ),
515  bool is_fp,
516  void *tls_area
517);
518
519/*
520 *  This routine is responsible for somehow restarting the currently
521 *  executing task.  If you are lucky, then all that is necessary
522 *  is restoring the context.  Otherwise, there will need to be
523 *  a special assembly routine which does something special in this
524 *  case.  Context_Restore should work most of the time.  It will
525 *  not work if restarting self conflicts with the stack frame
526 *  assumptions of restoring a context.
527 *
528 */
529
530#define _CPU_Context_Restart_self( _the_context ) \
531   _CPU_Context_restore( (_the_context) );
532
533/*
534 *  This routine is responsible to initialize the FP context.
535 *
536 *  The FP area pointer is passed by reference to allow the initial pointer
537 *  into a floating point context area (used to save the floating point
538 *  context) to be at an arbitrary place in the floating point context area.
539 *
540 *  This is necessary because some FP units are designed to have
541 *  their context saved as a stack which grows into lower addresses.
542 *  Other FP units can be saved by simply moving registers into offsets
543 *  from the base of the context area.  Finally some FP units provide
544 *  a "dump context" instruction which could fill in from high to low
545 *  or low to high based on the whim of the CPU designers.
546 */
547#define _CPU_Context_Initialize_fp( _fp_area_p ) \
548  memset( *( _fp_area_p ), 0, CPU_CONTEXT_FP_SIZE )
549
550/* end of Context handler macros */
551
552/* Fatal Error manager macros */
553
554/*
555 *  This routine copies _error into a known place -- typically a stack
556 *  location or a register, optionally disables interrupts, and
557 *  halts/stops the CPU.
558 *
559 */
560
561#include <inttypes.h>
562
563#define _CPU_Fatal_halt(_source, _error ) \
564        printk("Fatal Error %d.%" PRId32 " Halted\n",_source, _error); \
565        _OR1KSIM_CPU_Halt(); \
566        for(;;)
567
568/* end of Fatal Error manager macros */
569
570#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
571
572#endif /* ASM */
573
574#define CPU_SIZEOF_POINTER 4
575
576#define CPU_MAXIMUM_PROCESSORS 32
577
578#ifndef ASM
579typedef struct {
580  uint32_t r[32];
581
582  /* The following registers must be saved if we have
583  fast context switch disabled and nested interrupt
584  levels are enabled.
585  */
586#if !OR1K_FAST_CONTEXT_SWITCH_ENABLED
587  uint32_t epcr; /* exception PC register */
588  uint32_t eear; /* exception effective address register */
589  uint32_t esr; /* exception supervision register */
590#endif
591
592} CPU_Exception_frame;
593
594/**
595 * @brief Prints the exception frame via printk().
596 *
597 * @see rtems_fatal() and RTEMS_FATAL_SOURCE_EXCEPTION.
598 */
599void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
600
601
602/* end of Priority handler macros */
603
604/* functions */
605
606/*
607 *  _CPU_Initialize
608 *
609 *  This routine performs CPU dependent initialization.
610 *
611 */
612
613void _CPU_Initialize(
614  void
615);
616
617/*
618 *  _CPU_ISR_install_raw_handler
619 *
620 *  This routine installs a "raw" interrupt handler directly into the
621 *  processor's vector table.
622 *
623 */
624
625void _CPU_ISR_install_raw_handler(
626  uint32_t    vector,
627  proc_ptr    new_handler,
628  proc_ptr   *old_handler
629);
630
631/*
632 *  _CPU_ISR_install_vector
633 *
634 *  This routine installs an interrupt vector.
635 *
636 *  NO_CPU Specific Information:
637 *
638 *  XXX document implementation including references if appropriate
639 */
640
641void _CPU_ISR_install_vector(
642  uint32_t    vector,
643  proc_ptr   new_handler,
644  proc_ptr   *old_handler
645);
646
647/*
648 *  _CPU_Thread_Idle_body
649 *
650 *  This routine is the CPU dependent IDLE thread body.
651 *
652 *  NOTE:  It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
653 *         is TRUE.
654 *
655 */
656
657void *_CPU_Thread_Idle_body( uintptr_t ignored );
658
659/*
660 *  _CPU_Context_switch
661 *
662 *  This routine switches from the run context to the heir context.
663 *
664 *  Or1k Specific Information:
665 *
666 *  Please see the comments in the .c file for a description of how
667 *  this function works. There are several things to be aware of.
668 */
669
670void _CPU_Context_switch(
671  Context_Control  *run,
672  Context_Control  *heir
673);
674
675/*
676 *  _CPU_Context_restore
677 *
678 *  This routine is generally used only to restart self in an
679 *  efficient manner.  It may simply be a label in _CPU_Context_switch.
680 *
681 *  NOTE: May be unnecessary to reload some registers.
682 *
683 */
684
685void _CPU_Context_restore(
686  Context_Control *new_context
687) RTEMS_NO_RETURN;
688
689/*
690 *  _CPU_Context_save_fp
691 *
692 *  This routine saves the floating point context passed to it.
693 *
694 */
695
696void _CPU_Context_save_fp(
697  void **fp_context_ptr
698);
699
700/*
701 *  _CPU_Context_restore_fp
702 *
703 *  This routine restores the floating point context passed to it.
704 *
705 */
706
707void _CPU_Context_restore_fp(
708  void **fp_context_ptr
709);
710
711/*  The following routine swaps the endian format of an unsigned int.
712 *  It must be static because it is referenced indirectly.
713 *
714 *  This version will work on any processor, but if there is a better
715 *  way for your CPU PLEASE use it.  The most common way to do this is to:
716 *
717 *     swap least significant two bytes with 16-bit rotate
718 *     swap upper and lower 16-bits
719 *     swap most significant two bytes with 16-bit rotate
720 *
721 *  Some CPUs have special instructions which swap a 32-bit quantity in
722 *  a single instruction (e.g. i486).  It is probably best to avoid
723 *  an "endian swapping control bit" in the CPU.  One good reason is
724 *  that interrupts would probably have to be disabled to insure that
725 *  an interrupt does not try to access the same "chunk" with the wrong
726 *  endian.  Another good reason is that on some CPUs, the endian bit
727 *  endianness for ALL fetches -- both code and data -- so the code
728 *  will be fetched incorrectly.
729 *
730 */
731
732static inline unsigned int CPU_swap_u32(
733  unsigned int value
734)
735{
736  uint32_t   byte1, byte2, byte3, byte4, swapped;
737
738  byte4 = (value >> 24) & 0xff;
739  byte3 = (value >> 16) & 0xff;
740  byte2 = (value >> 8)  & 0xff;
741  byte1 =  value        & 0xff;
742
743  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
744  return( swapped );
745}
746
747#define CPU_swap_u16( value ) \
748  (((value&0xff) << 8) | ((value >> 8)&0xff))
749
750typedef uint32_t CPU_Counter_ticks;
751
752uint32_t _CPU_Counter_frequency( void );
753
754CPU_Counter_ticks _CPU_Counter_read( void );
755
756CPU_Counter_ticks _CPU_Counter_difference(
757  CPU_Counter_ticks second,
758  CPU_Counter_ticks first
759);
760
761/** Type that can store a 32-bit integer or a pointer. */
762typedef uintptr_t CPU_Uint32ptr;
763
764#endif /* ASM */
765
766#ifdef __cplusplus
767}
768#endif
769
770#endif
Note: See TracBrowser for help on using the repository browser.