Перейти к содержанию
    

Чтение по PCIe в блочном режиме

День добрый коллеги. Разбираюсь с ядром от Xilinx'a pcie endpoint. Отладочная плата Kintex7. Подключил корку pcie. В режимах одиночной записи и чтения все работает. В блочном режиме работает только запись. Блочное чтение не работает. Т.е. от ЦП на плату идет запрос (прочитать 16 слов). Я по шине возвращаю ответ с правильными данными (подключил chip scope), но считываются все FF. Не могу понят в чем причина.

Рассматриваю сейчас все поля ответного заголовка (Completion Header Field) все вроде как правильно. Впрочем различие между блочным и одиночным чтением у меня заключается только в длине посылки, но и в описании на "Completion Header Field" нет такого признака как блочное чтение. В чем может быть причина. Для организации блочных режимов записи/чтения используется установки MSR регистров ЦП.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

День добрый коллеги. Разбираюсь с ядром от Xilinx'a pcie endpoint. Отладочная плата Kintex7. Подключил корку pcie. В режимах одиночной записи и чтения все работает. В блочном режиме работает только запись. Блочное чтение не работает. Т.е. от ЦП на плату идет запрос (прочитать 16 слов). Я по шине возвращаю ответ с правильными данными (подключил chip scope), но считываются все FF. Не могу понят в чем причина.

Рассматриваю сейчас все поля ответного заголовка (Completion Header Field) все вроде как правильно. Впрочем различие между блочным и одиночным чтением у меня заключается только в длине посылки, но и в описании на "Completion Header Field" нет такого признака как блочное чтение. В чем может быть причина. Для организации блочных режимов записи/чтения используется установки MSR регистров ЦП.

А какой чипсет? root complex умеет запрашивать больше 64 бит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой чипсет? root complex умеет запрашивать больше 64 бит?

 

Чипсет интеловский. Root complex умеет запрашивать больше 64 бит. Для этого необходимо включить режим write combining.

Я же вижу что на шине инициирован запрос чтения с длиной 16 32-х разрядных слов данных (поле length = 10 hex). Смотрю чипскопом интерфейс AXI-ST ядра PCIe.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покопался. Нашел у себя, что не правильно формирую поле "byte count".

 

Было (для одного слова все работает, соответственно это было и для 16-ти слов, что не корректно):

always @ (req_1st_be) // req_1st_be - поле "1st DW BE"

begin

casex (req_1st_be)

4'b1xx1 : byte_count = 12'h004;

4'b01x1 : byte_count = 12'h003;

4'b1x10 : byte_count = 12'h003;

4'b0011 : byte_count = 12'h002;

4'b0110 : byte_count = 12'h002;

4'b1100 : byte_count = 12'h002;

4'b0001 : byte_count = 12'h001;

4'b0010 : byte_count = 12'h001;

4'b0100 : byte_count = 12'h001;

4'b1000 : byte_count = 12'h001;

4'b0000 : byte_count = 12'h001;

endcase

end

 

Исправил (вроде все стало корректно для нескольких слов данных):

always @ (req_1st_be or req_last_be or req_len) // req_last_be - поле "Last DW BE", req_len - поле "Length".

begin

casex ({req_last_be, req_1st_be})

8'b00001xx1: byte_count = 4;

8'b000001x1: byte_count = 3;

8'b00001x10: byte_count = 3;

8'b00000011: byte_count = 2;

8'b00000110: byte_count = 2;

8'b00001100: byte_count = 2;

8'b00000001: byte_count = 1;

8'b00000010: byte_count = 1;

8'b00000100: byte_count = 1;

8'b00001000: byte_count = 1;

8'b00000000: byte_count = 1;

8'b1xxxxxx1: byte_count = req_len << 2;

8'b01xxxxx1: byte_count = (req_len << 2) - 1;

8'b001xxxx1: byte_count = (req_len << 2) - 2;

8'b0001xxx1: byte_count = (req_len << 2) - 3;

8'b1xxxxx10: byte_count = (req_len << 2) - 1;

8'b01xxxx10: byte_count = (req_len << 2) - 2;

8'b001xxx10: byte_count = (req_len << 2) - 3;

8'b0001xx10: byte_count = (req_len << 2) - 4;

8'b1xxxx100: byte_count = (req_len << 2) - 2;

8'b01xxx100: byte_count = (req_len << 2) - 3;

8'b001xx100: byte_count = (req_len << 2) - 4;

8'b0001x100: byte_count = (req_len << 2) - 5;

8'b1xxx1000: byte_count = (req_len << 2) - 3;

8'b01xx1000: byte_count = (req_len << 2) - 4;

8'b001x1000: byte_count = (req_len << 2) - 5;

8'b00011000: byte_count = (req_len << 2) - 6;

default: byte_count = 12'h000;

endcase

end

 

Ниже привожу по циклам значения на шинах (взял из ChipScope):

 

Request Header Fields:

1. rx_data[63:0] = 64'h000011FF_00000010 // Requester ID = 16'h0000; Tag = 8'h11; Last BE = 4'hF; 1st BE = 4'hF; Fmt,Type = 7'd0 (запрос чтения в 32-х битном адресном пр.); Length = 10'h10 (16 СД); остальные поля - 0

2. rx_data[63:0] = 64'hE1853C29_FE9F8000 // 1-ое СД - мусор; FE9F8000 - адрес нашего бара (32 к).

 

Completion Header Fields (я формирую):

1. tx_data[63:0] = 64'h01000040_4A000010 // cfg_completer_id = 16'h0100; byte_count = 12'h40 (64 байта); Fmt,Type = 7'h4A (завершение обмена с данными - CplD); Length = 10'h10 (16 СД); остальные поля - 0

2. tx_data[63:0] = 64'h78563412_00001100 // Requester ID = 16'h0000; Tag = 8'h11; остальные поля - 0

 

Вроде все как нормально. С одним словом все проходит, т.е. вроде в разных полях cfg_completer_id, Requester ID и т.д. ошибок нет. Но что-то не хватает.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте, а можете поподробнее расписать, как вы заставляете ЦП работать в блочных режимах записи/чтения.

Три года назад писали драйвер под линукс, ЦП был интеловский. Программист, который за это отвечал, уверял, что блочная запись/чтения со стороны ЦП нереализуема, пришлось городить DMA-контроллер на стороне ПЛИС.

 

Для этого необходимо включить режим write combining.

Какими функциями это делается, что почитать порекомендуете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте, а можете поподробнее расписать, как вы заставляете ЦП работать в блочных режимах записи/чтения.

Три года назад писали драйвер под линукс, ЦП был интеловский. Программист, который за это отвечал, уверял, что блочная запись/чтения со стороны ЦП нереализуема, пришлось городить DMA-контроллер на стороне ПЛИС.

 

 

Какими функциями это делается, что почитать порекомендуете?

 

Здравствуйте. Сегодня не на работе и я занимаюсь только ПЛИС (железом). Завтра попрошу программиста описать подробнее механизм инициализации от ЦП блочного режима.

Сейчас могу лишь сказать что максимальная длина посылки определяется строкой кэша (в нашем случае это 64 байта - для интеловского чипсета). И используются пара регистров MTRR в режимах write back, write combining. Еще раз повторюсь подробности завтра (от программиста).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... подробности завтра (от программиста).

 

Все же хочется узнать подробности

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...