OSDev Wiki
Advertisement

Общие сведения

Универсальный контроллер прерываний (GIC, Generic Interrupt Controller) был предложен фирмой ARM в качестве стандартного контроллера прерываний для процессоров, основанных на ядрах версий ARMv7-A и ARMv7-R. До появления седьмой версии архитектуры стандарта не существовало, и фирмы-производители применяли различные контроллеры прерываний, которые не были совместимы друг с другом не только для процессоров разных фирм, но иногда и для разных процессоров одной и той же фирмы.

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

  • программно генерируемые прерывания (SGI, Software Generated Interrupts), возникающие вследствие записи определённых значений в соответствующие регистры GIC и предназначенные в первую очередь для организации межпроцессорного взаимодействия. Каждый процессор имеет свой набор SGI, имеющих коды идентификации от 0 до 15 включительно;
  • «личные» внешние прерывания (PPI, Private Peripheral Interrupts), уникальные для каждого процессора и имеющие коды идентификации от 16 до 31 включительно;
  • общие внешние прерывания (SPI, Shared Peripheral Interrupts), которые потенциально могут обрабатываться любым процессором в системе. Их коды идентификации находятся в диапазоне от 32 до 1019 включительно.

Код идентификации (ID) SPI позволяет однозначно установить, по какой именно линии запроса прерывания поступил данный запрос. Он может быть обслужен любым процессором в системе, хотя программное обеспечение, настроив GIC тем или иным образом, может управлять распределением SPI по процессорам.

Одинаковые ID для PPI, поступивших на разные процессоры, соответствуют разным устройствам. Чтобы узнать, какое именно устройство выдало PPI, надо знать не только ID, но и номер процессора, который осуществляет обработку этого прерывания.

Наконец, SGI с одним и тем же ID может адресоваться произвольному числу процессоров. Для каждого SGI, поступившего на обработку некоторому процессору, можно узнать, какой именно процессор выдал данное SGI, прочитав соответствующий регистр GIC.

Коды идентификации 1020–1023 имеют специальное назначение, описанное в следующем разделе.

Для передачи прерывания конкретному процессору GIC выдаёт ему один из стандартных сигналов IRQ или FIQ, который обрабатывается процессором по общим правилам. Некоторые варианты GIC могут обеспечить сквозную передачу определённых своих входных сигналов прямо на линии IRQ и FIQ того или иного процессора, как будто самого GIC не существует.

Логически GIC делится на распределитель (Distributor) и процессорные интерфейсы (CPU Interfaces); число последних совпадает с числом процессорных ядер, с которыми работает GIC. Распределитель принимает запросы прерываний, определяет их приоритеты, производит маскирование и выдаёт необходимые запросы процессорным интерфейсам. Последние определяют самый приоритетный из незамаскированных запросов, имеющихся для данного процессора, и, если его приоритет достаточно высок, выдают «своему» процессору сигнал IRQ или FIQ.

Заметим, что GIC может работать с процессорами, поддерживающих или не поддерживающих расширения безопасности. Более того, часть процессоров многопроцессорной системы может поддерживать эти расширения, а другая часть — не поддерживать.

Принципы обработки запросов прерываний

Общие сведения

Запросы внешних прерываний (PPI и SPI) поступают по соответствующим входным линиям GIC. Они могут распознаваться либо по фронту сигнала, либо по его уровню, что программируется индивидуально для каждой линии запроса прерывания с помощью регистров ICDICFR.

Запросы программных прерываний генерируются путём записи в регистр ICDSGIR. Любой процессор может выдать запрос прерывания любому другому процессору или нескольким процессорам, в том числе самому себе.

Прерывания могут индивидуально разрешаться и запрещаться путём записи в соответствующие регистры ICDICER и ICDISER. Если некое ожидающее обработки прерывание запрещено (замаскировано), то GIC будет его игнорировать. Заметим, что конкретная реализация GIC может не допускать запрещения некоторых прерываний, что можно обнаружить, выполняя запись и последующее считывание упомянутых регистров.

Пока запрос не поступил, соответствующее прерывание находится в состоянии «неактивно» (inactive). При поступлении запроса разрешённого прерывания последнее переходит в состояние «ожидает» (pending). Внешнее прерывание может быть переведено из неактивного состояния в ожидающее не только при поступлении запроса прерывания по соответствующей линии, но и программно путём записи в соответствующий регистр ICDISPR. Сбросить состояние ожидания и вернуть прерывание в состояние «неактивно» можно программно путём записи в соответствующий регистр ICDICPR. Однако, если запрос прерывания распознаётся не по фронту, а по уровню соответствующего сигнала, то прерывание всё равно останется в состоянии «ожидает» до тех пор, пока не будет снят сигнал запроса прерывания. В то же время снятие сигнала запроса прерывания, обнаруживаемого по уровню, не переводит прерывание в состояние «неактивно», если ранее была выполнена запись в соответствующий регистр ICDISPR: помимо снятия сигнала, в этом случае необходимо также выполнить запись в регистр ICDICPR. Наконец, с помощью считывания этих регистров можно узнать, какие прерывания являются ожидающими в данный момент.

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

Обычно GIC реализует существенно меньшее число прерываний, чем возможно теоретически (32 индивидуальных для каждого из восьми процессоров и ещё 988 общих, т.е. всего 1244 прерывания). Обнаружить, какие прерывания поддерживаются данным GICом и какие из них могут быть запрещены, а какие всегда остаются разрешёнными, можно путём чтения и записи регистров ICDICER и ICDISER.

Порядок обработки прерываний

1. Если некое прерывание запрещено записью в соответствующий регистр ICDICER, оно далее не анализируется и не может быть передано на обработку. Если SPI уже активно (обслуживается одним из процессоров), оно не выдаётся на процессорные интерфейсы, даже если сам запрос по-прежнему присутствует (т.е. прерывание находится в состоянии «активно и ожидает»). PPI и SGI являются уникальными для каждого процессорного интерфейса, поэтому состояние обработки такого прерывания на одном процессоре никак не влияет на выдачу запросов для других процессорных интерфейсов.

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

3. Для каждого процессорного интерфейса распределитель выбирает самое приоритетное из ожидающих прерываний и передаёт его процессорному интерфейсу. Если имеется несколько прерываний с одинаковым приоритетом, передаётся лишь одно из них, причём выбор передаваемого прерывания определяется особенностями реализации GICа. Приоритеты прерываний задаются содержимым регистров ICDIPR.

PPI всегда привязаны к конкретному процессору и поступают только на его процессорный интерфейс (если нет более приоритетных SGI или SPI). SGI, по сути, тоже являются индивидуальными для каждого процессора: хотя GIC позволяет выдать SGI сразу нескольким процессорам, для каждого процессора запрос SGI обрабатывается и запоминается отдельно. SPI потенциально могут обслуживаться любым из процессоров, однако путём программирования регистров ICDIPTR можно определить процессоры, которым будут передаваться те или иные прерывания.

4. Процессорный интерфейс определяет, достаточно ли высок приоритет поступившего от распределителя прерывания, чтобы это прерывание было передано процессору. Для этого, кроме приоритета поступившего запроса, анализируются приоритет текущего обрабатываемого прерывания (оно хранится в регистре ICCRPR), маска приоритета прерывания (регистр ICCPMR) и текущие установки вытеснения прерываний. Если приоритет нового прерывания достаточно велик, интерфейс выдаёт процессору сигнал запроса прерывания (IRQ или FIQ в зависимости от настроек GIC и режима безопасности).

5. Когда процессор приступает к обработке поступившего прерывания, он считывает содержимое регистра подтверждения прерывания ICCIAR, в котором содержится код идентификации источника, вызвавшего данное прерывание. Обнаружив считывание ICCIAR, процессорный интерфейс запоминает приоритет нового прерывания и сообщает распределителю, что его обработка начата. Распределитель переводит прерывание в состояние «активно» (active), если запрос прерывания обнаруживается по фронту сигнала либо если обнаруживается по уровню и в этот момент сигнал запроса прерывания уже имеет неактивный уровень, или в состояние «активно и ожидает» (active and pending), если запрос прерывания обнаруживается по уровню и в данный момент сигнал запроса активен.

Если активным стало общее внешнее прерывание (SPI), его выдача на другие процессорные интерфейсы прекращается, даже если прерывание продолжает считаться ожидающим. Заметим, однако, что прекращение выдачи запроса на другие интерфейсы, а от них — на соответствующие процессоры происходит не мгновенно. Поэтому может возникнуть ситуация, когда одно и то же SPI вызовет вход в обработчик прерывания на нескольких процессорах, о чём подробнее будет сказано ниже. Если же активным стало программно генерируемое прерывание (SGI), его подтверждение на одном процессоре не влияет на наличие запроса этого же прерывания на других процессорных интерфейсах, поскольку SGI, по сути, являются индивидуальными прерываниями для каждого конкретного процессора.

Узнать, какие прерывания в настоящий момент являются активными, можно путём считывания регистров ICDABR.

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

Обнаружив запись в ICCEOIR, процессорный интерфейс «откатывает» приоритет текущего обрабатываемого данным процессором прерывания к предыдущему значению и уведомляет распределитель о завершении обработки прерывания. Если в этот момент данное прерывание находилось в состоянии «активно», распределитель переведёт его в состояние «неактивно», а если оно находилось в состоянии «активно и ожидает» — в состояние «ожидает». После сброса состояния активности прерывание вновь может анализироваться распределителем для передачи его на обработку одному или нескольким процессорным интерфейсам.

Заметим, что в многопроцессорной системе одно и то же SPI может вызвать прерывание одновременно на нескольких процессорах, хотя оно должно обрабатываться лишь одним из них. Такая ситуация может возникнуть, если несколько процессоров практически одновременно приступят к обработке одного и того же прерывания: до считывания регистра ICCIAR GIC выдаёт запрос прерывания всем потенциально подходящим процессорам, и поэтому он просто может не успеть снять запрос. В такой ситуации для каждого процессора, вошедшего в обработчик прерывания, возможны два варианта:

  • при считывании ICCIAR получен ID реального источника прерывания;
  • при считывании ICCIAR получен ID, равный 1023.

Первый случай означает, что процессор должен начать обработку конкретного прерывания. Однако, поскольку она должна осуществляться лишь одним процессором, необходимо предусмотреть некую программную блокировку, которую обработчик любого конкретного прерывания должен попытаться захватить в самом начале своего выполнения. Если это удалось, прерывание обрабатывается, и в конце блокировка снимается, а в регистр ICCEOIR записывается идентификатор прерывания, что даёт GICу знать об окончании обработки данного прерывания этим процессором. Если же блокировку захватить не удалось, это означает, что прерывание уже обрабатывается другим процессором, и тогда обработчик должен лишь выполнить запись ID в ICCEOIR.

Идентификатор, равный 1023, соответствует ложному (spurious) прерыванию. Процессор, обнаружив это значение, прекращает обработку прерывания без записи в регистр ICCEOIR.

Приоритеты прерываний

GIC отводит под приоритет каждого прерывания поле размером один байт. Однако в конкретных его реализациях ширина этого поля может быть меньшей: до четырёх младших разрядов могут быть не реализованы. Таким образом, общее число уровней прерываний, обеспечиваемых конкретным вариантом GICа, может колебаться от 16 до 256. Значения приоритетов прерываний хранятся в регистрах ICDIPR. Каждый регистр хранит значения приоритетов для четырёх прерываний со смежными номерами.

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

Численно большее значение приоритета соответствует более низкому приоритету прерывания. Таким образом, наивысшим приоритетом является 0, а самым низким – значение, содержащее единицы во всех реализованных разрядах (255, если поддерживаются все восемь битов). Чтобы определить, какое количество разрядов приоритета прерывания поддерживается, необходимо записать в какой-либо байт одного из регистров ICDIPR значение 0xFF, а затем считать его. Все поддерживаемые разряды останутся равными 1, а нереализованные будут прочитаны как нули. Заметим, что присваивание некоему прерыванию численно максимально возможного значения приоритета полностью запретит это прерывание, поскольку оно будет отсекаться механизмом маскирования приоритетов (см. ниже).

Когда некоторый процессор обрабатывает прерывание, соответствующий процессорный интерфейс GICа хранит информацию об этом прерывании, в том числе его приоритет. Когда от распределителя поступает запрос нового прерывания, чей приоритет значительно превосходит приоритет текущего обрабатываемого прерывания, процессорный интерфейс выдаст своему процессору сигнал IRQ или FIQ и при получении подтверждения (считывании регистра ICCIAR) сделает новое прерывание текущим обрабатываемым. Таким образом, обработка прерываний является вытесняемой: более приоритетные прерывания могут прервать обработку менее приоритетных, которая возобновится после окончания обработки более приоритетных прерываний (так называемые вложенные прерывания).

Для определения того, является ли новый запрос прерывания существенно более приоритетным, чем текущий обрабатываемый, используется механизм маскирования приоритетов и группировки прерываний.

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

Механизм группировки приоритетов делит каждое значение приоритета на два поля: приоритет группы и приоритет внутри группы. Количество разрядов, относящихся к тому и другому полю, определяется регистром ICCBPR. Поле приоритета группы может содержать от нуля до семи разрядов, приоритета внутри группы — от одного до восьми (в последнем случае все приоритеты оказываются заключены внутри единственной группы).

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

Поддержка расширений безопасности

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

При обращении к GICу процессор, поддерживающий расширения безопасности, каждый раз указывает вид выполняемого им доступа — безопасный или небезопасный. При безопасных доступах имеется возможность производить программирование GICа в полном объёме, в частности, настраивать вид отдельных прерываний (безопасные или небезопасные) путём записи соответствующих значений в регистры ICDISR. При небезопасных доступах возможности программного обеспечения ограничены: оно не может менять состояние безопасных прерываний, не может считывать некоторую информацию и т.д. Логически это достигается введением двух банков многих регистров GICа: один банк предназначен для безопасных доступов, другой — для небезопасных.

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

Как уже отмечалось, если GIC поддерживает расширения безопасности, он позволяет с помощью регистров ICDISR настраивать прерывания как безопасные или небезопасные. Небезопасные прерывания всегда выдаются процессору с помощью сигнала IRQ; безопасные прерывания могут выдаваться с помощью сигналов IRQ или FIQ в зависимости от настройки GICа. Если GIC не поддерживает расширения безопасности, он всегда выдаёт сигнал IRQ. Реализовать поддержку обоих сигналов IRQ и FIQ для процессоров, не имеющих расширений безопасности, можно двумя путями:

  • использовать два отдельных GICа, не поддерживающих расширения безопасности, а значит, выдающих процессору лишь один сигнал запроса прерывания. Один из этих контроллеров будет подсоединён к линии процессора IRQ, второй — к линии FIQ;
  • использовать GIC, поддерживающий расширения безопасности, но реализовать в нём лишь «безопасный» банк регистров для «общения» с процессором. Все обращения данного процессора к GICу будут рассматриваться как безопасные, что позволит индивидуально настроить прерывания на выдачу IRQ или FIQ.

Считывание регистра ICCIAR всегда подтверждает наиболее приоритетное из имеющихся прерываний. Если это прерывание является безопасным, считывание ICCIAR должно выполняться в безопасном режиме процессора; при небезопасном считывании будет возвращён ID, равный 1023, т.е. GIC «притворится», будто произошло ложное прерывание (что, однако, не снимет сам запрос прерывания, и его всё равно нужно будет обрабатывать). Если же самым приоритетным является небезопасное прерывание, то по умолчанию его нужно подтверждать небезопасным считыванием ICCIAR; при безопасном считывании этого регистра в такой ситуации будет возвращён ID, равный 1022. Однако, установив бит AckCtl в регистре ICCICR, безопасное ПО получит возможность считыванием ICCIAR подтверждать все прерывания и получать их идентификаторы. За правильную обработку небезопасных прерываний в этом случае отвечает программное обеспечение.

GIC, поддерживающий расширения безопасности, обеспечивает как минимум 32 уровня приоритетов прерываний. Однако небезопасные доступы к GICу «видят» лишь половину от общего числа приоритетов. Это достигается «сдвигом» значения приоритета любого прерывания, считываемого или записываемого небезопасными доступами, на один бит. Когда небезопасное ПО присваивает приоритет, перед записью указанного им значения в соответствующий регистр распределителя GIC сдвигает это значение на один бит вправо и устанавливает старший разряд равным единице. Например, при небезопасной записи приоритета, равного 0xF0, в действительности будет установлен приоритет 0xF8. При небезопасном считывании производится обратная операция: истинное значение приоритета сдвигается влево на один разряд, и процессору возвращается полученное значение. Благодаря этому небезопасное ПО не может установить приоритеты своих прерываний выше, чем приоритеты безопасных прерываний, если только безопасное ПО не присвоит своим приоритетам слишком низкие значения. Заметим, что безопасное ПО может установить для небезопасных прерываний приоритет, содержащий нуль в старшем разряде, однако небезопасное считывание такого регистра всё равно вернёт значение, сдвинутое на бит влево, а при записи после сдвига на разряд вправо старший бит будет принудительно установлен.

Небезопасное считывание регистра ICCPMR, содержащего нуль в старшем разряде, возвращает значение, равное нулю, независимо от состояния других разрядов этого регистра; небезопасная запись в этот регистр в такой ситуации игнорируется. Если же старший бит этого регистра равен единице, т.е. соответствует уровню приоритета прерывания, который может быть установлен из небезопасного режима, считываемое или записываемое значение обрабатывается так же, как для приоритетов прерываний: оно сдвигается на один бит вправо при записи, при этом в старший разряд записывается единица, и сдвигается на один бит влево при чтении. Таким образом, небезопасное ПО может записать в этот регистр значения, запрещающие все или часть небезопасных прерываний, но не может разрешить или запретить безопасные прерывания.

Небезопасное считывание регистра приоритета текущего обрабатываемого прерывания ICCRPR вернёт значение 0, если старший разряд приоритета содержит нуль. Если же он содержит единицу, будет возвращено его значение, сдвинутое на бит влево, т.е. в обычной для небезопасного режима форме.

GIC с поддержкой расширений безопасности имеет две копии регистра ICCBPR — безопасную и небезопасную. Безопасный регистр используется для управления группировкой приоритетов (а соответственно, и возможностью вытеснения прерываний) для безопасных прерываний. Группировкой приоритетов небезопасных прерываний по умолчанию занимается небезопасный регистр ICCBPR, однако безопасное ПО может настроить GIC таким образом, чтобы и для них использовалось разделение на группы, задаваемое безопасным регистром ICCBPR (см. описание регистра ICCICR). Сама группировка различается для безопасных и небезопасных прерываний. Для первых значение приоритета прерывания делится на два поля по обычным правилам: безопасный регистр ICCBPR определяет, сколько разрядов находится в поле приоритета внутри группы и в поле приоритета группы. Приоритеты небезопасных прерываний, видимые для небезопасного ПО, будут сдвинуты на один бит вправо, а группировка будет касаться лишь разрядов, которые видны небезопасному ПО. По этой причине число разрядов в поле приоритета группы будет на единицу больше, чем задаётся регистром ICCBPR: благодаря этому безопасные прерывания (имеющие нуль в старшем разряде приоритета) всегда смогут вытеснить небезопасные (имеющие в этом разряде единицу, невидимую для небезопасного ПО).

Регистры контроллера

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

В GICах, поддерживающих расширения безопасности, некоторые регистры доступны только для безопасного ПО (при небезопасном доступе они считываются, как нули, а запись в них игнорируется), а ряд других логически имеют разные копии для безопасного и небезопасного доступа.

Блокировка настроек

В контроллерах прерываний, поддерживающих расширения безопасности, может быть предусмотрена возможность блокировки изменения определённых регистров после того, как настройка GICа была закончена.

SPI, поддерживающие фиксацию их настроек, называются блокируемыми (LSPI, lockable SPI). Их количество определяется реализацией и находится в диапазоне от 0 до 31; общее число LSPI может быть определено путём считывания поля LSPI регистра ICDICTR. Идентификатор первого из LSPI всегда равен 32, остальные LSPI расположены сразу за ним. Заметим, что ICDICTR.LSPI определяет лишь ширину диапазона идентификаторов LSPI; конкретный GIC может реализовывать не все прерывания в этом диапазоне.

Когда настройки заблокированы, GIC игнорирует попытки записи в следующие регистры:

  • безопасную копию ICDDCR;
  • безопасную копию ICCICR, за исключением разряда EnableNS;
  • относящиеся к LSPI поля регистров ICDISER, ICDICER, ICDISPR, ICDICPR, ICDIPR, ICDIPTR, ICDICFR;
  • относящиеся к LSPI поля ICDIS, если соответствующие прерывания настроены как безопасные.

Сама блокировка осуществляется путём подачи на GIC специального сигнала, именуемого в документации CFGSDISABLE и имеющего высокий активный уровень. Способ установки этого сигнала определяется реализацией; подразумевается, что он приходит откуда-то извне. Компания ARM рекомендует, чтобы этот сигнал невозможно было снять без выполнения сброса системы, но это не является безусловно обязательным требованием.

Регистры распределителя

Смещение Имя Доступ Исходное значение Описание
000
ICDDCR
RW
0
Регистр управления распределителем
004
ICDICTR
RO
определяется реализацией
Регистр типа контроллера прерываний
008
ICDIIDR
RO
определяется реализацией
Регистр идентификации реализации распределителя
00C–07C
Зарезервировано
080–0FC
ICDISRn
RW
прим. 1
Регистры безопасности прерываний
100–17C
ICDISERn
RW
определяется реализацией
Регистры разрешения прерываний
180–1FC
ICDICERn
RW
определяется реализацией
Регистры запрещения прерываний
200–27C
ICDISPRn
RW
0
Регистры установки запросов прерываний
280–2FC
ICDICPRn
RW
0
Регистры сброса запросов прерываний
300–37C
ICDABRn
RO
0
Регистры активных прерываний
380–3FC
Зарезервировано
400–7F8
ICDIPRn
RW
0
Регистры приоритетов прерываний
7FC
Зарезервировано
800–BF8
ICDIPTRn
RO/RW
прим. 2
Регистры распределения прерываний по процессорам
BFC
Зарезервировано
C00–CFC
ICDICFRn
RW
определяется реализацией
Регистры настройки прерываний
D00–DFC
Регистры, определяемые реализацией
E00–EFC
Зарезервировано
F00
ICDSGIR
WO
Регистр программной генерации прерываний
F04–FCC
Зарезервировано
FD0–FFC
RO
определяется реализацией
Регистры идентификации

Примечания. 1. Содержимое регистра ICDISR0 после сброса определяется реализацией, остальные регистры ICDISR будут равны нулю. Эти регистры реализованы только в GICах, поддерживающих расширения безопасности.

2. Содержимое регистра ICDIPTR0 в многопроцессорной системе определяется реализацией и не может быть изменено; содержимое остальных регистров ICDIPTR после сброса равно нулю и может изменяться программно. В однопроцессорной системе все эти регистры всегда равны нулю и не могут быть изменены.

ICDDCR

Регистр управления распределителем ICDDCR (Distributor Control Register) доступен в любых версиях GIC. Если поддерживаются расширения безопасности, существуют его отдельные копии для безопасного и небезопасного режимов. В GICах с возможностью блокировки настроек содержимое безопасного ICDDCR может быть заблокировано.

Назначение разрядов регистра ICDDCR приведено в таблице.

Название Разряды Описание
31:1
Зарезервировано
Enable
0
Когда сброшен, GIC игнорирует любые прерывания; когда установлен, распределитель обрабатывает поступающие запросы прерываний обычным образом и передаёт их процессорным интерфейсам

При запрещённой работе распределителя его регистры продолжают функционировать обычным образом, поэтому ПО может, например, программно запрашивать или снимать запросы внешних прерываний соответствующей запись в регистры ICDISPR и ICDICPR или снимать для них признак активности записью в регистр ICCEOIR. Заметим, что запись в ICDICPR снимает состояние ожидания для любого заданного там прерывания, в том числе фиксируемого по уровню сигнала, однако в последнем случае, как только работа распределителя будет разрешения, запрос прерывания сразу же будет зафиксирован вновь, если соответствующий входной сигнал имеет активный уровень.

При отключенном распределителе возможно запросить SGI обычной записью в регистр ICDSGIR. Однако снять этот запрос и сделать SGI неактивным программным путём невозможно, поскольку такой сброс происходит лишь тогда, когда соответствующее прерывание становится активным.

ICDICTR

Регистр типа контроллера прерываний ICDICTR (Interrupt Controller Type Register) доступен во всех вариантах GIC и является общим для безопасного и небезопасного режимов. Он предназначен для предоставления информации о GIC.

Назначение разрядов регистра ICDICTR приведено в таблице.

Название Разряды Описание
31:16
Зарезервировано
LSPI
15:11
Максимальное число SPI, настройки которых могут быть зафиксированы. Значение 0 означает, что фиксация настроек не поддерживается. Если GIC не поддерживает расширения безопасности, это поле является зарезервированным
SecurityExtn
10
Если равен нулю, расширения безопасности не поддерживаются, если равен единице — поддерживаются.
9:8
Зарезервировано
CPUNumber
7:5
Число реализованных процессорных интерфейсов минус один (нуль соответствует однопроцессорному варианту GIC)
ITLinesNumber
4:0
Максимальное количество SPI, поддерживаемых GICом, в группах по 32 прерывания. SGI и PPI, имеющие коды идентификации в пределах от 0 до 31 включительно, поддерживаются всегда; это поле относится только к SPI, коды идентификации которых начинаются со значения 32 и могут достигать 1019 (коды 1020–1023 являются зарезервированными). Нулевое значение соответствует отсутствию SPI

Значение поля ITLinesNumber определяет количество регистров, управляющих отдельными прерываниями. Следует, однако, помнить, что значение ITLinesNumber задаёт фактически максимально возможный код идентификации для прерывания, но не общее число прерываний, реально поддерживаемых контроллером. Определить наличие поддержки прерывания с конкретным номером ID можно путём манипуляций с регистрами разрешения и запрещения прерываний.

ICDIIDR

Регистр идентификации реализации распределителя ICDIIDR (Distributor Implementer Identification Register) существует во всех вариантах GICа и является общим для безопасного и небезопасного режимов. Он позволяет определить разработчика и версию варианта контроллера.

Назначение разрядов регистра ICDIIDR приведено в таблице.

Название Разряды Описание
ProductID
31:24
Код продукта, определяемый разработчиком
23:20
Зарезервировано
Variant
19:16
Код варианта, определяемый разработчиком
Revision
15:12
Номер ревизии, определяемый разработчиком
Implementer
11:0
Код JEP106, определяющий компанию-разработчика GICа. Для контроллеров разработки ARM это поле равно 0x43B.

ICDISR

Регистры безопасности прерываний ICDISR (Interrupt Security Registers) существуют лишь в контроллерах, реализующих расширения безопасности, и доступны только в безопасном режиме. Если GIC поддерживает блокировку настроек, соответствующая часть этих регистров может быть заблокирована. В небезопасном режиме эти регистры читаются как нули, а запись в них игнорируется. Это же относится к разрядам, соответствующим нереализованным прерываниям. Общее число регистров ICDISR равно ICDICTR.ITLinesNumber + 1. В многопроцессорной системе для каждого процессорного интерфейса существует свой регистр ICDISR0, отвечающий за SGI и PPI.

Назначение разрядов регистра ICDISR приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDISR0[0] относится к прерыванию с ID 0 и т.д.). Когда он сброшен, соответствующее прерывание является безопасным, когда единице — небезопасным

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

ICDISER

Регистры разрешения прерываний ICDISER (Interrupt Set-Enable Registers) существуют в любом варианте контроллера. Если GIC поддерживает расширения безопасности, существуют отдельные наборы этих регистров для безопасного и небезопасного доступов. Разряды этих регистров, соответствующие безопасным прерываниям, в небезопасном режиме считываются как нули, а запись в них игнорируется. Если контроллер поддерживает блокировку конфигурации, соответствующие разряды этих регистров могут быть заблокированы. Всего в контроллере реализовано ICDICTR.ITLinesNumber + 1 регистров ICDISER. В многопроцессорной системе для каждого процессорного интерфейса имеется свой регистр ICDISER0.

Назначение разрядов регистров ICDISER приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDISER0[0] относится к прерыванию с ID 0 и т.д.). При чтении нулевое значение означает, что прерывание с данным ID запрещено, единица — разрешено. Запись нулевого значения не изменяет маску соответствующего прерывания, запись единицы разрешает прерывание, если оно реализовано

Для определения того, поддерживается ли некоторое прерывание, программа должна записать единицу в разряд ICDISER, соответствующий данному прерыванию, а затем прочитать регистр и проверить значение этого же разряда. Если он будет равен нулю, прерывание с данным ID не поддерживается.

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

ICDICER

Регистры запрещения прерываний ICDICER (Interrupt Clear-Enable Registers) существуют в любом варианте контроллера. Если GIC поддерживает расширения безопасности, существуют отдельные наборы этих регистров для безопасного и небезопасного доступов. Разряды этих регистров, соответствующие безопасным прерываниям, в небезопасном режиме считываются как нули, а запись в них игнорируется. Если контроллер поддерживает блокировку конфигурации, соответствующие разряды этих регистров могут быть заблокированы. Всего в контроллере реализовано ICDICTR.ITLinesNumber + 1 регистров ICDICER. В многопроцессорной системе для каждого процессорного интерфейса имеется свой регистр ICDICER0.

Назначение разрядов регистров ICDICER приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDICER0[0] относится к прерыванию с ID 0 и т.д.). При чтении нулевое значение означает, что прерывание с данным ID запрещено, единица — разрешено. Запись нулевого значения не изменяет маску соответствующего прерывания, запись единицы запрещает прерывание, если оно реализовано

Определённые линии прерываний в конкретной реализации контроллера могут всегда быть разрешены. Чтобы определить наличие таких линий, необходимо выполнить запись единиц во все интересующие разряды регистров ICDICER, а затем прочитать и проверить значение этих же разрядов. Если некоторый разряд равен единице, это означает, что соответствующее прерывание всегда разрешено.

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

ICDISPR

Регистры установки запросов прерываний ICDISPR (Interrupt Set-Pending Registers) существуют в любом варианте контроллера. Если GIC поддерживает расширения безопасности, существуют отдельные наборы этих регистров для безопасного и небезопасного доступов. Разряды этих регистров, соответствующие безопасным прерываниям, в небезопасном режиме считываются как нули, а запись в них игнорируется. Если контроллер поддерживает блокировку конфигурации, соответствующие разряды этих регистров могут быть заблокированы. Всего в контроллере реализовано ICDICTR.ITLinesNumber + 1 регистров ICDISPR. В многопроцессорной системе для каждого процессорного интерфейса имеется свой регистр ICDISPR0.

Назначение разрядов регистров ICDISPR приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDISPR0[0] относится к прерыванию с ID 0 и т.д.). При чтении нулевое значение означает, что прерывание с данным ID не запрошено, единица — запрошено. Запись нулевого значения не оказывает никакого влияния, запись единицы запрашивает данное прерывание. В случае SGI и PPI считанные значения разрядов ICDISPR относятся только к данному процессору, причём запись в разряды, соответствующие SGI, игнорируется

Если запрос данного прерывания уже ожидал обработки, запись единицы в соответствующий разряд ICDISPR не изменяет состояние контроллера прерываний. Однако, если данное прерывание чувствительно к уровню и внешнее устройство сняло сигнал запроса прерывания, оно в случае записи единицы в соответствующий разряд ICDISPR по-прежнему останется ожидающим обработки. Чтобы отменить такой запрос, необходимо выполнить запись единицы в соответствующий разряд ICDISPR.

ICDICPR

Регистры сброса запросов прерываний ICDICPR (Interrupt Clear-Pending Registers) существуют в любом варианте контроллера. Если GIC поддерживает расширения безопасности, существуют отдельные наборы этих регистров для безопасного и небезопасного доступов. Разряды этих регистров, соответствующие безопасным прерываниям, в небезопасном режиме считываются как нули, а запись в них игнорируется. Если контроллер поддерживает блокировку конфигурации, соответствующие разряды этих регистров могут быть заблокированы. Всего в контроллере реализовано ICDICTR.ITLinesNumber + 1 регистров ICDICPR. В многопроцессорной системе для каждого процессорного интерфейса имеется свой регистр ICDICPR0.

Назначение разрядов регистров ICDICPR приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDICPR0[0] относится к прерыванию с ID 0 и т.д.). При чтении нулевое значение означает, что прерывание с данным ID не запрошено, единица — запрошено. Запись нулевого значения не оказывает никакого влияния, запись единицы сбрасывает ожидающий обработки запрос данного прерывания. В случае SGI и PPI считанные значения разрядов ICDISPR относятся только к данному процессору, причём запись в разряды, соответствующие SGI, игнорируется

Если запрос данного прерывания не ожидал обработки, запись единицы в соответствующий разряд ICDISPR не изменяет состояние контроллера прерываний. Если данное прерывание чувствительно к уровню, а ожидание обработки связано лишь с ранее выполненной записью в соответствующий регистр ICDISPR (т.е. устройство, подсоединённое к данной линии, не удерживает сигнал запроса прерывания в активном состоянии), запись единицы в нужный разряд ICDICPR сбросит состояние ожидания обработки данного прерывания. Если прерывание чувствительно к фронту, запись единицы в ICDICPR сбросит запрос, ожидающий обработки.

ICDABR

Регистры активных прерываний ICDABR (Interrupt Active Bit Registers) существуют в любом варианте контроллера и доступны только для чтения. Если GIC поддерживает расширения безопасности, существуют отдельные наборы этих регистров для безопасного и небезопасного доступов. Разряды этих регистров, соответствующие безопасным прерываниям, в небезопасном режиме считываются как нули. Всего в контроллере реализовано ICDICTR.ITLinesNumber + 1 регистров ICDABR. В многопроцессорной системе для каждого процессорного интерфейса имеется свой регистр ICDABR0.

Назначение разрядов регистров ICDABR приведено в таблице.

Название Разряды Описание
31:0
Каждый разряд соответствует своему прерыванию (бит ICDABR[0] относится к прерыванию с ID 0 и т.д.). При чтении нулевое значение означает, что прерывание с данным ID не активно, единица — что активно

ICDIPR

Регистры приоритетов прерываний ICDIPR (Interrupt Prioroty Registers) существуют в любом варианте контроллера и доступны как словами, так и отдельными байтами.

Поля, соответствующие не реализованным прерываниям, считываются как нули; запись в них игнорируется. Если GIC реализует менее, чем 256 приоритетов прерываний, сокращение числа приоритетов производится за счёт младших разрядов значений приоритета, причём всегда будут реализованы как минимум старшие 4 разряда (16 уровней приоритета). Нереализованные младшие разряды считываются как нули, а запись в них игнорируется.

Если GIC поддерживает расширения безопасности, при считывании значений приоритетов безопасных прерываний из небезопасного состояния всегда будут получены нули, а запись будет проигнорирована. Физически такой GIC поддерживает минимум 32 уровня приоритетов прерываний, однако небезопасная запись приоритета небезопасного прерывания приведёт к записи значения, сдвинутого вправо на один бит, к которому принудительно добавлен слева единичный разряд; при небезопасном считывании приоритета небезопасного прерывания истинное значение приоритета будет сдвинуто влево на один разряд, при этом старший бит будет отброшен. Благодаря этому небезопасное ПО может установить лишь приоритеты, имеющие физические значения 128–255, т.е. достаточно низкие. Высокие физические приоритеты (от нуля до 127 включительно) может установить лишь безопасное ПО.

Если поддерживается фиксация конфигурации, система может заблокировать изменение приоритетов безопасных SPI.

Всего в контроллере реализовано 8 * (ICDICTR.ITLinesNumber + 1) регистров ICDIPR. В многопроцессорной системе для каждого процессорного интерфейса имеется свой набор регистров ICDIPR0 — ICDIPR7.

Назначение разрядов регистров ICDIPR приведено в таблице.

Название Разряды Описание
31:24

23:16

15:8

7:0
Четыре 8-разрядных поля, каждое из которых задаёт приоритет своего прерывания. Поле ICDIPR0[7:0] задаёт приоритет для прерывания с ID=0, поле ICDIPR0[15:8] — для ID=1 и т.д.

ICDIPTR

Регистры распределения прерываний по процессорам ICDIPTR (Interrupt Processor Targets Registers) фактически существуют лишь в многопроцессорных вариантах GIC, хотя формально имеются и в однопроцессорных вариантах. В последнем случае запись в них игнорируется, а при считывании возвращаются нули. Эти регистры доступны как словами, так и отдельными байтами.

Поле регистра, соответствующее нереализованному прерыванию, считывается как нуль, а запись в него игнорируется. Регистры ICDIPTR0 — ICDIPTR7 свои для каждого процессорного интерфейса и доступны только для чтения. Находящиеся в них значения соответствуют номеру процессора, к которому подключен данный интерфейс. Доступны только для чтения и поля ICDIPTR, соответствующие SPI, жёстко закреплённым за определёнными процессорами.

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

Всего в контроллере реализовано 8 * (ICDICTR.ITLinesNumber + 1) регистров ICDIPR. В многопроцессорной системе для каждого процессорного интерфейса имеется свой набор регистров ICDIPTR0 — ICDIPTR7.

Назначение разрядов регистров ICDIPTR приведено в таблице.

Название Разряды Описание
31:24

23:16

15:8

7:0
Четыре 8-разрядных поля, каждое из которых задаёт распределение соответствующего прерывания по процессорам. Поле ICDIPTR0[7:0] задаёт распределение для прерывания с ID=0, поле ICDIPTR0[15:8] — для ID=1 и т.д. В поле, соответствующем некоторому прерыванию, будут установлены разряды, соответствующие процессорам, которым это прерывание будет передаваться для обработки (младший бит поля для процессора 0, следующий за ним — для процессора 1 и т.д.)

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

ICDICFR

Регистры настройки прерываний ICDICFR (Interrupt Configuration Registers) состоят из 2-битовых полей, каждое из которых определяет способ фиксации запроса соответствующего прерывания (по уровню или по фронту). В некоторых ранних реализациях GIC это поле позволяло определить для SPI модель обработки: только одним процессором или сразу несколькими процессорами, однако позднее эта возможность была упразднена (SPI должны обрабатываться только одним процессором).

Возможность настройки способа фиксации того или иного PPI определяется реализацией. Возможности настройки SGI нет, и регистр ICDICFR0 доступен только для чтения.

Поля, соответствующие отсутствующим прерываниям, считываются как 0, а запись в них игнорируется. Это же относится к небезопасным доступам к полям, соответствующим безопасным прерываниям.

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

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

Регистры ICDICFR реализованы во всех вариантах GIC и являются общими для безопасного и небезопасного доступов. Общее их число равно (2*(ICDICTR.ITLinesNumber+1)).

Назначение разрядов регистров ICDICFR приведено в таблице.

Название Разряды Описание
31:30

...

1:0
16 полей по 2 бита. Биты 1:0 соответствуют прерыванию с наименьшим значением ID из относящихся к данному регистру, биты 31:30 — прерыванию с наибольшим ID. Старший бит поля определяет, является ли соответствующее прерывание чувствительным к уровню сигнала (равен нулю) или к его фронту (равен единице). Для SGI он не может быть изменён, а считывается как единица. Для PPI возможность его изменения определяется реализацией.

Младший бит зарезервирован. В некоторых ранних вариантах GIC (до выхода спецификации версии 1.0) он определял модель обработки SPI: значение 0 определяло обработку прерывания сразу несколькими процессорами, значение 1 — только одним.

ICDSGIR

Регистр программной генерации прерываний ICDSGIR (Software Generated Interrupt Register) предназначен для выдачи SGI.

Регистр ICDSGIR реализован во всех вариантах GIC и является общим для безопасного и небезопасного режимов. Если GIC не поддерживает расширения безопасности, поле SATT в этом регистре отсутствует.

Назначение разрядов регистров ICDSGIR приведено в таблице.

Название Разряды Описание
31:26
Зарезервировано
TargetListFilter
25:24
* 00 — отправить прерывание процессорным интерфейсам, указанным полем CPUTargetList
  • 01 — отправить прерывание всем процессорным интерфейсам, за исключением запросившего выдачу этого прерывания
  • 10 — отправить прерывание только процессору, запросившему это прерывание
  • 11 — зарезервировано
CPUTargetList
23:16
При TargetListFilter = 0 это поле определяет набор процессоров, которые получат прерывание. Старший бит этого поля соответствует процессорному интерфейсу 7, младший — 0. Установка бита означает, что данному процессору прерывание должно быть выдано
SATT
15
Если GIC не поддерживает расширения безопасности, этот разряд зарезервирован. Если расширения безопасности поддерживаются, запись в это поле возможна лишь в безопасном режиме и имеет следующие значения:
  • 0 — отправить SGI, заданное полем SGIINTID, тем из заданных процессорных интерфейсов, для которых это SGI является безопасным
  • 1 — отправить SGI, заданное полем SGIINTID, тем из заданных процессорных интерфейсов, для которых это SGI является небезопасным

При записи в регистр ICDSGIR в небезопасном режиме значение поля SATT игнорируется, а SGI отправляется тем из заданных процессорных интерфейсов, для которых оно является небезопасным

14:4
Зарезервировано
SGIINTID
3:0
Идентификатор SGI, которое должно быть выдано

Регистры идентификации

Спецификация GIC определяет как обязательный только один регистр идентификации ICPIDR2, хотя резервирует для них достаточно большое адресное пространство, как показано в следующей таблице.

Смещение Имя Доступ Исходное значение Описание
FD0–FE4
RO
определяется реализацией
Регистры идентификации, определяемые реализацией
FE8
ICPIDR2
RO
0x00000010 Регистр идентификации 2
FEC–FFC
RO
определяется реализацией
Регистры идентификации, определяемые реализацией

Распределение пространства регистров и их именование, используемое фирмой ARM, соответствует схеме идентификации, принятой для компонентов PrimeCell и CoreSight, и будет описано ниже. Настоятельно рекомендуется и другим разработчикам придерживаться такой же схемы.

Регистр ICPIDR2

Регистр ICPIDR2 существует во всех вариантах GIC в единственном экземпляре. Назначение его разрядов описано в таблице.

Название Разряды Описание
31:8
Определяется реализацией
ArchRev
7:4
Версия архитектуры GIC. В настоящее время равна 1
3:0
Определяется реализацией

Регистры процессорного интерфейса

Смещение Имя Доступ Исходное значение Описание
00
ICCICR
RW
0
Регистр управления процессорным интерфейсом
04
ICCPMR
RW
0
Регистр приоритета маскирования
08
ICCBPR
RW
прим.
Регистр управления группировкой приоритетов
0C
ICCIAR
RO
000003FF
Регистр подтверждения прерываний
10
ICCEOIR
WO
Регистр конца обработки прерывания
14
ICCRPR
RO
000000FF
Регистр приоритета обрабатываемого прерывания
18
ICCHPIR
RO
000003FF
Регистр наиболее приоритетного ожидающего обработки прерывания
1C
ICCABPR
RW
0
Второй регистр управления группировкой приоритетов
20–3C
Зарезервировано
40–CF
Регистры, определяемые реализацией
D0–F8
Зарезервировано
FC
ICCIIDR
RO
определяется реализацией
Регистр идентификации процессорного интерфейса

Примечание. После сброса регистр ICCBPR может принимать значения от 0 до 3 включительно; см. его описание.

ICCICR

ICCPMR

ICCBPR

ICCIAR

ICCEOIR

ICCRPR

ICCHPIR

ICCABPR

ICCIIDR

Advertisement