source: rtems/c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h @ 574fb67

4.104.114.95
Last change on this file since 574fb67 was 574fb67, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/14/08 at 16:15:28

updated gen83xx BSP
updated haleakala BSP
added MPC55xx BSP

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup powerpc_shared
5 *
6 * @brief General purpose assembler macros, linker command file support and
7 * some inline functions for direct register access.
8 */
9
10/*
11 * Copyright (c) 2008
12 * Embedded Brains GmbH
13 * Obere Lagerstr. 30
14 * D-82178 Puchheim
15 * Germany
16 * rtems@embedded-brains.de
17 *
18 * access function for Device Control Registers inspired by "ppc405common.h"
19 * from Michael Hamel ADInstruments May 2008
20 *
21 * The license and distribution terms for this file may be found in the file
22 * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
23 */
24
25/**
26 * @defgroup powerpc_shared Shared PowerPC Code
27 */
28
29#ifndef LIBCPU_POWERPC_UTILITY_H
30#define LIBCPU_POWERPC_UTILITY_H
31
32#include <rtems/powerpc/registers.h>
33
34#ifndef ASM
35
36#include <stdint.h>
37
38#include <rtems/bspIo.h>
39#include <rtems/system.h>
40#include <rtems/score/cpu.h>
41
42#include <libcpu/cpuIdent.h>
43
44#define LINKER_SYMBOL( sym) extern char sym []
45
46/**
47 * @brief Read one byte from @a src.
48 */
49static inline uint8_t ppc_read_byte( const volatile void *src)
50{
51        uint8_t value;
52
53        asm volatile (
54                "lbz %0, 0(%1)"
55                : "=r" (value)
56                : "r" (src)
57        );
58
59        return value;
60}
61
62/**
63 * @brief Read one half word from @a src.
64 */
65static inline uint16_t ppc_read_half_word( const volatile void *src)
66{
67        uint16_t value;
68
69        asm volatile (
70                "lhz %0, 0(%1)"
71                : "=r" (value)
72                : "r" (src)
73        );
74
75        return value;
76}
77
78/**
79 * @brief Read one word from @a src.
80 */
81static inline uint32_t ppc_read_word( const volatile void *src)
82{
83        uint32_t value;
84
85        asm volatile (
86                "lwz %0, 0(%1)"
87                : "=r" (value)
88                : "r" (src)
89        );
90
91        return value;
92}
93
94/**
95 * @brief Write one byte @a value to @a dest.
96 */
97static inline void ppc_write_byte( uint8_t value, volatile void *dest)
98{
99        asm volatile (
100                "stb %0, 0(%1)"
101                :
102                : "r" (value), "r" (dest)
103        );
104}
105
106/**
107 * @brief Write one half word @a value to @a dest.
108 */
109static inline void ppc_write_half_word( uint16_t value, volatile void *dest)
110{
111        asm volatile (
112                "sth %0, 0(%1)"
113                :
114                : "r" (value), "r" (dest)
115        );
116}
117
118/**
119 * @brief Write one word @a value to @a dest.
120 */
121static inline void ppc_write_word( uint32_t value, volatile void *dest)
122{
123        asm volatile (
124                "stw %0, 0(%1)" :
125                : "r" (value), "r" (dest)
126        );
127}
128
129
130static inline void *ppc_stack_pointer()
131{
132        void *sp;
133
134        asm volatile (
135                "mr %0, 1"
136                : "=r" (sp)
137        );
138
139        return sp;
140}
141
142static inline void ppc_set_stack_pointer( void *sp)
143{
144        asm volatile (
145                "mr 1, %0"
146                :
147                : "r" (sp)
148        );
149}
150
151static inline void *ppc_link_register()
152{
153        void *lr;
154
155        asm volatile (
156                "mflr %0"
157                : "=r" (lr)
158        );
159
160        return lr;
161}
162
163static inline void ppc_set_link_register( void *lr)
164{
165        asm volatile (
166                "mtlr %0"
167                :
168                : "r" (lr)
169        );
170}
171
172static inline uint32_t ppc_machine_state_register()
173{
174        uint32_t msr;
175
176        asm volatile (
177                "mfmsr %0"
178                : "=r" (msr)
179        );
180
181        return msr;
182}
183
184static inline void ppc_set_machine_state_register( uint32_t msr)
185{
186        asm volatile (
187                "mtmsr %0"
188                :
189                : "r" (msr)
190        );
191}
192
193/**
194 * @brief Enables external exceptions.
195 *
196 * You can use this function to enable the external exceptions and restore the
197 * machine state with ppc_external_exceptions_disable() later.
198 */
199static inline uint32_t ppc_external_exceptions_enable()
200{
201        uint32_t current_msr;
202        uint32_t new_msr;
203
204        RTEMS_COMPILER_MEMORY_BARRIER();
205
206        asm volatile (
207                "mfmsr %0;"
208                "ori %1, %0, 0x8000;"
209                "mtmsr %1"
210                : "=r" (current_msr), "=r" (new_msr)
211        );
212
213        return current_msr;
214}
215
216/**
217 * @brief Restores machine state.
218 *
219 * @see ppc_external_exceptions_enable()
220 */
221static inline void ppc_external_exceptions_disable( uint32_t msr)
222{
223        ppc_set_machine_state_register( msr);
224
225        RTEMS_COMPILER_MEMORY_BARRIER();
226}
227
228static inline uint32_t ppc_decrementer_register()
229{
230        uint32_t dec;
231
232        PPC_Get_decrementer( dec);
233
234        return dec;
235}
236
237static inline void ppc_set_decrementer_register( uint32_t dec)
238{
239        PPC_Set_decrementer( dec);
240}
241
242#define PPC_STRINGOF(x) #x
243
244/* Do not use the following macros.  Use the inline functions instead. */
245
246#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr) \
247        uint32_t val; \
248        asm volatile ( \
249                "mfspr %0, " #spr \
250                : "=r" (val) \
251        ); \
252        return val;
253
254#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( spr) \
255        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr)
256
257#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
258        asm volatile ( \
259                "mtspr " #spr ", %0" \
260                : \
261                : "r" (val) \
262        );
263
264#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( spr, val) \
265        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val)
266
267/*
268 * PPC4xx have Device Control Registers...
269 */
270#define PPC_DEVICE_CONTROL_REGISTER(dcr)                        \
271  ({uint32_t val;asm volatile ("mfspr %0," PPC_STRINGOF(dcr)    \
272                               : "=r" (val)); val;})
273
274#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr,val)        \
275  do {                                                  \
276    asm volatile ("mtspr " PPC_STRINGOF(dcr)",%0"       \
277                  :: "r" (val));                        \
278    } while (0)
279
280
281static inline uint32_t ppc_special_purpose_register_0()
282{
283        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0);
284}
285
286static inline void ppc_set_special_purpose_register_0( uint32_t val)
287{
288        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0, val);
289}
290
291static inline uint32_t ppc_special_purpose_register_1()
292{
293        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1);
294}
295
296static inline void ppc_set_special_purpose_register_1( uint32_t val)
297{
298        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1, val);
299}
300
301static inline uint32_t ppc_special_purpose_register_2()
302{
303        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2);
304}
305
306static inline void ppc_set_special_purpose_register_2( uint32_t val)
307{
308        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2, val);
309}
310
311static inline uint32_t ppc_special_purpose_register_3()
312{
313        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3);
314}
315
316static inline void ppc_set_special_purpose_register_3( uint32_t val)
317{
318        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3, val);
319}
320
321static inline uint32_t ppc_special_purpose_register_4()
322{
323        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG4);
324}
325
326static inline void ppc_set_special_purpose_register_4( uint32_t val)
327{
328        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG4, val);
329}
330
331static inline uint32_t ppc_special_purpose_register_5()
332{
333        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG5);
334}
335
336static inline void ppc_set_special_purpose_register_5( uint32_t val)
337{
338        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG5, val);
339}
340
341static inline uint32_t ppc_special_purpose_register_6()
342{
343        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG6);
344}
345
346static inline void ppc_set_special_purpose_register_6( uint32_t val)
347{
348        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG6, val);
349}
350
351static inline uint32_t ppc_special_purpose_register_7()
352{
353        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG7);
354}
355
356static inline void ppc_set_special_purpose_register_7( uint32_t val)
357{
358        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG7, val);
359}
360
361static inline uint32_t ppc_user_special_purpose_register_0()
362{
363        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( USPRG0);
364}
365
366static inline void ppc_set_user_special_purpose_register_0( uint32_t val)
367{
368        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( USPRG0, val);
369}
370
371static inline uint32_t ppc_timer_control_register()
372{
373        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR);
374}
375
376static inline void ppc_set_timer_control_register( uint32_t val)
377{
378        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR, val);
379}
380
381static inline uint32_t ppc_timer_status_register()
382{
383        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR);
384}
385
386static inline void ppc_set_timer_status_register( uint32_t val)
387{
388        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR, val);
389}
390
391static inline uint32_t ppc_decrementer_auto_reload_register()
392{
393        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR);
394}
395
396static inline void ppc_set_decrementer_auto_reload_register( uint32_t val)
397{
398        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR, val);
399}
400
401static inline uint32_t ppc_hardware_implementation_dependent_register_0()
402{
403        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0);
404}
405
406static inline void ppc_set_hardware_implementation_dependent_register_0( uint32_t val)
407{
408        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0, val);
409}
410
411static inline uint32_t ppc_hardware_implementation_dependent_register_1()
412{
413        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID1);
414}
415
416static inline void ppc_set_hardware_implementation_dependent_register_1( uint32_t val)
417{
418        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( HID1, val);
419}
420
421static inline uint32_t ppc_time_base()
422{
423        uint32_t val;
424
425        CPU_Get_timebase_low( val);
426
427        return val;
428}
429
430static inline void ppc_set_time_base( uint32_t val)
431{
432        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( TBWL, val);
433}
434
435static inline uint32_t ppc_time_base_upper()
436{
437        PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( TBRU);
438}
439
440static inline void ppc_set_time_base_upper( uint32_t val)
441{
442        PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( TBWU, val);
443}
444
445static inline uint64_t ppc_time_base_64()
446{
447        return PPC_Get_timebase_register();
448}
449
450static inline void ppc_set_time_base_64( uint64_t val)
451{
452        PPC_Set_timebase_register( val);
453}
454
455#else /* ASM */
456
457#include <rtems/asm.h>
458
459.macro LA reg, addr
460        lis \reg, (\addr)@h
461        ori \reg, \reg, (\addr)@l
462.endm
463
464.macro LWI reg, value
465        lis \reg, (\value)@h
466        ori \reg, \reg, (\value)@l
467.endm
468
469.macro LW reg, addr
470        lis \reg, \addr@ha
471        lwz \reg, \addr@l(\reg)
472.endm
473
474/*
475 * Tests the bits in reg1 against the bits set in mask.  A match is indicated
476 * by EQ = 0 in CR0.  A mismatch is indicated by EQ = 1 in CR0.  The register
477 * reg2 is used to load the mask.
478 */
479.macro  TSTBITS reg1, reg2, mask
480        LWI     \reg2, \mask
481        and     \reg1, \reg1, \reg2
482        cmplw   \reg1, \reg2
483.endm   
484       
485.macro  SETBITS reg1, reg2, mask
486        LWI     \reg2, \mask
487        or      \reg1, \reg1, \reg2
488.endm
489
490.macro  CLRBITS reg1, reg2, mask
491        LWI     \reg2, \mask
492        andc    \reg1, \reg1, \reg2
493.endm
494
495.macro GLOBAL_FUNCTION name
496        .global \name
497        .type \name, @function
498\name:
499.endm
500
501/*
502 * Disables all asynchronous exeptions (interrupts) which may cause a context
503 * switch.
504 */
505.macro INTERRUPT_DISABLE level, mask
506        mfmsr   \level
507        mfspr   \mask, sprg0
508        andc    \mask, \level, \mask
509        mtmsr   \mask
510.endm
511
512/*
513 * Restore previous machine state.
514 */
515.macro INTERRUPT_ENABLE level
516        mtmsr   \level
517.endm
518
519#define LINKER_SYMBOL( sym) .extern sym
520
521#endif /* ASM */
522
523#endif /* LIBCPU_POWERPC_UTILITY_H */
Note: See TracBrowser for help on using the repository browser.