Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Потеря доступа к регистрам на плате PCI после ее запуска ...  (Прочитано 4602 раз)
0 Пользователей и 1 Гость смотрят эту тему.
baical
Гость
« : 27-11-2005 15:28 » 

Имеется следующая ситуация:

Есть PCI плата, которая использует 3 ресурса:
1. IRQ;
2. Memory (Mem0 - модержит 32-bit регистры управления устройством)
3. Memory (Mem1 - блок памяти для данных )

В моей функции StartDevice при запуске девайса все эти ресурсы обнаруживаются (привожу debug messages из StartDevice ) и обрабатываются без каких-то проблем:

MC431PCI - PNP Request (IRP_MN_START_DEVICE)
MC431PCI - Resources:
type CmResourceTypeMemory start 03FDFFF00 length 100
type CmResourceTypeMemory start 03FE00000 length 200000
type CmResourceTypeInterrupt level 16, vector 16, affinity FFFFFFFF
MC431PCI - Translated Resources:
type CmResourceTypeMemory start 03FDFFF00 length 100
type CmResourceTypeMemory start 03FE00000 length 200000
type CmResourceTypeInterrupt level 8, vector 194, affinity 3
MC431PCI - Found control memory block. Physical base address - 3FDFFF00, length - 255
MC431PCI - Found data memory block. Physical base address - 3FE00000, length - 2097152
MC431PCI - Got Interrupt Resource 2
MC431PCI - Mapping control memory ...
MC431PCI - Control memory virtual base address F7CD9F00
MC431PCI - Mapping data memory ...
MC431PCI - Data memory virtual base address A9687000


ПОсле того как оба блока памяти смапированы я пробую свои регистры управления (которые называются RUK№) поочередно вызывая READ_REGISTER_ULONG(). Ниже привожу debug messages c результатами чтения (помним, что я по прежнему нахожусь в StartDevice)

MC431PCI - Reading ruk0: 0h
MC431PCI - Reading ruk1: 0h
MC431PCI - Reading ruk2: 0h
MC431PCI - Reading ruk3: 1h
MC431PCI - Reading ruk4: 0h
MC431PCI - Reading ruk5: 0h
MC431PCI - Reading ruk6: 0h
MC431PCI - Reading ruk7: 0h
MC431PCI - Reading ruk9: 12000012h
MC431PCI - Reading ruk10: 0h
MC431PCI - Reading ruk11: 0h
MC431PCI - Reading ruk12: 0h
MC431PCI - Reading ruk13: 0h

Как видим все регистры читаются без каких-либо проблем.

Бит 15 регистра RUK2 управляет одним из индикаторов на плате. Чтобы совсем уже убедиться что все ок я записываю в него 0х8000 и индикатор зажигается.
Читая этот регистр я вижу, что там ровно то, что и записал:
MC431PCI - Reading ruk2: 0x8000h.


После это я со спокойной душой выхожу из StartDevice будучи абсолютно уверенным, что прибор готов к приему и отработке моих IOCTL. Диспетчер устройств показывает мою плату в соответсвие с тем, что я написал в inf файле и совершенно правильно отображает все 3 моих ресурса.

В тестевом приложении я получаю доступ к плате через CreateFile и затем используя DeviceIoControl просто шлю 0х0 в ruk2, чтобы погасить индикатор:
WRITE_REGISTER_ULONG((PULONG) (pdx->membase0 + RUK2), 0х00);,

И вот что моя функция DispatchControl возвращает мне:
....
MC431PCI - DATA TO BE WRITTEN: 0h
MC431PCI - ADDR TO BE WRITTEN TO: 8h прим. -- это смещение RUK2
MC431PCI - WRITING 0h TO RUK2 ....
MC431PCI - SEE WHAT'S IN RUK2: FFFFFFFFh
.....

Как видим индикаторо по прежнему горит, потомучто в него ничего не записалось и попытка чтения из него приводит к FFFFFFFFh... - гегистры перестали читаться.

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

Я попробовал и в обход HALа:

сначала пишу в RUK2 по проежнему надеясь, что LED все таки погаснет:
*((PULONG)(pdx->membase0+RUK2)) = 0x00;
и читаю из него
temp = *((PULONG) (pdx->membase0+RUK2)).
результат все тот же - FFFFFFFFh . Затем в менеджере устройв я дизэйблю свой девайс, добавляю строчку
WRITE_REGISTER_ULONG((PULONG) (pdx->membase0 + RUK2), 0х00) непосредственно в функцию StartDevice, перекомпилирую драйвер, переписываю его в .../system32/driver и инэйблю девайс. LED благополучно гаснет, оставляя меня в полном недоумении. Почему на этапе запуска девайса я спокойно общаюсь с платой, а потом после полной установки я теряю вский контакт с ней. ЧТо с моими драйвером не так. В Том, что что-то не так с драйвером я в этом уверен, потому что девайс сам ничего не блокирует - я ведь пишу в него сразу просле установки ресурсов.

Любые идеи что называется very welcome. Сам я уже что-то и не знаю куда смотреть. Если будет смысл вставить части кода драйвера- вставлю.
« Последнее редактирование: 15-12-2007 17:03 от Алексей1153++ » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 28-11-2005 17:04 » 

может ты память некорректно отмапировал... не в то адресное пространство процесса...?
сооветственно там где АддДевайс - адресное простаранство соответствует системному... а при ИОКонтрол работаешь в другом...
ты в верхнюю память мапировал или в нижнюю?
...
пардон если что не то спрашиваюю - я с мапируемой памятью только под 95 общался. а там четко свич был UserMode
//резервирование ресурсов для памяти
lpPCI_Res->hMemBase = _PageReserve(PR_SHARED,   //в память ring-3
    nNumPages,   //кол-во 4kb страниц
    0);      //дополнительных флагов - нет.
//обьединение диапазона физической памяти в зарезервированные страницы
_PageCommitPhys(   (DWORD)lpPCI_Res->hMemBase/4096,       //линейный физ. номер зарезервированной страницы
      nNumPages,             //количество страниц для обединения
      nFirstPhysPage,          //физ. номер первой страницы памяти для обединения
      PC_INCR|            //сответствие физ и линейного адреса./*запретить доступ в ring-3!!*/      PC_USER|            //доступно в ring-3
      PC_WRITEABLE)   )
//~все Ок - память выделена и отображена на физические страницы
lpPCI_Res->lpMemBase = lpPCI_Res->hMemBase;   //онкологично   ***

//теперь размещаем дополнительную память для
//скопированных значений
lpPCI_Res->hMemCopy =
_PageAllocate(  nNumPages,       //количество страниц по 4 кб (не может быть равным нулю!)
PG_VM,         //PG_SYS - системная область, or PG_VM/PG_HOOKED - ring-3 область
hSysVM,         //handle виртуальной машины( при PG_SYS равен 0)
0,            //маска выравнивания (0- кратно 4Kb)
0,            //начало размещения (только! при PAGEUSEALIGN)
0,            //конец размещения
&lpPCI_Res->lpMemCopy, //физ адрес (указатель)?
PAGEZEROINIT | PAGEFIXED); //флаги размещения
if (lpPCI_Res->hMemCopy)
{   
 //память успешно выделена.
 //при расположении памяти с помощью PAGEFIXED - линейый адрес вроде как должен соответствовать Handle!?
 _PageGetSizeAddr((DWORD)lpPCI_Res->hMemCopy,0,(PDWORD)&lpPCI_Res->lpMemCopy);
 }
как-то так у меня было... в 95
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines