Операционная система ЗОСРВ «Нейтрино» > Руководство разработчика > Программные интерфейсы общего назначения > Системные библиотеки > Системные библиотеки > Системная библиотека > I > struct intrinfo_entry



struct intrinfo_entry

Фрагмент системной страницы, характеризующий сведения о векторах прерываний

Прототип:

#include <sys/syspage.h>
struct intrinfo_entry {
uint32_t vector_base;
uint32_t num_vectors;
uint32_t cascade_vector;
uint32_t cpu_intr_base;
uint16_t cpu_intr_stride;
uint16_t flags;
struct __intrgen_data id();
struct __intrgen_data eoi();
int (*mask)( struct syspage_entry *,
int );
int (*unmask)( struct syspage_entry *,
int );
unsigned (*config)( struct syspage_entry *,
struct intrinfo_entry *,
int );
uint32_t spare[4];
};

Описание:

Структура содержит информацию системной страницы, характеризующую сведения о векторах прерываний и включает следующие поля:

vector_base
Базовый номер логического прерывания, который будет использоваться программами (т.е. вектор прерываний, передаваемый в функцию InterruptAttach()).
num_vectors
Количество векторов в записи, которая начинается с базового номера vector_base.
cascade_vector
Если запись описывает множество прерываний, которые каскадно подключены к другому контроллеру, эта переменная содержит номер логического прерывания, которое используется для каскадного подключения соответствующего контроллера.
cpu_intr_base
Связь между множеством прерываний и представлением источника прерываний на стороне ЦП (подробнее см. Информация о векторах прерываний).
cpu_intr_stride
Расстояние между записями векторов прерываний в системах с автоматическим назначением векторов. На платформе x86 со стандартным контроллером 8259 это значение равно 1, т.е. вектор прерывания, который соответствует аппаратным источникам прерываний, смещается на 1 (например, вектор прерывания 0 соответствует прерыванию 0x30, вектор прерывания 1 — прерыванию 0x31 и т.д.). В архитектурах, отличных от x86, автоматическое назначение векторов прерываний обычно не используется, и значение этого параметра равно 0.
flags
Этот параметр используется в модуле startup-* при генерации точек входа в функции обработки прерываний ядра. Первое множество относится к характеристикам прерываний:
INTR_FLAG_NMI
Указывает на немаскируемое прерывание, которое, в отличие от обычных прерываний, невозможно отключать сбросом флага включения прерывания ЦП. Немаскируемые прерывания обычно генерируются событиями, которые требуют немедленного реагирования (ошибка четности, аппаратный сбой или предстоящее отключение питания). Поскольку адрес обработчика немаскируемого прерывания хранится в таблице векторов прерываний BIOS в позиции 02H, немаскируемые прерывания часто обозначаются INT 02H.

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

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

INTR_FLAG_CASCADE_IMPLICIT_EOI
Указывает на отсутствие необходимости передавать главному контроллеру сигнал окончания прерывания при обработке каскадного прерывания (например, если он передается автоматически). Этот флаг устанавливается только в записи, которая описывает каскадный контроллер.
INTR_FLAG_CPU_FAULT
Указывает, что один или несколько векторов, которые определяются в записи, не подключены к аппаратному источнику прерываний, а генерируются при сбое ЦП (например, сбое шины или ошибке четности). Мы настоятельно не рекомендуем применять этот подход к проектированию аппаратной платформы. Он подразумевает, что необходимо проверять исключение в генерируемом потоке кода и передавать контроллеру сигнал завершения прерывания после его идентификации. Фрагмент кода завершения прерывания (EIO) должен дополнительно определять адрес, по которому возник сбой, считывать его тип, а затем передавать сбой. Основной недостаток этого подхода заключается в необходимости вводить дополнительные команды в код.
INTR_FLAG_SMP_BROADCAST_MASK
INTR_FLAG_SMP_BROADCAST_UNMASK
Включение / отключение широковещательных прерываний в SMP-системе.
INTR_FLAG_MSI
Отмечает диапазон векторов для использования в качестве векторов MSI.
INTR_FLAG_IOAPIC
Указывает, что идентификатор IOAPIC хранится в поле spare[1].
PPC_INTR_FLAG_400ALT
Этот флаг аналогичен флагу INTR_FLAG_NMI и указывает генератору кода, что необходимо использовать другую последовательность входа в ядро. Это связано с тем, что в процессорах серии PPC400 вместо немаскированных прерываний используется критически важное прерывание, которое можно маскировать. Поскольку критически важное прерывание отличается от «обычного» внешнего прерывания, данный флаг указывает ядру на это различие.
PPC_INTR_FLAG_CI
Аналогичен флагу PPC_INTR_FLAG_400ALT; CI обозначает критически важное прерывание (critical interrupt).
PPC_INTR_FLAG_SHORTVEC
Указывает, что размер текущего вектора в таблице исключений отличается от обычного (256 байт).
PPC_INTR_FLAG_APU_MC
Для внутреннего использования.


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

Note: При использовании callout-ов interrupt_id_dec(), interrupt_id_dec_smp() и interrupt_eoi_dec() необходимо указывать флаг INTR_GENFLAG_LOAD_SYSPAGE в поле genflags структуры intrinfo_entry в коде для конкретной платы.

INTR_GENFLAG_LOAD_INTRINFO
Аналогичен флагу INTR_GENFLAG_LOAD_SYSPAGE, но задает загрузку указателя на эту структуру.
INTR_GENFLAG_LOAD_INTRMASK
Используется только процедурами завершения прерывания устройств, в которых маскирование не выполняется автоматически на уровне микросхемы. Процедура завершения прерывания должна включать только те прерывания, которые разрешены на пользовательском уровне (т.е. управляются с помощью функций InterruptMask() и InterruptUnmask()). Если этот флаг установлен, существующая маска прерываний помещается в регистр, где она доступна процедуре завершения прерывания. Нулевое значение в регистре указывает на то, что следует демаскировать прерывание, а ненулевое — на то, что следует оставить его в маскированном состоянии.
INTR_GENFLAG_NOGLITCH
Используется при обработке прерывания с конкретным кодом для проверки его генерации по ошибке или другим контроллером. Если этот флаг установлен, проверка не выполняется — считается, что вход в обработчика прерываний возможен только при фактической генерации прерывания устройством. Если флаг не установлен, выполняется проверка, что устройство действительно является источником прерывания.
INTR_GENFLAG_LOAD_CPUNUM
Аналогичен флагу INTR_GENFLAG_LOAD_SYSPAGE, но приводит к загрузке указателя на номер процессора, который используется этой структурой.
INTR_GENFLAG_ID_LOOP
В некоторых контроллерах прерываний имеются регистры с очисткой после чтения. Первая операция чтения возвращает битовый набор ожидающих прерываний, а затем немедленно обнуляет регистр. Поскольку callout идентификатора прерывания возвращает только один номер прерывания, мы можем не обрабатывать некоторые прерывания, если в регистре состояния установлены несколько бит.

Если флаг INTR_GENFLAG_ID_LOOP установлен, ядро генерирует код возврата в callout идентификатора после завершения обработки прерывания.

В callout-е идентификатора необходимо выделять область чтения/записи для выполнения обычных процедур. По умолчанию в эту область записывается начальное нулевое значение. После запуска callout немедленно проверяет это значение:
  • если оно не равно нулю, callout с его помощью идентифицирует следующее прерывание для обработки, сбрасывает этот бит, записывает новое значение в область памяти и возвращает идентифицированный номер прерывания.
  • если область памяти содержит нулевое значение, callout считывает регистр состояния устройства (после чего он сбрасывается), определяет с его помощью номер прерывания, сбрасывает бит, записывает значение в область памяти и возвращает соответствующий номер прерывания.
  • если область памяти и регистр устройства содержат нулевые значения, функция возвращает -1, тем самым указывая на отсутствие прерывания.
id Фрагмент кода, который копируется в функцию обработки прерывания ядра, определяющую источник прерывания, если в результате нескольких аппаратных событий на процессор может поступать одно прерывание. Этот параметр дополнительно изменяется флагами INTR_GENFLAG_*.
eoi
Фрагмент кода, который копируется в функцию обработки прерывания ядра и выполняет действия по завершению прерывания (End Of Interrupt, EOI). Он сообщает контроллеру, что обработка прерывания окончена, и демаскирует уровень прерывания. Код eoi идентифицирует причину сбоя, который обрабатывается как прерывание.
mask
Callout, который маскирует источник прерывания на уровне аппаратного контроллера. Этот вызов принимает номера векторов прерываний (от 0 до num_vectors - 1).
unmask
Callout, который демаскирует источник прерывания на уровне аппаратного контроллера. Он принимает те же номера векторов, что описанный выше вызов mask.
config
Предоставляет информацию о конфигурации уровней отдельных прерываний. Эта функция принимает указатель на системную страницу (1-й аргумент), указатель на запись с информацией о прерывании (2-й аргумент) и уровень прерывания, отсчитываемый от нуля; возвращает битовую маску (подробнее см. INTR_CONFIG_FLAG_* и Информация о векторах прерываний).

Callout может возвращать 0 или следующие флаги в любых сочетаниях:
INTR_CONFIG_FLAG_PREATTACH
Обычно прерывание маскировано до тех пор, пока к нему не присоединяется процедура с помощью функции InterruptAttach() или InterruptAttachEvent(). Если сбои ЦП транслируются в аппаратное прерывание (не рекомендуется!), прерывание по умолчанию отключено. Установка этого флага приводит к созданию «пустого» соединения с этим источником и, как следствие, демаскированию уровня.
INTR_CONFIG_FLAG_DISALLOWED
Запрещает пользовательскому коду присоединяться к уровню прерывания. Обычно этот флаг используется совместно с флагом INTR_CONFIG_FLAG_PREATTACH, однако с его помощью можно запрещать пользовательскому коду присоединяться к любому прерыванию.
INTR_CONFIG_FLAG_IPI
Определяет вектор, который используется в качестве цели межпроцессорного прерывания в SMP-системе.

Классификация:

ЗОСРВ «Нейтрино»

Тематические ссылки:

struct syspage_entry

Руководство по разработке модуля startup




Предыдущий раздел: Описание API системной библиотеки