Jump to content

    
Sign in to follow this  
Ykidia

Адрес вектора прерываний в MIPS32r1, а именно, в изделиях ГУП НПЦ "Элвис"

Recommended Posts

Здравствуйте!

Имеем 1892ВМ8Я-подобный процессор (далее - "Процессор", паникеры попросили скрыть название, хотя упоминаний о нем полно, например, тут, стр.5). Дизайн по портам для внешней памяти следующий: CSCON0/1 - управление ПЛИСами; CSCON2 - flash-память, банк 0; CSCON3 - PROM (адреса 0xBFC00000-0xBFC07FFF); CSCON4 - flash-память, банк 1.

Flash-память NAND, Micron-MT29F4G16ABBDAH4-IT. Доступ при обмене ведется по одному адресу (любому со старшим байтом, указанным в CSCON2), микросхема сдвоенная, подключена так, что банк 0 выбирается сигналом nCS2 с Процессора, а банк 1 - сигналом nCS4. RE и WE подключены надлежащим образом, как и шина данных и все остальное.

Проблема с Процессором (1892ВМ8Я-подобный, паникеры попросили скрыть название): сигнал nCS4 формируется не так, как все остальные, в частности, nCS2; итог - если в момент операции PageRead (постоянное чтение по адресу, получаемому из CSCON2) происходит прерывание, итоговые прочитанные данные из страницы банка 1 flash-памяти - битые.

Причем с записью страницы таких проблем не наблюдается.

Много лет не могли понять, в чем дело, научились лишь экранироваться от проблемы, например: в прерывании увеличивается простой счетчик, запоминаем его состояние до чтения страницы, сравниваем после чтения страницы, если счетчик разный - данные скорее всего "битые", необходимо повторить операцию чтения. Запрет прерываний на время чтения страницы - не вариант, в этот момент может идти командный обмен по UART, размера FIFO не хватает, чтобы, в общем случае, сделать прерывания от UART достаточно редкими, чтобы, опять же, можно было позволить себе запрещать прерывания на все время чтения страницы.

При этом с банком, подключенным к nCS2 (банк 0), такой проблемы не возникает. А еще, раньше была другая NAND (совместимая по интерфейсу), а проблема - та же.

В итоге выяснили, в чем дело, точнее, что же так выборочно мешает работе с устройством через nCS4:
1) возникает прерывание;
2) происходит переход по вектору прерываний, находящемуся по адресу 0xBFC00380 (бит ST_BEV в регистре C0_STATUS всегда установлен);
3) выбирается порт 3, активируется сигнал nCS3, выбирая PROM;
4) сигнал nCS4 (да и любой другой) при этом деактивируется;
5) выполняется сохранение регистров, настройка стека и вызов основной процедуры обслуживания прерываний;
6) далее процедура обслуживания прерывания может выполняться и не в PROM, но возврат из этой процедуры означает возврат в PROM с активацией nCS3 вплоть до самого последнего "вздоха" прерывания (eret; nop);
7) дальнейшее первое после прерывания чтение по адресам flash-памяти (бит 20 "E" регистра CSCON2 равен 0) активирует nCS4, но что-то идет не так, получаем мусорный байт.

Waitstates для всех (кроме PROM) = 15, т.е. максимум. Пробовали меньше - подозрительно возрастает и количество ошибок, причем flash-память современная, быстрая.

Процессор работает на рекомендуемой частоте 80 МГц. Кеширование везде отключено, операционки, само собой, никакой нет, голый bare metal.

О чем думали/пробовали:
1) перед каждым чтением байта делали запрет прерываний и небольшую паузу перед непосредственно чтением байта (после чтения, разумеется, разрешение прерываний) - не помогло;
2) холостую запись перед непосредственно чтением - не помогло;
3) снижали частоту процессора до 20 МГц - не помогло;
4) меняли старшие байты адресов - не помогло (только временно добавилось проблем, когда профукали момент с кешированием);
5) куча других workaround-ов, от самых дебилоидных до заумных - толку мало;
6) на данный момент самый рабочий workaround - вышеописанный: если в момент чтения данных из страницы произошло прерывание, перечитываем страницу заново;
7) хотели избавиться от перехода в PROM по прерыванию перемещением вектора прерываний, но выбор тут невелик: либо в PROM (0xBFC00xxx), либо внешняя память (0x80000xxx), на которую, во-первых, уже нет свободных портов для внешней памяти, во-вторых, ее нет, и в-третьих, менять схемотехнику никто уже не будет (тем более когда есть более-менее рабочий workaround), даже перепаивать проводки, чтобы переиграть nCS-ы, никто не даст.
8) была мысль использовать бит TR_CRAM регистра CSR, если установить его в 1, а ST_BEV (регистр C0_STATUS) в 0, тогда базой для вектора прерываний может быть 0xB8000000, что нас более чем устроило бы. Но, несмотря на то, что бит TR_CRAM записывается и читается (вопреки документации на конкретно используемый Процессор), также несмотря на то, что в документации на другие аналогичные процессоры данный бит описан, а также есть примеры от "Элвиса", оперирующие данным битом, с перечислением в комментариях процессоров, для которых работают эти примеры, в т.ч. и для тех, где этот чертов бит не документирован; несмотря на все это, запустить обработчик из 0xB8000180 не удалось, т.к. судя по всему происходит переход на 0x80000180, т.е. бит TR_CRAM не учитывается.
9) есть мысль выход из прерывания делать не стандартным возвратом (и попаданием в PROM для восстановления регистров), а производить все необходимые действия "на месте", что есть небольшой изврат, но что делать;
10) тут уже немного подзабыл, не уверен, пробовали ли или нет - комбинирование методов 1 и 2;
11) перелопачивали программу и меняли логические банки местами, также комбинировали nCS4 с другими портами (0 и 1) - проблема стабильна и всегда указывает на nCS4;
12) небольшое подозрение на waistates для PROM - он отличается от стандартных 15-ти и равен 6;
13) кеширование везде отключено, кроме всего прочего, сегмент kseg1 - не кешируемый. Режим адресации - FM, думали сначала при помощи TLB решить проблему, так ведь нет - сегменты kseg0 и kseg1 еще и unmapped! Обложили, демоны...

Проблемы в коде и настройках - предлагаю рассчитывать на это в последнюю очередь.

Прошу всех тех, кто сумел все это прочитать и понять... Я описывал так много и долго лишь затем, чтобы проблема была ясна.

Пожалуйста, кто сталкивался или просто знает об особенностях данных изделий "Элвиса", прошу, ответьте мне вопросы, кто на какие сможет:
1) Возможно ли использование бита TR_CRAM? Да, в документации на Процессор его нет, и повторять это мне не нужно, прошу! Но ситуацию с документированием этого бита я описал выше. За наличие этого бита говорит все - и возможность его записи, вопреки той же документации, в которой его нет; и в принципе домыслы, что вряд ли менялись ревизии процессоров, тем более, что по документации у всех C0_PRID - одинаковый! Если этот бит есть, каков порядок его использования? Может, я что-то упустил, может, кроме ST_BEV в C0_STATUS нужен еще и IV в C0_CAUSE?
2) Можно ли как-то вручную заполнить кэш для kseg0, чтобы выполнялись нужные команды из этого кэша и обращений к физической памяти не происходило вообще (напоминаю, речь о kseg0, который всегда отображается на базовый адрес 0x00000000)?
3) Можно ли то же самое (п.2) проделать для адресов kseg1? В документации на тот же регистр CSR есть бит 11 "TST_CACHE" - что конкретно он делает?
4) Что еще можно сделать с настройкой nCS4?

Большое спасибо, что осилили все это. Пожалуйста, помогите!

Share this post


Link to post
Share on other sites

Только что попробовали пп.9/10:

2 hours ago, Ykidia said:

9) есть мысль выход из прерывания делать не стандартным возвратом (и попаданием в PROM для восстановления регистров), а производить все необходимые действия "на месте", что есть небольшой изврат, но что делать;
10) тут уже немного подзабыл, не уверен, пробовали ли или нет - комбинирование методов 1 и 2;

Не помогло. Т.е. просто сам факт деактивации nCS4 портит дальнейшую работу с этим портом (предположительно, какая-то рассинхронизация на одно чтение), даже если после этого факта заранее активировать nCS4 перед чтением.

Остается лишь заигрывание с тем, что мало - или совсем не - задокументировано.

Share this post


Link to post
Share on other sites

А с Элвисом связывались по этому поводу? Были похожие проблемы с НИИСИ, они промоделировали тест на симуляторе, удалось разобраться (у меня была проблема с настройкой кеша в программе).

Share this post


Link to post
Share on other sites

Связывались по разным техническим вопросам. Но, выискивая ответы на свои вопросы в сети Интернет (это зачастую гораздо быстрее и точнее, нежели ждать ответа конкретной техподдержки) внезапно наткнулся тут на смежную тему, и понял, что "Элвис" на этом форуме тоже тусуется, так что вопросы, озвученные здесь, "отработают" не хуже, чем если писать производителю (и еще дополнительно "продираться" сквозь то, что уже и так известно и, главное, уже обозначено в вопросе). Это не камень в огород техподдержки производителя; насколько я понял, здесь есть и другие люди, набившие себе шишки при работе с конкретными изделиями, а также есть и еще люди, отлично знающие MIPS в различных исполнениях; так что эта тема здесь - попытка сразу собрать больше информации, пусть не всегда точной, пусть косвенной и т.д., но ценной.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this