Процессор семейства Blackfin поддерживает иерархическую модель памяти с разными параметрами по размеру и быстродействию, в зависимости от размещения памяти в этой иерархии. Память Level 1 (L1) размещена на кристалле чипа процессора, и обладает самым большим быстродействием. Память Level 2 (L2) находится вне чипа, и у неё больше задержки при доступе на чтение и запись. Самая быстрая память L1 обычно используется как пул для временных переменных (scratchpad memory) или для кэширования других, более медленных, областей памяти. Здесь приведен перевод раздела "Memory" из даташита [1]. Все непонятные термины и сокращения см. в разделе "Словарик" и врезках статьи [2].
[Архитектура памяти]
Процессор обладает плоским, унифицированным адресным пространством размером в 4 гигабайта (32-битный адрес), которое покрывает комбинацию областей памяти, расположенных на кристалле и вне кристалла, а также регистры ввода/вывода и управления, адресуемые так же, как ячейки памяти (memory-mapped I/O resources). Все находится в одном адресном пространстве, что очень удобно для программирования. В этом диапазоне адресов 4 гигабайта некоторые области жестко выделены для внутренних ресурсов чипа. Порции адресного пространства процессора используются под следующие цели:
• Статическая память L1 с произвольным доступом и минимальными задержками (SRAM). • Статическая память L2 с произвольным доступом и минимальными задержками (SRAM). • Набор регистров, отображенных на адреса памяти (memory-mapped registers, MMR). • Память только для чтения, в которой находится код загрузки (boot read-only memory, ROM).
Часть памяти, отведенной под L1 SRAM, может быть также сконфигурирована под использование как кэш. Процессор также предоставляет поддержку внешнего адресного пространства, которая включает область асинхронной памяти (обычно используется для подключения параллельных микросхем памяти FLASH) и область синхронной динамической памяти (synchronous DRAM, SDRAM). Подробнее см. раздел "External Bus Interface Unit", где описан каждый из этих регионов памяти и контроллеры их поддержки.
Обратите внимание, что в архитектуре нет отдельного пространства адресов для ввода/вывода. Как уже упоминалось, все ресурсы процессора отображены на общее плоское 32-битное адресное пространство. Ячейки памяти адресуются побайтно.
Карта памяти ADSP-BF538/ADSP-BF538F.
Примечание: в зарезервированной области памяти, начиная с адреса 0xEF000000, находится код BootROM (подробнее см. [6]).
Рис. 6-1. Архитектура памяти ADSP-BF538/ADSP-BF538F.
Верхняя область внутренней памяти (самые старшие адреса) выделена под ядро и системные MMR. Доступ к этой области со стороны программы разрешен только в режиме супервизора процессора (например, когда он обрабатывает прерывание или исключение, подробнее см. [2]), или в режиме эмуляции.
Младшая часть внутренней памяти размером 1 килобайт отведена под код загрузки (boot ROM). В зависимости от выбранного режима загрузки соответствующая загрузочная программа будет выполнена из этой области памяти, когда процессор сброшен (см. врезку "Режимы загрузки" статьи [2]).
Области внешней памяти адресного пространства содержат 4 банка асинхронной памяти и один банк памяти SDRAM. Каждый из асинхронных банков имеет размер 1 мегабайт, и у банка SDRAM размер в 128 мегабайт.
Обзор внутренней памяти. Быстродействие системы памяти L1 предоставляет широкую полосу и низкие задержки. Из-за того, что SRAM предоставляет детерминированный доступ и очень высокую пропускную способность, системы на основе DSP имеют достойное повышение быстродействия, когда имеют в наличии быструю SRAM, встроенную в кристалл.
В дополнение к кэшам инструкции и данных (SRAM вместе с аппаратурой управления кэшированием) предоставляет и высокое быстродействие, и упрощенная модель программирования. Кэши устраняют от необходимости явно управлять перемещениями данных между памятью L1 и другими областями памяти, у которых быстродействие ниже. Код может быть быстрое портирован или разработан без специальных усилий по оптимизации, привязанных к организации памяти определенной модели чипа.
Память L1 предоставляет:
• Модифицированную Гарвардскую архитектуру, когда возможен до 4 доступов к памяти ядра на один такт (захват одной 64-разрядной инструкции, двух 32-разрядных загрузок данных, и один одно конвейеризированное сохранение 32-битных данных). • Одновременный доступ со стороны системы DMA, обслуживания кэша, ядра. • Доступ к SRAM на частоте тактов процессора (CCLK) для критических алгоритмов DSP и быстрого переключения контекста. • Опции кэширования инструкций и кэша для кода микроконтроллера, отличная поддержка языка высокого уровня, и упрощенное программирование инструкциями управления кэшем, такими как PREFETCH и FLUSH. • Защиту памяти.
Обзор Scratchpad Data SRAM. Процессор предоставляет выделенный банк 4 килобайта памяти scratchpad data SRAM (так называемая сверхоперативная память данных). Scratchpad не зависит от конфигурации других банков памяти L1, и не может быть сконфигурирована как кэш или быть целью для DMA. Типичные приложения для использования scratchpad data - места программы, где скорость критична. Например, стеки пользователя и супервизора должны быть привязаны к памяти scratchpad для быстрейшего переключения контекста при обработке прерываний.
Как уже упоминалось, области памяти L1 могут работать на частоте тактов ядра (CCLK). К scratchpad data SRAM не может получить доступ контроллер DMA.
[Память инструкций L1]
Память инструкций L1 состоит из комбинации выделенной SRAM и банков, которые могут быть сконфигурированы как SRAM или кэш. Для 16-килобайтного банка, который может быть либо кэшем, либо SRAM, можно использовать биты управления в регистре IMEM_CONTROL, чтобы организовать все 4 подбанка памяти инструкций L1 как:
• Простая память SRAM. • 4-направленный набор ассоциативного кэша инструкций. • Кэш с четырьмя способами запирания.
Память инструкций L1 может быть использована только для хранения инструкций (кода программы).
Регистр управления памятью инструкций (Instruction Memory Control, IMEM_CONTROL) содержит биты управления для памяти инструкций L1. По умолчанию после сброса кэш и система проверки адреса защиты кэша (cacheability protection lookaside buffer, CPLB) запрещены (см. раздел "Кэш инструкций L1").
Рис. 6-2. Регистр L1 Instruction Memory Control (IMEM_CONTROL, регистр управления памятью L1) ADSP-BF5xx.
LRUPRIORST. Когда бит LRUPRIORST установлен в 1, то очищается кэшированное состояние всех битов CPLB_LRUPRIO (см. "Регистры инструкций CPLB Data (ICPLB_DATAx)"). Это одновременно переводит все кэшированные строки в низкую важность. Политика замены кэша базируется на первой по важности строке, что индицируется по состоянию бит кэширования CPLB_LRUPRIO, и затем на LRU (least recently used, самые последние используемые). Подробности см. в разделе "Instruction Cache Locking by Line". Этот бит должен быть сброшен в 0, чтобы позволить быть сохраненным состоянию бит CPLB_LRUPRIO, когда будет кэшированы новые строки.
ILOC[3:0]. Эти биты предоставляют полезную возможность только после того, как код был вручную загружен в кэш, см. раздел "Instruction Cache Locking by Way". Эти биты задают, как будет происходить удаление из кэша в политике замены. Это влияет на то, как наличие захваченного кода в отсутствующих ветвлениях. Код в отсутствующих ветвлениях все еще может быть удален инструкцией IFLUSH. Если бит в ILOC[3:0] равен 0, соответствующий путь не захвачен, и этот путь участвует в политике замены кэша. Если бит ILOC[3:0] равен 1, то соответствующий путь захвачен, и не участвует в политике замены кэша.
IMC. Этот бит резервирует часть SRAM-памяти инструкций L1 для работы в качестве кэша. Обратите внимание, что резервирование памяти для обслуживания в качестве кэша не позволят само по себе кэшировать обращения к памяти L2. Также должны быть разрешены блоки CPLB с использованием бита EN_ICPLB и дескрипторы CPLB (в регистрах ICPLB_DATAx и ICPLB_ADDRx) должны указывать нужные страницы памяти, для которых разрешено кэширование.
ENICPLB. Бит разрешения CPLB инструкций (Instruction CPLB Enable). Если 0, то все CPLB запрещены, имеется только минимальная проверка адреса. Если 1, то CPLB разрешены.
После сброса блоки CPLB для инструкций по умолчанию запрещены. Когда эта функция запрещена, интерфейсом памяти LI производится только минимальная проверка адреса. Эта минимальная проверка генерирует исключение для процессора всякий раз, когда сделана попытка выборки инструкции из:
• Зарезервированной (не заполненной) области памяти инструкций L1. • Области памяти данных L1. • Области MMR.
CPLB должны быть запрещены с использованием этого бита до обновления их дескрипторов (регистров DCPLB_DATAx и DCPLB_ADDRx registers). Обратите внимание, что поскольку порядок сохранения слабый (см. "Ordering of Loads and Stores"), запрет CPLB должен быть продолжен импульсами CSYNC.
Когда разрешаются или запрещаются кэш или CPLB, должна произойти немедленная запись в IMEM_CONTROL вместе с CSYNC, чтобы гарантировать корректную работу. Чтобы гарантировать правильное поведение кода и будущую совместимость, все зарезервированные биты в этом регистре должны быть установлены в 0 всякий раз, когда этот регистр записывается.
L1 Instruction SRAM. Ядро процессора читает память инструкций через 64-битную шину выборки. Все адреса на этой шине выровнены на 64 бита. Каждая выборка инструкции может возвратить любую комбинацию из 16-, 32- или 64-битной инструкции (например, четыре 16-битные инструкции, две 16-битные инструкции и одну 32-битную инструкцию, или одну 64-битную инструкцию). DAG-и, которые описаны в разделе "Data Address Generators", не могут получить доступ к памяти инструкций напрямую. DAG, который обратился к области адресов SRAM, сгенерирует исключение (см. раздел "Исключения" в [3]).
Доступ на запись к памяти инструкций L1 SRAM должна быть сделана через 64-битный системный порт DMA. Поскольку SRAM реализована в виде набора одиночных, разделенных на порты подбанков, то память инструкций эффективно работает как двухпортовая память.
В таблице перечислены начальные области подбанков памяти инструкций L1.
Подбанк памяти
Место расположения в памяти
0
0xFFA0 0000
1
0xFFA0 1000
2
0xFFA0 2000
3
0xFFA0 3000
4
0xFFA0 4000
5
0xFFA0 5000
6
0xFFA0 6000
7
0xFFA0 7000
8
0xFFA0 8000
9
0xFFA0 9000
10
0xFFA0 A000
11
0xFFA0 B000
12
0xFFA0 C000
13
0xFFA0 D000
14
0xFFA0 E000
15
0xFFA0 F000
На рис. 6-4 показана архитектура памяти инструкций L1. Как видно на рисунке, каждый 16-килобайтный банк разделен на четыре подбанка по 4 килобайта.
Рис. 6-4. Архитектура банка памяти инструкций L1.
Примечание: закрашенные серым цветом блоки имеются не во всех моделях процессоров Blackfin. Для дополнительной информации обращайтесь к соответствующему руководству по аппаратуре Вашего процессора ([1] для BF538).
L1 Instruction ROM. Некоторые модели процессоров Blackfin имеют на борту до 64 килобайт ПЗУ инструкций L1 (L1 instruction ROM). Если это ROM есть, то оно встраивается в архитектуру L1 Instruction SRAM, показанную на рис. 6-4. L1 instruction ROM может быть прочитано секвенсером программы и DMA, но не может быть прочитано механизмом ITEST. Так что содержимое L1 instruction ROMS не может быть отображено в эмуляторе CrossCore Embedded Studio.
L1 Instruction Cache. Память инструкций L1 может быть также сконфигурирована, чтобы содержать 4-канальный ассоциативный 16-килобайтный кэш. Чтобы улучшить среднее время доступа для критических секций кода, каждая 2-я строка кэша может быть заблокирована независимо. Когда память сконфигурирована как кэш, то к ней нельзя получить прямой доступ.
Примечание: о терминах, которые будут встречаться в этом разделе, см. врезку "Терминология памяти". Незнакомые сокращения и термины также см. в разделе "Словарик" статьи [2].
Когда кэш разрешен, будут кэшироваться только страницы памяти, назначенные через CPLB как кэшируемые. Когда CPLB разрешены, то любое место в памяти, куда нужен доступ, должен иметь связанное описание страницы, иначе будет сгенерировано исключение CPLB. CPLB описаны в разделе "Защита и свойства памяти".
На рисунке 6-5 показана общая организация кэша инструкций процессора Blackfin.
Рис. 6-5. Организация кэша инструкций на подбанке.
Строки кэша. Как мы видим на рис. 6-5, кэш состоит из набора строк кэша. Каждая строка кэша содержит компонент тэга и компонент данных.
• В компоненте тэга имеется 20-разрядная метка адреса, биты LRU (как долго строка не использовалась), бит Valid (достоверность строки кэша) и бит Line Lock (блокировка строки кэша). • Компонент данных состоит из четырех 64-битных слов данных инструкции.
Компоненты тега и данных строк кэша сохраняются соответственно в массивы тэга и данных.
Метка адреса состоит из 18 бит плюс биты 11 и 10 физического адреса. Биты 12 и 13 физического адреса не входят в метку адреса. Вместо этого эти биты используются для идентификации 4-килобайтного подбанка, к которому должен быть доступ.
Биты LRU являются частью алгоритма LRU, используемого для вычисления строки кэша, которая должна быть заменена при промахе кэша.
Бит Valid показывает состояние строки кэша. Строка кэша всегда либо достоверна, либо не достоверна.
• В недостоверных строках кэша бит Valid очищен, показывая этим, что строка будет игнорироваться при операции сравнения метки адреса. • Достоверные строки имеют установленный бит Valid, это показывает, что строка содержит достоверные инструкции/данные, которые совпадают по содержимому с оригинальной памятью.
Компоненты тэга и данных строки кэша показаны на рисунке 6-6. Каждый 4-килобайтный подбанк имеют такую же структуру.
Рис. 6-6. Строка кэша – части тэга и данных.
Попадания и промахи кэша. Попадание кэша происходит тогда, когда адрес инструкции в запросе на выборку из памяти совпадает с достоверной записью в кэше. В частности попадание кэша определяется сравнением старших 18 битов и битов 11 и 10 адреса выборки инструкции с меткой адреса допустимых строк кэша. Набор кэша (строки кэша, распределенные по каналам) выбирается с использованием битов 9 .. 5 адреса выборки инструкции. Операция сравнения адрес-тэг показывает совпадение в любом из 4 каналов, и соответствующая строка достоверна, то происходит попадание в кэш. Если операция сравнения адреса не показала совпадения в любом из 4 каналов, или при совпадении не найдено достоверной строки, то произошел промах кэша.
При промахе кэша блок памяти инструкции генерирует доступ на заполнение строки кэша, чтобы получить отсутствующую в кэше строку из памяти, которая является внешней для ядра. Адрес для доступа к внешней памяти является адресом слова целевой инструкции. Когда произошел промах кэша, ядро приостанавливает выполнение, пока целевое слово инструкции не будет получено из внешней памяти.
Заполнения строки кэша. Заполнение строки кэша состоит из выборки из памяти 32 байт данных. Операция запускается, когда блок памяти инструкций запрашивает передачу читаемой строки на его внешнем порте чтения данных. Это пакет из четырех 64-битных слов данных их строки заполнения буфера. Затем строка заполнения буфера транслируется к ширине шины внешнего доступа (External Access Bus, EAB).
Адрес для передачи чтения является адресом слова целевой инструкции. Когда происходит ответ на запрос чтения строки от блока памяти инструкции, внешняя память возвратит сначала слово целевой инструкции. После этого будет возвращено 3 следующих слова, выбранных из памяти последовательно с увеличением адреса. При необходимости выборка повторяется по кругу, как это показано в таблице 6-1.
Таблица 6-1. Порядок выборки слов строки кэша.
Целевое слово
Порядок выборки для следующих 3 слов
WD0
WD0, WD1, WD2, WD3
WD1
WD1, WD2, WD3, WD0
WD2
WD2, WD3, WD0, WD1
WD3
WD3, WD0, WD1, WD2
Как только строка кэша заполнена, четыре 64-битных слова имеют фиксированный порядок в кэше, как показано на рис. 6-5. Это избавляет от необходимости сохранять младшие 5 бит (выборка байта) полного адреса слова в записи кэша.
Буфер заполнения строки кэша. Как только новая строка кэша получена из внешней памяти, каждое 64-битное слово буферизируется в строке буфера заполнения кэша до того, как это будет записано в 4-килобайтный банк памяти L1. Буфер строки позволяет ядру получить доступ к данным их новой строки кэша как только строка была получена из внешней памяти, без ожидания, пока она запишется в кэш. В то время как порт L1 буфера заполнения всегда шириной 64 бита, ширина порта к внешней памяти или к памяти L2 варьируется между производными.
Некоторые процессоры Blackfin имеют память L2 с двумя отдельными буферами заполнения строки, что позволяет загрузке из медленной внешней памяти продолжиться без перехода для остановки к более высокой скорости встроенной в чип памяти L2. Определение, какой буфер строки используется, зависит от бита CPLB_MEMLEV страницах памяти CPLB. См. раздел "Защита и свойства памяти".
Замена строки кэша. Когда блок памяти инструкций сконфигурирован как кэш, биты 9 .. 5 адреса выборки инструкции используются как индекс для выборки набора кэша для операции сравнения тэг-адрес. Если операция сравнения тэг-адрес приводит к промаху кэша, то биты Valid и LRU для выбранного набора проверяются блоком замены строки кэша, чтобы определить запись для новой строки кэша, т. е. использовать ли Way0, Way1, Way2 или Way3. См. рис. 6-5.
Блок замены строки кэша сначала проверяет кэш на недостоверные записи (т. е. в которых бит Valid очищен). Если найдена только одна недостоверная запись, то эта запись выбирается для новой строки кэша. Если найдено несколько недостоверных записей, то заменяемая запись для новой строки кэша выбирается по следующему приоритету:
• Сначала Way0 • Затем Way1 • Затем Way2 • Последний Way3
Например:
• Если Way3 недостоверен, и Ways0, 1, 2 достоверны, то Way3 выбирается для новой строки кэша. • Если Ways0 и 1 недостоверны, и Ways2 и 3 достоверны, то Way0 выбирается для новой строки кэша. • Если Ways2 и 3 недостоверны, и Ways0 и 1 достоверны, то Way2 выбирается для новой строки кэша.
Когда не найдено ни одной недостоверной записи, то логика замены кэша использует алгоритм LRU.
Управление кэшем инструкций. Системный контроллер DMA и DAG-и ядра не могут получить доступ к кэшу инструкций напрямую. Комбинацией инструкций и использования MMR ядра можно косвенно инициализировать массивы тэга и данных, и предоставить механизм для тестирования, инициализации и отладки кэша инструкций. См. раздел "Сброс достоверности кэша инструкций".
Когерентностью кэша нужно явно управлять. Чтобы выполнить это и гарантировать, что кэш инструкций заполнен последней версией модифицированного пространства инструкций, нужна инструкция недостоверности записей строки кэша.
Построчная блокировка кэша инструкций. Биты CPLB_LRUPRIO в регистрах ICPLB_DATAx (см. раздел "Защита и свойства памяти") используются для улучшения управления кодом, который остается резидентным в кэше инструкций. Когда строка кэша заполнена, состояние этих бит сохраняется вместе с тегом строки. Это используется в соединении с политикой LRU, чтобы определить, какой канал (Way) будет жертвой, когда все каналы кэша заняты при выборке новой кэшируемой строки. Этот бит показывает важность строки - "low" (низкая) или "high" (высокая). В модифицированной политике LRU, high может заменить low, но low не может заменить high. Если все каналы заняты строками high, кэшируемые low все еще будут выбираться ядром, но не будут кэшироваться. Выборка строк high стремятся сначала заменить не занятые Way, затем самые редко используемые, и наконец другие high-строки в соответствии с политикой LRU. Low-строки могут заменить только не занятые Way или другие low-строки, и также при этом используют политику LRU. Даже если все ранее кэшированные high-строки стали менее важны, они могут быть одновременно преобразованы в low-строки путем записи бита LRUPRIRST в регистре IMEM_CONTROL (см. раздел "Регистр IMEM_CONTROL").
Поканальная блокировка кэша инструкций. Кэш инструкций имеет 4 независимые бита блокировки (ILOC[3:0]), которые управляют каждым из 4 каналов (Way) кэша инструкции. Когда разрешен кэш, память инструкций L1 имеет 4 доступные канала. Установка бита блокировки для отдельного канала выводит этот канал из участия в политике замены LRU. Таким образом инструкция, закэшированная этим каналом, будет заблокирована, и её можно удалить только использованием инструкции IFLUSH, или "черным ходом" при манипуляции массивом тегов с использованием MMR.
Ниже приведен пример последовательности для демонстрации, как заблокировать Way0:
• Если интересующий код уже может находиться в кэше инструкций, сначала сделайте недостоверным весь кэш (для примера см. раздел "Сброс достоверности кэша инструкций"). • Если требуется, то запретите прерывания - чтобы запретить со стороны ISR потенциальную возможность порчи заблокированного кэша. • Установите блокировки на другие каналы кэша путем установки ILOC[3:1]. Теперь только канал Way0 кэша инструкций может быть заменен новым кодом. • Выполните интересующий код. Любые кэшируемые исключения, такие как код выхода, задействованные этим кодом, будут также заблокированы в кэше инструкций. • При выходе из критического кода очистите ILOC[3:1] и установите ILOC[0]. Критический код (и инструкции, у которых установлен ILOC[0]) теперь заблокированы в канале Way0. • Снова разрешите прерывания, если это необходимо.
Если все 4 канала кэша заблокированы, то все будущие размещения кода в кэше осуществляться не будут.
Сброс достоверности кэша инструкций. Кэш инструкций можно сделать недостоверным по адресу, по строке кэша, или полностью сделать недостоверным весь кэш инструкций. Инструкция IFLUSH может явно отменить достоверность строк кэша на базе их адресов строк. Целевой адрес инструкции генерируется из P-регистров. Поскольку кэш инструкций не должен содержать модифицированных (грязных) данных, то строка кэша просто делается недостоверной, её не надо синхронизировать с внешним носителем (т. е. не нужна операция сброса "flush").
В следующем примере регистр P2 содержит адрес достоверного места в памяти. Если этот адрес был внесен в кэш, то соответствующая строка кэша станет недостоверной после выполнения этой инструкции.
Этот пример инструкции IFLUSH:
iflush [p2]; /* Сброс достоверности строки кэша, содержащей адрес,
на который указывает P2. */
Поскольку инструкция IFLUSH используется для сброса достоверности отдельного адреса в карте памяти, и соответствующей ему строки кэша, то это является самым полезным, когда переводимый в недостоверное состояние буфер меньше, чем размер всего кэша. Дополнительную информацию по инструкции IFLUSH см. в разделе 17 "Cache Control" [5]. Вторая техника может использоваться для прямого перевода в недостоверное состояние больших порций кэша. В этой технике напрямую делает недостоверными биты Valid путем установки бита Invalid каждой строки кэша, переводя её в недостоверное состояние. Для реализации этой техники имеются дополнительные MMR (ITEST_COMMAND и ITEST_DATA[1:0]), которые позволяют произвольно читать/записывать все записи кэша. Этот метод обсуждается в следующей секции статьи.
Чтобы сделать недостоверным весь кэш, есть третий метод. Путем очистки бита IMC в регистре IMEM_CONTROL (см. рис. 6-2), все биты Valid кэша инструкций устанавливаются в недостоверное состояние. Вторая запись в регистр IMEM_CONTROL для установки бита IMC заново конфигурирует память инструкций как кэш. Перед переводом кэша в недостоверное состояние должна быть выполнена инструкция SSYNC, и инструкция CSYNC должна быть вставлена после каждой из этих операций.
[Регистры проверки инструкции]
Механизмом программного чтения и манипуляции памятью инструкций L1 (вне DMA) являются регистры проверки инструкции (Instruction Test registers). Эти регистры позволяют также произвольно напрямую читать/записывать все записи кэша L1. Регистры проверки делают возможным инициализировать массивы тэгов и данных кэша и предоставлять механизм для тестирования и отладки кэша инструкций. Содержимое ROM инструкций L1 не может быть прочитано с использованием механизма ITEST.
Когда используется регистр проверки инструкции (Instruction Test Command register, ITEST_COMMAND), осуществляется доступ к массивам тегов и данных кэша L1, и данные передаются через регистры проверки данных инструкции (Instruction Test Data registers, ITEST_DATA[1:0]). Регистры ITEST_DATAx содержат либо 64-битные данные с доступом на запись, либо 64-битные данные, которые были прочитаны при доступе. Младшие 32 бита сохраняются в регистре ITEST_DATA[0], и старшие 32 бита сохраняются в регистре ITEST_DATA[1]. Когда осуществляется доступ к массивам тэгов, то используется ITEST_DATA[0]. Графическое представление регистров ITEST начинается на рисунке 6-8.
Доступ к этим регистрам возможен только в режиме супервизора или эмуляции. Когда записываются регистры ITEST, всегда сначала записываются регистры ITEST_DATAx, и затем регистры ITEST_COMMAND. Когда читаются регистры ITEST, используется обратная последовательность - сначала читается ITEST_COMMAND, затем регистры ITEST_DATAx.
Когда записывается регистр проверки команды (Instruction Test Command register, ITEST_COMMAND), осуществляется доступ к массивам данных или тэгов кэша L1, и данные передаются через регистры проверки данных инструкции (Instruction Test Data registers, ITEST_DATA[1:0]).
Рис. 6-7. Instruction Test Command Register (ADSP-BF5xx).
WAYSEL[1:0] (Access Way). Эти биты выбирают канал доступа (биты адреса 11..10 SRAM).
00: доступ через канал Way0. 01: доступ через канал Way1. 10: доступ через канал Way2. 11: доступ через канал Way3.
Старший из регистров проверки данных инструкции (Instruction Test Data registers, ITEST_DATA[1:0]) используются для доступа к массивам данных и массивам тегов кэша L1. Оба этих регистра содержат либо 64-битные данные для записи, либо 64-битные прочитанные данные. ITEST_DATA1 содержит старшие 32 бита. При доступе к массиву данных здесь содержатся 32 старших бита инструкции из 64-битного слова - либо для записи, либо для чтения.
Регистр проверки данных инструкции 0 (Instruction Test Data 0 register, ITEST_DATA0) хранит младшие 32 бита из 64-битных данных, которые записываются или читаются при осуществлении доступа к кэшу L1. Регистр ITEST_DATA0 также используется для доступа к массивам тегов. Также этот регистр содержит биты Valid и Dirty, которые показывают состояние строки кэша. Младшие 32 бита регистра используются для доступа к массивам тэгов кэша L1.
Рис. 6-10. Instruction Test Data 0 Register.
Data [31:0]. Младшие 32 бита 64-битных данных.
Tag[19:4], Tag[3:2], Tag[1:0]. Адрес тэга состоит из старших 18 бит и битов 11 и 10 физического адреса (поля Tag[19:4], Tag[3:2], Tag[1:0] содержат 20 бит адреса тега).
Valid. Если в этом бите 0, то строка кэша не достоверна.
LRUPRIO. Если в этом бите 0, то для этой записи LRUPRIO очищен. Если 1, то для этой записи LRUPRIO установлен.
[Память данных L1]
L1 данные SRAM/кэш построены из однопортовых подразделов, но организованы для уменьшения вероятности коллизий доступа. В результате эта организация ведет себя как многопортовая. Когда нет коллизий, следующий трафик данных L1 может проходить за один тактовый цикл ядра:
• Две 32-разрядные загрузки данных • Одно конвейеризированное сохранение 32-битных данных • Один DMA I/O, до 64 битов • Один доступ к 64-битам кэша на заполнение/отбрасывание
Память данных L1 может использоваться только для сохранения данных.
Регистр управления памятью данных (Data Memory Control register, DMEM_CONTROL) содержит биты управления для L1 Data Memory.
Рис. 6-11. L1 Data Memory Control Register (ADSP-BF5xx).
PORT_PREF1. Бит выбирает порт данных, используемый для обработки DAG1 некэшируемых выборок L2. Кэшируемые выборки всегда обрабатываются портом данных, физически связанным с целевой памятью кэша. Направление DAG0, DAG1 и трафик кэша на разные порты оптимизирует быстродействие путем удержания наполнения очереди памяти L2.
PORT_PREF0. Бит выбирает порт данных, используемый для обработки DAG0 некэшируемых выборок L2. Кэшируемые выборки всегда обрабатываются портом данных, физически связанным с целевой памятью кэша. Направление DAG0, DAG1 и трафик кэша на разные порты оптимизирует быстродействие путем удержания наполнения очереди памяти L2.
Для оптимального быстродействия с двойным чтением DAG, DAG0 и DAG1 должны быть сконфигурированы на разные порты. Например, если PORT_PREF0 сконфигурирован как 1, то PORT_PREF1 должен быть запрограммирован в 0.
DCBS. Бит предоставляет некое управление алиасами адресов, указывающими в тот же набор. Этот бит может использоваться, чтобы влиять на то, какие адреса имеют тенденцию оставаться в кэше резидентными, избегая отбрасывания записей кэша при повторно используемых наборах. Это не влияет на работу, за исключением ситуаций, когда оба банка Data Bank A и Data Bank B работают как кэш (биты DMC[1:0] в этом регистре установлены в 11).
ENDCPLB. Бит используется для разрешения/запрета 16 Cacheability Protection Lookaside Buffers (CPLBs), используемых для данных (см. раздел "Кэш данных L1"). После сброса по умолчанию данные CPLB запрещены. При запрете интерфейсом L1 производится только минимальная проверка адреса. Эта минимальная проверка генерирует исключение, когда процессор:
• Адресует не существующее (зарезервированное) пространство памяти L1 • Пытается выполнить не выровненный доступ к памяти • Пытается получить доступ к области MMR либо с использованием DAG1, либо в режиме пользователя (User mode).
CPLB должны быть запрещены перед тем, как будут обновлены их дескрипторы (регистры DCPLB_DATAx и DCPLB_ADDRx). Имейте в виду, что поскольку порядок загрузки сохранения слабый (см. "Ordering of Loads and Stores"), то запрету CPLB должна предшествовать инструкция CSYNC.
Когда разрешается или запрещается кэш или CPLB, сразу делайте запись DMEM_CONTROL вместе с SSYNC, чтобы гарантировать правильное поведение.
DMC[1:0]. По умолчанию после сброса вся L1 Data Memory работает как SRAM. Вместо этого биты DMC[1:0] могут использоваться для резервирования порций этой памяти как кэш. Резервирование памяти под кэш не разрешает кэширование доступа к памяти L2. Чтобы сделать это, должны быть также разрешены CPLB (с использованием бита ENDCPLB) и дескрипторы CPLB (регистры DCPLB_DATAx и DCPLB_ADDRx) должны указывать выбранные страницы памяти, для которых разрешен кэш. По умолчанию после сброса запрещены как кэш, так и проверка адреса CPLB.
Чтобы гарантировать правильное поведение и совместимость в будущем, все зарезервированные биты в этом регистре должны быть установлены в 0 всякий раз при записи этого регистра.
Биты RDCHK в этом регистре подобны битам разрешения кэша (cache enable bits, CEN[1:0]). Запись в биты RDCHK не вступит в силу, пока не будет выдана SSYNC. Состояние этого бита не влияет на доступ для записи; при доступе на запись всегда вычисляются и сохраняются биты четности. По умолчанию этот после сброса этот бит снимается.
Биты CBYPASS в этом регистре подобны битам разрешения кэша (cache enable bits, CEN[1:0]). Запись в биты CBYPASS не вступит в силу, пока не будет выдана SSYNC. Этот бит не блокирует команду DTEST_COMMAND, регистровый "черный ход" для доступа к кэшу.
Как и с другими битами управления MMR, изменения состояния битов PARCTL и PARSEL должны сопровождаться SSYNC, чтобы гарантировать вступление в силу нового состояния.
L1 Data SRAM. При доступе к SRAM нет коллизий, если все из следующего верно: осуществляется доступ с одинаковой полярности 32-битных слов (биты 2 адресов совпадают), один и тот же подбанк 4 килобайта (совпадают биты адреса 13 и 12), одинаковый полубанк 16 килобайт (биты 16 адреса совпадают), и это один и тот же банк (биты адреса 21 и 20 совпадают). Когда была детектирована коллизия данных, сначала доступ номинально дается для DAG-ов, затем для буфера хранения, и наконец для DMA и трафика заполнения/отбрасывания кэша. Чтобы гарантировать адекватную полосу DMA, DMA отдан самый высокий приоритет, если это было блокировано на больше чем 16 последовательных тактов ядра, или если второй DMA I/O поставлен в очередь до того, как был обработан первый DMA I/O.
На рисунке 6-13 показана архитектура L1 Data Memory. Пунктирными линиями показаны функции, которые есть только в некоторых процессорах Blackfin (подробности см. в руководстве пользователя по конкретному процессору). В то время как на некоторых процессорах шины EAB и DCB подключены напрямую к контроллерам EBIU и DMA, на других производных моделях с несколькими ядрами или встроенной в кристалл памятью L2 они должны пересечь дополнительные модули арбитража. Также эти шины на некоторых моделях шире 16 бит.
Рис. 6-13. Архитектура L1 Data Memory.
Примечание: закрашенные серым цветом блоки имеются не во всех моделях процессоров Blackfin. Для дополнительной информации обращайтесь к соответствующему руководству по аппаратуре Вашего процессора ([1] для BF538).
L1 Data Cache. Подробности по терминологии кэша см. во врезке "Терминология памяти".
В отличие от кэша инструкций, которая 4-Way set associative, кэш данных 2-Way set associative. Когда доступно и разрешено 2 банка для кэша, то создаются дополнительные наборы, а не каналы (Ways). Когда у обоих банков Data Bank A и Data Bank B есть память, работающая кэшем, может использоваться бит DCBS в регистре DMEM_CONTROL, чтобы управлять, какая половина адресного пространства работает с каким банком памяти кэша. Бит DCBS выбирает либо бит адреса 14, либо бит адреса 23, чтобы направлять трафик между банками кэша. Это дает некоторое управление алиасами адресов, указывающими в тот же набор. Поэтому такая функция может использоваться, чтобы влиять на то, какие адреса имеют тенденцию оставаться в кэше резидентными, избегая отбрасывания записей кэша при повторно используемых наборах.
Доступ к кэшу происходит без коллизий, за исключением ситуаций, когда это тот же 4 килобайтный подбанк, и тот же самый банк. Кэш имеет менее очевидное многопортовое поведение, чем SRAM, из-за затрат на поддержку тэгов. Когда происходит коллизия адресов, сначала предоставляется доступ для регистра DTEST, затем к буферу хранения, и наконец к трафику заполнения/отбрасывания кэша.
Доступно 3 разных режима кэша.
• Сквозная запись (Write-through) со строкой кэша, выделенной только на чтение. • Сквозная запись со строкой кэша, выделенной и на чтение, и на запись. • Обратная запись (Write-back) с выделением строк кэша и на чтение, и на запись.
Режим кэша выбирается дескрипторами DCPLB (см. раздел "Защита и свойства памяти"). Любая комбинация этих режимов кэша может использоваться одновременно, поскольку режим кэша независимо выбирается для каждой страницы памяти.
Если кэш разрешена (это управляется битами DMC[1:0] регистра DMEM_CONTROL), должны быть также разрешены CPLB данных (управляется битом ENDCPLB в регистре DMEM_CONTROL). Будут кэшироваться только те страницы памяти, которые указаны как кэшируемые CPLB данных. По умолчанию CPLB данных запрещены, и никакого кэширования нет.
Ошибочное поведение может быть в результате ситуации, когда область MMR сконфигурирована как кэшируемая через CPLB данных, или когда банки данных, работающие как L1 SRAM, сконфигурированы как кэшируемые через CPLB данных.
Ниже показан пример, как кэшируемое адресное пространство привязано к двум банкам данных.
Когда 2 банка сконфигурированы как кэш, они работают как 2 независимых, размером 16 килобайт, 2-Way set associative кэша, которые можно независимо привязать к адресному пространству процессора Blackfin.
Если оба банка данных сконфигурированы как кэш, бит DCBS в регистре DMEM_CONTROL обозначает бит адреса A[14] или A[23] будет использоваться как селектор кэша. Бит адреса A[14] или A[23] выбирает, реализована кэш банком Data Bank A, или банком Data Bank B.
• Если DCBS = 0, то A[14] является частью индекса адреса, и все адреса, где A[14] = 0, используют Data Bank B. Все адреса, где A[14] = 1, используют Data Bank A.
В этом случае A[23] интерпретируется как просто другой бит в адресе, который сохраняется с тегом кэша и сравнивается с целевым адресом для анализа попадания/промаха кэша.
• Если DCBS = 1, то A[23] является частью индекса адреса, и все адреса, где A[23] = 0, используют Data Bank B. Все адреса, где A[23] = 1, используют банк Data Bank A.
В этом случае A[14] интерпретируется как просто другой бит в адресе, который сохраняется с тегом кэша и сравнивается с целевым адресом для анализа попадания/промаха кэша.
Результат выбора DCBS = 0 или DCBS = 1 следующий:
• Если DCBS = 0, A[14] выбирает Data Bank A вместо Data Bank B.
Чередование 16 килобайтных страниц карты памяти отображается на каждую из двух 16 килобайтных кэшей, реализованных двумя банками данных. Следовательно:
Любые данные в первом блоке памяти 16 килобайт могут быть сохранены только в Data Bank B.
Любые данные в следующем диапазоне адресов (от 16K до 32K байт)-1 могут быть сохранены только в Data Bank A.
Любые данные в следующем диапазоне (от 32K до 48K байт)–1 были бы сохранены в Data Bank B. И так далее - чередование банков будет продолжаться.
В результате кэш работает, как будто это одиночная, непрерывная, 2-Way set associative 32K байт кэш. Каждый канал (Way) длиной 16K байт, и все элементы данных с одинаковыми первыми 14 битами адреса индексируют уникальный набор, в котором можно сохранить до 2 элементов (один на каждый канал).
• Если DCBS = 1, A[23] выбирает Data Bank A вместо Data Bank B.
С DCBS = 1 система работает наподобие 2 независимых кэшей, каждая 2-Way set associative кэш, по 16K байт. Каждый банк обслуживает чередующийся набор блоков памяти 8 мегабайт.
Например, Data Bank B кэширует все доступы к первому диапазону адресного пространства размером 8M байт. Т. е. каждый диапазон 8M байт соперничает для 2 записей строк (а не каждое повторение по 16K байт). Соответственно Data Bank A кэширует данные выше 8M байт и ниже 16M байт.
Например, если приложение работает с набором данных размером 1M мегабайт, и он размещен полностью в первом 8M байтном блоке памяти, он эффективно обслуживается только одной половиной кэша, т. е. банком Data Bank B (2-Way set associative 16K байт кэш). В таком сценарии приложение никогда не получает преимуществ от использования Data Bank A.
Для большинства приложений лучше всего работать с DCBS = 0.
Однако если приложение работает с 2 наборами данных, размещенных друг от друга в двух областях памяти, расположенных друг от друга на расстоянии не менее 8M байт, можно точнее управлять тем, как кэш привязан к данным. Например, если программа делает серию двойных MAC-операций, в которых оба DAG-а обращаются к данным в каждом цикле, то путем размещения набора данных DAG0 в одном блоке, и набора данных DAG1 в другом, то система может реализовать следующее:
• DAG0 получает свои данные из Data Bank A для всех своих обращений, и • DAG1 получает свои данные из Data Bank B.
Это распределение заставляет ядро использовать обе шины данных для передач строки кэша, и достигается максимальная пропускная способность по передаче данных между кэшем и ядром.
На рис. 6-14 показан пример, какое получается распределение памяти при DCBS = 1.
Выбор DCBS можно менять динамически; однако, чтобы гарантировать отсутствие потерь данных, сначала засинхронизируйте (flush) кэш, и сделайте его целиком недостоверным.
Figure 6-14. Маппинг кэша данных при DCBS = 1.
Доступ к кэшу данных. Контроллер кэша проверяет адрес от DAG-ов на соответствие битов тэгов. Если логический адрес присутствует в кэше L1, то происходит попадание в кэш (cache hit), и происходит доступ к данным, находящимся в L1. Если логический адрес отсутствует в кэше, то происходит промах кэша (cache miss), и транзакция по памяти переходит на следующий уровень памяти через интерфейс системы. Индекс строки и политика замены контроллера кэша определяет тэг кэша и пространство данных, которое выделяется для данных, которые возвращаются из внешней памяти.
Строка кэша данных находится в одном из 3 состояний: недостоверная (invalid), эксклюзивная (достоверная и чистая, valid and clean), и модифицированная (достоверная и грязная, valid and dirty, т. е. не засинхронизированная с внешней памятью). Если достоверные данные уже занимают выделенную строку и кэш сконфигурирован как хранилище write-back, контроллер проверяет состояние строки кэша и обрабатывает это соответствующим образом:
• Если состояние строки кэша эксклюзивное (чистое), то новый тэг и данные записываются поверх старой строки. • Если состояние строки модифицировано (она "грязная"), то кэш содержит только достоверную копию данных. В этом случае содержимое кэша копируется обратно во внешнюю память до того, как новые данные будут записаны в кэш.
Процессор предоставляет буферы-жертвы и буферы заполнения строки. Эти буферы используются, если промах загрузки кэша генерирует необходимость замены строки-жертвы кэша. Операция заполнения строки переходит на внешнюю память. Кэш данных выполняет запрос заполнения строки для системы как критический (или запрошенный), и перенаправляет данные к ожидающему DAG, поскольку это обновит строку кэша. Другими словами, кэш выполняет перенаправление критического слова.
Кэш данных поддерживает промахи типа hit-under-a-store (совпадение при сохранении) и hit-under-a-prefetch (совпадение на операции предвыборки). Другими словами, при промахе на записи или выполнении инструкции PREFETCH, которая промахнулась в кэше (и это кэшируемый регион), в конвейере инструкции происходит приостановка минимум на 4-цикла. Кроме того, последующая инструкция загрузки или сохранения может выполнить попадание в кэш L1, когда завершится заполнение строки.
Прерывания с достаточным приоритетом (по отношению к текущему контексту выполнения) отменяет приостановленную инструкцию загрузки. Следовательно, если операция загрузки промахнется мимо кэша данных L1 и на системном интерфейсе сгенерируется высоколатентная операция заполнения строки, то можно прерывать ядро и перейти к обработке другого контекста. Доступ системы к заполнению кэша не отменяется, и кэш данных обновится новыми данными для соответствующего обслуживаемого банка, до любой будущей операции с промахом.
Методы записи в кэш. Операции записи в кэш могут быть реализованы либо сквозной записью (write-through), либо обратной записью (write-back):
• Для каждой операции сохранения сквозная запись в кэш (write-through) инициирует запись во внешнюю память сразу после записи в кэш.
Если строка кэша заменена, или явным образом сброшена программным обеспечением во внешнюю память (flushed), то содержимое строки кэша делается недостоверным, а не записывается обратно во внешнюю память.
• Обратная запись в кэш (write-back) не будет осуществлять запись во внешнюю память, пока строка не будет заменена операцией загрузки, которая будет нуждаться в этой строке.
Для большинства приложений кэш write-back более эффективен, чем кэш write-through, поскольку обращения к внешней памяти менее частые.
В этом режиме на промахе кэша, которое происходит при записи в память, вся 32-байтная строка, содержащая записываемые байты, сначала выбирается в кэш. Затем модифицированные байты записываются в кэш. Эта строка не будет записана во внешнюю память, пока не произойдет операция загрузки, которая потребует замены данных этой строки.
Память данных L1 использует для каждого банка буфер обратного копирования на полную ширину строки. Кроме того, буфер записи с двумя ячейками в памяти данных L1 принимает все хранилища с запрещенным кэшем или защитой store-through. Инструкция SSYNC сбрасывает (flushes) буфер записи.
Регистр приоритетов прерывания (Interrupt Priority register, IPRIO) может использоваться для управления размером буфера записи для Port A (см. "L1 Data Memory Architecture").
Рис. 6-15. Interrupt Priority Register.
IPRIO_MARK[0:3] (Priority Watermark). Эти биты могут быть запрограммированы для отражения границы прерывания низкого приоритета. Когда происходит прерывание, что принуждает процессор перейти от менее приоритетного ISR к более приоритетному, размер буфера записи увеличивается в глубину от 2 до 8 слов по 32 бита. Это позволяет ISR запуститься и отправить записи без начальной приостановки в случае, когда буфер уже был заполнен в менее приоритетном ISR. Это особенно полезно, когда отправлены записи в медленное внешнее устройство памяти. Когда происходит возврат из высокоприоритетного ISR в низкоприоритетный ISR или в пользовательский режим, ядро приостановится, пока запись буфера не завершит необходимые записи и возвратится в состояние двойной глубины. По умолчанию буфер записи работает как FIFO двойной глубины.
0000: состояние по умолчанию, все приоритеты прерываний низкие. 0001: прерывания от 15 до 1 имеют низкий приоритет, прерывание 0 считается с высоким приоритетом. 0010: прерывания от 15 до 2 имеют низкий приоритет, прерывания 1 и 0 считаются с высоким приоритетом. ... 1110: прерывания 15 и 14 имеют низкий приоритет, прерывание от 13 до 0 считаются с высоким приоритетом. 1111: прерывание 15 имеет низкий приоритет, остальные прерывания считаются с высоким приоритетом.
Инструкции управления кэшем данных. В процессоре определены 3 инструкции управления кэшем данных, которые можно использовать в режимах пользователя (User mode) и супервизора (Supervisor mode) - PREFETCH, FLUSH и FLUSHINV. Примеры каждой из этих инструкций можно найти в главе 17 "Cache Control" руководства программирования [5].
• PREFETCH (Data Cache Prefetch, предварительная выборка данных кэша) пытается выделить строку в кэше L1. Если предварительная выборка приводит к попаданию в кэш, генерируется исключение, или адресуется кэш запрещенной области, то инструкция PREFETCH работает как NOP. Это может использоваться, чтобы начать выборку данных до того, как процессору они понадобятся, чтобы повысить быстродействие.
• FLUSH (Data Cache Flush, сброс кэша данных) приводит к тому, что кэш данных синхронизирует указанную строку кэша с внешней (медленной) памятью. Если кэшируемая строка данных грязная, инструкция записывает строку во внешнюю память и помечает строку в кэше данных как чистую. Если указанная строка данных кэша уже чистая или не существует, то FLUSH срабатывает как NOP.
• FLUSHINV (Data Cache Line Flush and Invalidate, сброс строки памяти и перевод её в недостоверное состояние) срабатывает так же, как и FLUSH, и затем делает указанную строку кэша недостоверное. Если строка находится в кэше и грязная, то она записывается во внешнюю память. Затем очищается бит Valid строки кэша. Если строка не находится в кэше, то FLUSHINV работает как NOP.
Если программное обеспечение требует синхронизации с аппаратурой системы, поместите инструкцию SSYNC после инструкции FLUSH, чтобы гарантировать, что операция flush завершилась. Если требуется упорядочивание, чтобы гарантировать, что предыдущие сохранения были вытолкнуты через все очереди, поместите инструкцию SSYNC перед инструкцией FLUSH.
Перевод кэша данных в состояние недостоверности (Data Cache Invalidation). Помимо инструкции FLUSHINV, описанной в предыдущей секции, есть два дополнительных метода для того, чтобы сделать недостоверными данные кэша, когда синхронизация кэша (flushing) не требуется. Первая техника требует прямого перевода битов Valid в недостоверность путем установки бита Invalid каждой строки кэша, которая переводится в недостоверное состояние. Чтобы реализовать эту технику, имеются дополнительные MMR (DTEST_COMMAND и DTEST_DATA[1:0]), чтобы можно было напрямую, произвольно читать/записывать все все записи кэша. Этот метод описывается в следующей секции.
Чтобы сделать полностью недостоверным весь кэш, есть второй метод. Путем очистки битов DMC[1:0] в регистре DMEM_CONTROL (см. рис. 6-11) все биты Valid в кэше данных переходят в недостоверное состояние. Вторая запись в DMEM_CONTROL для установки DMC[1:0] в их предыдущее состояние конфигурирует память данных обратно в свою предыдущую конфигурацию кэш/SRAM. Перед переводом кэша в недостоверное состояние нужно запустить инструкцию SSYNC, и инструкция CSYNC должна быть вставлена после каждой из этих операций. Этот метод полезен, если буфер данных, который делается недостоверным, больше, чем размер кэша.
[Регистры тестирования данных (Data Test Registers)]
Наподобие памяти инструкций L1 (L1 Instruction Memory), память данных L1 (L1 Data Memory) содержит дополнительные MMR, чтобы позволить прямые, произвольные операции чтение/запись всех ячеек кэша. Регистры предоставляют механизм для тестирования, инициализации и отладки кэша данных.
Когда записывается регистр команд тестирования данных (Data Test Command register, DTEST_COMMAND), массивы данных или тэгов кэша L1 становятся доступны, и их данные передаются через регистры тестирования данных (Data Test Data registers, DTEST_DATA[1:0]). Регистры DTEST_DATA[1:0] содержат 64-битные данные для записи, или содержат место назначения для 64-битных читаемых данных. Младшие 32 бита сохраняются в регистре DTEST_DATA[0], и старшие 32 бита в DTEST_DATA[1]. Когда осуществляется доступ к массивам тегов, то используется регистр DTEST_DATA[0].
После записи DTEST_COMMAND MMR требуется инструкция SSYNC.
Доступ к этим регистрам возможен только в режимах Supervisor или Emulation. Когда осуществляется запись в регистры DTEST, всегда сначала записывайте DTEST_DATA, затем регистр DTEST_COMMAND.
Когда записывается регистр команд тестирования данных (Data Test Command register, DTEST_COMMAND), осуществляется доступ к массивам данных или тегов кэша L1, и данные передаются через регистры тестирования данных (Data Test Data registers, DTEST DATA[1:0]).
Бит Data/Instruction Access позволяет прямой доступ через DTEST_COMMAND MMR к памяти инструкций L1 (L1 instruction SRAM).
Рис. 6-16. Data Test Command Register (ADSP-BF5xx)
Как с другими управляющими битами MMR, изменение состояния битов PARCTL и PARSEL должно сопровождаться инструкцией SSYNC, чтобы гарантировать, что новое состояние вступило в силу.
Access Way/Instruction Address Bit 11. Если 0, то Access Way/Instruction Address Bit 11 = 0, иначе он равен 1.
Data/Instruction Access. 0: доступ к данным, 1: доступ к инструкции.
Data Bank Access. Подробнее о значении этого бита см. аппаратное руководство по Вашему процессору. К примеру, для ADSP-BF538 этот бит означает следующее:
0: доступ к банку A данных / памяти инструкций 0xFFA0 0000. 1: доступ к банку B данных / памяти инструкций 0xFFA0 8000.
Subbank Access[1:0] (SRAM ADDR[13:12]). Биты определяют, к какому подбанку осуществляется доступ.
00: доступ к subbank 0. 01: доступ к subbank 1. 10: доступ к subbank 2. 11: доступ к subbank 3.
Data Cache Select/Address Bit 14. 0 - зарезервировано/Instruction bit 14 = 0, 1 - выбор банка кэша данных/Instruction bit 14 = 1.
Set Index[5:0]. Выбирает один из 64 наборов.
Double Word Index[1:0]. Индекс двойного слова. Выбирает одно из четырех 64-битных двойных слов в 256-битной строке.
Array Access. Определяет, к какому массиву осуществляется доступ: 0 к массиву тэгов, 1 к массиву данных.
Read/Write Access. Определяет вид доступа: 0 чтение, 1 запись.
Регистры тестирования данных (Data Test Data registers, DTEST_DATA[1:0]) содержат 64-битные данные для записи, или содержат 64-битные данные, которые были прочитаны. Регистр DTEST_DATA1 хранит старшую половину из 32 бит.
Рис. 6-18. Data Test Data 1 Register.
При доступе к массивам тэгов все помеченные серым цветом биты зарезервированы.
Регистры тестирования данных (Data Test Data registers, DTEST_DATA[1:0]) содержат 64-битные данные для записи, или содержат 64-битные данные, которые были прочитаны. Регистр DTEST_DATA0 хранит младшую половину из 32 бит. DTEST_DATA0 также использует для доступа к массивам тегов, которые содержат биты Valid и Dirty, показывающие состояние строки кэша. Младшие 32 бита регистра используются для доступа к массивам тэгов кэша L1. Адрес тэга состоит из старших 18 бит и бита 11 физического адреса.
Рис. 6-19. Data Test Data 0 Register.
Data [31:0]. Младшие 32 бита 64-битных данных.
Tag[19:4], Tag[3:2], Tag. Адрес тэга состоит из старших 18 бит и бита 11 физического адреса (поля Tag[19:4], Tag[3:2], Tag содержат 19 бит адреса тега).
LRU. 0: последним использовался канал Way0, 1: последним использовался канал Way1.
Valid. Если в этом бите 0, то строка кэша не достоверна.
Dirty. 0: строка кэша не была модифицирована, поскольку была скопирована из исходной памяти. 1: строка кэша была изменена после того, как была скопирована из исходной памяти.
[Встроенная в кристалл память Level 2 (L2)]
Некоторые процессоры Blackfin предоставляют дополнительную низколатентную, широкополосную память, которая называется Level 2 Memory (L2). Память L2 работает с частотой CCLK, что требует для доступа несколько циклов.
Одновременный доступ к многобанковой, встроенной в чип памяти L2 со стороны ядра и системы DMA может происходить параллельно при условии, что они осуществляют доступ к разным банкам. Конфликты разруливает схема арбитража с фиксированным приоритетом. Встроенные в чип системные контроллеры DMA совместно используют специальную 32-битную шину данных к системе памяти L2. Этот интерфейс работает на частоте SCLK.
Модели со встроенной памятью L2 предоставляют не только простую память как таковую. К ней также прилагается соответствующая инфраструктура шины и DMA. Широкие шины между L1 и L2 гарантируют высокую пропускную способность для данных.
В следующих секциях предоставлены примеры поведения L2. Обратитесь к руководству по аппаратуре для конкретного процессора (например [1]), чтобы получить подробную информацию по нему.
Доступ к банку внутренней L2. Два порта доступа L2, порт ядра процессора и системный порт, предоставляют параллельный доступ к памяти L2 при условии, что эти 2 порта осуществляют доступ в разные подбанки памяти. Если произойдет попытка одновременного доступа к одному и тому же банку, логика детектирования коллизии доступа к L2 предоставит арбитраж. Это арбитр с фиксированным приоритетом; порт DMA всегда имеет приоритет выше, за исключением случая, когда ядру дан доступ к подбанку для ускоренной/пакетной передачи (burst transfer). В этом случае L2 закончит burst transfer перед тем, как будет предоставлен доступ системной шине.
Латентность (Latency, задержки). Когда разрешен кэш, шина между ядром и памятью L2 полностью конвейеризирована для непрерывных пакетных передач (burst transfers). Заполнение строки кэша из встроенной памяти происходит так же, как выбираются данные и инструкции. Операции, которые промахиваются мимо кэша, вызывают срабатывание замены строки кэша. Эта замена заполняет одну 256-битную (32 байта) строку четырьмя 64-битными чтениями. При этом строка кэша L1 заполняется из L2 SRAM в течение 9+2+2+2=15 циклов ядра. Другими словами, после 9 циклов ядра первые 64 бита (8 байт) станут доступны для процессора. На рис. 6-20 показан пример латентности L2 с включенным кэшем.
Рис. 6-20. Латентность L2 с включенным кэшем.
В этом примере по окончании 15 циклов ядра 32 байта инструкций или данных перейдут в кэш и станут доступны для секвенсера. Если все инструкции содержат 16 бит, то 16 инструкций попадут в кэш по окончании 15 тактов ядра. Дополнительно первая инструкция, которая будет частью заполнения строки кэша, будет выполнена на 10 цикле; вторая инструкция выполнится на 11 цикле, и третья инструкция выполнится на 12 цикле - все это параллельно с заполнением строки кэша.
Каждое заполнение строки кэша будет выровнено по 32-байтной границе блока. Когда запрашивается инструкция или данные, которые не выровнены на 32 байта, Запрошенный элемент всегда будет загружен на первом чтении; каждое чтение будет направлено ядру по мере наполнения строки. Последовательный доступ к памяти промахивается мимо кэша только когда доступ дошел до конца строки кэша.
Когда on-chip L2 memory сконфигурирована как не кэшируемая, выборки инструкций и выборки данных происходят 64-битными заполнениями. В этом случае каждое заполнение занимает 7 тактов ядра. На рисунке 6-21 показана ситуация когда встроенная память L2 сконфигурирована как не кэшируемая. Чтобы проиллюстрировать концепцию латентности L2, когда кэш выключена, используются простые инструкции, которые не требуют дополнительных выборок внешних данных. В этом случае последовательные инструкции выдаются на последовательных тактах ядра, если несколько инструкций попали в ядро при имеющейся выборке.
Рис. 6-21. Латентность L2 с выключенным кэшем.
[Встроенная в кристалл память Level 3 (L3)]
Многие процессоры Blackfin также имеют на кристалле постоянную память с кодом загрузчика (Boot ROM), которая работает на частоте SCLK. Она работает через блок интерфейса внешней шины (External Bus Interface Unit, EBIU), и имеет такие же возможности, как и другая память, подключаемая к чипу снаружи, то только по своей природе она предназначена только для чтения. К памяти L3 можно получить доступ не только с использованием выборки инструкции, но также можно получить доступ через инструкции загрузки и DMA. Память L3 может кэшироваться через память L1.
Поскольку память L3 не требует циклов ожидания для доступа, то она обычно быстрее, чем любая внешняя память, подключаемая к чипу снаружи. Обратитесь к руководству по аппаратуре конкретного процессора, чтобы узнать размер его памяти L3, использование и содержимое.
Примечание: например, у процессора ADSP-538F (обратите внимание, в конце буква F) имеется на кристалле 1 мегабайт памяти FLASH, которая работает как память L3, и может использоваться в разных областях карты памяти - в зависимости от того, как это сконфигурировано внешними выводами. Подробнее см. [2].
[Защита и свойства памяти]
Эта секция описывает блок управления памятью (Memory Management Unit, MMU), страницы памяти, управление CPLB, управление MMU, и регистры CPLB.
Memory Management Unit. Процессор Blackfin содержит основанный на страницах блок управления памятью (Memory Management Unit, MMU). Этот механизм предоставляет управление кэшированием участков памяти, а также управления атрибутами защиты на уровне страниц. MMU предоставляет большую гибкость в выделении памяти и ресурсов I/O и распределении их между задачами, с полным контролем прав доступа и поведения кэша.
MMU реализован как два блока Content Addressable Memory (CAM) по 16 записей. Каждая запись называется как дескриптор буфера с возможностью кэширования и защиты, Cacheability Protection Lookaside Buffer (CPLB) descriptor. Когда это разрешено, каждая запись в MMU проверяется на любую операцию выборки, загрузки или сохранения, чтобы определить, есть ли соответствие между запрошенным адресом и атрибутами защиты страницы, содержащимися в дескрипторе, используемом для транзакции по памяти, без затрат дополнительных циклов при выполнении инструкции.
Из-за того, что области памяти L1 разделены на память инструкций и память данных, записи CPLB также делятся на CPLB инструкций и данных. 16 записей CPLB используются для запросов выборки инструкции; они называются ICPLB. Другие 16 записей CPLB используются для транзакций данных; они называются DCPLB. ICPLB и DCPLB разрешаются путем установки соответствующих бит в регистрах управления памятью L1 (L1 Instruction Memory Control, IMEM_CONTROL) и управления памятью данных L1 (L1 Data Memory Control, DMEM_CONTROL) соответственно. Эти регистры показаны на рис. 6-2 (врезка "Регистр IMEM_CONTROL ...") и 6-11 (врезка "Регистр DMEM_CONTROL ...") соответственно.
Каждая запись CPLB содержит пару 32-битных значений. Для выборок инструкции:
• ICPLB_ADDR[n] определяет начальный адрес страницы, описанной дескриптором CPLB. • ICPLB_DATA[n] определяет свойства страницы, описанной дескриптором CPLB.
Для операций с данными принцип тот же:
• DCPLB_ADDR[m] определяет начальный адрес страницы, описанной дескриптором CPLB. • DCPLB_DATA[m] определяет свойства страницы, описанной дескриптором CPLB.
Есть 2 дескриптора CPLB по умолчанию для доступа данным области памяти scratchpad, и к области системы и MMR ядра. Эти дескрипторы по умолчанию задают вышеуказанные пространства памяти как не кэшируемые, так что не нужны дополнительные CPLB для настройки доступа к этим регионам памяти.
Если допустимые CPLB были настроены для этой области памяти, то CPLB по умолчанию игнорируются.
Страницы памяти. Адресное пространство 4 гигабайта (4G байт) процессора можно поделить на участки памяти или I/O, так называемые страницы памяти. Каждый адрес, находящийся в пределах страницы, использует одни и те же атрибуты, заданные для этой страницы. Архитектура поддерживает четыре разные размера страниц:
• 1K байт • 4K байт • 1M байт • 4M байт
Различные размеры страниц предоставляют гибкий механизм для соответствия атрибутов привязки к разным видам памяти и I/O.
Атрибуты страницы памяти. Каждая страница определена дескриптором из 2 слов. Это слово адреса дескриптора xCPLB_ADDR[n] и слово свойств дескриптора xCPLB_DATA[n]. Слово адреса дескриптора предоставляет базовый адрес страницы в памяти. Страницы должны быть выровнены по адресу, который нацело делится на размер страницы. Например, страница размером 4M байта должна начинаться с адреса, который делится на 4M байт; страница размером 1 килобайт может начинаться с любой границы блока 1K байт. Второе слово дескриптора указывает другие свойства (или атрибуты) страницы. Эти свойства включают:
• Размер страницы (1K байт, 4K байт, 1M байт, 4M байт). • Кэширование/нет кэширования. Доступ к этой странице будет происходить через кэш L1, если кэширование включено. • Если кэширование включено: write-through/write-back. Записываемые данные будут немедленно копироваться на привязанную к кэшу память, или синхронизация будет отложена до момента, когда потребуется перераспределить память кэша под другой адрес памяти. Если write-through, то выделите это только для чтения или для чтения и записи. • Грязная/модифицированная. Данные на этой странице были изменены с момента последней загрузки CPLB. Это свойство должно управляться программно, состояние не поменяется автоматически. • Разрешение на запись для Supervisor: разрешает или запрещает запись этой страницы в режиме супервизора. Применяется только для страниц данных. • Разрешение на запись для User: разрешает или запрещает запись этой страницы в режиме пользователя. Применяется только для страниц данных. • Разрешение на чтение для User: разрешает или запрещает чтение этой страницы в режиме пользователя. • Valid. Проверьте этот бит, чтобы определить, является ли это допустимым CPLB данных. • Lock. Сохраните эту запись в MMR; это не участвует в политике замены CPLB.
Таблица дескрипторов страниц (Page Descriptor Table). Для доступа к памяти через кэш, когда разрешены CPLB для доступа к инструкции, данным, или для того и другого, в паре MMR должна быть допустимая запись CPLB. Области хранения MMR для записей CPLB ограничены 16 дескрипторами для выборок инструкции и 16 дескрипторами для операций загрузки и сохранения данных.
Для маленьких и/или простых моделей памяти можно определить набор дескрипторов CPLB, которые поместятся в эти 32 записи, покрывающие все адресуемое пространство так, что их никогда не понадобится заменять. Этот тип определения называется статической моделью управления памятью.
Однако рабочие окружения операционных системы обычно определяют больше дескрипторов CPLB, чтобы накрыть всю адресуемую память и области I/O, чем доступно в CPLB MMR кристалла. Когда это произошло, то используется основанная на памяти структура данных, называемая Page Descriptor Table (таблица дескрипторов страниц); в ней могут быть сохранены все потенциально необходимые дескрипторы CPLB. Конкретный формат этой таблицы не определен как часть архитектуры процессора Blackfin. Различные операционные системы, которые имеют разные модели управления памятью, могут реализовать структуры Page Descriptor Table в соответствии с требованиями OS. Это позволяет делать подстройки компромисса между уровнем защиты и атрибутами быстродействия в подпрограммах поддержки управления памятью.
[Управление CPLB]
Когда процессор Blackfin выдает операцию с памятью, для которой в паре MMR нет допустимого дескриптора CPLB (cacheability protection lookaside buffer), произойдет исключение. Это исключение переведет процессор в режим супервизора, и перенаправит поток выполнения на обработчик исключения MMU (подробнее см. "Исключения" в [3]). Обработчик обычно является частью ядра операционной системы (OS), которое реализует политику замещения CPLB.
Перед тем, как разрешить CPLB, должны существовать допустимые дескрипторы CPLB и для Page Descriptor Table, и для обработчика исключения MMU. Биты LOCK этих дескрипторов CPLB обычно устанавливаются, чтобы их случайно не испортило программное обеспечение.
Обработчик использует ошибочный адрес для индексирования по структуре Page Descriptor Table, чтобы найти корректные данные дескриптора CPLB, чтобы загрузить их в одну из пар встроенных в кристалл регистровых пар CPLB. Если все встроенные в кристалл регистры содержат допустимые записи CPLB, то обработчик выберет один из этих дескрипторов для замены, и в него будет загружена новая информация дескриптора. Перед загрузкой новых данных дескриптора в любой CPLB, соответствующая группа из 16 CPLB должна быть запрещена с использованием:
• Битом Enable DCPLB (ENDCPLB) в регистре DMEM_CONTROL для дескрипторов данных, или • Битом Enable ICPLB (ENICPLB) в регистре IMEM_CONTROL для дескрипторов инструкции.
За политику замены CPLB и её алгоритм отвечает системный обработчик исключения MMU. Эта политика, которая диктуется требованиями операционной системы, обычно реализует принципы модифицированного LRU (Least Recently Used, т. е. последний использованный), шедулинг round robin (замена по кругу), или псевдослучайную замену.
После того, как загружен новый дескриптор CPLB, происходит выход из обработчика исключения, и операция с памятью, которая споткнулась по ошибке, перезапускается. Теперь эта операция должна соответствовать новому допустимому для неё дескриптору CPLB для запрошенного адреса, и операция успешно завершится.
Одна инструкция может генерировать как выборку инструкции, так и один или два доступа к памяти. Может произойти такое, что больше одной из этих операций с памятью не имеют допустимого дескриптора CPLB в паре MMR. В этом случае исключения приоритезируются и обрабатываются в следующем порядке:
• Промах страницы инструкции • Промах страницы на DAG0 • Промах страницы на DAG1
Применение MMU. Управление памятью является опциональной (не обязательной для использования) функцией в архитектуре процессора Blackfin. Использовать её или нет - зависит от требований к системе для конкретного приложения. После сброса все CPLB запрещены, и блок управления памятью (Memory Management Unit, MMU) не используется.
MMU не поддерживает аппаратную автоматическую трансляцию адресов.
Если вся память L1 сконфигурирована как SRAM, то функции данных и инструкции MMU не обязательны, в зависимости от требований приложения по защите областей памяти либо между задачами, либо между режимами пользователя (User mode) и супервизора (Supervisor mode). Для защиты памяти между задачами операционная система может содержать отдельные таблицы инструкций и/или данных для страниц памяти, доступных для каждой задачи, и сделать эти страницы доступными только для той или иной запущенной задачи. Когда происходит переключение между задачами, операционная система может гарантировать отмену достоверности любого дескриптора CPLB чипа, который больше не должен быть доступен для новой задачи. Также операционная система может подгрузить дескрипторы, подходящие для новой задачи.
Для многих операционных систем программа приложения работает в User mode, в то время как операционная система и её службы работают в Supervisor mode. Это желательно для защиты кода и структур данных, используемых операционной системой, от непреднамеренной модификации со стороны приложения, работающего в User mode. Эта защита может быть достигнута путем определения дескрипторов CPLB для защиты диапазонов памяти, которые будут позволять доступ на запись только в режиме Supervisor. Если произойдет попытка записи защищенной области памяти в User mode, будет сгенерировано исключение до того, как память будет модифицирована. Опционально приложению в User mode может быть дан доступ на чтение для структур, которые полезны для приложения. Даже для функций, работающих в Supervisor mode, может быть заблокирован доступ на запись некоторых страниц памяти, которые содержат код, который не предназначен для модификации. Поскольку записи CPLB это MMR, которые могут быть записаны только в Supervisor mode, программы пользователя не могут получить доступ к ресурсам, защищенным этим способом.
Если либо память инструкций L1, либо память данных L1 сконфигурирована частично или полностью как кэш, должны быть разрешены соответствующие CPLB. Когда инструкция генерирует доступ запрос доступа к памяти, и кэш разрешен, то процессор сначала проверяет ICPLB, чтобы определить, находится ли адрес в кэшируемом диапазоне адресов. Если нет допустимой записи ICPLB в паре MMR, соответствующей запрошенному адресу, то генерируется исключение MMU, чтобы получить допустимые дескрипторы ICPLB и определить, кэшируется память или нет. В результате если L1 Instruction Memory разрешена в качестве кэша, то любой регион памяти, который содержит инструкции, должен иметь допустимый дескриптор ICPLB, определенный для этого региона. Эти дескрипторы должны находиться либо всегда в MMR, либо в специальной таблице (находящейся где-то в памяти) Page Descriptor Table, которой управляет обработчик исключения MMU. Аналогично, если либо один, либо оба банка данных L1 сконфигурированы как кэш, все потенциальные диапазоны памяти данных должны поддерживаться дескрипторами DCPLB.
Перед разрешением кэша должны быть настроены и разрешены MMU и их соответствующие структуры данных.
Примеры защищенных регионов памяти. На рисунке 6-22 предоставлена начальная точка базового выделения CPLB для инструкций и данных. Обратите внимание, что некоторые ICPLB и DCPLB имеют общие дескрипторы для одного и того же адресного пространства.
Рис. 6-22. Примеры защищенных областей памяти.
Ниже приведены описания регистров, предназначенных для настройки CPLB. Адреса MMR даны в соответствующих таблицах для каждого регистра.
Рисунок 6-23 описывает регистры данных ICPLB (ICPLB_DATAx).
Чтобы гарантировать правильное поведение и совместимость в будущем, все зарезервированные биты в этом регистре должны быть установлены в 0 всякий раз, когда этот регистр записывается.
CPLB_L1_CHBL. Очистите этот бит всякий раз, когда память L1 сконфигурирована как SRAM. 0 - не кэшируется в L1, 1 - кэшируется в L1.
CPLB_MEM_LEV. Этот бит доступен только в тех устройствах, у которых на кристалле есть память L2 - см. руководство по аппаратуре Вашего процессора. Например, у BF538 [1] этот бит отсутствует.
CPLB_LRUPRIO. Приоритет политики LRU, привязанный к строке, подробнее см. "Построчная блокировка кэша инструкций". 0 низкий приоритет, 1 высокий приоритет.
CPLB_L1SRAM. Тип обработки ситуации обращения к нереализованной области памяти L1. 0: доступ перенаправляется блоку EBIU (если запрос нелегален, то генерируется аппаратная ошибка), 1: генерируется исключение (программист имеет возможность корректно обработать ситуацию не реализованной области L1).
CPLB_USER_RD. 0: попытка доступа на чтение в User mode сгенерирует исключение нарушения доступа, 1: разрешен доступ на чтение в User mode.
CPLB_VALID. 0: недопустимая (запрещенная) запись CPLB, 1: допустимая (разрешенная) запись CPLB.
CPLB_LOCK. Этот бит может использоваться в алгоритмах замены CPLB программного обеспечения. 0: не заблокировано, запись CPLB может быть заменена, 1: запись CPLB заблокирована и не должна быть изменена.
Таблица 6-2. Привязанные к памяти адреса регистров ICPLB Data (MMR).
На рисунке 6-24 показаны регистры данных DCPLB (DCPLB_DATAx).
Чтобы гарантировать правильное поведение и совместимость в будущем, все зарезервированные биты в этом регистре должны быть установлены в 0 всякий раз, когда этот регистр записывается.
CPL7B_L1_AOW. Допустим только если применено сквозное кэширование (CPLB_VALID = 1, CPLB_WT = 1). 0: выделяются строки кэша только для операций чтения, 1: выделяются строки кэша и для записи, и для чтения.
CPLB_WT. Работает только в режиме кэширования. 0: принцип кэширования записи "обратная запись" (write-back), 1: сквозной принцип кэширования записи (write-through).
CPLB_L1_CHBL. Очистите этот бит всякий раз, когда память L1 сконфигурирована как SRAM. 0 - не кэшируется в L1, 1 - кэшируется в L1.
CPLB_MEM_LEV. Этот бит доступен только в тех устройствах, у которых на кристалле есть память L2 - см. руководство по аппаратуре Вашего процессора. Например, у BF538 [1] этот бит отсутствует.
CPLB_DIRTY. Допустим только в случае write-back кэширования. (CPLB_VALID = 1, CPLB_WT = 0 и CPLB_L1_CHBL = 1). 0: кэш "чистая", 1: "грязная". Когда этот бит 0, то при доступе к этой странице на сохранение будет генерироваться исключение нарушения защиты. Состояние этого бита модифицируется только записью в этот регистр. Обработчик исключения должен установить этот бит.
CPLB_L1SRAM. Тип обработки ситуации обращения к нереализованной области памяти L1. 0: доступ перенаправляется блоку EBIU (если запрос нелегален, то генерируется аппаратная ошибка), 1: генерируется исключение (программист имеет возможность корректно обработать ситуацию не реализованной области L1).
CPLB_SUPV_WR. 0: доступ на запись в Supervisor mode сгенерирует исключение нарушения защиты, 1: доступ на запись в Supervisor mode разрешен.
CPLB_USER_WR. 0: доступ на запись в User mode сгенерирует исключение нарушения защиты, 1: доступ на запись в User mode разрешен.
CPLB_USER_RD. доступ на чтение в User mode сгенерирует исключение нарушения защиты, 1: доступ на чтение в User mode разрешен.
CPLB_VALID. 0: недопустимая (запрещенная) запись CPLB, 1: допустимая (разрешенная) запись CPLB.
CPLB_LOCK. Этот бит может использоваться в алгоритмах замены CPLB программного обеспечения. 0: не заблокировано, запись CPLB может быть заменена, 1: запись CPLB заблокирована и не должна быть изменена.
Таблица 6-3. Привязанные к памяти адреса регистров DCPLB Data.
Биты в регистре состояния DCPLB (DCPLB_STATUS) и регистре состояния ICPLB (ICPLB_STATUS) идентифицируют запись CPLB, которая запустила связанные с CPLB исключения. Обработчик исключения может определить причину отказа, исследуя записи CPLB.
Регистры DCPLB_STATUS и ICPLB_STATUS являются достоверными только в сбойной подпрограмме обработки исключения.
Биты FAULT_DAG, FAULT_USERSUPV и FAULT_RW в регистре состояния DCPLB (DCPLB_STATUS) используются для идентификации записи CPLB, которая вызвала связанное с CPLB исключение (см. рис. 6-27).
Рис. 6-27. Регистр состояния DCPLB. Бит FAULT_USERSUPV в регистре состояния ICPLB (ICPLB_STATUS) используется для идентификации записи CPLB, которая вызвала связанное с CPLB исключение (см. рис. 6-28).
FAULT_ILLADDR. 0: не было сбоя, 1: была попытка записи в не существующую память.
FAULT_DAG. 0: доступ был сделан через DAG0, 1: через DAG1.
FAULT_USERSUPV. 0: доступ был сделан в User mode, 1: в Supervisor mode.
FAULT_RW. 0: был доступ на чтение, 1: на запись.
FAULT[15:0]. Каждый бит показывает состояние попадание/промах связанной записи CPLB.
Рис. 6-28. Регистр состояния ICPLB.
FAULT_ILLADDR. 0: не было сбоя, 1: была попытка записи в не существующую память.
FAULT_USERSUPV. 0: доступ был сделан в User mode, 1: в Supervisor mode.
FAULT[15:0]. Каждый бит показывает состояние попадание/промах связанной записи CPLB.
Регистр адреса DCPLB (DCPLB_FAULT_ADDR) и регистр адреса сбоя ICPLB (ICPLB_FAULT_ADDR) содержат адрес, которые был причиной сбоя в L1 Data Memory или L1 Instruction Memory, соответственно. См. рис. 6-29 и рис. 6-30.
Регистры DCPLB_FAULT_ADDR и ICPLB_FAULT_ADDR достоверны только в сбойной подпрограмме обработчика исключения.
Рис. 6-29. Регистр адреса DCPLB.
FAULT_ADDR[31:16], FAULT_ADDR[15:0]. Адрес данных, который привел к ошибке в памяти данных L1.
Рис. 6-30. Регистр адреса сбоя ICPLB.
FAULT_ADDR[31:16], FAULT_ADDR[15:0]. Адрес инструкции, который привел к ошибке в памяти инструкций L1.
[Модель транзакций памяти]
И внутренняя, и внешняя области памяти доступны в порядке следования байт little endian. Рис. 6-31 показывает слово данных, сохраненное в регистре R0 и в памяти по адресу addr. B0 относится к самому младшему байту 32-битного слова.
Рис. 6-31. Данные, сохраненные в порядке Little Endian.
Рисунок 6-32 показывает 16- и 32-битные инструкции, сохраненные в памяти. Диаграмма слева показывает 16-битные инструкции, сохраненные в памяти, где самый старший по значимости байт хранится в большем по значению адресе (байт B1 находится по адресу addr+1), и самый младший по значимости байт находится в меньшем адресе (байт B0 находится по адресу addr).
Рис. 6-32. Инструкции, сохраненные в порядке Little Endian.
Диаграмма справа показывает 32-битные инструкции, сохраненные в памяти. Обратите внимание, что самое старшее 16-битное полуслово инструкции (байты B3 и B2) сохранено в младших адресах (addr+1 и addr), и самое младшее полуслово (байты B1 и B0) сохранено в старших адресах (addr+3 и addr+2).
[Операция загрузки/сохранения (Load/Store)]
Архитектура процессора Blackfin поддерживает концепцию RISC машины Load/Store. Эта машина - характеристика архитектуры RISC, где операции с памятью (загрузки и сохранения) преднамеренно отделены от арифметических функций, которые используют цели операций памяти. Разделение сделано потому, что операции с памятью, в частности инструкции, которые обращаются к памяти вне чипа или к устройствам I/O, часто занимают несколько циклов для своего завершения, что обычно останавливало бы процессор, не давая выполняться программе по инструкции за один цикл.
При операциях записи инструкция store считается завершенной, как только она выполняется, даже если могут пройти несколько циклов до того, как данные действительно будут записаны во внешнюю память или ячейку I/O. Такая организация позволяет процессору выполнять одну инструкцию за каждый такт, и это подразумевает отсутствие гарантии синхронизации между тем, когда запись завершится и когда выполнится следующая инструкция. Кроме того, эта синхронизация считается не имеющей значения в контексте большинства операций с памятью.
Interlocked Pipeline. При выполнении инструкций архитектура процессора Blackfin реализует interlocked pipeline (взаимно блокируемый конвейер). Когда выполняется инструкция загрузки, то целевой регистр операции чтения помечается занятым, пока значение для него не будет возвращено системой памяти. Если последующая инструкция пытается получить доступ к этому регистру до того, как новое значение получено, конвейер остановится до завершения операции с памятью. Эта приостановка гарантирует, что инструкции, которые требуют использования данных результата загрузки, не будут использовать предыдущие или недостоверные данные в регистре, даже при том, что инструкции разрешено запустится до того, как чтение памяти завершится.
Этот механизм позволяет выполнение независимых инструкций (т. е. тех, для которых не нужна задержка) между загрузкой и инструкцией, которая использует результат чтения без необходимости для программиста или компилятора знать, сколько циклов в действительности нужно для завершения операции чтения. Если инструкция, немедленно следующая за загрузкой, использует тот же регистр, конвейер просто останавливается, пока не будет возвращено значение операции чтения. Следовательно, это работает так, как ожидал программист. Однако если 4 других инструкции будут помещены после инструкции загрузки, и до инструкции, которая использует тот же самый регистр, то все они выполняться без задержки, и общее быстродействие процессора улучшится.
Порядок загрузок и сохранений. Релаксация синхронизации между инструкциями доступа к памяти и окружающими их инструкциями упоминается как слабое упорядочивание загрузок и сохранений. Слабое упорядочивание подразумевает, что время действительного завершения операций с памятью - даже порядок, в котором эти события происходят - могут не соответствовать тому, что программист видит в исходном коде программы. Вот все, что гарантируется:
• Операции загрузки завершатся до того, как возвращенные данные будут использоваться следующей инструкцией. • Операции загрузки, использующие ранее записанные данные, будут использовать обновленные значения. • Операции сохранения так или иначе перешлют значения в нужное место.
Из-за слабого упорядочивания система памяти использует приоритет чтений перед записями. В этом случае запись, которая поставлена в очередь на конвейере, но еще не завершенная, может быть отложена последующей операцией чтения, и чтению разрешено завершиться до записи. Чтения имеют приоритет перед записями потому, что операция чтения зависит от ожидания её завершения, в то время как процессор считает запись сразу завершенной, и запись не останавливает конвейер, даже если в действительности понадобится несколько циклов, чтобы записанное значение попало в память. Так что чтение, которое в коде программы стоит позже записи, на самом деле могло бы завершиться раньше и вернуть значение до того, как будет завершена запись. Такое упорядочивание значительно повышает быстродействие выполнения большинства инструкций, работающих с памятью. Однако это может привести к побочным эффектам, которых программист должен избегать, чтобы не допустить неправильной работы системы.
Когда происходит запись в области, не принадлежащие памяти, или чтение из таких областей, например регистры устройств I/O вне кристалла, то порядок, в котором происходят операции чтения и записи, часто имеет большое значение. Например, чтение регистра состояния может зависеть от записи в регистр управления. Если адрес тот же самый, то чтение вернуло бы значение из буфера хранения, а не из реального регистра I/O устройства, и порядок чтения и записи регистра может поменяться на обратный. Оба этих случая могут дать нежелательные побочные эффекты в работе программы и периферии - все будет работать не так, как ожидалось. Чтобы гарантировать, что эти эффекты не произойдут в коде, который требуют точного (жесткого) порядка выполнения инструкций загрузки и сохранения, должны использоваться инструкции синхронизации (CSYNC или SSYNC).
Инструкции синхронизации. Когда требуется упорядочивание загрузок и сохранений, как может быть в случае последовательных записей в устройство I/O для настройки и управления, используйте инструкции синхронизации ядра или системы, CSYNC или SSYNC соответственно.
Инструкция CSYNC гарантирует, что все ожидающие операции ядра завершены, и буфер хранения (между ядром процессора и памятью L1) был сброшен перед переходом к выполнению следующей инструкции. Ожидающие операции ядра могут включать любые ожидающие прерывания, спекулятивные состояния (такие как предсказания ветвления), или исключения.
Рассмотрим следующий пример последовательности кода:
IF CC JUMP away_from_here;
CSYNC;
R0 = [P0];
away_from_here:
В этом примере инструкция CSYNC гарантирует:
• Ветвление по условию (IF CC JUMP away_from_here) обработано, при этом принудительно приостановлен конвейер выполнения до момента завершения обработки условия, и любые записи в буфере хранения процессора были сброшены (flushed). • Все отложенные прерывания или исключения были обработаны до завершения CSYNC. • Не было спекулятивной загрузки из памяти.
Загрузки данных и выборки инструкций условия (инструкции CALL) в тени перехода по условию обычно не потерпят сбой, когда они не защищены инструкцией CSYNC, как показано в примере выше. Однако если будет попытка загрузки или выборки из регионов недопустимой или не инициализированной памяти, контроллер памяти может генерировать аппаратную ошибку из-за нежелательного доступа, даже если он будет немедленно прерван. Особенное внимание нужно уделить ситуациям, когда условный переход защищает от доступа по нулевому указателю (NULL). Помните, что адрес 0x00000000 находится в области SDRAM.
Инструкция SSYNC гарантирует, что все побочные эффекты предыдущей операции распространились наружу через интерфейс между памятью L1 и остальным кристаллом. В дополнение к функциям синхронизации ядра CSYNC, инструкция SSYNC сбрасывает любые буферы записи между памятью L1 и доменом системы, и генерирует запрос синхронизации к системе, который требует подтверждения до завершения SSYNC.
Спекулятивное выполнение чтения памяти. Операции загрузки из памяти не меняют значение памяти. Следовательно, выдача спекулятивной операции чтения памяти для последующей операции загрузки обычно не приводит к нежелательным побочным эффектам. В некоторых последовательностях кода, таких как инструкция условного ветвления, за которой идет загрузка, может быть улучшено быстродействие спекулятивной выдачей запроса на чтение к подсистеме памяти до того, как будет распознано ветвление по условию. Пример:
IF CC JUMP away_from_here
RO = [P2];
...
away_from_here:
Если взято ветвление, то загрузка будет сброшена из конвейера, и любые результаты, которые были возвращены, могут игнорироваться. С другой стороны, если ветвления не будет, память вернет корректное значение раньше, чем если бы работа была приостановлена до момента окончания распознавания ветвления.
Однако в случае устройства I/O вне кристалла, это могло бы привести к нежелательному побочному эффекту для периферии, которая возвратит последовательные данные из FIFO или регистра, который изменит значение в зависимости от количества запрошенного количества чтений. Чтобы избежать этого эффекта, используйте инструкции синхронизации (CSYNC или SSYNC), чтобы гарантировать корректное поведение между операциями чтения.
Операции сохранения никогда не осуществляют спекулятивный доступ к памяти, потому что могло бы привести к модификации значения памяти до того как будет определено, должна ли инструкция выполняться.
Все процессоры, за исключением ADSP-BF535, защищают периферийные устройства кристалла от разрушения из-за спекулятивных чтений. Здесь отдельный строб инициирует побочный эффект чтения, когда инструкция действительно выполняется.
Поведение чтения памяти по условию. Инструкции синхронизации заставляют распознать все спекулятивные состояния до того, как инструкция загрузки инициирует обращение к памяти. Однако инструкция загрузки сама может генерировать больше одной операции чтения памяти, потому что это может быть прервано. Если произойдет прерывание с достаточным приоритетом между завершением инструкции синхронизации и завершением инструкции загрузки, то секвенсер отменит инструкцию загрузки. После выполнения прерывания прерванная загрузка выполнится снова. Это поведение минимизирует латентность для запуска ISR. Однако может случиться, что цикл чтения памяти был инициирован до отмены загрузки, и в результате последует вторая операция чтения после того, как загрузка запустится снова. Для большинства доступов к памяти множественное чтение по одному и тому же адресу не составит никаких проблем. Однако для некоторых устройств вне кристалла, отображенных на адреса памяти, таких как периферийные FIFO данных, лишние чтения окажутся деструктивными. Каждый раз, когда устройство читается, стек FIFO сдвигается, и данные не могут быть восстановлены и прочитаны заново.
Когда осуществляется доступ к устройствам вне кристалла, отображенным на адреса памяти, и у этих устройств имеется зависимость от количества операций чтения по указанному адресу, запретите прерывания перед выполнением операции загрузки. В этих условиях используйте следующую последовательность для запрета и разрешения прерываний (пример кода, приведенный ниже). Обратите внимание на инструкции NOP после инструкции CLI. Эта последовательность требуется для защиты фазы чтения конвейера от того, что он увидит инструкцию чтения до того, как прерывания будут выключены.
CLI R0;
NOP; NOP; NOP; /* добавлено для защиты конвейера */
R1 = [P0];
STI R0;
Все процессоры, за исключением ADSP-BF535, защищают периферийные устройства вне кристалла от этой проблемы. Так что для процессора ADSP-BF535 используйте эту последовательность как для устройств в кристалле, так и для устройств вне кристалла.
[Работа с памятью]
Эта секция содержит информацию по выравниванию данных в памяти и операциях с памятью, которые поддерживают семафоры между задачами. Также кратко рассмотрены регистры MMR и примеры программирования MMR ядра.
Выравнивание. Не выровненные операции с памятью напрямую не поддерживаются. Не выровненные обращения к памяти генерируют событие не выровненного обращения к памяти (Misaligned Access exception event, см. "Исключения" [l3]). Однако, поскольку некоторые потоки данных (такие как 8-битные данные видео) могут быть нормально не выровненными в памяти, исключения выравнивания могут быть запрещены инструкцией DISALGNEXCPT. Кроме того, некоторые инструкции в группе quad 8-bit автоматически запрещают исключения выравнивания.
Когерентность кэша. Для общих данных программное обеспечение должно обеспечить требуемую поддержку когерентности данных. Чтобы достичь этого, используйте инструкцию FLUSH (см. "Инструкции управления кэшем данных"), и/или явное выведение строки кэша из достоверности с использованием MMR ядра (см. раздел "Регистры тестирования данных").
Атомарные операции. Процессор поддерживает одну атомарную операцию: TESTSET. Атомарные операции используются для предоставления не прерываемых операций с памятью в поддержке семафоров между задачами. Инструкция TESTSET загружает косвенно адресованное в памяти полуслово, проверяет, является ли младший байт нулем, и затем устанавливает самый старший бит (MSB) младшего байта памяти, не влияя на все остальные биты. Если первоначально байт равен 0, то инструкция устанавливает бит CC. Если первоначально байт не равен 0, то инструкция очистит бит CC. Последовательность этой транзакции с памятью атомарная - аппаратная блокировка шины гарантирует, что не могут произойти другие операции с памятью между порциями проверки и установки в этой инструкции. Инструкция TESTSET может быть прервана ядром. Если это произошло, то инструкция TESTSET выполнится снова после возврата из прерывания.
Инструкция TESTSET может адресовать все адресное пространство 4 гигабайта, однако она не должна быть направлена на память ядра (пространство L1 или MMR) поскольку атомарный доступ к этой памяти не поддерживается.
Архитектура памяти всегда обрабатывает атомарные операции как доступ без кэша, даже если дескриптор CPLB для адреса показывает доступ с разрешенным кэшем. Однако выполнение операций TESTSET на кэшируемых регионах памяти не рекомендуется, поскольку архитектура не может гарантировать, что кэшируемое место в памяти когерентно в момент выполнения инструкции TESTSET.
Отображенные на память регистры (Memory-Mapped Registers, MMR). Под MMR зарезервирована область в верхней части адресного пространства (начиная с 0xFFC00000). Этот регион определен как не кэшируемый, и он поделен между системными MMR (0xFFC00000 .. 0xFFE00000) и MMR ядра (0xFFE00000 .. 0xFFFFFFFF).
Как и регистры, не отображенные на память, MMR ядра подключены к 32-разрядному регистру доступа к шине (Register Access Bus, RAB). Они работают на частоте CCLK.
Системные MMRs подключены к шине доступа к периферии (Peripheral Access Bus, PAB), которая реализована либо как 16-битная, либо как 32-битная шина, в зависимости от модели процессора. Шина PAB работает на частоте SCLK. Записи в системные MMR выполняются ни через буферы записи, ни через буферы сохранения. Скорее есть простой мост между шинами RAB и PAB, который только делает трансляцию между доменами тактовых частот (и шириной шины).
Только для ADSP-BF535: системные MMR находятся за буферами хранения и записи. Здесь системные MMR ведут себя как устройства I/O вне кристалла, как это описано в разделе "Операции загрузки/сохранения". Следовательно, нужны инструкции SSYNC после инструкций сохранения, чтобы гарантировать строгое упорядочивание доступов к MMR.
Ко всем MMR можно получить доступ только в Supervisor mode. Доступ к MMR в User mode приведет к генерации исключения нарушения защиты доступа (protection violation exception). Попытки доступа к MMR с использованием DAG1 также приведет к генерированию исключения нарушения защиты доступа.
Все MMR ядра читаются и записываются с использованием 32-битного выравнивания. Однако у некоторых MMR определено меньше 32 бит. В этом случает не используемые биты зарезервированы. Системные MMR могут быть 16-разрядные.
Попытки доступа к несуществующим MMR генерируют исключение недопустимого доступа. Система игнорирует записи в MMR, предназначенные только для чтения.
Аппаратура порождает исключение, когда multi-issue инструкция пытается выполнить два доступа в область MMR.
В приложении B предоставляется общее описание всех MMR ядра.
Пример программирования MMR ядра. К MMR ядра можно получить доступ только как к выровненным на 32 бита словам. Не выровненный доступ к регистрам MMR генерирует событие исключения. Листинг 6-1 показывает требуемые инструкции для манипуляции стандартными MMR ядра.
Листинг 6-1. Программирование Core MMR.
CLI R0; /* остановка прерываний и сохранение IMASK */
P0 = MMR_BASE; /* 32-битная инструкция для загрузки базового адреса области MMR */
R1 = [P0 + TIMER_CONTROL_REG]; /* получить значение регистра управления */
BITSET R1, #N; /* установить бит N */
[P0 + TIMER_CONTROL_REG] = R1; /* восстановить регистр управления */
CSYNC; /* это дает гарантию, что регистр управления был записан */
STI R0; /* разрешить прерывания */
Инструкция CLI сохраняет содержимое регистра IMASK и запрещает прерывания очисткой IMASK. Инструкция STI восстанавливает содержимое IMASK, что разрешает прерывания. Код между CLI и STI непрерывен (во время его выполнения не могут произойти прерывания).
Для описания памяти используется следующая терминология. Другие термины и сокращения, которых нет в этой врезке, см. в разделе "Словарик" и врезках статьи [2].
Блок кэша (cache block). Самый маленький блок памяти, который может быть передан между уровнями памяти (например, из памяти L2 в память L1 или наоборот) как результат промаха кэша.
Попадание кэша (cache hit). Доступ к медленной памяти через кэш, для которой есть допустимый образ в кэше.
Строка, линия кэша (cache line). То же самое, что и блок кэша. В этой статье термин "строка кэша" используется в качестве термина "блок кэша".
Промах кэша (cache miss). Доступ к медленной памяти через кэш, когда в кэше нет допустимого образа для этой области памяти.
Прямое отображение (direct-mapped). Архитектура кэша, когда каждая строка кэша соответствует только одному месту, которое может появиться в кэше. Также это описывается как кэш 1-way associative. Подробнее см. [4]. На рисунке ниже показан 1-way ассоциативный кэш.
Грязный или модифицированный (dirty or modified). Бит состояния, сохраненный вместе с тэгом, показывающий, были ли данные в строке кэша изменены, когда они были скопированы из исходной памяти и, таким образом, должны быть обновлены в исходной памяти.
Эксклюзивный, чистый (exclusive, clean). Состояние строки кэша, показывающее, что строка кэша достоверна, и данные в ней соответствуют исходной памяти. Данные в чистом кэше не нуждаются в синхронизации с исходной памятью до их замены.
Полностью ассоциативный (fully associative). Архитектура кэша, в которой каждая строка может быть размещена в любом месте кэша. Подробнее см. [4]. На рисунке ниже показан полностью ассоциативный кэш.
Индекс. Часть адреса, которая используется для выбора элемента массива (например, индекс строки кэша).
Недопустимая, не достоверная (invalid). Описывает состояние строки кэша. Когда строка кэша не достоверна, не может произойти совпадения строки кэша.
Алгоритм последнего использованного (least recently used, LRU). Алгоритм замены, используемый в кэше, в котором будут заменены строки, которые не использовались дольше всего.
Память Level 1 (L1). Самая быстрая память, к которой может напрямую обратиться ядро без вмешательства дополнительных подсистем памяти (осуществляющих синхронизацию, кэширование или согласование времени доступа).
little endian. Стандартный формат хранения данных для процессора Blackfin. Слова и половинки слов сохраняются в памяти (и регистрах) так, что самый младший по значимости байт имеет самый меньший адрес по отношению к другим байтам в слове (или половинке слова), и соответственно самый значимый байт имеет самый большой адрес памяти хранения.
Политика замены (replacement policy). Функция, используемая процессором, чтобы определить строку для замены при промахе кэша. Часто используется алгоритм LRU.
Набор (set). Группа из N строк кэша в каналах N-канального кэша, выбранная по полю индекс INDEX адреса (см. рис. 6-5).
Ассоциативный набор (set associative). Архитектура кэша, которая ограничивает размещение строк кэша количеством наборов (или каналов).
Тэг (tag). Старшие биты адреса, сохраненные вместе с кэшированной строкой данных, чтобы идентифицировать отдельный адрес источника в памяти, который представляют кэшированную строку.
Достоверность (valid). Бит состояния, сохраняемый вместе с тэгом, показывающий, что соответствующий тэги данные являются текущими и корректными, и могут использоваться для удовлетворения доступа к памяти.
Жертва (victim). Грязная строка кэша, которая должна быть записана в медленную память до того, как её можно заменить на свободное место для выделения строки кэша под другие данные.
Канал (Way). Массив элементов хранения строк в N-канальном кэше (см. рис. 6-5).
Обратная запись (write back). Политика записи кэша, также известная как обратное копирование (copyback). Записываемые данные записываются только в строку кэша. Модифицированная строка кэша записывается в исходную память только когда она была заменена. Строки кэша выделяются как для чтений, так и для записей.
Сквозная запись (write through). Политика кэша, известная также как прямое сохранение (store through). Данные записываются как в строку кэша, так и в исходную память. Модифицированная строка кэша не записывается в исходную память, когда они заменяется. Строки кэша должны быть выделены для чтений, и могут быть выделены для записей (в зависимости от режима).
Регистры процессора Blackfin, отображенные на адресное пространство памяти (memory-mapped registers, MMR) находятся в диапазоне адресов 0xFFE00000 .. 0xFFFFFFFF.
Ко всем MMR ядра доступ должен осуществляться как 32-битное чтение или запись.
В этом приложении перечислены адреса MMR ядра их имена. Чтобы получить больше информации про MMR, см. столбец "Подробнее в разделе".
Регистры контроллера памяти данных L1 (0xFFE00000 – 0xFFE00404)
Таблица B-1. Регистры L1 Data Memory Controller.
Адрес MMR
Имя регистра
См. секцию
0xFFE0 0004
DMEM_CONTROL
Регистр DMEM_CONTROL
0xFFE0 0008
DCPLB_STATUS
Регистры DCPLB_STATUS и ICPLB_STATUS
0xFFE0 000C
DCPLB_FAULT_ADDR
Регистры DCPLB_FAULT_ADDR и ICPLB_FAULT_ADDR
0xFFE0 0100
DCPLB_ADDR0
Регистры DCPLB_ADDRx
0xFFE0 0104
DCPLB_ADDR1
0xFFE0 0108
DCPLB_ADDR2
0xFFE0 010C
DCPLB_ADDR3
0xFFE0 0110
DCPLB_ADDR4
0xFFE0 0114
DCPLB_ADDR5
0xFFE0 0118
DCPLB_ADDR6
0xFFE0 011C
DCPLB_ADDR7
0xFFE0 0120
DCPLB_ADDR8
0xFFE0 0124
DCPLB_ADDR9
0xFFE0 0128
DCPLB_ADDR10
0xFFE0 012C
DCPLB_ADDR11
0xFFE0 0130
DCPLB_ADDR12
0xFFE0 0134
DCPLB_ADDR13
0xFFE0 0138
DCPLB_ADDR14
0xFFE0 013C
DCPLB_ADDR15
0xFFE0 0200
DCPLB_DATA0
Регистры DCPLB_DATAx
0xFFE0 0204
DCPLB_DATA1
0xFFE0 0208
DCPLB_DATA2
0xFFE0 020C
DCPLB_DATA3
0xFFE0 0210
DCPLB_DATA4
0xFFE0 0214
DCPLB_DATA5
0xFFE0 0218
DCPLB_DATA6
0xFFE0 021C
DCPLB_DATA7
0xFFE0 0220
DCPLB_DATA8
0xFFE0 0224
DCPLB_DATA9
0xFFE0 0228
DCPLB_DATA10
0xFFE0 022C
DCPLB_DATA11
0xFFE0 0230
DCPLB_DATA12
0xFFE0 0234
DCPLB_DATA13
0xFFE0 0238
DCPLB_DATA14
0xFFE0 023C
DCPLB_DATA15
0xFFE0 0300
DTEST_COMMAND
Регистр DTEST_COMMAND
0xFFE0 0400
DTEST_DATA0
Регистр DTEST_DATA0
0xFFE0 0404
DTEST_DATA1
Регистр DTEST_DATA1
Регистры контроллера памяти инструкций L1 (0xFFE01004 – 0xFFE01404)