| 827 | } |
| 828 | |
| 829 | static VirtMachine *riscv_machine_init(const VirtMachineParams *p) |
| 830 | { |
| 831 | RISCVMachine *s; |
| 832 | VIRTIODevice *blk_dev; |
| 833 | int irq_num, i, max_xlen, ram_flags; |
| 834 | VIRTIOBusDef vbus_s, *vbus = &vbus_s; |
| 835 | |
| 836 | |
| 837 | if (!strcmp(p->machine_name, "riscv32")) { |
| 838 | max_xlen = 32; |
| 839 | } else if (!strcmp(p->machine_name, "riscv64")) { |
| 840 | max_xlen = 64; |
| 841 | } else if (!strcmp(p->machine_name, "riscv128")) { |
| 842 | max_xlen = 128; |
| 843 | } else { |
| 844 | vm_error("unsupported machine: %s\n", p->machine_name); |
| 845 | return NULL; |
| 846 | } |
| 847 | |
| 848 | s = mallocz(sizeof(*s)); |
| 849 | s->common.vmc = p->vmc; |
| 850 | s->ram_size = p->ram_size; |
| 851 | s->max_xlen = max_xlen; |
| 852 | s->mem_map = phys_mem_map_init(); |
| 853 | /* needed to handle the RAM dirty bits */ |
| 854 | s->mem_map->opaque = s; |
| 855 | s->mem_map->flush_tlb_write_range = riscv_flush_tlb_write_range; |
| 856 | |
| 857 | s->cpu_state = riscv_cpu_init(s->mem_map, max_xlen); |
| 858 | if (!s->cpu_state) { |
| 859 | vm_error("unsupported max_xlen=%d\n", max_xlen); |
| 860 | /* XXX: should free resources */ |
| 861 | return NULL; |
| 862 | } |
| 863 | /* RAM */ |
| 864 | ram_flags = 0; |
| 865 | cpu_register_ram(s->mem_map, RAM_BASE_ADDR, p->ram_size, ram_flags); |
| 866 | cpu_register_ram(s->mem_map, 0x00000000, LOW_RAM_SIZE, 0); |
| 867 | s->rtc_real_time = p->rtc_real_time; |
| 868 | if (p->rtc_real_time) { |
| 869 | s->rtc_start_time = rtc_get_real_time(s); |
| 870 | } |
| 871 | |
| 872 | cpu_register_device(s->mem_map, CLINT_BASE_ADDR, CLINT_SIZE, s, |
| 873 | clint_read, clint_write, DEVIO_SIZE32); |
| 874 | cpu_register_device(s->mem_map, PLIC_BASE_ADDR, PLIC_SIZE, s, |
| 875 | plic_read, plic_write, DEVIO_SIZE32); |
| 876 | for(i = 1; i < 32; i++) { |
| 877 | irq_init(&s->plic_irq[i], plic_set_irq, s, i); |
| 878 | } |
| 879 | |
| 880 | cpu_register_device(s->mem_map, HTIF_BASE_ADDR, 16, |
| 881 | s, htif_read, htif_write, DEVIO_SIZE32); |
| 882 | s->common.console = p->console; |
| 883 | |
| 884 | memset(vbus, 0, sizeof(*vbus)); |
| 885 | vbus->mem_map = s->mem_map; |
| 886 | vbus->addr = VIRTIO_BASE_ADDR; |
nothing calls this directly
no test coverage detected