| 752 | } |
| 753 | |
| 754 | static void copy_bios(RISCVMachine *s, const uint8_t *buf, int buf_len, |
| 755 | const uint8_t *kernel_buf, int kernel_buf_len, |
| 756 | const uint8_t *initrd_buf, int initrd_buf_len, |
| 757 | const char *cmd_line) |
| 758 | { |
| 759 | uint32_t fdt_addr, align, kernel_base, initrd_base; |
| 760 | uint8_t *ram_ptr; |
| 761 | uint32_t *q; |
| 762 | |
| 763 | if (buf_len > s->ram_size) { |
| 764 | vm_error("BIOS too big\n"); |
| 765 | exit(1); |
| 766 | } |
| 767 | |
| 768 | ram_ptr = get_ram_ptr(s, RAM_BASE_ADDR, TRUE); |
| 769 | memcpy(ram_ptr, buf, buf_len); |
| 770 | |
| 771 | kernel_base = 0; |
| 772 | if (kernel_buf_len > 0) { |
| 773 | /* copy the kernel if present */ |
| 774 | if (s->max_xlen == 32) |
| 775 | align = 4 << 20; /* 4 MB page align */ |
| 776 | else |
| 777 | align = 2 << 20; /* 2 MB page align */ |
| 778 | kernel_base = (buf_len + align - 1) & ~(align - 1); |
| 779 | memcpy(ram_ptr + kernel_base, kernel_buf, kernel_buf_len); |
| 780 | if (kernel_buf_len + kernel_base > s->ram_size) { |
| 781 | vm_error("kernel too big"); |
| 782 | exit(1); |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | initrd_base = 0; |
| 787 | if (initrd_buf_len > 0) { |
| 788 | /* same allocation as QEMU */ |
| 789 | initrd_base = s->ram_size / 2; |
| 790 | if (initrd_base > (128 << 20)) |
| 791 | initrd_base = 128 << 20; |
| 792 | memcpy(ram_ptr + initrd_base, initrd_buf, initrd_buf_len); |
| 793 | if (initrd_buf_len + initrd_base > s->ram_size) { |
| 794 | vm_error("initrd too big"); |
| 795 | exit(1); |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | ram_ptr = get_ram_ptr(s, 0, TRUE); |
| 800 | |
| 801 | fdt_addr = 0x1000 + 8 * 8; |
| 802 | |
| 803 | riscv_build_fdt(s, ram_ptr + fdt_addr, |
| 804 | RAM_BASE_ADDR + kernel_base, kernel_buf_len, |
| 805 | RAM_BASE_ADDR + initrd_base, initrd_buf_len, |
| 806 | cmd_line); |
| 807 | |
| 808 | /* jump_addr = 0x80000000 */ |
| 809 | |
| 810 | q = (uint32_t *)(ram_ptr + 0x1000); |
| 811 | q[0] = 0x297 + 0x80000000 - 0x1000; /* auipc t0, jump_addr */ |
no test coverage detected