|
адресация 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# должны соответствовать двум младшим разрядам адреса порта ?
|
|
|
|
|
 |
Ответов
(15 - 29)
|
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 //-------------------------------------------------------------------------------------------------//
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|