diff options
Diffstat (limited to 'bbl')
-rw-r--r-- | bbl/bbl.ac | 8 | ||||
-rw-r--r-- | bbl/bbl.c | 97 | ||||
-rw-r--r-- | bbl/bbl.h | 8 | ||||
-rw-r--r-- | bbl/bbl.lds | 5 | ||||
-rw-r--r-- | bbl/bbl.mk.in | 12 | ||||
-rw-r--r-- | bbl/kernel_elf.c | 54 | ||||
-rw-r--r-- | bbl/logo.c | 25 | ||||
-rw-r--r-- | bbl/payload.S | 10 | ||||
-rw-r--r-- | bbl/raw_logo.S | 7 | ||||
-rw-r--r-- | bbl/riscv_logo.txt | 23 |
10 files changed, 100 insertions, 149 deletions
@@ -1,8 +1,12 @@ -AC_ARG_ENABLE([logo], AS_HELP_STRING([--disable-logo], [Disable boot logo])) -AS_IF([test "x$enable_logo" != "xno"], [ +AC_ARG_ENABLE([logo], AS_HELP_STRING([--enable-logo], [Enable boot logo])) +AS_IF([test "x$enable_logo" == "xyes"], [ AC_DEFINE([PK_ENABLE_LOGO],,[Define if the RISC-V logo is to be displayed]) ]) AC_ARG_WITH([payload], AS_HELP_STRING([--with-payload], [Set ELF payload for bbl]), [AC_SUBST([BBL_PAYLOAD], $with_payload, [Kernel payload for bbl])], [AC_SUBST([BBL_PAYLOAD], [dummy_payload], [Kernel payload for bbl])]) + +AC_ARG_WITH([logo], AS_HELP_STRING([--with-logo], [Specify a better logo]), + [AC_SUBST([BBL_LOGO_FILE], $with_logo, [Logo for bbl])], + [AC_SUBST([BBL_LOGO_FILE], [riscv_logo.txt], [Logo for bbl])]) @@ -4,73 +4,64 @@ #include "vm.h" #include "bits.h" #include "config.h" +#include "fdt.h" #include <string.h> -static kernel_elf_info info; -static volatile int elf_loaded; +static const void* entry_point; +long disabled_hart_mask; -static void supervisor_vm_init() +static uintptr_t dtb_output() { - uintptr_t highest_va = DRAM_BASE - first_free_paddr; - mem_size = MIN(mem_size, highest_va - info.first_user_vaddr) & -MEGAPAGE_SIZE; + extern char _payload_end; + uintptr_t end = (uintptr_t) &_payload_end; + return (end + MEGAPAGE_SIZE - 1) / MEGAPAGE_SIZE * MEGAPAGE_SIZE; +} - pte_t* sbi_pt = (pte_t*)(info.first_vaddr_after_user + info.load_offset); - memset(sbi_pt, 0, RISCV_PGSIZE); - pte_t* middle_pt = (void*)sbi_pt + RISCV_PGSIZE; -#if __riscv_xlen == 32 - size_t num_middle_pts = 1; - pte_t* root_pt = middle_pt; - memset(root_pt, 0, RISCV_PGSIZE); -#else - size_t num_middle_pts = (-info.first_user_vaddr - 1) / GIGAPAGE_SIZE + 1; - pte_t* root_pt = (void*)middle_pt + num_middle_pts * RISCV_PGSIZE; - memset(middle_pt, 0, (num_middle_pts + 1) * RISCV_PGSIZE); - for (size_t i = 0; i < num_middle_pts; i++) - root_pt[(1<<RISCV_PGLEVEL_BITS)-num_middle_pts+i] = ptd_create(((uintptr_t)middle_pt >> RISCV_PGSHIFT) + i); -#endif +static void filter_dtb(uintptr_t source) +{ + uintptr_t dest = dtb_output(); + uint32_t size = fdt_size(source); + memcpy((void*)dest, (void*)source, size); - for (uintptr_t vaddr = info.first_user_vaddr, paddr = vaddr + info.load_offset, end = info.first_vaddr_after_user; - paddr < DRAM_BASE + mem_size; vaddr += MEGAPAGE_SIZE, paddr += MEGAPAGE_SIZE) { - int l2_shift = RISCV_PGLEVEL_BITS + RISCV_PGSHIFT; - size_t l2_idx = (info.first_user_vaddr >> l2_shift) & ((1 << RISCV_PGLEVEL_BITS)-1); - l2_idx += ((vaddr - info.first_user_vaddr) >> l2_shift); - middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT, PTE_G | PTE_R | PTE_W | PTE_X); - } + // Remove information from the chained FDT + filter_harts(dest, &disabled_hart_mask); + filter_plic(dest); + filter_compat(dest, "riscv,clint0"); + filter_compat(dest, "riscv,debug-013"); +} + +void boot_other_hart(uintptr_t unused __attribute__((unused))) +{ + const void* entry; + do { + entry = entry_point; + mb(); + } while (!entry); - // map SBI at top of vaddr space - extern char _sbi_end; - uintptr_t num_sbi_pages = ((uintptr_t)&_sbi_end - DRAM_BASE - 1) / RISCV_PGSIZE + 1; - assert(num_sbi_pages <= (1 << RISCV_PGLEVEL_BITS)); - for (uintptr_t i = 0; i < num_sbi_pages; i++) { - uintptr_t idx = (1 << RISCV_PGLEVEL_BITS) - num_sbi_pages + i; - sbi_pt[idx] = pte_create((DRAM_BASE / RISCV_PGSIZE) + i, PTE_G | PTE_R | PTE_X); + long hartid = read_csr(mhartid); + if ((1 << hartid) & disabled_hart_mask) { + while (1) { + __asm__ volatile("wfi"); +#ifdef __riscv_div + __asm__ volatile("div x0, x0, x0"); +#endif + } } - pte_t* sbi_pte = middle_pt + ((num_middle_pts << RISCV_PGLEVEL_BITS)-1); - assert(!*sbi_pte); - *sbi_pte = ptd_create((uintptr_t)sbi_pt >> RISCV_PGSHIFT); - mb(); - root_page_table = root_pt; - write_csr(sptbr, (uintptr_t)root_pt >> RISCV_PGSHIFT); + enter_supervisor_mode(entry, hartid, dtb_output()); } -void boot_loader() +void boot_loader(uintptr_t dtb) { - extern char _payload_start, _payload_end; - load_kernel_elf(&_payload_start, &_payload_end - &_payload_start, &info); - supervisor_vm_init(); + extern char _payload_start; + filter_dtb(dtb); #ifdef PK_ENABLE_LOGO print_logo(); #endif +#ifdef PK_PRINT_DEVICE_TREE + fdt_print(dtb_output()); +#endif mb(); - elf_loaded = 1; - enter_supervisor_mode((void *)info.entry, 0); -} - -void boot_other_hart() -{ - while (!elf_loaded) - ; - mb(); - enter_supervisor_mode((void *)info.entry, 0); + entry_point = &_payload_start; + boot_other_hart(0); } @@ -8,14 +8,6 @@ #include <stdint.h> #include <stddef.h> -typedef struct { - uintptr_t entry; - uintptr_t first_user_vaddr; - uintptr_t first_vaddr_after_user; - uintptr_t load_offset; -} kernel_elf_info; - -void load_kernel_elf(void* blob, size_t size, kernel_elf_info* info); void print_logo(); #endif // !__ASSEMBLER__ diff --git a/bbl/bbl.lds b/bbl/bbl.lds index 6833e47..2fd0d7c 100644 --- a/bbl/bbl.lds +++ b/bbl/bbl.lds @@ -44,9 +44,10 @@ SECTIONS /* HTIF, isolated onto separate page */ /*--------------------------------------------------------------------*/ . = ALIGN(0x1000); - htif : + .htif : { - *(htif) + PROVIDE( __htif_base = .); + *(.htif) } . = ALIGN(0x1000); diff --git a/bbl/bbl.mk.in b/bbl/bbl.mk.in index 1bb4cd1..2bc96e1 100644 --- a/bbl/bbl.mk.in +++ b/bbl/bbl.mk.in @@ -8,13 +8,21 @@ bbl_hdrs = \ bbl.h \ bbl_c_srcs = \ - kernel_elf.c \ logo.c \ bbl_asm_srcs = \ payload.S \ + raw_logo.S \ -payload.o: $(bbl_payload) +payload.o: bbl_payload + +bbl_payload: $(BBL_PAYLOAD) + if $(READELF) -h $< 2> /dev/null > /dev/null; then $(OBJCOPY) -O binary $< $@; else cp $< $@; fi + +raw_logo.o: bbl_logo_file + +bbl_logo_file: @BBL_LOGO_FILE@ + cat $^ | sed 's/$$/\r/' > $@ bbl_test_srcs = diff --git a/bbl/kernel_elf.c b/bbl/kernel_elf.c deleted file mode 100644 index e22c35c..0000000 --- a/bbl/kernel_elf.c +++ /dev/null @@ -1,54 +0,0 @@ -// See LICENSE for license details. - -#include "mtrap.h" -#include "bbl.h" -#include "bits.h" -#include "vm.h" -#include <elf.h> -#include <string.h> - -void load_kernel_elf(void* blob, size_t size, kernel_elf_info* info) -{ - Elf_Ehdr* eh = blob; - if (sizeof(*eh) > size || - !(eh->e_ident[0] == '\177' && eh->e_ident[1] == 'E' && - eh->e_ident[2] == 'L' && eh->e_ident[3] == 'F')) - goto fail; - - if (IS_ELF64(*eh) != (sizeof(uintptr_t) == 8)) - goto fail; - - uintptr_t min_vaddr = -1, max_vaddr = 0; - size_t phdr_size = eh->e_phnum * sizeof(Elf_Ehdr); - Elf_Phdr* ph = blob + eh->e_phoff; - if (eh->e_phoff + phdr_size > size) - goto fail; - first_free_paddr = ROUNDUP(first_free_paddr, MEGAPAGE_SIZE); - for (int i = 0; i < eh->e_phnum; i++) - if (ph[i].p_type == PT_LOAD && ph[i].p_memsz && ph[i].p_vaddr < min_vaddr) - min_vaddr = ph[i].p_vaddr; - min_vaddr = ROUNDDOWN(min_vaddr, MEGAPAGE_SIZE); - uintptr_t bias = first_free_paddr - min_vaddr; - for (int i = eh->e_phnum - 1; i >= 0; i--) { - if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { - uintptr_t prepad = ph[i].p_vaddr % RISCV_PGSIZE; - uintptr_t vaddr = ph[i].p_vaddr + bias; - if (vaddr + ph[i].p_memsz > max_vaddr) - max_vaddr = vaddr + ph[i].p_memsz; - if (ph[i].p_offset + ph[i].p_filesz > size) - goto fail; - memcpy((void*)vaddr, blob + ph[i].p_offset, ph[i].p_filesz); - memset((void*)vaddr - prepad, 0, prepad); - memset((void*)vaddr + ph[i].p_filesz, 0, ph[i].p_memsz - ph[i].p_filesz); - } - } - - info->entry = eh->e_entry; - info->load_offset = bias; - info->first_user_vaddr = min_vaddr; - info->first_vaddr_after_user = ROUNDUP(max_vaddr - bias, RISCV_PGSIZE); - return; - -fail: - die("failed to load payload"); -} @@ -1,30 +1,7 @@ #include <string.h> #include "mtrap.h" -static const char logo[] = -" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" -" vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv\n" -"rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv \n" -"rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv \n" -"rr vvvvvvvvvvvvvvvvvvvvvv \n" -"rr vvvvvvvvvvvvvvvvvvvvvvvv rr\n" -"rrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrr\n" -"rrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrr\n" -"rrrrrrrr vvvvvvvvvvvvvvvvvv rrrrrrrr\n" -"rrrrrrrrrr vvvvvvvvvvvvvv rrrrrrrrrr\n" -"rrrrrrrrrrrr vvvvvvvvvv rrrrrrrrrrrr\n" -"rrrrrrrrrrrrrr vvvvvv rrrrrrrrrrrrrr\n" -"rrrrrrrrrrrrrrrr vv rrrrrrrrrrrrrrrr\n" -"rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr\n" -"rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr\n" -"rrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr\n" -"\n" -" INSTRUCTION SETS WANT TO BE FREE\n"; +extern const char logo[]; void print_logo() { diff --git a/bbl/payload.S b/bbl/payload.S index 7ff1e58..6a175aa 100644 --- a/bbl/payload.S +++ b/bbl/payload.S @@ -1,7 +1,9 @@ -.section ".payload","a",@progbits -.align 3 +#include "encoding.h" -.globl _payload_start, _payload_end + .section ".payload","a",@progbits + .align RISCV_PGSHIFT + RISCV_PGLEVEL_BITS + + .globl _payload_start, _payload_end _payload_start: -.incbin BBL_PAYLOAD + .incbin BBL_PAYLOAD _payload_end: diff --git a/bbl/raw_logo.S b/bbl/raw_logo.S new file mode 100644 index 0000000..bddf8f4 --- /dev/null +++ b/bbl/raw_logo.S @@ -0,0 +1,7 @@ +#include "encoding.h" + + .section .rodata + .globl logo +logo: + .incbin BBL_LOGO_FILE + .byte 0 diff --git a/bbl/riscv_logo.txt b/bbl/riscv_logo.txt new file mode 100644 index 0000000..1f4c9f5 --- /dev/null +++ b/bbl/riscv_logo.txt @@ -0,0 +1,23 @@ + vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + vvvvvvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv +rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv +rr vvvvvvvvvvvvvvvvvvvvvv +rr vvvvvvvvvvvvvvvvvvvvvvvv rr +rrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrr +rrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrr +rrrrrrrr vvvvvvvvvvvvvvvvvv rrrrrrrr +rrrrrrrrrr vvvvvvvvvvvvvv rrrrrrrrrr +rrrrrrrrrrrr vvvvvvvvvv rrrrrrrrrrrr +rrrrrrrrrrrrrr vvvvvv rrrrrrrrrrrrrr +rrrrrrrrrrrrrrrr vv rrrrrrrrrrrrrrrr +rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr +rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr +rrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr + + INSTRUCTION SETS WANT TO BE FREE |