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

4.104.114.95
Last change on this file since 31282767 was 31282767, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/10/08 at 06:43:45

changed names of internal macros

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