Fixed bug #512.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6997 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
6711ff45ea
commit
852f75dabe
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,10 +483,10 @@ 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 */
|
||||||
|
|
||||||
/* Shutting down clocks that are no more required, if any.*/
|
/* Shutting down clocks that are no more required, if any.*/
|
||||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
|
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue