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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Не пишет в PCI регистры для WinXP  (Прочитано 19322 раз)
0 Пользователей и 1 Гость смотрят эту тему.
magbob
Интересующийся

ru
Offline Offline

« : 17-03-2009 11:15 » 

Есть драйвер PCI устройства (под WIN2000) работает без проблем. А под XP на некоторых материнках не хочет писать в регистры PCI.
Причем когда только проинсталируешь драйвер все работает. Только перегрузишь машину все уже не работает. (Удалишь драйвер из системы заново поставишь все ОК работает. А если Отключить включить не помогает) На машине 256М ОЗУ. Добовляешь до 512 тоже все ОК. Не могу понять в чем может быть дело.

Вот куски кода (Подключения ресурсов Numega сгенерила):

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Do whatever initialization needed when starting the device:
    // gather information about it,  update the registry, etc.
    // At this point, the lower level drivers completed the IRP
    if ((irpStack->Parameters.StartDevice.AllocatedResources != NULL) &&
        (irpStack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL))
    {
        // Parameters.StartDevice.AllocatedResources points to a
        // CM_RESOURCE_LIST describing the hardware resources that
        // the PnP Manager assigned to the device. This list contains
        // the resources in raw form. Use the raw resources to program
        // the device.

        partialResourceList =
            &irpStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;

        resource = &partialResourceList->PartialDescriptors[0];

        // Parameters.StartDevice.AllocatedResourcesTranslated points
        // to a CM_RESOURCE_LIST describing the hardware resources that
        // the PnP Manager assigned to the device. This list contains
        // the resources in translated form. Use the translated resources
        // to connect the interrupt vector, map I/O space, and map memory.

        partialResourceListTranslated =
            &irpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;

        resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];

        // reset the total memory range count
        memCount = 0;

        // search the resources
        for (ii = 0;
             ii < partialResourceList->Count;
             ++ii, ++resource, ++resourceTrans)
        {

            switch (resource->Type)
            {
            case CmResourceTypePort:
                DebugPrint(DBG_PNP, DBG_INFO,  "Resource Type Port");
                DebugPrint(DBG_PNP, DBG_INFO, "Port.Start %I64x", resource->u.Port.Start.QuadPart);
                DebugPrint(DBG_PNP, DBG_INFO, "Port.Length %x", resource->u.Port.Length);
                break;
            case CmResourceTypeMemory:
                DebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Memory");
                DebugPrint(DBG_PNP, DBG_TRACE, "Memory.Start %I64x", resource->u.Memory.Start.QuadPart);
                DebugPrint(DBG_PNP, DBG_TRACE, "Memory.Length %x", resource->u.Memory.Length);

                switch (memCount)
                {
                case 0:
                    if (resourceTrans->Type == CmResourceTypeMemory)
                    {
                        DeviceExtension->bm_MemoryRangeIsIo = FALSE;
                        DeviceExtension->bm_MemoryRangeMapped = TRUE;

                        DeviceExtension->m_MemoryRangeLength = resourceTrans->u.Memory.Length;
                        DeviceExtension->m_MemoryRangeBase = (PUCHAR)MmMapIoSpace(
                                                            resourceTrans->u.Memory.Start,
                                                            resourceTrans->u.Memory.Length,
                                                            MmNonCached
                                                            );
                    }
                    else
                    {
                        ASSERT(resourceTrans->Type == CmResourceTypePort);

                        DeviceExtension->bm_MemoryRangeIsIo = TRUE;

                        DeviceExtension->m_MemoryRangeLength = resourceTrans->u.Port.Length;
                        DeviceExtension->bm_MemoryRangeMapped = (resourceTrans->Flags & CM_RESOURCE_PORT_IO) == 0;
                        if (DeviceExtension->bm_MemoryRangeMapped)
                        {
                            DeviceExtension->m_MemoryRangeBase = (PUCHAR)MmMapIoSpace(
                                                                    resourceTrans->u.Port.Start,
                                                                    resourceTrans->u.Port.Length,
                                                                    MmNonCached
                                                                    );
                        }
                        else
                        {
                            DeviceExtension->m_MemoryRangeBase = (PUCHAR)resourceTrans->u.Port.Start.QuadPart;
                        }
                    }
                    break;
                default:
                    DebugPrint(DBG_PNP, DBG_INFO,  "Extra Memory Range");
                    break;
                }

                ++memCount;
                break;
            case CmResourceTypeInterrupt:
                DebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Interrupt");
                DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Level %x", resourceTrans->u.Interrupt.Level);
                DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Vector %x", resourceTrans->u.Interrupt.Vector);
                DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Affinity %x\n", resourceTrans->u.Interrupt.Affinity);

                DeviceExtension->InterruptVector = resourceTrans->u.Interrupt.Vector;
                DeviceExtension->InterruptLevel = (KIRQL)resourceTrans->u.Interrupt.Level;
                DeviceExtension->InterruptAffinity = resourceTrans->u.Interrupt.Affinity;
                DeviceExtension->bInterruptShared = resourceTrans->ShareDisposition == CmResourceShareShared;
                DeviceExtension->InterruptMode =
                    (resourceTrans->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
                break;
            default:
                DebugPrint(DBG_PNP, DBG_TRACE, "Unknown Resource Type %x", resourceTrans->Type);
                break;
            }
        }
    }

Таким образом пишу:

    if (DeviceExtension->bm_MemoryRangeIsIo) {
       WRITE_PORT_ULONG((PULONG)(DeviceExtension->m_MemoryRangeBase+MyAddr),Value);       
    } else {
       WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->m_MemoryRangeBase+MyAddr),Value);
    }


Помогите пожалуйста  Не понял
Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #1 : 18-03-2009 08:39 » 

Заметил еще одну непонятку.
Если драйвер отключить и включать его только после загрузки винды то все работает.
Можно ли винде както сказать чтобы она его загружала в последнюю очередь?
Или в какую степь копать хотябы подскажите уже весь инет перерыл и memcpy, memmove пробовал и

IoAllocateMdl(DeviceExtension->m_MemoryRangeBase, resourceTrans->u.Memory.Length, FALSE, FALSE,NULL);
MmBuildMdlForNonPagedPool(DeviceExtension->pMdl);

делал все безтолку.
Цо делать незнаю.
 А черт его знает...
Записан
Ochkarik
Модератор

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

« Ответ #2 : 18-03-2009 23:09 » 

а что за железка? может PCI разъем отвалился? у нас такие чудеса через это были... мы разболтали на нескольких материнках слоты, частым перетыканием платы... глючило страшно.
может быть шина адреса на железке обрезана как-то хитро?

MmMapIoSpace - это так надо? честно говоря с отображаемой памятью только под 98 работал, да и то давно и немного... это же ее имеете в виду?
PS поздняя загрузка... похоже что железка по разному воспринимает разные окна адресного пространства. при второй загрузке - выделяется второе окно в других адресах... может это...
« Последнее редактирование: 18-03-2009 23:21 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
magbob
Интересующийся

ru
Offline Offline

« Ответ #3 : 19-03-2009 07:30 » 

Железку сами разработали. На Altera. Можно было бы предположить что проблемы в железе, да вот только если не трогая железо ставить win2000 то все работает как часы. А на WinXP вот такие глюки непонятные. Отображаю регистры в память именно при помощи MmMapIoSpace - помоему другого способа и нет для w2k(xp).
А вот как винде объяснить в какое адресное пространство грузить?
Или может можно как-то ей объяснить чтобы грузила мой драйвер самым последним?
Уже две недели бьюсь а толку ноль.  С ума сойти...
Записан
Ochkarik
Модератор

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

« Ответ #4 : 19-03-2009 08:41 » 

хм... а проверьте ка состояние DeviceExtension->m_MemoryRangeBase+MyAddr в момент вызова записи в регистр?..

на что это очень похоже -  где то выход за пределы структуры/массива.... когда то работает - то не работает.... 

"под XP на некоторых материнках" - то есть на XP все таки иногда работает?

        for (ii = 0;
             ii < partialResourceList->Count;
             ++ii, ++resource, ++resourceTrans)
- опять меня ставит в тупик префиксный инкремент)

Drivers for Windows Vista and later operating systems can use RtlCmDecodeMemIoResource and RtlCmEncodeMemIoResource to read and update the u.Memory member, rather than updating it directly.
- в описании на u.Memory  структуры CM_PARTIAL_RESOURCE_DESCRIPTOR. почитайте, может быть - это то самое? хотя не похоже...
насчет изменить - вроде бы можно менят эту структуру.... до IRP_MJ_START вызывается кажется что то типа запроса ресурсов.... там помоему можно попробовать изменить.

еще подумаю... а то на работу пора бежать)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sss
Специалист

ru
Offline Offline

« Ответ #5 : 19-03-2009 09:49 » 

magbob, а что значит "не хочет писать"? Ошибка какая возникает или какое нить окно, типа "Я не хочу писать"...  Или ресурс повторно кем то занимается и надо отловить некое событие перераспределения ресурсов. Вообще, можно протестировать устройство чтением VID и понять - оно все еще там или нет...
Записан

while (8==8)
magbob
Интересующийся

ru
Offline Offline

« Ответ #6 : 19-03-2009 10:07 » 

DeviceExtension->m_MemoryRangeBase+MyAddr - смотрел нормальное (соответствует истине) - т.е. реально равно тому адресу который возвращает MmMapIoSpace плюс смещение. За границы Length не выхожу.
Да на XP работает но не на всех мамках.  Он и на этой маме работает если память до 512М нарастить (а под win2000 прексрано и на 128М и на 64М работает), или если: 1.отключить драйвер  2:потом загрузить винду 3: включить драйвер - тоже все работает. А если закрузить при включеном драйвере то все уже не пашет - что только не делай.

Переделал в более удобный вид
        for (ii = 0;
             ii < partialResourceList->Count;
             ii++)//, ++resource, ++resourceTrans)
        {

            resource = &partialResourceList->PartialDescriptors[ii];
       resourceTrans = &partialResourceListTranslated->PartialDescriptors[ii];

  .......
 }

А насчет RtlCmDecodeMemIoResource and RtlCmEncodeMemIoResource так там написано что только для Vista и поздних версий, а у меня с XP проблемы.
Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #7 : 19-03-2009 10:22 » 

sss Дело в том что он всегда читает регистры и устройство получается на месте. Т.е. Я нормально считываю конфигурацию устройства из регистров. А вот когда посылаю ему команды устройство их не воспринимает. Опять можно было-бы грешить на устройство если бы оно и на win2000 не работало да и на XP при большом объеме памяти тоже работает. Я еще в драйвере выделяю два буфера по 65К для Dma чтения и записи и два буфера по 1М для времменого хранения данных если пользовательское приложение не успело считать данные или хочет записать данные больше чем Dma буфер записи в устройство. Но с их размерами я уже эксперементировал не помогло.
Записан
Ochkarik
Модератор

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

« Ответ #8 : 19-03-2009 19:45 » 

хmagbob, тогда вот что интересно посмотреть... выведете значения физического адреса в которые отображается память. и посмотрите в каких случаях и чем он (адрес) отличается.
как он выделяется на W2K, как он выделяется на XP с 256М(там где не работает) и XP 512М. будет ли разница по адресам?
причем имеет смысл смотреть одновременно физические адреса в Raw и Translated листах - до сих пор не знаю отличаются они в x86 или нет)

..... а чтение из тех же портов - когда отвалилась запись - работает??? есть возможность проконтроллировать?

если зависимость будет выявлена, тогда можно попробовать принудительно выделять память там где надо по запросу IRP_MN_FILTER_RESOURCE_REQUIREMENTS

PS я так понял потоковая передача? скорости небольшие?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sss
Специалист

ru
Offline Offline

« Ответ #9 : 20-03-2009 04:22 » 

Ochkarik, я как понял, чтение работает... А ведь правда, может дело в выравниваниях адресов для DMA?
Записан

while (8==8)
Ochkarik
Модератор

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

« Ответ #10 : 20-03-2009 07:55 » 

вообще если чтение работает... очень странно. проверьте физические адреса для разных случаев и их выравнивание...
PCI контроллер - корка на плисе или готовый контроллер? может там все таки бага?

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
magbob
Интересующийся

ru
Offline Offline

« Ответ #11 : 20-03-2009 09:54 » 

Вот результаты эксперементов:
WIN2000
регистры физ: FC 00 00 00 Вир: F1 1E 20 00
dma1 физ: 01 76 E0 00 Вир: 81 76 E0 00
dma2 физ: 01 75 E0 00 Вир: 81 75 E0 00

WIN XP 512 ОЗУ
регистры физ: FC 00 00 00 Вир: F7 C7 F0 00
dma1 физ: 05 70 90 00 Вир: 85 30 70 00
dma2 физ: 04 F7 70 00 Вир: 84 B7 70 00

WIN XP 256 ОЗУ - рабочая
регистры физ: FC 00 00 00 Вир: F9 F3 40 00
dma1 физ: 00 08 70 00 Вир: F5 F9 E0 00
dma2 физ: 00 10 10 00 Вир: F6 05 E0 00

WIN XP 256 ОЗУ - не рабочая
регистры физ: FC 00 00 00 Вир: F9 FF 30 00
dma1 физ: 00 00 50 00 Вир: F5 E2 70 00
dma2 физ: 00 04 50 00 Вир: F5 C4 00 00

Вроде есть закономерность между win200 и xp512 ну и то только для DMA
Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #12 : 20-03-2009 09:56 » 

PCI на ПЛИС но мега функция PCI от Altera
Записан
urock
Участник

ru
Offline Offline

« Ответ #13 : 20-03-2009 11:41 » 

а какие ресурсы требует ваше устройства? в пространстве памяти или ввода/вывода? и какого объема? правильно ли они отображаются в Device Manager?

вот мой код выделения ресурсов для устройства, требующего 16 байт в I/O space и 32 Кб в memory space, у меня точно все работает и при чтении и при записи в обоих операционках, посмотрите, может поможет..

Цитата
NTSTATUS
StartDevice(IN PROSTA_DEVICE_EXT DevExt,
               IN PIO_STACK_LOCATION IoStackLocation)
{
    NTSTATUS code = STATUS_SUCCESS;
    ULONG index;
    DEVICE_DESCRIPTION deviceDescription;
    PCM_RESOURCE_LIST pResourceList, pResourceListTranslated;
    PCM_PARTIAL_RESOURCE_LIST prl, prlTranslated;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR prd, prdTranslated;
    PCM_FULL_RESOURCE_DESCRIPTOR frd, frdTranslated;
   
   DbgPrint("\nRSP-517:::Entering RostaStartDevice..\n");

    pResourceList = IoStackLocation->Parameters.StartDevice.AllocatedResources;
    pResourceListTranslated = IoStackLocation->Parameters.StartDevice.AllocatedResourcesTranslated;

    frd = &pResourceList->List[0];
    frdTranslated = &pResourceListTranslated->List[0];
 
    prl = &frd->PartialResourceList; // значения уровня шины
    prlTranslated = &frdTranslated->PartialResourceList; //  значения уровня системы -- именно они нам и нужны

   DbgPrint("RSP-517:::CM_PARTIAL_RESOURCE_LIST extracted\n");


   DevExt->Bar[0].pBase = NULL;

   for (index = 0, 
       prdTranslated = &prlTranslated->PartialDescriptors[index],
       prd = &prl->PartialDescriptors[index];
       index < prlTranslated->Count;
       index++, prdTranslated++, prd++)
       {
      
          DbgPrint("RSP-517:::Res type = %d\n",prd->Type);
      switch(prd->Type)
      {
         
         case CmResourceTypePort:

               if(prdTranslated->Type == CmResourceTypePort)
               {
                  DbgPrint("RSP-517:::Getting Port Resourses..\n");
                  DbgPrint("RSP-517:::DevExt->Mapped = FALSE\n");
                  DevExt->Bar[0].Mapped = FALSE;
                  DevExt->Bar[0].pBase = (PULONG) prdTranslated->u.Port.Start.LowPart;
                  DbgPrint("RSP-517:::DevExt->Bar[0].pBase = %x\n",DevExt->Bar[0].pBase);
                  DevExt->Bar[0].length = prdTranslated->u.Port.Length;
                  DevExt->Bar[0].type = RESOURCE_PORT;

                   }
               else
               {
                  DbgPrint("RSP-517:::Getting Port Resourses..\n");
                  DbgPrint("RSP-517:::DevExt->Mapped = TRUE\n");
                    DevExt->Bar[0].Mapped = TRUE;
                  DevExt->Bar[0].length = prdTranslated->u.Memory.Length;
                  DevExt->Bar[0].physAddress = prdTranslated->u.Memory.Start;
                   DevExt->Bar[0].pBase = (PULONG)
                        MmMapIoSpace(   prdTranslated->u.Memory.Start,
                              prdTranslated->u.Memory.Length,
                              MmNonCached);
                  DevExt->Bar[0].type = RESOURCE_PORT;

                   }
            
                break;
               
         
            case CmResourceTypeInterrupt:


            DbgPrint("RSP-517:::Getting Interrupt Resourses..\n");

                DevExt->InterruptLevel       = (UCHAR)prdTranslated->u.Interrupt.Level;
                DevExt->InterruptVector      = prdTranslated->u.Interrupt.Vector;
                DevExt->InterruptAffinity    = prdTranslated->u.Interrupt.Affinity;
               
                if (prdTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
                    DevExt->InterruptMode = Latched;
                } else {
                    DevExt->InterruptMode = LevelSensitive;
                }

                //
                // Because this is a PCI device, we KNOW it must be
                // a LevelSensitive Interrupt
                //
                ASSERT(DevExt->InterruptMode == LevelSensitive);

            DbgPrint("RSP-517:::Got Interrupt Resourses..\n");

                break;

         case CmResourceTypeMemory:

            DbgPrint("RSP-517:::Getting memory Resourses..\n");
            DevExt->Bar[1].Mapped = TRUE;
            DevExt->Bar[1].length = prdTranslated->u.Memory.Length;
            DevExt->Bar[1].physAddress = prdTranslated->u.Memory.Start;
            DevExt->Bar[1].pBase =
               MmMapIoSpace(prdTranslated->u.Memory.Start,
                         prdTranslated->u.Memory.Length,
                         MmNonCached);
            DbgPrint("RSP-517:::DevExt->Bar[1].pBase = %x\n",DevExt->Bar[1].pBase);
            DbgPrint("RSP-517:::DevExt->Bar[1].physAddress = %x\n",DevExt->Bar[1].physAddress.LowPart);
            DbgPrint("RSP-517:::DevExt->Bar[1].length = %x\n",DevExt->Bar[1].length);
            DevExt->Bar[1].type = RESOURCE_MEMORY;
            break;
            

            default:
            // Ресурсы таких типов мы не ожидаем и не обслуживаем
                break;
        }
    }
Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #14 : 20-03-2009 12:35 » 

Я кажется разобрался спасибо Ochkarik навел на путь истинный  Улыбаюсь)
После экспериментов пришел к выводу что похоже у меня глючит не чтение запись в регистры а DMA т.к. Когда физ адрес DMA больше 00 08 00 00 все работает (или мне так кажется).

Каким образом можно задать физ адрес не автоматом а самому или по условиям?

Сейчас я в цикле выделяю и освобождаю память пока не попаду в нужный дипазон но это не хорошо.
Записан
Ochkarik
Модератор

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

« Ответ #15 : 20-03-2009 21:44 » 

только маленький нюанс, проверьте все таки...
есть поле
resourceTrans->u.Memory.Start  а есть  resource->u.Memory.Start
первый адрес- если правильно понимаю, физический для адресации памяти по процессорной шине памяти
второй - это адрес соответствующий адресации по Не понял чему то еще... логический, что ли... короче сам с этим не работрался)
проверьте, скорее всего они будут равны.

второе... выделяете вы 64к.... кстати? 64 или 65(как вы писали выше)?
насчет выделения памяти выше 80000 - странно, я бы понял если бы было наоборот. или  я бы понял если бы было  требование выравнивания стартового адреса на нули по log2(length) младшим битам (так сумматор в железе не надо ставить)...
а так... похоже больше на глюк в железе, на залипуху между выводами плисы, на глюки в прошивке... на отвалившуюся ножку..

теперь насчет DMA. ваша корка в режиме master работает? или как slave?
потому что про slave я совсем не помню... как вы память для DMA выделяете?

PS да, попробуйте статистику побольше для рабочего и не работчего режима собрать, может быть какой нибудь бит битый всплывет? плиса штука тонкая.... у нас постоянно глюки с ней, несмотря на выполнившуюся времянку и синхронную (теоретически) работу. правда и проекты у нас здоровые...

PPS посмотрите в сторону GetDmaAlignment () и непонятой мной фразы
Цитата
A driver can call this routine to determine alignment requirements for DMA buffers it allocates. The returned value should be used to set the AlignmentRequirement field in the device object. A driver may need to increase this value because of additional hardware device restrictions. For more information, see Initializing a Device Object.

urock, да вроде то же самое... тоже на нумегувскую рыбу похоже)
« Последнее редактирование: 20-03-2009 21:53 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
magbob
Интересующийся

ru
Offline Offline

« Ответ #16 : 21-03-2009 16:45 » 

Я еще поэксперементирую.

Я выделяю 0x10000 байт (65536)
насчет адреса 80000 над меньшими адресами я не эксперементировал. Тоже попробую.

Моя железка в мастер режиме работает я ей передаю адрес памяти DMA и она уже там сама рулит. На чтение и запись.
Сумматор стоит единственное выравнивание это по 64 байта (6 первыхбит д.б. 0) но это условие всегда выполняется.

Если бы была залипуха, то и данные бы глючили, а так данные нормально идут.
В прошивке глюк м.б. (хотя там довольновсе все прозрачно). Хотя может алгоритмический...
Прикол заключается в том что такие глюки вылазиют только на VIA чипсете вылазиют еще ни одной мамы intel с таким глюком не наблюдалось.
Записан
Ochkarik
Модератор

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

« Ответ #17 : 21-03-2009 23:29 » 

про VIA ничего не могу сказать...  как сейчас не знаю, с раньше она мне доверия не внушала... мы исключительно асусом и интелом пользуемся...
мастер используем довольно давно... отладили и больше туда не лезем.
у с тех пор, с чем-чем а с передачей по шине проблем не было. хотя потоки до 30МБайт гоняли. памяти я что то около 2-8 Мб выделяю - тоже проблемм не было никогда ни на 2000 ни на XP.
долго мучались с корректной отработкой незавершенной транзакции по шине, но победили...

залипуха или отвалившаяся ножка по какой нибудь шине адреса PCI, - там же раздельные вроде? я почему подумал, мы на паре тестовых материнок расшатали PCI разъемы - стали биты данных пропадать. вроде все работает а в данных ошибки. потому и подумал что с шиной адреса впринципе то же самое может происходить.
какой нибуь  бит отвалился - и опа. работать будет только если этот бит в адресации не используется.
PS а вобще при выделении памяти все равно сегменты на 4к. так что можно и больше бит в сумматоре сэкономить)
« Последнее редактирование: 21-03-2009 23:31 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Skyf
Гость
« Ответ #18 : 22-03-2009 07:55 » 

Предположительно, ХРюша на определенных материнках хапает себе слишком много памяти из PCI региона. Проверь, сколько там. Похоже, что выходит за пределы смапированой памяти и попадает в простую, где нет железяки, поэтому и не выдает ошибок и адреса нормальные.
Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #19 : 23-03-2009 09:59 » 

В результате экспериментов мне добиться выделения памяти меньше адреса 0x40000 не вышло (после 0x5000 сразу 0x45000 по 0x40000К скачет) но и на этом адресе уже работает.

что касается GetDmaAlignment ()  она мне всегда 1 возвращает.  Что бы я в AlignmentRequirement не писал. Я так понял эта привелегия только дискам дана (запоминающим устройствам). Странно почему только им ? Так полезная в моем случае была бы.

resourceTrans->u.Memory.Start  и  resource->u.Memory.Start проверил они одинаковые.

в общем проблема решилась. А загадка осталась. Почему не нравится адрес 0x5000. Либо в системную область залазиет либо еще чо?  Здесь была моя ладья...  Как проверить незнаю  А черт его знает...

Всеравно спасибо за помощь.
Записан
Ochkarik
Модератор

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

« Ответ #20 : 23-03-2009 12:15 » 

кстати а счетчик адресов в железе у вас скольки разрядный? то бишь... 0x5000 это меньше 20кб, то бишь меньше окна 64к.
вы говорили сумматор использовали - может там что не так срослось?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
magbob
Интересующийся

ru
Offline Offline

« Ответ #21 : 23-03-2009 12:58 » 

Алгоритм таков адрес который выделяет система (BA) 31..6 складываю со смещением (SM) 31..6 где в смещении 31..16 всегда 0.
15..6 бит у меня счетчик щитает блоки по 64 байта. А 5..0 бит равны 0 (размер блока).
Записан
Skyf
Гость
« Ответ #22 : 23-03-2009 14:49 » 

Цитата
Почему не нравится адрес 0x5000.
ОС мапирует адреса. Для PCI региона выделяется определенный промежуток, который завязывается ан железо, в частности на системные регистры.
При выделении памяти за пределами, а я вполне верю, что мелкомягкие могут и не проверять наличие выхода за пределы региона, или, я просто сейчас не помню, ты не проверяешь валидность адреса, обращения к железу не происходит, а происходит вполне легитимная запись в память.

Записан
magbob
Интересующийся

ru
Offline Offline

« Ответ #23 : 23-03-2009 17:01 » 

Не совсем понял проверку валидности адреса. Какой адрес мне проверять на валидность Регистров? или DMA? - Так путем контрольных точек и просмотр дебагмонитора адреса остаются верными в смыли нигде я их случайно не теряю (Если это имеется ввиду)
И каким образом посмотреть диапазон этого PCI региона?
Записан
Ochkarik
Модератор

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

« Ответ #24 : 23-03-2009 19:25 » 

Skyf, вы перепутали)
речь идет о транзакциях DMA в режиме мастер.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Skyf
Гость
« Ответ #25 : 25-03-2009 08:18 » 

Ochkarik, Возможно. Но из описания понятно, что адреса валидны, внешне, но не работают с железом.
Да и DMA дескрипторы размещаются обычно в спец. регионах. Я не прав? Я давно в винде не писал.


magbob, посмотри, что за адреса ты используешь, максимальный размер своего контрольного PCI регистра.
Короче - стоит просмотреть все железо-зависимые параметра на PCI.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines