|
адресация pci |
|
|
|
Aug 30 2011, 05:17
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата Шина PCI использует 32-разрядную адресацию портов ввода-вывода. В фазе адреса задатчик указывает точный адрес младшего из байтов, к которому осуществляется обращение. Для передачи значащих байтов будут использоваться те линии AD, которые соответствуют положению этих байтов в двойном слове. Например, если выполняется чтение байта из порта 00001012h, то в фазе адреса будет задан именно этот адрес, а сам байт будет находиться на линиях AD[23:16], чему соответствует комбинация 1011 на линиях C/BE[3:0]#.
Линии разрешения байтов C/BE# должны соответствовать двум младшим разрядам адреса порта. Немного не понятно подскажите, Например мастеру нужно прочитать ввод вывод, мастер устанавливает frame, на C/BE команда 0010 на AD адрес и фронт такта, в следующих тактах C/BE указывает где расположен байт на линиях AD. Но если C/Be 0000 то байт будет на ad0-ad7 . тут написано Цитата Линии разрешения байтов C/BE# должны соответствовать двум младшим разрядам адреса порта ?
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 32)
|
Aug 31 2011, 06:41
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(vitan @ Aug 30 2011, 22:54)  CBE инверсные, младший байт надо по 1110 выдавать. Это да. Цитата Остальные отключены от шины, скорее всего будет 1, но не факт. Не отключены. Активное устройство обязанно драйвить все исходящие шины. Данные с этих разрядов AD использоваться не будут, но какие то данные там присуствовать должны.
|
|
|
|
|
Sep 4 2011, 15:51
|
не указал(а) ничего о себе.
     
Группа: Свой
Сообщений: 3 325
Регистрация: 6-04-06
Пользователь №: 15 887

|
Цитата(sergey sva @ Sep 4 2011, 15:52)  Еще вопрос , На моем ПК 5разъемов PCI, как устройство узнает в каком оно слоте если на ad0-1 всегда 0 оно же должно ответить сигналом adsel если адрес совпал? Не, ну нельзя же так мучить общественность... Ну почитайте же стандарт, он в открытом доступе. 1. Сигнал называеnся IDSEL, а не adsel 2. Ответить этим сигналом устройство не может, ибо это для него вход. 3. Метод генерации IDSEL может быть любым, но обычно реализуют предложенный в стандарте. Фактически устройство может знать только логический номер слота. Физическое его расположение оно никогда не узнает. В стандарте CompactPCI, например, для этого предусмотрены пины т.н. географического адреса (для общего развития).
|
|
|
|
|
Sep 4 2011, 16:11
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата Не, ну нельзя же так мучить общественность Ну я не специально разбираюсь с vhdl и PCI всего неделю. Цитата Сигнал называеnся IDSEL, а не adsel Отпечатка вышла. хотел написать devsel Сейчас бы хоть один пример запустить что бы можно было дальше разбираться, три примера прикрутил все собираются без ошибок заливаются, но комп не запускается после перезагрузки вентиляторы работают стартовый экран не появляется. Буду дальше разбираться.
Сообщение отредактировал sergey sva - Sep 4 2011, 19:16
|
|
|
|
|
Sep 4 2011, 19:11
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergey sva @ Sep 4 2011, 15:52)  Еще вопрос , На моем ПК 5разъемов PCI, как устройство узнает в каком оно слоте Устройство не должно интересовать в каком оно слоте. Равно как и сколько этих слотов вообще. Ваше устройство должно реагировать на адреса, прописанные в BARx ОС при инициализации PCI. ОС в процессе инициализации перебирает все устройства, какие найдет. Перебирает оно их по конфигурационному пространству, доступ к которому как раз и производится по географическому признаку (т.е. по номеру разъема, в вашем случае). Занимается этой адресацией PCI хаб, и если вы не пытаетесь разработать именно хаб, то способ как он это делает вас интересовать не должен
|
|
|
|
|
Sep 5 2011, 08:35
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergey sva @ Sep 4 2011, 23:32)  Номер шины это имеется ввиду через мосты , Ну если грубо, то да. Цитата если устройство включено через мост то 1 если через два то 2? Нет. Каждый мост в системе представляется шиной. Когда система сканирует конфигурацию PCI, она находит все мосты и присваивает им последовательные номера. Эти номера и будут номером шины. Цитата здесь написано про конфигурацию со стороны драйвера ? Про доступ к Config Space там написано со стороны ядра ОС. Драйвер обычно на такой уровень не спускается. ОС (точнее даже BIOS) самостоятельно находит все устройства на PCI шине, самостоятельно их настраивает и отдает драйверу каждого конкретного устройства уже в готовом к работе виде. Драйвер в регистры из Configuration Space уже обычно не обращается.
|
|
|
|
|
Sep 7 2011, 06:52
|
не указал(а) ничего о себе.
     
Группа: Свой
Сообщений: 3 325
Регистрация: 6-04-06
Пользователь №: 15 887

|
Цитата(sergey sva @ Sep 7 2011, 08:46)  Вычитал из книги Петрова вывод m66en должен соединяться с clk + резистор нагрузочный, его к земле присоединять, не совсем понимаю что здесь написано. Ух! Ржунимагупаццталом. Это в книжках нынче так пишут? Да еще и в таком олбанском стиле? Да, спасти этот мир тяжело... Для сегмента с поддержкой 66 МГц M66EN равен 1. Для сегмента 33 МГц- нулю. Сегмент - это несколько слотов, на которых пины M66EN соединены между собой. Читайте стандарт, не надо больше книжек..
|
|
|
|
|
Sep 7 2011, 10:46
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата Немного не понял как адресуется бар например для памяти? младшие байты 1-2указывают разрешение 64 или 32 , Биты, а не байты. Ставьте 32х битный BAR. Цитата а как адрес указать к примеру: в устройстве 16 регистров 32бита нужно что бы доступ к ним был с адреса 0xf0 и по 0xff. Не выйдет. Адреса будут всегда с 0 (относительно BAR'а) Если вам надо 16 регистров, то биты в BAR0 должны быть такими - 0,1 - RO - 01 (Насколько помню, т.е. memory/32bit) 2-6 - RO - 0 7-31 - RW В дешифраторе на вашем устройстве должны сравниваться биты адреса 7-31 с такими же битами BAR0 Цитата Что устройство должно записать BAR ? Устройство - ничего. Писать будет ОС (с PC)
|
|
|
|
|
Sep 7 2011, 11:29
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата Писать будет ОС (с PC) Система будет перебирать все адреса, например нужно прочитать 15й регистр? В устройстве дешифраторе должен ждать когда система запишет 15 в BAR (7-31)? Прочитал еще: система вначале сохраняет значение BAR после записывает туда FFFFFFFF после читает отбрасывает биты 0-3 и вычисляет адрес. Что то не пойму как это происходит.
Сообщение отредактировал sergey sva - Sep 7 2011, 11:41
|
|
|
|
|
Sep 7 2011, 12:07
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата Система будет перебирать все адреса, например нужно прочитать 15й регистр? Нет конечно Цитата В устройстве дешифраторе должен ждать когда система запишет 15 в BAR (7-31)? Тоже нет Цитата Что то не пойму как это происходит. Пример: Код Есть начало окна адресов для PCI. Пусть это будет 0xC0000000 (TOP) ОС находит ваше устройство, пишет 0xFFFFFFFF в ваш BAR0, читает, что получилось - 0xFFFFFF81 ОС получает размер окна, для регистров вашего устройства (число нулей в BAR0) - 128 байтов ОС выравнивает TOP на 128 байтов (ваш TOP уже выровнен) и записывает его в BAR0. Там теперь 0xC0000001 TOP смещается на 128 байтов - 0xC0000080 Теперь запись в 15 регистр (смещение регистра в BAR0 - 15*4 = 0x3C) Код ОС (драйвер) берет базу из образа вашего BAR0 (0xC0000000), который запомнен во внутренних структурах ОС, прибавляет смещение (результат 0xC000003C) и пишет по этому адресу 4х байтовое значение. В вашем устройстве ловится запись по адресу 0xC000003C, старшие биты адреса (32-7=25 битов) сравниваются с содержимым BAR0. Т.к. они совпадают, то устройство производит запись в регистр 15 (биты адреса 2-6).
|
|
|
|
|
Sep 8 2011, 05:02
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Понятно, не то что в книгах пишут)) Цитата Пусть это будет 0xC0000000 (TOP) Любой может быть ? Цитата что получилось - 0xFFFFFF81 Как посчитали ?
|
|
|
|
|
Sep 8 2011, 08:23
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergey sva @ Sep 8 2011, 09:02)  Любой может быть ? Это определит система Цитата Как посчитали ? Все разряды BAR0, которые RO намертво привязаны к константам и запись в них 1 игнорируется. Все разряды RW запишут 1, которая впоследствии и прочтется
|
|
|
|
|
Sep 8 2011, 08:42
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата RO намертво привязаны к константам и запись в них 1 игнорируется. Понятно, бит 0 1 2 служебные, а 3456 бит это количество доступных регистров. Остальные прочитаются как 1. немного не уловил, 0xFFFFFF81 это нужно сдвинуть на 128 байт? откуда 128получилось? Вот из книги, не пойму "а затем все значения увеличиваются на 1"
Сообщение отредактировал sergey sva - Sep 8 2011, 09:18
|
|
|
|
|
Oct 10 2011, 16:05
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Набросал функцию которая должна из прочитанного бара определять диапазон ,размер и тип. но пока не работает Помогите разобраться. Код TBarReg GetPciBar(uint8_t bus, uint8_t dev, uint8_t func,uint8_t barnum) { TBarReg barstr; uint32_t bartemp = PciReadConfigDWord(bus, dev, func, barnum); uint32_t baradrran = 0;
if(bartemp !=0){
if(bartemp&0x00000001){ baradrran = 7; for(uint32_t bari = 2; bari < 16; bari++ ){ if((bartemp>>bari)&0x00000001)break; baradrran = baradrran | (0x00000001<<bari);
}//end for barstr.Value = bartemp; barstr.RangeStart = ((bartemp>>2)<<2)&0x0000ffff; barstr.RangeEnd = baradrran | barstr.RangeStart; barstr.Size = barstr.RangeEnd - barstr.RangeStart; memcpy(barstr.TypeB,"P I/O",6);
}else{
baradrran = 0x0f; for(dword bari = 3; bari < 32; bari++ ){ if((bartemp>>bari)&0x00000001)break; baradrran = baradrran | (0x00000001<<bari);
}//end for barstr.Value = bartemp; barstr.RangeStart = (bartemp>>3)<<3; barstr.RangeEnd = baradrran | barstr.RangeStart; barstr.Size = barstr.RangeEnd-barstr.RangeStart; memcpy(barstr.TypeB,"MEMORY",6);
}//end else }else{ barstr.Value = 0; barstr.RangeStart = 0; barstr.RangeEnd = 0; barstr.Size = 0; memcpy(barstr.TypeB,"No BAR",6); }//end else bartemp != 0
return barstr; }//end GetPciBar //-------------------------------------------------------------------------------------------------//
|
|
|
|
|
Oct 11 2011, 05:46
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Вот в спецификации написано, в чем ошибся не соображу? Код Число старших битов, которые устройство фактически устанавливает, зависит от того, сколько адресного пространства устройство может адресовать. Устройство, которое хочет адресное пространство памяти 1 МБ (использующее 32-разрядный регистр базового адреса) должно сформировать старшие 12 битов адресного регистра, аппаратно другие биты установлены в 0. Программное обеспечение Включения питания может определять количество адресного пространства требуемое устройству для записи всех единиц в регистр и для чтения значений обратно. Устройство должно возвращать 0 во все незадействованные биты адреса , точно определяя требуемое адресное пространство. Эта конструкция предполагает, что все задействованное адресное пространство питается от двух источников и располагается линейно. Устройства могут задействовать больше адресного пространства чем требуется, но декодирование для 4КБ пространства Памяти и для 256-байтового ввода/вывода предложено для устройств, которые нуждаются в меньшем их количестве. Устройства, которые потребляют больше адресного пространства чем они используют, не требуются, чтобы ответить на неиспользуемую часть того адресного пространства.
|
|
|
|
|
Oct 11 2011, 09:32
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата в чем ошибся не соображу? Для того, что бы обнаружить биты в BAR регистре, которые можно установить, в них необходимо записать 1, а не надеяться на то, что она там будет сама по себе. Вы туда ничего не писали, соответственно все младшие нулевые биты адреса, которые туда записала ОС вы посчитали немодифицируемыми, а это не так Вот, что должно быть: Код uint32_t barorg = PciReadConfigDWord(bus, dev, func, barnum); PciWriteConfigDWord(bus, dev, func, barnum,-1); uint32_t bartemp = PciReadConfigDWord(bus, dev, func, barnum); PciWriteConfigDWord(bus, dev, func, barnum, barorg);
barstr.Value = barorg; barstr.RangeStart = barorg&~7; barstr.Size = -(bartemp&~7); barstr.RangeEnd = barstr.RangeStart+barstr.Size;
|
|
|
|
|
Oct 11 2011, 15:29
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Спасибо. переделал вроде правильно работает, Может еще что посоветуете? Код TBarReg GetPciBar(uint8_t bus, uint8_t dev, uint8_t func,uint8_t barnum) { TBarReg barstr; uint32_t BarReg1 = 0, BarReg2 = 0;
BarReg1 = PciReadConfigDWord(bus, dev, func, barnum); PciWriteConfigDWord(bus, dev, func, barnum,0xffffffff); BarReg2 = PciReadConfigDWord(bus, dev, func, barnum); PciWriteConfigDWord(bus, dev, func, barnum,BarReg1);
if(BarReg1!=0){
if(BarReg1&0x00000001){ BarReg2&=0x0000ffff; barstr.Value = BarReg1; barstr.RangeStart = BarReg2&~0x07; barstr.Size = 0x0000ffff-(BarReg2&~0x07); barstr.RangeEnd = barstr.RangeStart+barstr.Size; memcpy(barstr.TypeB,"P I/O",6);
}else{ barstr.Value = BarReg1; barstr.RangeStart = BarReg2&~0x0f; barstr.Size = 0xffffffff-(BarReg2&~0x07); barstr.RangeEnd = barstr.RangeStart+barstr.Size; memcpy(barstr.TypeB,"MEMORY",6);
}//end else }else{ barstr.Value = 0; barstr.RangeStart = 0; barstr.RangeEnd = 0; barstr.Size = 0; memcpy(barstr.TypeB,"No BAR",6); }//end else bartemp != 0
return barstr; }//end GetPciBar
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|