mirror of https://github.com/ARMmbed/mbed-os.git
i.MX RT1050: Reactivate data cache
Since commit 12c6b1bd8
, the i.MX RT1050 has effectively had its data
cache disabled, as the SDRAM was marked Shareable; for the Cortex-M7,
shareable memory is not cached.
This was done to make the Ethernet driver work without any cache
maintenance code. This commit adds cache maintenance and memory barriers
to the Ethernet driver, and removes the Shareable attribute from the
SDRAM, so the data cache is used again.
Cache code in the base fsl_enet.c driver has not been activated - the
bulk of it is in higher-level Read and Write calls that we're not using,
and there is one flawed invalidate in its initialisation. Instead
imx_emac.cpp takes full cache responsibility.
This commit also marks the SDRAM as read/write-allocate. As the
Cortex-M7 has its "Dynamic read allocate mode" to automatically switch
back to read-allocate in cases where write allocate is working poorly
(eg large memset), this should result in a performance boost with no
downside.
Activating write-allocate is also an attempt to provoke any flaws in
cache maintenance - the Ethernet transmit buffers for example will be
more likely to have a little data in the cache that needs cleaning.
pull/10314/head
parent
65942ba906
commit
6fe50763f3
|
@ -99,6 +99,9 @@ static void update_read_buffer(uint8_t *buf)
|
|||
g_handle.rxBdCurrent[0]->buffer = buf;
|
||||
}
|
||||
|
||||
/* Ensures buffer pointer is written before control. */
|
||||
__DMB();
|
||||
|
||||
/* Clears status. */
|
||||
g_handle.rxBdCurrent[0]->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
|
||||
|
||||
|
@ -112,6 +115,9 @@ static void update_read_buffer(uint8_t *buf)
|
|||
g_handle.rxBdCurrent[0]++;
|
||||
}
|
||||
|
||||
/* Ensures descriptor is written before kicking hardware. */
|
||||
__DSB();
|
||||
|
||||
/* Actives the receive buffer descriptor. */
|
||||
ENET->RDAR = ENET_RDAR_RDAR_MASK;
|
||||
}
|
||||
|
@ -195,6 +201,7 @@ bool Kinetis_EMAC::low_level_init_successful()
|
|||
return false;
|
||||
|
||||
rx_ptr[i] = (uint32_t*)memory_manager->get_ptr(rx_buff[i]);
|
||||
SCB_InvalidateDCache_by_Addr(rx_ptr[i], ENET_ALIGN(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT));
|
||||
}
|
||||
|
||||
tx_consume_index = tx_produce_index = 0;
|
||||
|
@ -277,6 +284,7 @@ emac_mem_buf_t *Kinetis_EMAC::low_level_input(int idx)
|
|||
|
||||
/* Zero-copy */
|
||||
p = rx_buff[idx];
|
||||
SCB_InvalidateDCache_by_Addr(rx_ptr[idx], length);
|
||||
memory_manager->set_len(p, length);
|
||||
|
||||
/* Attempt to queue new buffer */
|
||||
|
@ -295,6 +303,7 @@ emac_mem_buf_t *Kinetis_EMAC::low_level_input(int idx)
|
|||
|
||||
rx_buff[idx] = temp_rxbuf;
|
||||
rx_ptr[idx] = (uint32_t*)memory_manager->get_ptr(rx_buff[idx]);
|
||||
SCB_InvalidateDCache_by_Addr(rx_ptr[idx], ENET_ALIGN(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT));
|
||||
|
||||
update_read_buffer((uint8_t*)rx_ptr[idx]);
|
||||
}
|
||||
|
@ -399,6 +408,8 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
buf = copy_buf;
|
||||
}
|
||||
|
||||
SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(memory_manager->get_ptr(buf)), memory_manager->get_len(buf));
|
||||
|
||||
/* Check if a descriptor is available for the transfer (wait 10ms before dropping the buffer) */
|
||||
if (xTXDCountSem.wait(10) == 0) {
|
||||
memory_manager->free(buf);
|
||||
|
@ -415,6 +426,8 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
/* Setup transfers */
|
||||
g_handle.txBdCurrent[0]->buffer = static_cast<uint8_t *>(memory_manager->get_ptr(buf));
|
||||
g_handle.txBdCurrent[0]->length = memory_manager->get_len(buf);
|
||||
/* Ensures buffer and length is written before control. */
|
||||
__DMB();
|
||||
g_handle.txBdCurrent[0]->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
|
||||
|
||||
/* Increase the buffer descriptor address. */
|
||||
|
@ -424,6 +437,9 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
g_handle.txBdCurrent[0]++;
|
||||
}
|
||||
|
||||
/* Ensures descriptor is written before kicking hardware. */
|
||||
__DSB();
|
||||
|
||||
/* Active the transmit buffer descriptor. */
|
||||
ENET->TDAR = ENET_TDAR_TDAR_MASK;
|
||||
|
||||
|
|
|
@ -102,13 +102,13 @@ void BOARD_ConfigMPU(void)
|
|||
* this suggestion is referred from chapter 2.2.1 Memory regions,
|
||||
* types and attributes in Cortex-M7 Devices, Generic User Guide */
|
||||
#if defined(SDRAM_IS_SHAREABLE)
|
||||
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
/* Region 7 setting: Memory with Normal type, shareable, outer/inner write back, write/read allocate */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
#else
|
||||
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back, write/read allocate */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
#endif
|
||||
|
||||
/* Region 8 setting, set last 2MB of SDRAM can't be accessed by cache, glocal variables which are not expected to be
|
||||
|
|
|
@ -1916,7 +1916,6 @@
|
|||
"XIP_BOOT_HEADER_DCD_ENABLE=1",
|
||||
"SKIP_SYSCLK_INIT",
|
||||
"FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE",
|
||||
"SDRAM_IS_SHAREABLE",
|
||||
"MBED_MPU_CUSTOM"
|
||||
],
|
||||
"inherits": ["Target"],
|
||||
|
|
Loading…
Reference in New Issue