Jump to content

    
Sign in to follow this  
amaora

Конвейеры и кэши cortex-m7

Recommended Posts

Есть несколько мест в коде на счёт которых я сомневаюсь в их корректности для m7 в частности и для всех других cortex-**. Хотел бы спросить чужого мнения об этом.

 

(1) Это реализация критической секции. Вызываться может из контекста потоков rtos и из обработчиков прерываний. Безопасно ли так читать BASEPRI? Нужны ли ISB/DSB и в каком порядке? Наоборот? Нужно ли обкладываться запретом прерываний как говорит 837070 erratum?

int hal_lock_irq()
{
	int		irq;

	irq = __get_BASEPRI();
	__set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS));

	__ISB();
	__DSB();

	return irq;
}

void hal_unlock_irq(int irq)
{
	__set_BASEPRI(irq);
}

 

(2) По поводу 837070 erratum, во freertos в сохранялке контекста сделали вот так:

$ diff -u ARM_CM4F/port.c ARM_CM7/r0p1/port.c
...
@@ -449,9 +437,11 @@
        "                                                                               \n"
        "       stmdb sp!, {r0, r3}                                     \n"
        "       mov r0, %0                                                      \n"
+       "       cpsid i                                                         \n" /* Errata workaround. */
        "       msr basepri, r0                                         \n"
        "       dsb                                                                     \n"
        "       isb                                                                     \n"
+       "       cpsie i                                                         \n" /* Errata workaround. */
        "       bl vTaskSwitchContext                           \n"
        "       mov r0, #0                                                      \n"
        "       msr basepri, r0                                         \n"

Нужно ли это? Почему не достаточно dsb/isb если в описании erratum речь шла только про то, что под угрозой лишь одна инструкция после msr? В других местах freertos где делается запись в BASEPRI ничего не добавили.

 

(3) При записи данных во флешь делаю сброс и аннулирование кэша по этому адресу, уходит вся строка кэша как я понимаю. Но так же известно, что для области флеша используется write-through и может быть ничего и не нужно специально предпринимать (если предположить, что перечитывать флешь не хотим)? А может быть ещё и ISB не хватает перед обращением к DCCIMVAC?

	while (long_flash < long_end) {

		/* Program flash memory.
		 * */
		*long_flash = *long_s++;

		__DSB();

#ifdef _HW_STM32F722

		/* D-Cache Clean and Invalidate.
		 * */
		SCB->DCCIMVAC = (u32_t) long_flash;

		__DSB();
		__ISB();

#endif /* _HW_STM32F722 */

		long_flash++;
      ...

 

(4) После стирания страницы флеша очевидно необходимо аннулировать эту область в кэше, здесь вопроса нет, код не привожу.

 

Спасибо.

Share this post


Link to post
Share on other sites
6 minutes ago, GenaSPB said:

4 - я бы озаботился инвалидацией кеша перед стиранием

Не понимаю зачем, после делаю инвалидацию для того чтобы последующие операции чтения не взяли мусор из кэша, а до стирания для чего?

Share this post


Link to post
Share on other sites

Чтобы, если случайно кеш потребуется для другого участка памяти,   старое не попыталось записаться во флешку 

Share this post


Link to post
Share on other sites
35 minutes ago, GenaSPB said:

Чтобы, если случайно кеш потребуется для другого участка памяти,   старое не попыталось записаться во флешку 

Здесь много чего мешает:

- Для области адресов внутренней флешь действует write-through, то есть данные на запись не лежат в кэше а сразу отправляются на запись. Ну допустим на другом cortex-** будет write-back кэш (или через MPU наверно это можно организовать, не знаю не проверял).

- Запись во флешь не делается случайно, выше приводил код записи, и там уже сделан сброс кэша непосредственно после записи каждого слова, принудительный write-through.

- Запись не пройдёт без команды через периферийные регистры флеша, так если из кэша вдруг сбросятся данные когда мы собрались стирать (или уже стерли) страницу, то наверно будет MemoryFault.

Edited by amaora

Share this post


Link to post
Share on other sites

В Cortex-M7 кэш реализован криво (ид ошибки 1259864), поэтому нужны пляски с бубном, включая использование MPU, чтобы вместо write-through использовать write-back (первый глючный, второй -- нормальный).

Share this post


Link to post
Share on other sites
2 hours ago, amaora said:

(1) Это реализация критической секции. Вызываться может из контекста потоков rtos и из обработчиков прерываний. Безопасно ли так читать BASEPRI? Нужны ли ISB/DSB и в каком порядке? Наоборот? Нужно ли обкладываться запретом прерываний как говорит 837070 erratum?

Ставить ISB DSB надо везде где идет запись в System Control Space. 
ARM DAI 0321A параграф 3 , пункт 3, стр 11. 
 

Share this post


Link to post
Share on other sites
16 hours ago, amaora said:

Нужно ли это? Почему не достаточно dsb/isb если в описании erratum речь шла только про то, что под угрозой лишь одна инструкция после msr? В других местах freertos где делается запись в BASEPRI ничего не добавили.

Это пофиксили в r0p2. STM32H750, например, - это уже r1p1...

13 hours ago, SII said:

В Cortex-M7 кэш реализован криво (ид ошибки 1259864), поэтому нужны пляски с бубном, включая использование MPU, чтобы вместо write-through использовать write-back (первый глючный, второй -- нормальный).

Опять же есть STM32H7B/730(r1p2) в которых этого бага уже нет.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this