B1 Обработка исключений и простые операционные системы

После имплементации IOE следующим шагом мы реализуем CTE на NEMU и NPC. После имплементации мы сможем запускать операционные системы, которые уже нельзя назвать тривиальными!

Запуск RT-Thread в NEMU

Реализовать операции Trap в NEMU

Выполните фазу 1 PA3 в соответствии с конспектами лекций PA, пока не увидите следующий блок-подсказку:

Дружеское напоминание

Этап 1 PA3 заканчивается здесь.

Запустить RT-Thread в NEMU

Выполните фазу 1 PA4 в соответствии с конспектами лекций PA, пока RT-Thread не загрузится. Последующее содержимое, связанное с Nanos-lite, пока не требуется.

Добавление CSR в NPC

В RISC-V существует класс системных регистров, используемых для указания состояния процессора, называемых Control and Status Registers (CSR, регистры управления и состояния). В отличие от регистров общего назначения, обычные вычислительные инструкции не могут напрямую обращаться к CSR. Поэтому RISC-V также предоставляет CSR-инструкции для обмена данными между CSR и регистрами общего назначения. В отличие от обычных инструкций, CSR-инструкции атомно читают и записывают один и тот же CSR.

Адресное пространство CSR в RISC-V составляет 12 бит, то есть 4096 регистров, однако RISC-V определяет лишь немногим более 300 CSR; если исключить счётчики производительности и CSR, связанные с PMP (Physical Memory Protection, физическая защита памяти), останется только 78; если дополнительно учитывать только CSR M-mode, останется лишь 28; если же рассматривать только несколько CSR, необходимых для запуска RT-Thread и реализованных в NEMU, их будет меньше пяти. Поэтому нам нет необходимости инстанцировать сотни или даже 4096 CSR. Хотя для NEMU это заняло бы лишь некоторый объём памяти, для NPC это привело бы к значительным затратам площади. Конкретно, нам нужно инстанцировать только те CSR, которые нам необходимы, а затем читать и записывать их в соответствии с их адресами.

Первый CSR, который вам необходимо добавить, — это mcycle, счётчик, который увеличивается на 1 каждый такт. С его помощью мы можем преобразовать количество тактов во время на основе частоты процессора, тем самым реализовав функциональность AM, связанную с часами. Согласно руководству RISC-V, сам mcycle является 64-битным счётчиком. В RV32, поскольку ширина регистров общего назначения составляет 32 бита, для доступа этот счётчик необходимо разделить на два 32-битных CSR — mcycle и mcycleh.

Добавить mcycle

Конкретно, вам необходимо имплементировать инструкцию csrrs в NPC и добавить mcycle. Для этого вам нужно прочитать руководство по привилегированной архитектуре RISC-V и найти номера mcycle и mcycleh, а также другую информацию.

После имплементации попробуйте несколько раз прочитать регистр mcycle через inline assembly и проверьте, увеличивается ли его значение автоматически. В inline assembly можно использовать псевдоинструкцию csrr, соответствующей реальной инструкцией для которой является csrrs.

Чтобы различать NPC разных студентов, мы можем использовать идентификационные регистры в CSR. Конкретно, RISC-V определяет два CSR — mvendorid и marchid, которые мы можем использовать для хранения некоторой идентификационной информации. После этого программа во время выполнения может прочитать эту идентификационную информацию в регистры общего назначения через CSR-инструкции, а затем вывести её.

Добавить CSR с ID студента и вывести ID студента

Конкретно, вам необходимо реализовать инструкцию csrrs в NPC и добавить следующие два CSR:

  • mvendorid — при чтении должен возвращать ASCII-код ysyx, то есть 0x79737978
  • marchid — при чтении должен возвращать десятичное представление числовой части вашего ID студента. Предположим, что ваш ID студента — ysyx_22068888; если считать прочитанную информацию целым числом, она должна быть равна 22068888, то есть 0x150be98

После имплементации, до того как TRM войдёт в функцию main(), прочитайте значения двух вышеуказанных CSR через inline assembly, а затем выведите их через printf().

Запуск RT-Thread в NPC

С помощью AM мы можем запустить RT-Thread с очень небольшими затратами. Что касается аппаратной части, нам нужно реализовать лишь несколько CSR, несколько CSR-инструкций, инструкции ecall и mret, а также соответствующий механизм реакции на исключения. Вы уже познакомились с ними при имплементации NEMU. Здесь мы кратко обсудим, как реализовать их через RTL.

CSR, которые сейчас необходимо реализовать, не имеют каких-либо специальных побочных эффектов. Хотя руководство RISC-V описывает различные функции mstatus, в настоящее время нам не нужно их использовать. Нам достаточно правильно инициализировать их, чтобы пройти DiffTest.

В настоящее время мы можем игнорировать свойства чтения/записи в CSR (если вы о них не слышали, вам необходимо внимательно RTFM), включая WPRI, WLRL и WARL, которые определяют поведение при записи недопустимых значений в поля CSR. Программы, которые мы сейчас запускаем, не зависят от такого поведения, поэтому мы можем временно не реализовывать эти атрибуты чтения и записи.

И ecall, и mret заставляют NPC выполнить переход, что можно легко реализовать, повторно используя тракт данных логики следующего адреса.

В настоящее время нам необходимо реализовать только исключение ecall, которое является trap-исключением, на которое NPC должен реагировать безусловно. Нам достаточно одновременно установить mcause и mepc, а затем перейти по адресу входа в обработчик исключения, хранящемуся в mtvec.

Запустить RT-Thread в NPC

Реализуйте простой механизм обработки исключений в NPC и запустите RT-Thread.

Исправить проблему, из-за которой RT-Thread не выводит финальную командную строку

Вы заметите, что, в отличие от NEMU, при запуске RT-Thread на NPC финальная строка msh /> не выводится. Если вас интересует эта проблема, вы можете сейчас подумать о том, как её решить. Вы также можете проигнорировать эту проблему, поскольку позже, при подключении к SoC, вы столкнётесь с похожими проблемами.

Полный механизм обработки исключений в RISC-V значительно сложнее того, что мы сейчас реализуем, и коммерческие процессоры RISC-V должны точно реализовывать каждую деталь, описанную в руководстве, независимо от того, будут ли клиенты её использовать. Имплементация всех CSR и тщательная обработка каждого бита на самом деле является довольно инженерно-ориентированной задачей, требующей больших усилий со стороны инженерной команды. Однако «One Student One Chip» в конечном счёте является образовательным проектом, и его цель не состоит в разработке процессора RISC-V, соответствующего требованиям коммерческой поставки. Поэтому мы можем упрощать различные сложные механизмы при условии, что демонстрационные программы работают корректно, позволяя всем сосредоточиться на изучении ключевых принципов и разработке основных функций. По мере того как в будущем мы будем запускать больше программ на этапе A, мы постепенно будем добавлять различные CSR и их основные функции.

Подача заявки на итоговую аттестацию этапа C

Подача заявки на итоговую аттестацию этапа C

Поздравляем! Вы завершили всё содержимое этапа C. Вы можете подать заявку на итоговую аттестацию этапа C, чтобы проверить результаты своего обучения. Если вы успешно пройдёте аттестацию, мы выдадим вам сертификат.

Однако это не является обязательным. Вы можете продолжить обучение, но участвовать в tapeout-аттестации этапа B можно только после успешного прохождения итоговой аттестации этапа C.

SA