USB

Структуры данных и регистры контроллера OHC

Все структуры данных OHC, расположенные в системной памяти, выровнены по границе параграфа (четыре младших бита адреса — нулевые). Для работы с OHC в памяти размещают дескрипторы конечных точек (ED) выбранных интерфейсов сконфигурированных устройств, дескрипторы передач (TD) для них и коммуникационную область HCCA. Дескрипторы передач подключаются драйвером к очередям требуемых конечных точек. Дескрипторы исполненных передач (завершенных нормально или снятых аварийно) контроллером подключаются к очереди Done Queue. Буфер данных для каждого дескриптора передачи может размещаться в одной или двух физических страницах, физические адреса этих страниц определяются по физическому адресу начала (начальное значение CBP) и физическому адресу конца буфера. Дескрипторы передач делятся на два типа: общий (для передач Bulk, Control, Interrupt) и изохронный.

Дескриптор конечной точки (ED) имеет размер 4 двойных слова (16 байт), его формат приведен на рисунке ниже, назначение полей приведено ниже:

  • FA (FunctionAddress) — адрес устройства;
  • EN (EndpointNumber) — номер точки;
  • D (Direction) — направление передачи: 01 — OUT; 10 — IN; 00, 11 — брать из поля PID дескриптора передачи TD;
  • S (Speed) — скорость: 0 — FS, 1 — LS;
  • K (sKip) — пропустить (не начинать транзакций с данной точкой);
  • F (Format) — признак формата TD, связанного с данной точкой: 0 — общий (Bulk, Control, Interrupt), 1 — дескриптор изохронной передачи;
  • MPS (MaximumPacketSize) — максимальный размер пакета;
  • TailP (TD Queue Tail Pointer) — указатель на конец очереди TD, если совпадает с HeadP — очередь пуста;
  • HeadP (TD Queue Head Pointer) — указатель на очередной TD, который должен быть исполнен для данной точки;
  • H (Halted) — признак останова точки;
  • C (toggleCarry) — текущее значение переключателя Toggle Bit;
  • NextED (Next Endpoint Descriptor) — указатель на дескриптор следующей конечной точки (если ноль, то эта точка — последняя в списке).

 

Формат общего дескриптора передач приведен на рисунке 2 (см. выше). Дескриптор позволяет описывать передачу данных указанной длины в пределах 8 кбайт. Количество транзакций для передачи контроллер определяет сам из поля длины пакета в дескрипторе точки (ED) и длины буфера; количество транзакций при приеме определяется длиной пакетов, переданных устройством. Назначение полей общего дескриптора передач приведено ниже:

  • R (bufferRounding) — требование совпадения длины последнего принимаемого пакета с объявленной длиной буфера (обнаружение коротких пакетов): 0 — сообщать об ошибке, если длина последнего пакета меньше длины буфера, 1 — не реагировать на несовпадение длины;
  • DP (Direction/PID) — тип маркера (направление, должно соответствовать полю D в ED): 00 — SETUP, 01 —OUT, 10 — IN, 11 — резерв;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • T (DataToggle) — поле, используемое для генерации и сравнения переключателя типа пакетов данных. Вместе с битом C из ED обеспечивает корректное переключение при передачах данных, описанных серией TD. При постановке в очередь TD для передач типов Bulk и Interupt драйвер должен установить T = 00; для передач типа Control в фазе Setup драйвер должен установить T = 10; в фазе Status и в первой фазе данных — T = 11. Дальнейшие модификации поля выполняет контроллер;
  • EC (ErrorCount) — счетчик ошибок передачи для текущей транзакции. Если при EC = 2 происходит ошибка, ее код помещается в CC и вся передача аварийно завершается. При успешном завершении транзакции счетчик обнуляется;
  • CC (ConditionCode) — состояние последней попытки транзакции
  • CBP (Current Buffer Pointer) — текущий физический адрес в буфере, по которому будет записан или прочитан очередной передаваемый пакет. После успешного завершения передачи поле обнуляется, при нештатном завершении — указывает на текущее положение;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD.

Формат дескриптора изохронной передачи приведен на рисунке ниже. Дескриптор позволяет описывать передачу данных длиной до 8 кбайт, состоящую из 1–8 транзакций (их количество задано в дескрипторе). Транзакции исполняются в последовательных кадрах, начиная с кадра с указанным номером. Длина пакета в каждой из этих транзакций вычисляется из значений полей OffsetN смежных транзакций (возможны и транзакции с нулевой длиной поля данных). Физический адрес буфера для каждой из этих транзакций определяется следующим образом: младшие 12 бит берутся из младших 12 бит соответствующего поля Offset, старшие биты (номер физической страницы) берутся либо из поля BPO (если в поле Offset бит 12 = 0), или из BE (если в поле Offset бит 12 = 1). Контроллер нормально отрабатывает переход буфера с одной страницы на другую даже в середине пакета. Назначение полей дескриптора изохронной передачи приведено ниже:

  • SF (StartingFrame) — младшие 16 бит номера кадра, в котором должен быть передан первый пакет;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • FC (FrameCount) — число пакетов данных, описанных в данном TD (0 — 1 пакет, 7 — 8 пакетов);
  • CC (ConditionCode) — код завершения на момент отправки TD в очередь выполненных заданий;
  • BP0 (BufferPage0) — физический номер страницы с первым байтом буфера данных;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD;
  • Offset0… Offset7 — смещение, используемое для определения размера и стартового адреса данных каждого пакета;
  • PSW0…PSW7 — слово состояния каждого пакета: биты [15:12] — код завершения, биты [10:0] — длина принятого пакета данных (в транзакциях OUT — 0), бит 11=0.

Коды завершения для всех типов передач приведены в таблице ниже.

Код CC Условие
0000 NoError — нормальное завершение без ошибок
0001 CRC — последний принятый пакет содержит ошибку CRC
0010 BitStuffing — последний принятый пакет содержит ошибку вставки бит
0011 DataToggleMismatch — последний принятый пакет данных имеет PID, не отвечающий ожидаемому значению переключателя
0100 Stall — конечная точка остановлена (получен одноименный пакет подтверждения)
0101 DeviceNotResponding — устройство не отвечает
0110 PIDCheckFailure — ошибка контроля достоверности поля PID
0111 UnexpectedPID — прием неожиданного или недопустимого PID
1000 DataOverrun — пакет данных от устройства длиннее разрешенного в поле MPS дескриптора точки
1001 DataUnderrun — точка вернула пакет, меньший чем MPS, и недостаточный для заполнения указанного буфера
1010, 1011 Резерв
1100 BufferOverrun — во время приема данных контроллер не успел записать данные в системную память
1101 BufferUnderrun — во время вывода данных контроллер не успел считать данные из системной памяти
111x NotAccessed — не было обработки (драйвер записывает этот код в TD перед помещением его в очередь)

 

Таблица. Формат коммуникационной области HCCA контроллера OHC

Смещение Длина Назначение
0 128 HccaInterrruptTable — таблица дескрипторов точек прерываний, 32 двойных слова, указывающих на дескрипторы EP
80 2 HccaFrameNumber — текущий номер кадра, модифицируется контроллером перед обходом списка периодических передач
82h 2 HccaPad1 — это слово контроллер обнуляет, когда модифицирует значение номера кадра
84h 4 HccaDoneHead — указатель на очередь исполненных передач. Контроллер модифицирует указатель по мере исполнения передач и сигнализирует об этом установкой бита WDH в регистре HcInterruptStatus. Указатель не будет повторно модифицироваться, пока программа не сбросит бит WDH. Бит 0 указателя используется для сигнализации о наличии иных незамаскированных условий прерываний (если обработчик прерывания, считывая указатель, получает нулевое значение бита, он может не анализировать регистр HcInterruptStatus)
88h 116 Резерв для контроллера

Кроме дескрипторов драйвер OHCI взаимодействует с контроллером через коммуникационную область в системной памяти — HCCA. На начало этой области указывает регистр HCCA.

Для оперативного взаимодействия драйвера и хост-контроллера в OHC имеется блок операционных регистров, приписанный к пространству памяти (его положение определяется регистрами BAR в конфигурационном пространстве устройства PCI, каковым и является OHC). К этому блоку система должна обеспечивать доступ и в режиме SMM. Размер блока регистров определяется числом нисходящих портов (NDP) корневого хаба, входящего в OHC; при наличии регистров поддержки эмуляции традиционного контроллера клавиатуры и мыши размер достигает 272 байт. Все регистры, кроме специальных регистров эмуляции, требуют 32-разрядных обращений. Операционные регистры обеспечивают управление хост-контроллером в целом, планирование загрузки кадров, связь контроллера с памятью и управление корневым хабом.

Таблица. Операционные регистры OHC

Смещение Назначение
Регистры общего управления и состояния OHC
00h HcRevision — ревизия контроллера: биты [7:0] — номер версии в BCD-формате, бит 8 — признак поддержки эмуляции контроллера клавиатуры и мыши, остальные биты не используются
04h HcControl — управление операционными режимами контроллера. Назначение полей:
CBSR (ControlBulkServiceRatio) — соотношение числа обслуживаемых непустых ED для точек типов Control и Bulk: 0 — 1:1, 1 — 2:1, 2 — 3:1, 3 — 4:1, Определяет приоритет управляющих передач относительно передач массивов
PLE (PeriodicListEnable) — разрешение обслуживания списка периодических транзакций (в следующем кадре)
IE (IsochronousEnable) — разрешение обслуживания изохронных передач (в следующем кадре)
CLE (ControlListEnable) — разрешение обслуживания управляющих передач (в следующем кадре)
BLE (BulkListEnable) — разрешение обслуживания передач массивов (в следующем кадре)
HCFS (HostControllerFunctionalState) — состояние хост-контроллера в плане USB: 00 — Reset, 01 — Resume, 10 — нормальный режим, 11 — Suspend
IR (InterruptRouting) — маршрутизация прерываний (сигнализация событий, указанных в регистре HcInterruptStatus: 0 — нормальные прерывания, 1 — SMI
RWC (RemoteWakeupConnected) — признак подключенности контроллера к системе «пробуждения» хоста
RWE (RemoteWakeupEnable) — разрешение сигнализации «пробуждения» хоста по установке бита ResumeDetected в регистре HcInterruptStatus
08h HcCommandStatus — управление и состояние контроллера.Назначение полей:
HCR (HostControllerReset) — сброс контроллера (обнуляется контроллером по завершении сброса)
CLF (ControlListFilled) — признак наличия дескрипторов в очереди управляющих передач (если бит обнулен, контроллер и не начнет обход списка ED точек управления). Устанавливается драйвером по помещении дескриптора в очередь, дальше отслеживается и модифицируется контроллером.
BLF (BulkListFilled) — признак наличия дескрипторов в очереди передач массивов (аналогично CLF)
OCR (OwnershipChangeRequest) — запрос передачи права управления контроллером
SOC (SchedulingOverrunCount) — счетчик ошибок планирования (переполнений)
0Ch HcInterruptStatus — идентификация событий, вызывающих прерывание. Назначение полей:
SO (SchedulingOverrun) — признак переполнения при планирования кадра (транзакция не умещается до конца кадра)
WDH (WritebackDoneHead) — признак помещения дескриптора в очередь выполненных заданий
SF (StartofFrame) — признак начала кадра
RD (ResumeDetected) — признак получения сигнала Resume
UE (UnrecoverableError) — признак неисправимой ошибки, не связанной с USB (требуется сброс контроллера)
FNO (FrameNumberOverflow) — переполнение счетчика кадров (перенос из 15-го разряда)
RHSC (RootHubStatusChange) — признак смены состояния корневого хаба
OC (OwnershipChange) — признак передачи права управления контроллером (вызывает SMI)
10h HcInterruptEnable — разрешение прерываний по событиям. Назначение полей аналогично предыдущему, дополнительно имеется бит MIE (MasterInterruptEnable) — общее разрешение прерываний. При записи единичное значение каждого бита разрешает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
14h HcInterruptDisable — запрет прерываний по событиям. Назначение полей аналогично предыдущему. При записи единичное значение каждого бита запрещает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
Указатели областей памяти
18h HcHCCA — физический адрес HCCA (биты [7:0]=0)
1Ch HcPeriodCurrentED — текущий физический адрес дескриптора ED точки периодических передач (биты [3:0]=0), устанавливается контроллером, драйвер может только читать
20h HcControlHeadED — физический адрес первого дескриптора точки управления (биты [3:0]=0), устанавливается драйвером
24h HcControlCurrentED — физический адрес текущего дескриптора точки управления (биты [3:0]=0), устанавливается контроллером
28h HcBulkHeadED — физический адрес первого дескриптора точки передач массивов (биты [3:0]=0), устанавливается драйвером
2Ch HcBulkCurrentED — физический адрес текущего дескриптора точки передач массивов (биты [3:0]=0), устанавливается контроллером
30h HcDoneHead — физический адрес начала очереди завершенных передач (биты [3:0]=0), устанавливается контроллером
Регистры управления кадром
34h HcFmInterval — параметры кадра:
Биты [13:0] — FI (FrameInterval), длительность кадра (в bt), по умолчанию 2EDFh (11999)
Биты [30:16] — FSMPS (FSLargestDataPacket), значение максимального размера пакета данных, загружаемое в счетчик Data Packet Counter в начале каждого кадра (счетчик отражает длину пакета данных, допустимую в текущий момент времени без переполнения планирования)
Бит 31 — FIT (FrameIntervalToggle), переключением этого бита драйвер сигнализирует о смене длительности кадр
38h HcFmRemaining, остаток кадра:
Биты [13:0] — FR (FrameRemaining), текущее количество битовых интервалов до конца кадра. Автоматически декрементируется; по обнулению загружается значением из FI и генерируется SOF;
Бит 31 — FRT (FrameRemainingToggle), принимает значение FIT по обнулению FI
3Ch HcFmNumber — номер кадра FN (биты [15:0]), автоматически меняется на границе кадра
40h HcPeriodicStart — момент начала обхода списка периодических транзакций PS (биты [13:0]), обычно устанавливается на 10% меньше FI. Контроллер приступает к периодическим транзакциям, когда FR достигает значения PS
44h HcLSThreshold — порог LST (биты [11:0]), до которого контроллер может выполнять LS-транзакции с максимальным (8 байт) размером пакета. Эти транзакции могут начинаться только при FR≥LST, по умолчанию LST=628h (1576)
Регистры управления и состояния корневого хаба
48h HcRhDescriptorA — дескриптор-A корневого хаба. Назначение полей:
NDP (NumberDownstreamPorts) — число нисходящих портов (1–15)
PSM (PowerSwitchingMode) — режим управления питанием портов: 1 — селективное управление, 0 — общее
NPS (NoPowerSwitching) — признак отсутствия ключа подачи питания (1 — порты запитаны постоянно)
DT (DeviceType) — тип устройства: всегда 0, поскольку корневой хаб не может быть компаундным устройством
OCPM (OverCurrentProtectionMode) — режим сообщения о срабатывании токовой защиты питания портов: 0 — коллективное, 1 — индивидуальное. Действительно только при NOCP=0
NOCP (NoOverCurrentProtection) — признак невозможности сообщения о перегрузке
POTPGT (PowerOnToPowerGoodTime) — время ожидания перед обращением драйвера к контроллеру после подачи питания на порт (в 2-мс интервалах)
4Ch HcRhDescriptorB — дескриптор-B корневого хаба:
Биты [15:0] — DR (DeviceRemovable), признаки отсоединяемости устройств от портов (бит 1 — порт 1,…бит 15 — порт 15)
Биты [31:16] — PPCM (PortPowerControlMask), маски управления питанием портов: 0 — глобальное, 1 — селективное
50h HcRhStatus — регистр состояния корневого хаба. Назначение полей:
LPS (LocalPowerStatus) — чтение всегда дает 0, запись «1» выключает питание портов с глобальным управлением, запись «0» не имеет значения
OCI (OverCurrentIndicator) — индикатор перегрузки для глобальной защиты по току
DRWE (DeviceRemoteWakeupEnable) — запись «1» разрешает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
LPSC (LocalPowerStatusChange) — чтение всегда дает 0, запись «1» включает питание портов с глобальным управлением, запись «0» не имеет значения
OCIC (OverCurrentIndicatorChange) — запись «1» сбрасывает индикатор перегрузки для глобальной защиты, запись «0» не имеет значения
CRWE (ClearRemoteWakeupEnable) — запись «1» запрещает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
54h HcRhPortStatus[1], состояние первого порта корневого хаба.Назначение полей:
CCS: чтение (CurrentConnectStatus) — текущее состояние подключения к порту:
1 — подключено устройство, 0 — нет; запись «1» запрещает порт, запись «0» не имеет эффекта
PES (PortEnableStatus) — состояние разрешения порта: 0 — Disabled, 1 — Enabled; запись «1» разрешает порт, запись «0» не имеет эффекта
PSS (PortSuspendStatus) — состояние приостановки порта: 0 — не приостановлен, 1 — приостановлен или находится в процессе возобновления; запись «1» приостанавливает порт, запись «0» не имеет эффекта
POCI: чтение (PortOverCurrentIndicator) — перегрузка порта по питанию (только при селективной защите портов): 1 — защита сработала, 0 — нет; запись «1» инициирует возобновление порта (resume), запись «0» не имеет эффекта
PRS (PortResetStatus) — чтение состояния сброса порта: 1 — подается сигнал Reset, 0 — нет; запись «1» инициирует подачу сигнала Reset, запись «0» не имеет эффекта.
PPS (PortPowerStatus) — состояние питания порта: 0 — порт не запитан, 1 — порт запитан; запись «1» включает питание порта при селективном управлении, запись «0» не имеет эффекта
LSDA (LowSpeedDeviceAttached) — признак низкой скорости: 1 — обнаружено подключение LS-устройства, 0 — нет
CSC (ConnectStatusChange) — признак смены состояния подключения порта, сбрасывается записью «1»
PESC (PortEnableStatusChange) — признак смены состояния разрешения порта, сбрасывается записью «1»
PSSC (PortSuspendStatusChange) — признак завершения последовательности возобновления для порта, сбрасывается записью «1»
OCIC (PortOverCurrentIndicatorChange) — признак смены состояния индикатора селективной защиты порта, сбрасывается записью «1»
PRSC (PortResetStatusChange) — признак завершения формирования сигнала Reset, сбрасывается записью «1»
Состояние портов корневого хаба (аналогично предыдущему)
54h+4×NDP HcRhPortStatus[NDP], состояние последнего порта корневого хаба (аналогично предыдущему)
Регистры поддержки эмуляции контроллера клавиатуры и мыши (KBC)
100h HceControl — управление эмуляцией
104h HceInput — эмуляция входных буферов KBC: программный вывод байта по адресу порта 60h или 64h вызывает запись данных в биты [7:0] этого регистра, биты [31:8] — резерв
108h HceOutput — эмуляция выходного буфера KBC: программный ввод байта из порта 60h вернет данные из бит [7:0] этого регистра (и сбросит флаг BufferFull в HceStatus), биты [31:8] — резерв
10Ch HceStatus — эмуляция регистра состояния KBC

 

При разрешенной эмуляции контроллера клавиатуры и мыши контроллер OHC перехватывает (декодирует) обращения по адресам ввода/вывода 60h и 64h:

  • инструкция IN, обращенная к порту 60h, вернет байт из регистра HceOutput, а также установит в регистре HceStatus флаг OutputFull = 0;
  • инструкция OUT, обращенная к порту 60h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 1 и CmdData = 0;
  • инструкция IN, обращенная к порту 64h, вернет байт текущего состояния из регистра HceStatus;
  • инструкция OUT, обращенная к порту 64h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 0 и CmdData = 1.

ПО эмуляции отрабатывает эти обращения, пользуясь клавиатурой и мышью, подключенными к USB. Ряд обращений требует действий, которые эмулятор должен выполнить невидимо для ПО. Эти действия вызывают условие прерывания для эмулятора, которое может выполняться как системное прерывание SMI. При этом оказывается, что с хост-контроллером должны взаимодействовать как нормальный драйвер ОС, так и драйвер эмулятора, работающий в режиме системного управления (SMM). Чтобы корректно передавать право на управление контроллером между этими драйверами, в регистрах HcCommandStatus и HcInterruptStatus предусмотрены соответствующие биты.

 

Таблица. Назначение бит регистров управления и состояния эмуляции

Бит Назначение
Регистр HceControl
0 EmulationEnable, разрешение эмуляции
1 EmulationInterrupt, признак условия прерывания для эмуляции
2 CharacterPending, разрешение прерывания эмуляции по обнулению бита OutputFull в регистре HceStatus (требуется следующий байт от клавиатуры или мыши)
3 IRQEn, разрешение генерации IRQ1 или IRQ12 по установке бита OutputFull в регистре HceStatus
4 ExternalIRQEn, разрешение формирования сигнала прерывания эмуляции по сигналу IRQ1 и IRQ12 от KBC (независимо от состояния EmulationEnable)
5 GateA20Sequence, признак команды управления вентилем GateA20, устанавливается по записи байта D1h в порт 64h, сбрасывается по записи любого другого значения в этот порт
6 IRQ1Active, признак сигнала IRQ1 от KBC (сбрасывается записью «1»)
7 IRQ12Active, признак сигнала IRQ12 от KBC (сбрасывается записью «1»)
8 A20State, индикатор состояния сигнала GateA20 от KBC
9-31 Резерв (0)
Регистр HceStatus
0 OutputFull, выходной буфер контроллера полон. Сбрасывается при чтении порта 60h. При установке этого бита и при IRQEn = 1 вырабатывается IRQ1 (при AuxOutputFull = 0) или IRQ12 (при AuxOutputFull = 1)
1 InputFull, входной буфер полон. Устанавливается при записи в порт 60h или 64h (кроме команд управления вентилем GateA20)
2 Flag, системный флаг для определения «холодной» или «теплой» загрузки
3 CmdData, признак команды или данных для контроллера: запись в порт 60h сбрасывает бит, запись в порт 64h — устанавливает
4 Inhibit Switch, состояние ключа запрета клавиатуры (1 — клавиатура не запрещена)
5 AuxOutputFull, признак прихода данных от мыши
6 Time-out, признак тайм-аута при обмене с клавиатурой
7 Parity, признак ошибки четности при обмене с клавиатурой


Sitelinkx by eXtro-media.de
Яндекс.Метрика