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

4.104.114.9
Last change on this file since 3c6fe2e was 3c6fe2e, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 14, 2008 at 8:46:06 AM

added haleakala BSP contributed by Michael Hamel

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