riscv-software-src / riscv-pk

RISC-V Proxy Kernel
Other
570 stars 304 forks source link

hart_init should call first, avoid the risk of illegal instructions caused by unset mstatus. #284

Open yorange1 opened 1 year ago

yorange1 commented 1 year ago

Hello, I noticed that in the init_first_hart function, the hart_init function is after some Confirm console functions and start printing.

void init_first_hart(uintptr_t hartid, uintptr_t dtb)
{
  // Confirm console as early as possible
  query_uart(dtb);
  query_uart16550(dtb);
  query_uart_litex(dtb);
  query_htif(dtb);
  printm("bbl loader\r\n");

  hart_init();
  hls_init(0); // this might get called again from parse_config_string
. ...

And the mstatus register is set in hart_init, such as the VS and FS flag bits,which may cause the v-extended instruction in the code before the hart_init function to be recognized as an illegal instruction.

void query_uart(uintptr_t fdt)
{
  struct fdt_cb cb;
  struct uart_scan scan;

  memset(&cb, 0, sizeof(cb));
  cb.open = uart_open;
  cb.prop = uart_prop;
  cb.done = uart_done;
  cb.extra = &scan;

  fdt_scan(fdt, &cb);
}

For example, the memset function has a high probability of compiling with v-extended instructions. (Actually, this has happened to me).

Therefore, I think it is necessary to call the hart_init function first to ensure that the mstatus register can be set in time.