Сбой использования эмулятора c++ при вызове системного вызова printf из программы baremetal risc-v

Я работаю над проектом на базе инструментов Rocket-Chip. Я сделал простую программу для baremetal, которая хорошо работает на Spike (даже с несколькими ядрами и т. Д.).

Проблема в том, что когда я запускаю его в эмуляторе C++, последний останавливается при первом вызове printf.

Мой вопрос: можно ли вызывать системные вызовы (например, printf, putchar ..) из эмулятора C? Или есть способ распечатать результаты программы из симуляции, например, извлечь данные из памяти или что-то в этом роде? (Я боролся с этим, и я не нашел, где он сохраняет переменные данных).

PS: Программа основана на riscv-тесты / тесты, там уже определены системные вызовы.

Что такое Эмулятор C++?

user7860670 11.04.2018 12:12

Для чего нужен языковой тег C, если вы используете C++? Пожалуйста, не используйте несвязанные теги.

Gerhardh 11.04.2018 13:01

@VTT C++ Emulator - это симулятор CABA (с точностью до цикла), используемый для моделирования программного обеспечения с учетом вашего персонализированного оборудования. Spike - это просто функциональный симулятор, который не принимает во внимание ваше оборудование.

noureddine-as 11.04.2018 15:57

@Gerhardh, потому что эмулятор запрограммирован на C++, но программа, работающая на нем, находится на C.

noureddine-as 11.04.2018 15:57
0
4
504
1

Ответы 1

Is it possible to call syscalls (like printf, putchar ..) from the C Emulator?

Да, эти функции уже определены здесь в базе кода

Согласно базе кода, адрес данных указывается глобальной внешней переменной, с этого адреса вам нужно прочитать 4 индекса 64-битных данных

extern volatile uint64_t tohost;
extern volatile uint64_t fromhost;

printf(), putchar(), реализованный с использованием этого syscall

static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2)
{
  volatile uint64_t magic_mem[8] __attribute__((aligned(64)));
  magic_mem[0] = which;
  magic_mem[1] = arg0;
  magic_mem[2] = arg1;
  magic_mem[3] = arg2;
  __sync_synchronize();

  tohost = (uintptr_t)magic_mem;
  while (fromhost == 0)
    ;
  fromhost = 0;

  __sync_synchronize();
  return magic_mem[0];
}

Я знаю это. Я привел здесь небольшой пример: github.com/noureddine-as/riscv-baremetal-DefaultConfig Выполнение этого в эмуляторе правильно распечатывает приветственное сообщение. Затем я сделал еще один, но на этот раз он дает мне *** FAILED *** (tohost = 1337) *** FAILED *** via dtm (code = 1337, seed 1523460801) after 208588 cycles в эмуляторе C++, даже если он хорошо работает в моделировании Spike! Любая идея?

noureddine-as 11.04.2018 15:44

здесь размер массива uint64_t magic_mem[8] __attribute__((aligned(64))); - 8 * 8, так что возможно его переполнение приводит к сбою после цикла 208588

ntshetty 12.04.2018 03:36

Я решил это. Я заметил, что если я поставлю, например, printf("something"); без \ n, он не будет печататься в обоих случаях с pk или baremetal. Я не исследовал реальный источник, но думаю, это потому, что printf переопределен в системных вызовах, а я не использую стандартный. Более того, я предполагаю, что Спайк все еще ждет, пока \ n напечатает текст. Во всяком случае, теперь это работает. Я хотел бы знать @Thiru, как отлаживать программы с помощью Spike и особенно эмулятора C++?

noureddine-as 12.04.2018 09:11

Другие вопросы по теме