Перейти к содержанию
    

MMU D-Cache I-Cache для ARM926EJ-S

Доброго всем здравия!

 

Уважаемые специалисты, помогите разобраться с этими монстрами.

Имеется AT91SAM9260 на базе процессора ARM926EJ-S. Для повышения скорости работы нужно настроить:

 

1) MMU (Memory Management Unit) - Блок управления памятью. Он отвечает за управление доступом к памяти, запрашиваемым центральным процессором путем трансляции адресов виртуальной памяти в адреса физической памяти. MMU разделяет виртуальное адресное пространство на участки одинакового размера (4 Кб, 64 Кб или 1 Mb ) называемые страницами.

Процесс обращается к памяти с помощью адреса виртуальной памяти, который содержит в себе номер страницы и смещение внутри страницы. Процессор преобразует номер виртуальной страницы в адрес соответствующей ей физической страницы при помощи буфера ассоциативной трансляции.

Младшие n бит адреса (смещение внутри страницы) остаются неизменными. Старшие биты адреса представляют собой номер (виртуальной) страницы. MMU обычно преобразует номера виртуальных страниц в номера физических страниц используя TLB(Translation Lookaside Buffer) - Буфер Ассоциативной Трансляции.

Вопрос 1. Как настроить это MMU для указанного выше процессора? Как организовать и заполнить TLB? Как ее подключить к MMU и пользоваться ей?

 

2) Нужно настроить D-Cache (Data Cache - Кэш данных) и I-Cache (Instruction Cache - Кэш комманд процессора).

Кэш — это некий промежуточный буфер, содержащий информацию, которая может быть запрошена с наибольшей вероятностью. Доступ к данным в кэше идёт быстрее, чем выборка исходных данных из внешней памяти. Таким образом комманды и данные выбираются из быстрее и производительность растет.

Кэш состоит из набора записей. Каждая запись ассоциирована с данными, являющимися копией данных в основной памяти. Каждая запись имеет идентификатор, определяющий соответствие между элементами данных в кэше и их копиями в основной памяти.

 

Области (сегменты) основной памяти жёстко привязываются к строкам кэш-памяти (в каждой строке могут быть данные из фиксированного набора адресов), что значительно сокращает время поиска. С каждой ячейкой ОЗУ может быть связано более одной строки кэш-памяти. Таким образом, одна запись в Кэше может содержать несколько комманд (наиболе часто употребляемых) из сооветствующей области памяти.

 

Вопрос 2. Как инициализировать D-Cache и I-Cache? Как и когда (при каких условиях) их очищать? Как с ними работать?

 

 

Что имеется у меня: ARM926EJ-S Technical Reference Manual - написано много, очень грузно, четких инструкций не обнаружено. Много всяких режимов, я так и не понял какой нужен именно мне.

Имеется пример, а точнее функции от IAR, но ни в одном проекте они не применяются, т.е. функции нигдек не используются. Тем самым я не могу понять последовательность действий при инициализации вышеупомянутых модулей. Также есть пример из темы данного форума Производительность SAM9XE, непонятки с этим процом. Там есть как раз пример Translation Table, но не очень понятно как с ней работать и почему именно такие адреса.

 

В ARM926EJ-S еще есть некий регистр TTBR - Translation Table Base Register - я так понял, это регистр указателя начального (базового) адреса расположения TLB. Вопрос где хранить TLB и по какому адресу?

 

 

У меня никак не может сложиться общая картина совместной работы этих модулей. Буду признателен специалистам, которые смогут прояснить мне эти вопросы.

Изменено пользователем ZED

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

unsigned int AT91F_ARM_ReadControl()
{
    register unsigned int ctl;
    ctl = __MRC(15, 0, 1, 0, 0);
        return ctl;
}

void AT91F_ARM_WriteControl(unsigned int ctl)
{
     __MCR(15, 0, ctl, 1, 0, 0);
}

void AT91F_ARM_WriteTTB(unsigned int ttb)
{
    __MCR(15, 0, ttb, 2, 0, 0);
}
void AT91F_ARM_WriteDomain(unsigned int domain)
{
    __MCR(15, 0, domain, 3, 0, 0);
}

void AT91F_InitMMU(void)
{
unsigned int   *TLB  =(unsigned int *) (0x21FF8000);//last 32 K
unsigned int i,ctl;
    // Program the TTB
AT91F_ARM_WriteTTB(0x21FF8000);
AT91F_ARM_WriteDomain(0xFFFFFFFF); // access are not checked
for (i = 0; i < 4096; ++i) TLB[i] = 0;
TLB[0x0]   =  (0x000<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2;
TLB[0x200] =  (0x200<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2;//screen
for (i=0x201;i<(0x201+31);i++)
    TLB[i] = (i<<20)|(1<<10)|(15<<5)|(1<<4)|(3<<2)|0x2;   
TLB[0x006] = (0x006<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; // LCD

TLB[0x21E] = (0x21E<<20)|(1<<10)|(15<<5)|(1<<4)|(0<<2)|0x2; //Peripheria    
TLB[0x21F] = (0x21F<<20)|(1<<10)|(15<<5)|(1<<4)|(1<<2)|0x2; //Peripheria    

TLB[0xFFF] = (0xFFF<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; //Peripheria    

//enable MMU
    ctl = AT91F_ARM_ReadControl();
    ctl |= (1 << 0);
    AT91F_ARM_WriteControl(ctl);
//enable I
        ctl = AT91F_ARM_ReadControl();
    ctl |= (1 << 12);
    AT91F_ARM_WriteControl(ctl);
//enable D
    ctl = AT91F_ARM_ReadControl();
    ctl |= (1 << 2);
    AT91F_ARM_WriteControl(ctl);
}

 

Это для 9261.

Все виртуальные адреса совпадают с физическими.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо DpInRock за Ваш пример. А не могли бы вы описать принцип заполнения TLB.И пояснить как и когда (при каких условиях) очищать кэши? Я просто хочу у сеяб в голове сложить целостную картину.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто почитайте что-нибудь для начала. Ответить на конкретный вопрос - нет проблем. Читать курс лекций - не тот формат.

В мануале про заполнение TLB четко написано. Что означает каждый бит. А я уже успел забыть подробности.

Могу посоветовать только смотреть код и мануал одновременно. И говорить ... ага... (так протяжно и задумчиво).

 

 

Кэш инструкций надо очищать, если вы пишете что-то в область кода (и собираетесь этот код в ближайшем будущем исполнить) - действие не рекомендуемое (в плане, писать что-то в область программ поверх другого кода, который уже исполнлся когда-либо).

 

Данные можно не очищать. Но кэшироваться не должны аппаратные регистры. Я лично не кэширую память экрана.

 

Иными словами, если вы не извращенец - про все типы кэшей - включить и забыть.

 

Посему подстройте мой код под свои адреса, инит - и забыть про все.

 

Наскоко помню у 9260 совсем мало SRAM и код у вас будет из SDRAM? наверное...

Тогда типа рекомендация.

Сначала загрузить программу (не включая кэша и прочая), а уже из самой программы все это инициализировать. Не будет лишних вопросов и кэш будет чище.

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так понял, что Ваша таблица TLB располагается в SDRAM. Базовый адрес TBL 0x21FF 8000.

Сама программа у Вас располагалась в SRAM? начиная с адреса 0x30 0000.

Строчка

TLB[0x006] = (0x006<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; // LCD

видимо отключает кэширование и буфферизацию LCD.

 

TLB[0x0]   =  (0x000<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2;

Это для Boot Memory.

 

Я просто тут немного запутался, разве нам не нужно кэшировать весь Boot Memory, т.е. адреса 0x0000 0000 .. 0x0010 0000? Или достаточно указать только начальный адрес?

 

Что делает эта строчка и для чего нужен режим Write-Back почему не Write-Trough:

for (i=0x201;i<(0x201+31);i++)
    TLB[i] = (i<<20)|(1<<10)|(15<<5)|(1<<4)|(3<<2)|0x2;

 

Видимо я не совсем понимаю, что скрывается за понятием адреса в битах [31:20] Form the corresponding bits of the physical address for a section.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У 9261 - 192К SRAM. (у 9260 совсем мало кажется).

В SDRAM у меня ничего такого не располагается. И вам не советую. Все самое дорогое и заветное - в Срам.

 

При работе учитывайте ремапинг.!!!!!

 

Укажите Write-Trough. Мне больше нра Write-Back.

 

То и значит. Соотв. адресные биты этой секции.

 

Боюсь соврать сильно.

Каждый эл. ТЛБ - это мегабайтаня страница физической памяти от 0 до 4 гиг.

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

 

Эта хрень имеет отношение к защите памяти, виртуального адресного пространства для защиты программ друг от друга в ОС. В нашем сельском хозяйстве это вообще нафик не уперлось. Посему виртуальные адреса в моем случае совпадают с реальными. Все виды защит выключены. Ибо я сам распоряжусь памятью и советы всяких там ММУ мне не нужны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Боюсь соврать сильно.

Таки получилось :) Индексом в Translation Table служат виртуальные адреса, дескрипторы описывают привязанные к ним физические.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

НУ может быть. Уже год как не лазил в 926. А то и больше....

Я ж говорил - лучше читать (это топикастеру). Пробовать. Главное - аккуратно.

Мелкими шажками. Чтоб точно знать, когда ММУ завалило вашу программу, а когда не ММУ.

 

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Иными словами, если вы не извращенец - про все типы кэшей - включить и забыть.

Очень опасный совет. Дело в том, что у ARM9 кеш-контроллер и DMA ничем не связаны, так что если работать по DMA с кешируемой памятью, то можно поиметь целую кучу непонятных глюков.

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

В том примере у меня один из 32 мегабайтов ОЗУ отводился именно под такие буфера. Заодно туда и TLB засунул. Адреса в примере определяются конфигурацией железа (SAM9XE).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я чего-то не понимаю, но по карте памяти адресу 0x21FF 8000 соответствует область EBI Chip Select 1/SDRAMC. Если я ничего не путаю, то Remap всего лишь отображает SRAM на нулевой адрес 0x0000 0000. Тогда нижеуказанная строчка, которая задает начальный адрес расположения таблицы TLB 0x21FF 8000, определяет расположение этой таблицы в SDRAM?

unsigned int   *TLB  =(unsigned int *) (0x21FF8000);//last 32 K

.

 

Правильно ли я понял, что программа у меня будет лежать в SDRAM, тогда мне таблицу нужно разместить, например в SRAM1, базовый адрес расположения таблицы тогда будет 0x30 0000 (Расположение SRAM1 на карте памяти), а в саму TLB записывать адреса расположение программы, т.е начальные адрес SDRAM, т.е. 0x2000 0000.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да.

Зачем я туда засунул эту таблицу - не помню. Пожалел 16k скорее всего.

Тогда да.

 

Видите, как я выполняю принцип - сделал - и забыл.

Но у вас наверное нет столько памяти... Но если есть - лучше все в срам запихать.

---

Где-то внутри примеров ИАР есть пример с MMU.

Изменено пользователем DpInRock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно еще такой вопрос? Поскольку у меня такие маленькие размеры SRAM (4 Кб) мне нужно делить память на блоки по 4 Кб? И если все делить не Мегабайтными страницами (Section), а блоками по 4 Кб (Coarse page). Тогда получается, что необходимо два дескриптора: грубый (1-ого уровня) и точный (2-ого уровня). Как тогда вести описание?

Я предполагаю так:

 

1) Задать базовый адрес расположения Грубого дескриптора что-то типа (размещаю в SRAM1, она у меня 4 Кб):

unsigned int   *TLB  =(unsigned int *) (0x30 0000);//last 32 K

 

2) Заполнить ее базовыми адресами точного дескриптора (Coarse page table base address) т.е. проинициализировать TLB;

 

3) Задать базовый адрес расположения точного дескриптора. Тут вопрос куда его положит, во всю ту же SRAM1? Ну напримерпо адресу 0x30 0500 (последний адрес: 0x30 1000). И вопрос хватит ли мне ее? По идее не хватит, мне нужно описать 4096

 

4) Заполнить (проинициализировать) точные дескрипторы.

 

 

Или такой вариант: Структура:

typedef struct __TTL {
    unsigned int Descriptor_1;         // Дескриптор 1-ого уровня
    unsigned int Descriptor_2[256]; // Дескриптор 2-ого уровня
} TTL;

 

 

И еще вопрос, откуда переферия по этим адресам (0x21E0 0000 и 0x21F0 0000):

TLB[0x21E] = (0x21E<<20)|(1<<10)|(15<<5)|(1<<4)|(0<<2)|0x2; //Peripheria    
TLB[0x21F] = (0x21F<<20)|(1<<10)|(15<<5)|(1<<4)|(1<<2)|0x2; //Peripheria

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Периферия по этим адресам - это копипасте строчек с периферией. (Экран у меня с 2000 0000).

 

Нет необходимости ВООБЩЕ думать о распределении страниц и прочего. Надо сделать, чтоб реальные совпадали с виртуальными.

 

Ибо наскоко помню, вся это возня с ММу связана с тем, что нельзя включить кэш не заполнив эту таблицу. Т.е. все это исключительно ради кэша.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кэш инструкций включается установкой соответствующего бита в управляющем регистре. Кэш данных можно включить только в том случае, если включено MMU, а чтобы его включить, надо сначала подготовить таблицы переадресации. Если виртуальная память и защита памяти не нужны (т.е. если MMU включается исключительно ради кэша), то есть смысл использовать секции, а не страницы, и всё отображение памяти описать одной таблицей первого уровня (4096 элементов по слову каждое, всего 16 Кбайт). Что же касается TLB, то он, как и кэши, работает автоматически, и вручную манипулировать им необходимо лишь в весьма специфических случаях.

 

Если с английским проблемы, можно посмотреть на ru.osdev.wikia.com.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

MMU включается исключительно ради кэша), то есть смысл использовать секции, а не страницы, и всё отображение памяти описать одной таблицей первого уровня (4096 элементов по слову каждое, всего 16 Кбайт).

 

Это получается, что у меня таблица по-любому не влезет в SRAM1 объемом 4 Кб. Тогда получается, что TLB нужно хранить в SDRAM?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...