git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6997 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2014-06-29 16:42:19 +00:00
parent 6711ff45ea
commit 852f75dabe
7 changed files with 69 additions and 87 deletions

View File

@ -83,8 +83,10 @@ static uint32_t tb[STM32_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE];
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] reg register number * @param[in] reg register number
* @param[in] value new register value * @param[in] value new register value
*
* @notapi
*/ */
static void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) { void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
ETH->MACMIIDR = value; ETH->MACMIIDR = value;
ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR | ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR |
@ -100,8 +102,10 @@ static void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
* @param[in] reg register number * @param[in] reg register number
* *
* @return The PHY register content. * @return The PHY register content.
*
* @notapi
*/ */
static uint32_t mii_read(MACDriver *macp, uint32_t reg) { uint32_t mii_read(MACDriver *macp, uint32_t reg) {
ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MB; ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MB;
while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0) while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0)

View File

@ -328,6 +328,8 @@ extern MACDriver ETHD1;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void mii_write(MACDriver *macp, uint32_t reg, uint32_t value);
uint32_t mii_read(MACDriver *macp, uint32_t reg);
void mac_lld_init(void); void mac_lld_init(void);
void mac_lld_start(MACDriver *macp); void mac_lld_start(MACDriver *macp);
void mac_lld_stop(MACDriver *macp); void mac_lld_stop(MACDriver *macp);

View File

@ -475,7 +475,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
dma_streams_mask &= ~(1 << dmastp->selfindex); dma_streams_mask &= ~(1 << dmastp->selfindex);
/* Disables the associated IRQ vector.*/ /* Disables the associated IRQ vector.*/
#if !(STM32_HAS_DMA2 && !defined(STM32F10X_CL)) || defined(__DOXYGEN__) #if !(STM32_HAS_DMA2 && !defined(STM32F10X_CL))
nvicDisableVector(dmastp->vector); nvicDisableVector(dmastp->vector);
#else #else
/* Check unless it is 10 or 11 stream. If yes, make additional check before /* Check unless it is 10 or 11 stream. If yes, make additional check before
@ -483,7 +483,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
if (dmastp->selfindex < 10) if (dmastp->selfindex < 10)
nvicDisableVector(dmastp->vector); nvicDisableVector(dmastp->vector);
else { else {
if (dma_streams_mask & (3 << 10) == 0) if ((dma_streams_mask & (3 << 10)) == 0)
nvicDisableVector(dmastp->vector); nvicDisableVector(dmastp->vector);
} }
#endif /* STM32_HAS_DMA2 && !STM32F10X_CL */ #endif /* STM32_HAS_DMA2 && !STM32F10X_CL */

View File

@ -60,21 +60,21 @@
* @note The PendSV vector is only used in advanced kernel mode. * @note The PendSV vector is only used in advanced kernel mode.
*/ */
void SVC_Handler(void) { void SVC_Handler(void) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing unstacking of the FP part of the context.*/
SCB_FPCCR &= ~FPCCR_LSPACT;
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Discarding the current exception context and positioning the stack to /* Discarding the current exception context and positioning the stack to
point to the real one.*/ point to the real one.*/
ctxp++; ctxp++;
#if CORTEX_USE_FPU /* Restoring real position of the original stack frame.*/
/* Restoring the special register FPCCR.*/
FPU->FPCCR = (uint32_t)ctxp->fpccr;
FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx);
#endif
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp); __set_PSP((uint32_t)ctxp);
/* Restoring the normal interrupts status.*/ /* Restoring the normal interrupts status.*/
@ -90,20 +90,20 @@ void SVC_Handler(void) {
* @note The PendSV vector is only used in compact kernel mode. * @note The PendSV vector is only used in compact kernel mode.
*/ */
void PendSV_Handler(void) { void PendSV_Handler(void) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing unstacking of the FP part of the context.*/
SCB_FPCCR &= ~FPCCR_LSPACT;
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Discarding the current exception context and positioning the stack to /* Discarding the current exception context and positioning the stack to
point to the real one.*/ point to the real one.*/
ctxp++; ctxp++;
#if CORTEX_USE_FPU
/* Restoring the special register FPCCR.*/
FPU->FPCCR = (uint32_t)ctxp->fpccr;
FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx);
#endif
/* Writing back the modified PSP value.*/ /* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp); __set_PSP((uint32_t)ctxp);
} }
@ -120,29 +120,31 @@ void _port_irq_epilogue(void) {
port_lock_from_isr(); port_lock_from_isr();
if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) { if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
(void) __get_FPSCR();
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Adding an artificial exception return context, there is no need to /* Adding an artificial exception return context, there is no need to
populate it fully.*/ populate it fully.*/
ctxp--; ctxp--;
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp);
/* Setting up a fake XPSR register value.*/ /* Setting up a fake XPSR register value.*/
ctxp->xpsr = (regarm_t)0x01000000; ctxp->xpsr = (regarm_t)0x01000000;
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp);
/* The exit sequence is different depending on if a preemption is /* The exit sequence is different depending on if a preemption is
required or not.*/ required or not.*/
if (chSchIsRescRequiredI()) { if (chSchIsRescRequiredI()) {
/* Preemption is required we need to enforce a context switch.*/ /* Preemption is required we need to enforce a context switch.*/
ctxp->pc = (regarm_t)_port_switch_from_isr; ctxp->pc = (regarm_t)_port_switch_from_isr;
#if CORTEX_USE_FPU
/* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
(void) __get_FPSCR();
#endif
} }
else { else {
/* Preemption not required, we just need to exit the exception /* Preemption not required, we just need to exit the exception
@ -150,20 +152,6 @@ void _port_irq_epilogue(void) {
ctxp->pc = (regarm_t)_port_exit_from_isr; ctxp->pc = (regarm_t)_port_exit_from_isr;
} }
#if CORTEX_USE_FPU
{
uint32_t fpccr;
/* Saving the special register SCB_FPCCR into the reserved offset of
the Cortex-M4 exception frame.*/
(ctxp + 1)->fpccr = (regarm_t)(fpccr = FPU->FPCCR);
/* Now the FPCCR is modified in order to not restore the FPU status
from the artificial return context.*/
FPU->FPCCR = fpccr | FPU_FPCCR_LSPACT_Msk;
}
#endif
/* Note, returning without unlocking is intentional, this is done in /* Note, returning without unlocking is intentional, this is done in
order to keep the rest of the context switch atomic.*/ order to keep the rest of the context switch atomic.*/
return; return;

View File

@ -238,7 +238,7 @@ struct port_extctx {
regarm_t s14; regarm_t s14;
regarm_t s15; regarm_t s15;
regarm_t fpscr; regarm_t fpscr;
regarm_t fpccr; regarm_t reserved;
#endif /* CORTEX_USE_FPU */ #endif /* CORTEX_USE_FPU */
}; };
@ -395,12 +395,12 @@ static inline void port_init(void) {
* @return The interrupts status. * @return The interrupts status.
*/ */
static inline syssts_t port_get_irq_status(void) { static inline syssts_t port_get_irq_status(void) {
syssts_t sts; register uint32_t sts;
#if !CORTEX_SIMPLIFIED_PRIORITY #if !CORTEX_SIMPLIFIED_PRIORITY
sts = (syssts_t)__get_BASEPRI(); sts = __get_BASEPRI();
#else /* CORTEX_SIMPLIFIED_PRIORITY */ #else /* CORTEX_SIMPLIFIED_PRIORITY */
sts = (syssts_t)__get_PRIMASK(); sts = __get_PRIMASK();
#endif /* CORTEX_SIMPLIFIED_PRIORITY */ #endif /* CORTEX_SIMPLIFIED_PRIORITY */
return sts; return sts;
} }

View File

@ -60,21 +60,21 @@
* @note The PendSV vector is only used in advanced kernel mode. * @note The PendSV vector is only used in advanced kernel mode.
*/ */
void SVC_Handler(void) { void SVC_Handler(void) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing unstacking of the FP part of the context.*/
SCB_FPCCR &= ~FPCCR_LSPACT;
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Discarding the current exception context and positioning the stack to /* Discarding the current exception context and positioning the stack to
point to the real one.*/ point to the real one.*/
ctxp++; ctxp++;
#if CORTEX_USE_FPU /* Restoring real position of the original stack frame.*/
/* Restoring the special register FPCCR.*/
FPU->FPCCR = (uint32_t)ctxp->fpccr;
FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx);
#endif
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp); __set_PSP((uint32_t)ctxp);
/* Restoring the normal interrupts status.*/ /* Restoring the normal interrupts status.*/
@ -90,20 +90,20 @@ void SVC_Handler(void) {
* @note The PendSV vector is only used in compact kernel mode. * @note The PendSV vector is only used in compact kernel mode.
*/ */
void PendSV_Handler(void) { void PendSV_Handler(void) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing unstacking of the FP part of the context.*/
SCB_FPCCR &= ~FPCCR_LSPACT;
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Discarding the current exception context and positioning the stack to /* Discarding the current exception context and positioning the stack to
point to the real one.*/ point to the real one.*/
ctxp++; ctxp++;
#if CORTEX_USE_FPU
/* Restoring the special register FPCCR.*/
FPU->FPCCR = (uint32_t)ctxp->fpccr;
FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx);
#endif
/* Writing back the modified PSP value.*/ /* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp); __set_PSP((uint32_t)ctxp);
} }
@ -120,29 +120,31 @@ void _port_irq_epilogue(void) {
port_lock_from_isr(); port_lock_from_isr();
if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) { if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) {
struct port_extctx *ctxp;
#if CORTEX_USE_FPU
/* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
(void) __get_FPSCR();
#endif
/* The port_extctx structure is pointed by the PSP register.*/ /* The port_extctx structure is pointed by the PSP register.*/
struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); ctxp = (struct port_extctx *)__get_PSP();
/* Adding an artificial exception return context, there is no need to /* Adding an artificial exception return context, there is no need to
populate it fully.*/ populate it fully.*/
ctxp--; ctxp--;
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp);
/* Setting up a fake XPSR register value.*/ /* Setting up a fake XPSR register value.*/
ctxp->xpsr = (regarm_t)0x01000000; ctxp->xpsr = (regarm_t)0x01000000;
/* Writing back the modified PSP value.*/
__set_PSP((uint32_t)ctxp);
/* The exit sequence is different depending on if a preemption is /* The exit sequence is different depending on if a preemption is
required or not.*/ required or not.*/
if (chSchIsPreemptionRequired()) { if (chSchIsPreemptionRequired()) {
/* Preemption is required we need to enforce a context switch.*/ /* Preemption is required we need to enforce a context switch.*/
ctxp->pc = (regarm_t)_port_switch_from_isr; ctxp->pc = (regarm_t)_port_switch_from_isr;
#if CORTEX_USE_FPU
/* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
(void) __get_FPSCR();
#endif
} }
else { else {
/* Preemption not required, we just need to exit the exception /* Preemption not required, we just need to exit the exception
@ -150,20 +152,6 @@ void _port_irq_epilogue(void) {
ctxp->pc = (regarm_t)_port_exit_from_isr; ctxp->pc = (regarm_t)_port_exit_from_isr;
} }
#if CORTEX_USE_FPU
{
uint32_t fpccr;
/* Saving the special register SCB_FPCCR into the reserved offset of
the Cortex-M4 exception frame.*/
(ctxp + 1)->fpccr = (regarm_t)(fpccr = FPU->FPCCR);
/* Now the FPCCR is modified in order to not restore the FPU status
from the artificial return context.*/
FPU->FPCCR = fpccr | FPU_FPCCR_LSPACT_Msk;
}
#endif
/* Note, returning without unlocking is intentional, this is done in /* Note, returning without unlocking is intentional, this is done in
order to keep the rest of the context switch atomic.*/ order to keep the rest of the context switch atomic.*/
return; return;

View File

@ -238,7 +238,7 @@ struct port_extctx {
regarm_t s14; regarm_t s14;
regarm_t s15; regarm_t s15;
regarm_t fpscr; regarm_t fpscr;
regarm_t fpccr; regarm_t reserved;
#endif /* CORTEX_USE_FPU */ #endif /* CORTEX_USE_FPU */
}; };
@ -396,12 +396,12 @@ static inline void port_init(void) {
* @return The interrupts status. * @return The interrupts status.
*/ */
static inline syssts_t port_get_irq_status(void) { static inline syssts_t port_get_irq_status(void) {
syssts_t sts; uint32_t sts;
#if !CORTEX_SIMPLIFIED_PRIORITY #if !CORTEX_SIMPLIFIED_PRIORITY
sts = (syssts_t)__get_BASEPRI(); sts = __get_BASEPRI();
#else /* CORTEX_SIMPLIFIED_PRIORITY */ #else /* CORTEX_SIMPLIFIED_PRIORITY */
sts = (syssts_t)__get_PRIMASK(); sts = __get_PRIMASK();
#endif /* CORTEX_SIMPLIFIED_PRIORITY */ #endif /* CORTEX_SIMPLIFIED_PRIORITY */
return sts; return sts;
} }