когда я создаю отображение памяти для pcidevice, я всегда получаю одно и то же значение для getPhysicalAddress и getVirtualAddress: например,
Являются ли значения случайно в диапазоне 0x0..0xffff
?
Я очень сильно подозреваю, что это диапазон ввода-вывода в вашем PCI-устройстве , а не диапазон памяти.
Способ проверки это в вашем коде:
if (0 != (kIOPCIIOSpace & pciDevice->configRead32(kIOPCIConfigBaseAddress0))
{
// port mapped range
}
else
{
// memory mapped range
}
Смотрите также: { ссылка }
Теперь, на самом деле, я не слишком удивлен этим, потому что я думаю, что это точка «DMA».
Нет, сопоставленный с портами ввод-вывод в значительной степени противоположен DMA. Конечно, вы можете использовать сопоставленные с портом входы / выходы, чтобы инициировать передачу DMA, если именно так работает ваше устройство, поэтому, возможно, было бы лучше сформулировать это как ортогональное к DMA.
DMA - это устройства, имеющие прямой доступ системная память. PCI-шины - это регистры или память, которые обращаются к процессору.
Если у нас есть какое-то отображение в драйвере, то все, что нам нужно, это один. то есть физический адрес - это виртуальный адрес, так как это единственное место, где нам нужно выполнить «память в память» (восстановление данных процессора на звуковую карту PCI), верно ли это понимание?
Нет, по крайней мере на x86 адресное пространство порта ввода / вывода полностью отделено от адресного пространства физической памяти и поэтому также не может быть отображено в виртуальное адресное пространство, поскольку MMU выполняет преобразование между виртуальным и физическим памятью пространствами. На x86 есть специальные машинные инструкции, in
и out
, для чтения и записи с портов ввода / вывода. На большинстве архитектур (для OS X, в частности, PP C, но я думаю, что это также относится и к ARM), существует некоторая форма отображения памяти, однако. Я не знаю, как это работает в деталях на этих архитектурах, но для целей этого вопроса вам не нужно особенно заботиться:
Независимый от архитектуры способ выполнения операций ввода-вывода для порта диапазон отображения в кеше macOS должен использовать методы ioread*
и iowrite*
для IOPCIDevice
, где *
может быть 8
, 16
или 32
для 3 различных возможных операций ввода-вывода размеры слов, разрешенные стандартом PCI.
Теперь для основной проблемы: я испытываю панику ядра, вызванную любым доступом или назначением членов deviceRegisters, например:
Предполагая, что вы на самом деле имеете дело с диапазоном портов ввода-вывода в вашем устройстве, это объясняет панику ядра. Используйте pciDevice->ioread16(register_offset, deviceMap)
или аналогичный.
мудрец (pmj) предложил мне использовать функции ioRead / Write для назначения / доступа к этим значениям, но это на самом деле не сочетается с (по общему признанию, старым) скелетом код, предоставленный Apple.
В документе, на который вы ссылаетесь, предполагается, что BAR устройства относится к диапазону сопоставленной памяти, а не к диапазону ввода-вывода с сопоставлением портов.