Лисья Нора

Оглавление


§ Регистры PMP

При помощи этих регистров можно задавать регионы памяти, которым требуется дать определенный доступ. Информация об этом хранится в регистрах pmpcfgX и pmpaddrX, где X – номер регистра, начиная с 0.
РЕГИСТР | АДРЕС | РЕГИОНЫ
========+=======+==========
pmpcfg0 | 0x3A0 | 0..3
pmpcfg1 | 0x3A1 | 4..7
pmpcfg2 | 0x3A2 | 8..11
pmpcfg3 | 0x3A3 | 12..15
Всего можно задавать до 16 регионов памяти, и давать им права на запись, чтение, исполнение, определять диапазон и стартовый адрес. Один регион кодируется 8 битами (1 байтом) в регистре pmpcfg:
7 | 6 5 | 4 3 | 2 1 0 БИТЫ
LOCK | 0 0 | MODE | X W R КОНФИГ
Объяснение значений полей:
Всего существует 4 режима:
Важно: проверка регистров идет от младшего (0) к старшему, так что если где-то на этапе проверки возник запрет доступа к диапазону памяти, то даже если старшее правило разрешает доступ, запрет все равно будет.

§ Метод адресации TOR

Как пример, для диапазона 0x4000 – 0x8000 необходимо записать в pmpaddr0=0x1000 и pmpaddr1=0x2000, выставить режим TOR именно в pmp1cfg – то есть это будет второй байт [15:8] в регистре pmpcfg0.
Особенно важно: в регистре pmpaddr0 все адреса записываются, делённые на 4. То есть реально надо будет записать не 0x1000, а именно 0x0400, что соответствует региону памяти 0x1000
Все адреса кодируются через верхнюю границу, это значит, что в случае когда нижний адрес (диапазон) записан в pmpaddr3, а старший в pmpaddr4, то режим адресации TOR ставится в конфигурационном регистре именно pmp4cfg (младший байт регистра CFG1), а не 3.

§ Метод адресации NAPOT

Второй метод, который позволяет одним регистром pmpaddrX задать и базу и диапазон, хотя и не без определенных ограничений.
И базовый адрес, и размер задаются в одном и том же регистре (32 бит). Размер сегмента кратен степени двойки и его наименьший размер – 8 байт, потом идут 16, 32, 64 и т.д.
......0 - 8 байт
.....01 - 16 байт
....011 - 32 байта
...0111 - 64 байта
..01111 - 128 байт
И так далее. То есть получается префиксная запись. Вначале, в младших битах идут единицы, и там где впервые встретился 0 – это и есть "раздел" диапазона и адреса, так как биты, которые идут за нулем (старшие) отвечают именно уже за базовый адрес. Но есть два замечания:
Формула для вычисления диапазона и адрес будет такой:
mask0 = 1 << (sizebits - 1) - 1 # Гранулярность адреса
mask1 = 1 << (sizebits - 2) - 1 # Диапазон
pmpXcfg = ((base >> 2) & ~mask0) | mask1
Если задаем sizebits = 3 (то есть 8 байт), то получаем 0, в base записывается реальное значение адреса в байтах.