os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

boot.c (2984B)


      1 // Copyright 2022, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0
      3 
      4 #include <hw/riscv.h>
      5 #include <hw/context.h>
      6 #include <hw/intrinsics.h>
      7 #include <hw/debug.h>
      8 
      9 #include <hw/platform.h>
     10 #include <hw/litex.h>
     11 
     12 #include <string.h>
     13 
     14 #include "boot.h"
     15 
     16 eframe_t *EF;
     17 volatile int STOP = 0;
     18 
     19 // we expect the supervisor program to be in memory after the end of the bootloader
     20 #define SVC_ENTRY (DRAM_BASE + BOOTLOADER_SIZE)
     21 
     22 
     23 #define uart_rd(a) io_rd32(UART0_BASE + LX_UART_ ## a)
     24 #define uart_wr(a,v) io_wr32(UART0_BASE + LX_UART_ ## a, v)
     25 
     26 static char cmdbuf[128];
     27 static unsigned cmdlen = 0;
     28 
     29 void console_char(uint32_t ch) {
     30 	if ((ch == '\r') || (ch == '\n')) {
     31 		xputs("\r\n");
     32 		cmdbuf[cmdlen] = 0;
     33 		// rd32safe, rd8safe modify MTVEC/MSTATUS
     34 		// ensure they're saved and restored here
     35 		uint32_t status = csr_read(CSR_MSTATUS);
     36 		console_line(cmdbuf);
     37 		csr_write(CSR_MSTATUS, status);
     38 		csr_write(CSR_MTVEC, ((uintptr_t) mach_exception_entry) );
     39 		cmdlen = 0;
     40 		return;
     41 	}
     42 	if ((ch == 8) || (ch == 127)) {
     43 		if (cmdlen > 0) {
     44 			xputs("\x08 \x08");
     45 			cmdlen--;
     46 		} else {
     47 			xputc(7);
     48 		}
     49 		return;
     50 	}
     51 	if ((ch < ' ') || (ch > 127)) {
     52 		return;
     53 	}
     54 	if (cmdlen == (sizeof(cmdbuf) - 1)) {
     55 		xputc(7);
     56 		return;
     57 	}
     58 	cmdbuf[cmdlen++] = ch;
     59 	xputc(ch);
     60 }
     61 
     62 void mach_exception_handler(eframe_t *ef) {
     63 	uint32_t cause = csr_read(CSR_MCAUSE);
     64 
     65 	if (cause == 0x8000000b) {
     66 		EF = ef;
     67 		do {
     68 			while (uart_rd(RXEMPTY) == 0) {
     69 				unsigned ch = uart_rd(RX);
     70 				uart_wr(EV_PENDING, LX_UART_EVb_RX);
     71 				console_char(ch);
     72 			}
     73 		} while (STOP);
     74 		return;
     75 	}
     76 
     77 	xprintf("\n** MACHINE EXCEPTION **\n");
     78 	xprint_m_exception(ef);
     79 	xprintf("\nHALT\n");
     80 	for (;;) ;
     81 }
     82 
     83 // interrupts and exceptions to delegate to supervisor mode
     84 #define INT_LIST (INTb_SVC_SW|INTb_SVC_TIMER|INTb_SVC_EXTERN)
     85 //#define EXC_LIST (EXCb_ECALL_UMODE)
     86 #define EXC_LIST (0xFFFF)
     87 
     88 void start(uint32_t hartid, uint32_t fdt) {
     89 	xprintf("\n** Frobozz Magic Bootloader v0.2 **\n\n");
     90 
     91 	int qemu = (csr_read(CSR_MVENDORID) == 0);
     92 
     93 	// set mach exception vector and stack pointer
     94 	csr_write(CSR_MTVEC, ((uintptr_t) mach_exception_entry) );
     95 
     96 	// use the free ram below the supervisor entry as our exception stack
     97 	csr_write(CSR_MSCRATCH, SVC_ENTRY);
     98 
     99 	// QEMU currently emulates memory protection, which we must appease
    100 	if (qemu) {
    101 		// U/S allow access to all memory
    102 		csr_write(CSR_PMPCFG(0), PMP_CFG_A_TOR | PMP_CFG_X | PMP_CFG_W | PMP_CFG_R);
    103 		csr_write(CSR_PMPADDR(0), 0xFFFFFFFF);
    104 	}
    105 
    106 	// delegate interrupts and exceptions
    107 	csr_set(CSR_MIDELEG, INT_LIST);
    108 	csr_set(CSR_MEDELEG, EXC_LIST);
    109 
    110 	// set previous status to S_MODE, previous interrupt status ENABLED
    111 	csr_write(CSR_MSTATUS, (PRIV_S << MSTATUS_MPP_SHIFT) | MSTATUS_MPIE);
    112 
    113 	xprintf("SVC ENTRY @0x%08x\n\n", SVC_ENTRY);
    114 
    115 	uart_wr(EV_ENABLE, LX_UART_EVb_RX);
    116 	uart_wr(EV_PENDING, LX_UART_EVb_RX);
    117 	csr_write(CSR_M_INTC_ENABLE, UART0_IRQb);
    118 	csr_set(CSR_MIE, INTb_MACH_EXTERN);
    119 
    120 	exit_mode_m(hartid, fdt, SVC_ENTRY, 0);
    121 
    122 }
    123