Update for exception support changes.

This commit is contained in:
Thomas Doerfler
2009-10-23 07:32:46 +00:00
parent cc1e864dfe
commit 2d2de4eba1
103 changed files with 1609 additions and 1588 deletions

View File

@@ -29,165 +29,182 @@
#ifndef LIBCPU_POWERPC_UTILITY_H
#define LIBCPU_POWERPC_UTILITY_H
#ifndef ASM
#include <rtems.h>
#endif
#include <rtems/score/cpu.h>
#include <rtems/powerpc/registers.h>
#include <rtems/powerpc/powerpc.h>
#ifndef ASM
#include <stdint.h>
#include <rtems/bspIo.h>
#include <rtems/system.h>
#include <rtems/score/cpu.h>
#include <libcpu/cpuIdent.h>
#define LINKER_SYMBOL( sym) extern char sym []
#define LINKER_SYMBOL(sym) extern char sym []
/**
* @brief Read one byte from @a src.
*/
static inline uint8_t ppc_read_byte( const volatile void *src)
static inline uint8_t ppc_read_byte(const volatile void *src)
{
uint8_t value;
uint8_t value;
asm volatile (
"lbz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
asm volatile (
"lbz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
return value;
return value;
}
/**
* @brief Read one half word from @a src.
*/
static inline uint16_t ppc_read_half_word( const volatile void *src)
static inline uint16_t ppc_read_half_word(const volatile void *src)
{
uint16_t value;
uint16_t value;
asm volatile (
"lhz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
asm volatile (
"lhz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
return value;
return value;
}
/**
* @brief Read one word from @a src.
*/
static inline uint32_t ppc_read_word( const volatile void *src)
static inline uint32_t ppc_read_word(const volatile void *src)
{
uint32_t value;
uint32_t value;
asm volatile (
"lwz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
asm volatile (
"lwz %0, 0(%1)"
: "=r" (value)
: "b" (src)
);
return value;
return value;
}
/**
* @brief Write one byte @a value to @a dest.
*/
static inline void ppc_write_byte( uint8_t value, volatile void *dest)
static inline void ppc_write_byte(uint8_t value, volatile void *dest)
{
asm volatile (
"stb %0, 0(%1)"
:
: "r" (value), "b" (dest)
);
asm volatile (
"stb %0, 0(%1)"
:
: "r" (value), "b" (dest)
);
}
/**
* @brief Write one half word @a value to @a dest.
*/
static inline void ppc_write_half_word( uint16_t value, volatile void *dest)
static inline void ppc_write_half_word(uint16_t value, volatile void *dest)
{
asm volatile (
"sth %0, 0(%1)"
:
: "r" (value), "b" (dest)
);
asm volatile (
"sth %0, 0(%1)"
:
: "r" (value), "b" (dest)
);
}
/**
* @brief Write one word @a value to @a dest.
*/
static inline void ppc_write_word( uint32_t value, volatile void *dest)
static inline void ppc_write_word(uint32_t value, volatile void *dest)
{
asm volatile (
"stw %0, 0(%1)" :
: "r" (value), "b" (dest)
);
asm volatile (
"stw %0, 0(%1)" :
: "r" (value), "b" (dest)
);
}
static inline void *ppc_stack_pointer()
static inline void *ppc_stack_pointer(void)
{
void *sp;
void *sp;
asm volatile (
"mr %0, 1"
: "=r" (sp)
);
asm volatile (
"mr %0, 1"
: "=r" (sp)
);
return sp;
return sp;
}
static inline void ppc_set_stack_pointer( void *sp)
static inline void ppc_set_stack_pointer(void *sp)
{
asm volatile (
"mr 1, %0"
:
: "r" (sp)
);
asm volatile (
"mr 1, %0"
:
: "r" (sp)
);
}
static inline void *ppc_link_register()
static inline void *ppc_link_register(void)
{
void *lr;
void *lr;
asm volatile (
"mflr %0"
: "=r" (lr)
);
asm volatile (
"mflr %0"
: "=r" (lr)
);
return lr;
return lr;
}
static inline void ppc_set_link_register( void *lr)
static inline void ppc_set_link_register(void *lr)
{
asm volatile (
"mtlr %0"
:
: "r" (lr)
);
asm volatile (
"mtlr %0"
:
: "r" (lr)
);
}
static inline uint32_t ppc_machine_state_register()
static inline uint32_t ppc_machine_state_register(void)
{
uint32_t msr;
uint32_t msr;
asm volatile (
"mfmsr %0"
: "=r" (msr)
);
asm volatile (
"mfmsr %0"
: "=r" (msr)
);
return msr;
return msr;
}
static inline void ppc_set_machine_state_register( uint32_t msr)
static inline void ppc_set_machine_state_register(uint32_t msr)
{
asm volatile (
"mtmsr %0"
:
: "r" (msr)
);
asm volatile (
"mtmsr %0"
:
: "r" (msr)
);
}
static inline void ppc_synchronize_data(void)
{
RTEMS_COMPILER_MEMORY_BARRIER();
asm volatile ("sync");
}
static inline void ppc_synchronize_instructions(void)
{
RTEMS_COMPILER_MEMORY_BARRIER();
asm volatile ("isync");
}
/**
@@ -196,21 +213,21 @@ static inline void ppc_set_machine_state_register( uint32_t msr)
* You can use this function to enable the external exceptions and restore the
* machine state with ppc_external_exceptions_disable() later.
*/
static inline uint32_t ppc_external_exceptions_enable()
static inline uint32_t ppc_external_exceptions_enable(void)
{
uint32_t current_msr;
uint32_t new_msr;
uint32_t current_msr;
uint32_t new_msr;
RTEMS_COMPILER_MEMORY_BARRIER();
RTEMS_COMPILER_MEMORY_BARRIER();
asm volatile (
"mfmsr %0;"
"ori %1, %0, 0x8000;"
"mtmsr %1"
: "=r" (current_msr), "=r" (new_msr)
);
asm volatile (
"mfmsr %0;"
"ori %1, %0, 0x8000;"
"mtmsr %1"
: "=r" (current_msr), "=r" (new_msr)
);
return current_msr;
return current_msr;
}
/**
@@ -218,59 +235,59 @@ static inline uint32_t ppc_external_exceptions_enable()
*
* @see ppc_external_exceptions_enable()
*/
static inline void ppc_external_exceptions_disable( uint32_t msr)
static inline void ppc_external_exceptions_disable(uint32_t msr)
{
ppc_set_machine_state_register( msr);
ppc_set_machine_state_register(msr);
RTEMS_COMPILER_MEMORY_BARRIER();
RTEMS_COMPILER_MEMORY_BARRIER();
}
static inline uint32_t ppc_decrementer_register()
static inline uint32_t ppc_decrementer_register(void)
{
uint32_t dec;
uint32_t dec;
PPC_Get_decrementer( dec);
PPC_Get_decrementer(dec);
return dec;
return dec;
}
static inline void ppc_set_decrementer_register( uint32_t dec)
static inline void ppc_set_decrementer_register(uint32_t dec)
{
PPC_Set_decrementer( dec);
PPC_Set_decrementer(dec);
}
/**
* @brief Preprocessor magic for stringification of @a x.
*/
#define PPC_STRINGOF( x) #x
#define PPC_STRINGOF(x) #x
/**
* @brief Returns the value of the Special Purpose Register with number @a spr.
*
* @note This macro uses a GNU C extension.
*/
#define PPC_SPECIAL_PURPOSE_REGISTER( spr) \
( { \
uint32_t val; \
asm volatile ( \
"mfspr %0, " PPC_STRINGOF( spr) \
: "=r" (val) \
); \
val;\
} )
#define PPC_SPECIAL_PURPOSE_REGISTER(spr) \
({ \
uint32_t val; \
asm volatile (\
"mfspr %0, " PPC_STRINGOF(spr) \
: "=r" (val) \
); \
val;\
} )
/**
* @brief Sets the Special Purpose Register with number @a spr to the value in
* @a val.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
do { \
asm volatile ( \
"mtspr " PPC_STRINGOF( spr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
#define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val) \
do { \
asm volatile (\
"mtspr " PPC_STRINGOF(spr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
/**
* @brief Sets in the Special Purpose Register with number @a spr all bits
@@ -278,17 +295,17 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val |= mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable(level); \
val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
val |= mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
rtems_interrupt_enable(level); \
} while (0)
/**
* @brief Sets in the Special Purpose Register with number @a spr all bits
@@ -297,19 +314,19 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED( spr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
uint32_t mymask = mask; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val &= ~mymask; \
val |= mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(spr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
uint32_t mymask = mask; \
rtems_interrupt_disable(level); \
val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
val &= ~mymask; \
val |= mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
rtems_interrupt_enable(level); \
} while (0)
/**
* @brief Clears in the Special Purpose Register with number @a spr all bits
@@ -317,17 +334,17 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS( spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val &= ~mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable(level); \
val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
val &= ~mybits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
rtems_interrupt_enable(level); \
} while (0)
/**
* @brief Returns the value of the Device Control Register with number @a dcr.
@@ -336,15 +353,15 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* @note This macro uses a GNU C extension.
*/
#define PPC_DEVICE_CONTROL_REGISTER( dcr) \
( { \
uint32_t val; \
asm volatile ( \
"mfdcr %0, " PPC_STRINGOF( dcr) \
: "=r" (val) \
); \
val;\
} )
#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
({ \
uint32_t val; \
asm volatile (\
"mfdcr %0, " PPC_STRINGOF(dcr) \
: "=r" (val) \
); \
val;\
} )
/**
* @brief Sets the Device Control Register with number @a dcr to the value in
@@ -352,14 +369,14 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* The PowerPC 4XX family has Device Control Registers.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val) \
do { \
asm volatile ( \
"mtdcr " PPC_STRINGOF( dcr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val) \
do { \
asm volatile (\
"mtdcr " PPC_STRINGOF(dcr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
/**
* @brief Sets in the Device Control Register with number @a dcr all bits
@@ -367,17 +384,17 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS( dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val |= mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable(level); \
val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
val |= mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
rtems_interrupt_enable(level); \
} while (0)
/**
* @brief Sets in the Device Control Register with number @a dcr all bits
@@ -386,19 +403,19 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED( dcr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
uint32_t mymask = mask; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val &= ~mymask; \
val |= mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED(dcr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
uint32_t mymask = mask; \
rtems_interrupt_disable(level); \
val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
val &= ~mymask; \
val |= mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
rtems_interrupt_enable(level); \
} while (0)
/**
* @brief Clears in the Device Control Register with number @a dcr all bits
@@ -406,52 +423,54 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS( dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val &= ~mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
uint32_t mybits = bits; \
rtems_interrupt_disable(level); \
val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
val &= ~mybits; \
PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
rtems_interrupt_enable(level); \
} while (0)
static inline uint32_t ppc_time_base()
static inline uint32_t ppc_time_base(void)
{
uint32_t val;
uint32_t val;
CPU_Get_timebase_low( val);
CPU_Get_timebase_low(val);
return val;
return val;
}
static inline void ppc_set_time_base( uint32_t val)
static inline void ppc_set_time_base(uint32_t val)
{
PPC_SET_SPECIAL_PURPOSE_REGISTER( TBWL, val);
PPC_SET_SPECIAL_PURPOSE_REGISTER(TBWL, val);
}
static inline uint32_t ppc_time_base_upper()
static inline uint32_t ppc_time_base_upper(void)
{
return PPC_SPECIAL_PURPOSE_REGISTER( TBRU);
return PPC_SPECIAL_PURPOSE_REGISTER(TBRU);
}
static inline void ppc_set_time_base_upper( uint32_t val)
static inline void ppc_set_time_base_upper(uint32_t val)
{
PPC_SET_SPECIAL_PURPOSE_REGISTER( TBWU, val);
PPC_SET_SPECIAL_PURPOSE_REGISTER(TBWU, val);
}
static inline uint64_t ppc_time_base_64()
static inline uint64_t ppc_time_base_64(void)
{
return PPC_Get_timebase_register();
return PPC_Get_timebase_register();
}
static inline void ppc_set_time_base_64( uint64_t val)
static inline void ppc_set_time_base_64(uint64_t val)
{
PPC_Set_timebase_register( val);
PPC_Set_timebase_register(val);
}
void ppc_code_copy(void *dest, const void *src, size_t n);
#else /* ASM */
#include <rtems/asm.h>
@@ -523,7 +542,7 @@ static inline void ppc_set_time_base_64( uint64_t val)
mtmsr \level
.endm
#define LINKER_SYMBOL( sym) .extern sym
#define LINKER_SYMBOL(sym) .extern sym
#endif /* ASM */