@ -1162,6 +1162,100 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
return aplic_m ;
}
static void virt_machine_done ( Notifier * notifier , void * data )
{
RISCVVirtState * s = container_of ( notifier , RISCVVirtState ,
machine_done ) ;
const MemMapEntry * memmap = virt_memmap ;
MachineState * machine = MACHINE ( s ) ;
target_ulong start_addr = memmap [ VIRT_DRAM ] . base ;
target_ulong firmware_end_addr , kernel_start_addr ;
uint32_t fdt_load_addr ;
uint64_t kernel_entry ;
/*
* Only direct boot kernel is currently supported for KVM VM ,
* so the " -bios " parameter is not supported when KVM is enabled .
*/
if ( kvm_enabled ( ) ) {
if ( machine - > firmware ) {
if ( strcmp ( machine - > firmware , " none " ) ) {
error_report ( " Machine mode firmware is not supported in "
" combination with KVM. " ) ;
exit ( 1 ) ;
}
} else {
machine - > firmware = g_strdup ( " none " ) ;
}
}
if ( riscv_is_32bit ( & s - > soc [ 0 ] ) ) {
firmware_end_addr = riscv_find_and_load_firmware ( machine ,
RISCV32_BIOS_BIN , start_addr , NULL ) ;
} else {
firmware_end_addr = riscv_find_and_load_firmware ( machine ,
RISCV64_BIOS_BIN , start_addr , NULL ) ;
}
if ( machine - > kernel_filename ) {
kernel_start_addr = riscv_calc_kernel_start_addr ( & s - > soc [ 0 ] ,
firmware_end_addr ) ;
kernel_entry = riscv_load_kernel ( machine - > kernel_filename ,
kernel_start_addr , NULL ) ;
if ( machine - > initrd_filename ) {
hwaddr start ;
hwaddr end = riscv_load_initrd ( machine - > initrd_filename ,
machine - > ram_size , kernel_entry ,
& start ) ;
qemu_fdt_setprop_cell ( machine - > fdt , " /chosen " ,
" linux,initrd-start " , start ) ;
qemu_fdt_setprop_cell ( machine - > fdt , " /chosen " , " linux,initrd-end " ,
end ) ;
}
} else {
/*
* If dynamic firmware is used , it doesn ' t know where is the next mode
* if kernel argument is not set .
*/
kernel_entry = 0 ;
}
if ( drive_get ( IF_PFLASH , 0 , 0 ) ) {
/*
* Pflash was supplied , let ' s overwrite the address we jump to after
* reset to the base of the flash .
*/
start_addr = virt_memmap [ VIRT_FLASH ] . base ;
}
/*
* Init fw_cfg . Must be done before riscv_load_fdt , otherwise the device
* tree cannot be altered and we get FDT_ERR_NOSPACE .
*/
s - > fw_cfg = create_fw_cfg ( machine ) ;
rom_set_fw ( s - > fw_cfg ) ;
/* Compute the fdt load address in dram */
fdt_load_addr = riscv_load_fdt ( memmap [ VIRT_DRAM ] . base ,
machine - > ram_size , machine - > fdt ) ;
/* load the reset vector */
riscv_setup_rom_reset_vec ( machine , & s - > soc [ 0 ] , start_addr ,
virt_memmap [ VIRT_MROM ] . base ,
virt_memmap [ VIRT_MROM ] . size , kernel_entry ,
fdt_load_addr , machine - > fdt ) ;
/*
* Only direct boot kernel is currently supported for KVM VM ,
* So here setup kernel start address and fdt address .
* TODO : Support firmware loading and integrate to TCG start
*/
if ( kvm_enabled ( ) ) {
riscv_setup_direct_kernel ( kernel_entry , fdt_load_addr ) ;
}
}
static void virt_machine_init ( MachineState * machine )
{
const MemMapEntry * memmap = virt_memmap ;
@ -1169,10 +1263,6 @@ static void virt_machine_init(MachineState *machine)
MemoryRegion * system_memory = get_system_memory ( ) ;
MemoryRegion * mask_rom = g_new ( MemoryRegion , 1 ) ;
char * soc_name ;
target_ulong start_addr = memmap [ VIRT_DRAM ] . base ;
target_ulong firmware_end_addr , kernel_start_addr ;
uint32_t fdt_load_addr ;
uint64_t kernel_entry ;
DeviceState * mmio_irqchip , * virtio_irqchip , * pcie_irqchip ;
int i , base_hartid , hart_count ;
@ -1302,98 +1392,12 @@ static void virt_machine_init(MachineState *machine)
memory_region_add_subregion ( system_memory , memmap [ VIRT_DRAM ] . base ,
machine - > ram ) ;
/* create device tree */
create_fdt ( s , memmap , machine - > ram_size , machine - > kernel_cmdline ,
riscv_is_32bit ( & s - > soc [ 0 ] ) ) ;
/* boot rom */
memory_region_init_rom ( mask_rom , NULL , " riscv_virt_board.mrom " ,
memmap [ VIRT_MROM ] . size , & error_fatal ) ;
memory_region_add_subregion ( system_memory , memmap [ VIRT_MROM ] . base ,
mask_rom ) ;
/*
* Only direct boot kernel is currently supported for KVM VM ,
* so the " -bios " parameter is not supported when KVM is enabled .
*/
if ( kvm_enabled ( ) ) {
if ( machine - > firmware ) {
if ( strcmp ( machine - > firmware , " none " ) ) {
error_report ( " Machine mode firmware is not supported in "
" combination with KVM. " ) ;
exit ( 1 ) ;
}
} else {
machine - > firmware = g_strdup ( " none " ) ;
}
}
if ( riscv_is_32bit ( & s - > soc [ 0 ] ) ) {
firmware_end_addr = riscv_find_and_load_firmware ( machine ,
RISCV32_BIOS_BIN , start_addr , NULL ) ;
} else {
firmware_end_addr = riscv_find_and_load_firmware ( machine ,
RISCV64_BIOS_BIN , start_addr , NULL ) ;
}
if ( machine - > kernel_filename ) {
kernel_start_addr = riscv_calc_kernel_start_addr ( & s - > soc [ 0 ] ,
firmware_end_addr ) ;
kernel_entry = riscv_load_kernel ( machine - > kernel_filename ,
kernel_start_addr , NULL ) ;
if ( machine - > initrd_filename ) {
hwaddr start ;
hwaddr end = riscv_load_initrd ( machine - > initrd_filename ,
machine - > ram_size , kernel_entry ,
& start ) ;
qemu_fdt_setprop_cell ( machine - > fdt , " /chosen " ,
" linux,initrd-start " , start ) ;
qemu_fdt_setprop_cell ( machine - > fdt , " /chosen " , " linux,initrd-end " ,
end ) ;
}
} else {
/*
* If dynamic firmware is used , it doesn ' t know where is the next mode
* if kernel argument is not set .
*/
kernel_entry = 0 ;
}
if ( drive_get ( IF_PFLASH , 0 , 0 ) ) {
/*
* Pflash was supplied , let ' s overwrite the address we jump to after
* reset to the base of the flash .
*/
start_addr = virt_memmap [ VIRT_FLASH ] . base ;
}
/*
* Init fw_cfg . Must be done before riscv_load_fdt , otherwise the device
* tree cannot be altered and we get FDT_ERR_NOSPACE .
*/
s - > fw_cfg = create_fw_cfg ( machine ) ;
rom_set_fw ( s - > fw_cfg ) ;
/* Compute the fdt load address in dram */
fdt_load_addr = riscv_load_fdt ( memmap [ VIRT_DRAM ] . base ,
machine - > ram_size , machine - > fdt ) ;
/* load the reset vector */
riscv_setup_rom_reset_vec ( machine , & s - > soc [ 0 ] , start_addr ,
virt_memmap [ VIRT_MROM ] . base ,
virt_memmap [ VIRT_MROM ] . size , kernel_entry ,
fdt_load_addr , machine - > fdt ) ;
/*
* Only direct boot kernel is currently supported for KVM VM ,
* So here setup kernel start address and fdt address .
* TODO : Support firmware loading and integrate to TCG start
*/
if ( kvm_enabled ( ) ) {
riscv_setup_direct_kernel ( kernel_entry , fdt_load_addr ) ;
}
/* SiFive Test MMIO device */
sifive_test_create ( memmap [ VIRT_TEST ] . base ) ;
@ -1429,6 +1433,13 @@ static void virt_machine_init(MachineState *machine)
drive_get ( IF_PFLASH , 0 , i ) ) ;
}
virt_flash_map ( s , system_memory ) ;
/* create device tree */
create_fdt ( s , memmap , machine - > ram_size , machine - > kernel_cmdline ,
riscv_is_32bit ( & s - > soc [ 0 ] ) ) ;
s - > machine_done . notify = virt_machine_done ;
qemu_add_machine_init_done_notifier ( & s - > machine_done ) ;
}
static void virt_machine_instance_init ( Object * obj )