Win2K vs. XP: глюк с чтением памяти PCI-девайса

Тема в разделе "WASM.ELECTRONICS", создана пользователем Monsta, 24 фев 2005.

  1. Monsta

    Monsta New Member

    Публикаций:
    0
    Регистрация:
    8 дек 2004
    Сообщения:
    13
    Адрес:
    Москва
    Дано:

    Простенький PCI-девайс с небольшой внутренней памятью.



    Нужно:

    Прочесть значение памяти (32-х битное слово) по адресу, например, 0х10 от начала памяти.



    Что получается:

    В Win2k значение возвращается нормально.

    В XP почему-то вместо значения ячейки памяти упорно возвращается адрес этой ячейки. Например, если адрес 0хE0000010 (BAR = 0xE0000000, смещение = 0х10), то и возвращается 0xE0000010.



    Вопрос:

    Что это, Бэрримор?



    Дополнительные данные:

    Драйвер для девайса написан на VC++ 6.0 с использованием DDK2000 и DriverStudio 2.0. Могу кинуть кусок кода, но там ничего особенного - только запись и чтение KMemoryRegister...
     
  2. Monsta

    Monsta New Member

    Публикаций:
    0
    Регистрация:
    8 дек 2004
    Сообщения:
    13
    Адрес:
    Москва
    Внесу кое-какие уточнения.

    В XP значение адреса возвращается, похоже, тогда, когда драйвер не успевает читать значение из памяти девайса. В Win2K такое "неуспевание" тоже бывало, только возвращалось значение 0xFFFFFFFF (т.е. как будто на эту область памяти не отображено ничего). Значение я читаю в цикле (сначала запись, потом чтение - это весь цикл), и на некоторых итерациях цикла такое и происходит.

    Компы такие: Celeron 1700 с WinXP и P4-2600 с Win2K. На обоих заметен этот глюк. Зато на старом P-90 (c Win2K) всё нормально, все итерации цикла проходят без ошибок. Такое впечатление, что девайс не успевает за слишком быстрым процессором... :-D



    Приведу куски кода из драйвера:
    Код (Text):
    1.  
    2. ...кусок из заголовочного файла:
    3.  
    4.     // внутренняя память девайса
    5.     KMemoryRange InfRegs;
    6.    
    7.     // регистр RSO
    8.     KMemoryRegister regRSO;
    9.  
    10. ...кусок из обработчика OnStartDevice:
    11.  
    12.     PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
    13.     PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();
    14.  
    15.     KPciConfiguration PciConfig(m_Lower.TopOfStack());
    16.  
    17.     status = InfRegs.Initialize(
    18.         pResListTranslated,
    19.         pResListRaw,
    20.         PciConfig.BaseAddressIndexToOrdinal(0)
    21.         );
    22.  
    23.     // регистр regRSO - одно 32-битное слово по смещению 0x20 от начала памяти девайса
    24.     regRSO = InfRegs[0x20];
    25.  
    26. ...кусок из обработчика IOCTL-функции, которая пишет и сразу читает память девайса:
    27.  
    28. NTSTATUS Device406::TEST_STATUS_REGISTER_Handler(KIrp I)
    29. {
    30.     ULONG *bufData;
    31.  
    32.     // получаем указатель на юзерский буфер
    33.     bufData = (ULONG *) I.IoctlBuffer();
    34.  
    35.     // тестируем (пишем/читаем) регистр RSO
    36.     regRSO = *bufData;
    37.     *bufData = regRSO;
    38.  
    39.     // количество записанных байт
    40.     I.Information() = 4;
    41.  
    42.     return STATUS_SUCCESS;
    43. }




    Вот эту функцию я как раз и вызываю в цикле из проги.



    Подозреваю, что между записью и чтением нужно поставить проверку на готовность девайса к чтению. Как это сделать, если, конечно, проблема именно в этом?