|
Прикрутить стандарный драйвер к новой шине |
|
|
|
Jan 28 2013, 09:05
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Вот примерно такая задачка нарисовалась. Имеется ПЛИС, подключенная к процессору через интерфейс VLYNQ. И хотя исходно VLYNQ предназначен для peer-to-peer соединения, наличие ПЛИС позволяет реализовать несколько подсистем. Ну, для простоты пусть это будут UART 16550, несколько штук. Вопрос заключается в том, можно ли подцепить стандартные драйверы системы и не писать ничего заново? Сам по себе интерфейс VLYNQ, если отбросить его инициализацию, представляет собой аналогию шины: он прозрачно транслирует чтение/запись в определенном окне адресного пространства в пакетные обращения по шине, плюс еще умеет делать некие конфигурационные обращения. В общем, структурно даже несколько на PCI похоже, только без hotplug. То есть, после того, как сам VLYNQ поднят, можно вычислить базовый адрес регистров UART 16550 и он ничем не будет отличаться от такого же UART, встроенного в процессор. То есть, казалось бы, можно как-то приживить к работе с таким UART-ом обычные драйвера, вроде serial8250. Теоретически, правда, есть пара нюансов: 1. Tсли линк у VLYNQ пропадет, то чтение через VLYNQ завешивает систему. То есть, по хорошему перед чтением чего-то нужно проверять линк на исправность (статус в локальном регистре контроллера VLYNQ). Но вот на практике никогда у нас линк не падал пока. 2. Адресное пространство шины VLYNQ вообще-то тоже 32-битное. Но так как оно доступно через окошко в адресном пространстве процессора, то единовременно видно только около 64М адресов, которые мапятся через регистр страниц. То есть, по хорошему, обращение драйверов к регистрам устройства должно вестись через spinlock, ассоциированный с драйвером шины VLYNQ. 3. Прерывания по VLYNQ идут как специальный пакетик между пакетами данных. Хотя контроллер VLYNQ поддерживает 32 бита флагов прерываний и умеет сам выделять наиболее приоритетный флаг, процессору он показывает только одно прерывание, собственно от контроллера VLYNQ. То есть, нужно как-то уметь воткнуть между обработчиком прерывания стандартного драйвера UART и собственно UARTом обработчик прерывания VLYNQ. Почитав linux device drivers 3-го издания я так и не смог до конца уяснить, требует ли новая шина написания новых драйверов, если устройства имеют стандартный интерфейс управления. Точнее говоря, из повествования следует, что требует, если я устройство зарегистрирую именно на этой шине. С другой стороны, теоретически же можно сам драйвер шины написать так, что он найдет устройства UART на шине VLYNQ, но зарегистриует их как простые platform_device. И тогда они окажутся на шине platfrom_bus, где подбор драйверов идет просто по имени. Так делать можно, или это грабли? По поводу прерывания. В ядре 2.6.37 есть исходничек drivers/vlynq/vlynq.c. К сожалению, он нам не подходит целиком, так ка заточен на одно устройство peer-to-peer, да и применялся он, судя по всему, только для arch/mips/ar7. Но вот там прерывания интересно сделаны. 32 прерывания от VLYNQ просто замаплены на диапазон номеров прерываний выше контроллера прерываний. Код static irqreturn_t vlynq_irq(int irq, void *dev_id) { struct vlynq_device *dev = dev_id; u32 status; int virq = 0;
status = readl(&dev->local->int_status); writel(status, &dev->local->int_status);
if (unlikely(!status)) spurious_interrupt();
while (status) { if (status & 1) do_IRQ(dev->irq_start + virq); status >>= 1; virq++; }
return IRQ_HANDLED; } Короче, обработчик прерывания VLYNQ, похоже, дергает сам обработчики виртуальных прерываний. То есть, можно зарегистрировать несколько platform_device, в ресурсах которых заказать прерывания с номером, соответствующим диапазону vlynq, и обработчик основного прерывания от vlynq сам передаст прерывание драйверу UART. И тогда, по идее, стандартный драйвер должен отработать. Еще есть вопрос, можно ли иным способом повторно использовать код обычного драйвера UART? Ну, например, написать обертки ко всем его функциям, чтобы учитывать специфику шины (spinlock'и, проверки линка и пр).
|
|
|
|
|
 |
Ответов
|
Feb 18 2013, 09:42
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Да дело не в PNP. Я хочу, собственно, двух вещей: 1) минимальную защиту от дурака сделать. То есть, что бы при изменении прошивки ПЛИС для другого проекта с другим набором периферии система ругнулась и не подняла старые устройства на VLYNQ. 2) Чтобы не надо было собирать ядро по всяком мало-мальски пустяковому поводу. Проблема, естественно, не в том, чтобы его собрать, а в том, что система поддержки изделий после поставки должна быть как-то унифицирована. И переделка всего ядра - это формально слишком большое изменение, которое потребует тестирования всей системы. При замене только стандартного модуля можно говорить о тестировании подсистемы. Про шашечки изречение я не понял, я пока спросил про то, как устроен стандартный путь в линукс, когда требуется повторно использовать уже имеющийся код драйвера с новой шиной. Или стандартный путь - это шашечки и есть?  Что касается структур типа board_info, и, если смотреть глубже, вообще встраивания описания железа платы непосредственно в ядро, то налицо тенденция отказа от этой практики и замены ее на передачу описателя device_tree в виде внешней структуры как параметра запуска ядра. Придумано именно для унификации ядер и упрощения себе и пользователю жизни впоследствии. Пока что это не наш путь, так как еще пока не доделаны ядра для прочих кристаллов семейства, а все те, что есть, конфигурируются в рантайм. Слишком много работы, и это задача не первого этапа. В отношении vlynq наш путь заключается в том, чтобы создать полноценную инфраструктуру управления шиной и устройствами на ней. Например, для 8250 нужно указать прерывание, но реально VLYNQ имеет свою подсистему прерываний, для управления которой нужно зарегистрировать в ядре еще один irq_chip. То есть в той или иной степени драйвер шины нужен, и "просто и быстро" не сделать. Кроме того, нам нужен еще драйвер собственно главного сопра на ПЛИС, который будет уметь делать трансферы по VLYNQ со скоростями до 35 МБ/с, и это естественно будет уже DMA, а не жалкие там обертки воде ioread/iowrite. Пока что мне видится такая схема: 1) Регистрируем ресурсы для драйвера vlynq_bus. 2) запускаем драйвер, он регистрирует устройство vlynq_bus типа platform_device, определяет функции чтения-записи vlynq_шины, создает обработчик прерывания для шины. 3) Этот же драйвер сканирует удаленное устройство и регистрирует в системе первое и единственное vlynq_device с dev_id, равное прочитанному из конфигурационного пространства Vlynq удаленного устройства. 4) Мы делаем insmod и втыкаем в систему драйвер в виде модуля. который говорит, что он знает и поддерживает устройство с нужным dev_id. 5) Драйвер просто декодирует dev_id и регистрирует в системе перечень новых ресурсов. Ресурсы UART регистрируются в виде platform_device, ресурсы для собственных драйверов регистрируются как vlynq_device. 6) Система сама подключает драйверы UART с шины platform_bus к новым устройствам UART. 7) Мы делаем insmod и втыкаем в систему драйверы новых устройств для своих прикладных задач. Система связывает их с устройствами, делает probe и стартует драйвер для приложений. 8) Для приложений появляются интерфейсы через /dev, /sys или /proc и прикладные программы начинают работу с ними. Это правильный путь?
|
|
|
|
Сообщений в этой теме
Hoodwin Прикрутить стандарный драйвер к новой шине Jan 28 2013, 09:05 SM по поводу vlynq - тут не подскажу.
а вот по повод... Jan 28 2013, 12:39 Hoodwin Ну, допустим. Но ведь чтобы переопределенные seria... Jan 28 2013, 12:46 SM Цитата(Hoodwin @ Jan 28 2013, 16:46) Ну, ... Jan 28 2013, 13:04 Hoodwin Поглядел два примера:
1) i2c_register_board_info -... Feb 18 2013, 07:26 SM А зачем все эти трудности? Вам реально PnP нужен н... Feb 18 2013, 08:27 SM Да, путь в общем правильный. Только я не знаю, как... Feb 18 2013, 10:20 Hoodwin Хм. А почему нет? Что мне мешает сделать точно так... Feb 18 2013, 13:02 SM Цитата(Hoodwin @ Feb 18 2013, 17:02) Хм. ... Feb 18 2013, 13:34 Hoodwin ЦитатаКак я понимаю, в принципе на шине могут быть... Feb 18 2013, 14:58 SM Цитата(Hoodwin @ Feb 18 2013, 18:58) Ну т... Feb 18 2013, 16:49 Hoodwin Что-то пока накопал, что все прерывания живут в бо... Feb 18 2013, 17:14 SM Ну, то есть, Вы хотите для всех-всех устройств, ко... Feb 18 2013, 18:37 Hoodwin ЦитатаНу, то есть, Вы хотите для всех-всех устройс... Feb 18 2013, 20:57 SM Цитата(Hoodwin @ Feb 19 2013, 00:57) 3) А... Feb 19 2013, 05:02 Hoodwin Да я думаю, что написать маленький минидрайвер не ... Feb 19 2013, 09:14 SM Цитата(Hoodwin @ Feb 19 2013, 13:14) То л... Feb 19 2013, 13:34 Hoodwin А я извратился, сделал регулярную трансляцию всех ... Feb 20 2013, 08:31 Hoodwin А вот еще совсем простой вопрос. Если я хочу собир... Feb 20 2013, 16:45 SM Цитата(Hoodwin @ Feb 20 2013, 20:45) А из... Feb 20 2013, 17:17 sasamy Цитата(Hoodwin @ Feb 20 2013, 20:45) Как ... Feb 20 2013, 17:44 Idle Цитата(Hoodwin @ Feb 20 2013, 20:45) каки... Feb 20 2013, 18:46 Hoodwin SM
Цитататам именно в makefile первой строчкой иду... Feb 21 2013, 11:18 SM Цитата(Hoodwin @ Feb 21 2013, 15:18) SM
... Feb 21 2013, 11:40 sasamy Цитата(Hoodwin @ Feb 21 2013, 15:18) Как ... Feb 21 2013, 13:08 Idle Цитата(Hoodwin @ Feb 21 2013, 15:18) Ну, ... Feb 21 2013, 13:36  SM Цитата(Idle @ Feb 21 2013, 17:36) А, это ... Feb 21 2013, 13:47 Hoodwin А еще дурацкий вопрос. Как узнать строчку OS relea... Feb 21 2013, 14:05 SM Цитата(Hoodwin @ Feb 21 2013, 18:05) А ка... Feb 21 2013, 16:13 Hoodwin Говорю же, добился не я, а дядьки, которые сочинял... Feb 21 2013, 18:15 SM Цитата(Hoodwin @ Feb 21 2013, 22:15) WARN... Feb 21 2013, 18:34 Hoodwin Сейчас вот приделал совсем красиво, чтобы драйвер ... Feb 22 2013, 14:28
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|