mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 04:06:46 +00:00 
			
		
		
		
	Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
* 'ppc-1.0' of git://repo.or.cz/qemu/agraf: pseries: Fix qdev.id handling in the VIO bus code pseries: Allow kernel's early debug output to work pseries: Default reg for vty should be SPAPR_VTY_BASE_ADDRESS pseries: Check we have a chardev in spapr_vty_init() pseries: Fix buggy spapr_vio_find_by_reg() pseries: Correct RAM size check for SLOF PPC: Fix for the gdb single step problem on an rfi instruction tcg-ppc64: Fix compile errors for userspace only builds with gcc 4.6 pseries: Fix initialization of sPAPREnvironment structure
This commit is contained in:
		
						commit
						05a86f23e5
					
				
							
								
								
									
										10
									
								
								hw/spapr.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								hw/spapr.c
									
									
									
									
									
								
							| @ -57,7 +57,7 @@ | ||||
| #define FW_MAX_SIZE             0x400000 | ||||
| #define FW_FILE_NAME            "slof.bin" | ||||
| 
 | ||||
| #define MIN_RAM_SLOF		512UL | ||||
| #define MIN_RMA_SLOF		128UL | ||||
| 
 | ||||
| #define TIMEBASE_FREQ           512000000ULL | ||||
| 
 | ||||
| @ -407,7 +407,9 @@ static void ppc_spapr_init(ram_addr_t ram_size, | ||||
|     long pteg_shift = 17; | ||||
|     char *filename; | ||||
| 
 | ||||
|     spapr = g_malloc(sizeof(*spapr)); | ||||
|     spapr = g_malloc0(sizeof(*spapr)); | ||||
|     QLIST_INIT(&spapr->phbs); | ||||
| 
 | ||||
|     cpu_ppc_hypercall = emulate_spapr_hypercall; | ||||
| 
 | ||||
|     /* Allocate RMA if necessary */ | ||||
| @ -560,9 +562,9 @@ static void ppc_spapr_init(ram_addr_t ram_size, | ||||
| 
 | ||||
|         spapr->entry_point = KERNEL_LOAD_ADDR; | ||||
|     } else { | ||||
|         if (ram_size < (MIN_RAM_SLOF << 20)) { | ||||
|         if (rma_size < (MIN_RMA_SLOF << 20)) { | ||||
|             fprintf(stderr, "qemu: pSeries SLOF firmware requires >= " | ||||
|                     "%ldM guest RAM\n", MIN_RAM_SLOF); | ||||
|                     "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF); | ||||
|             exit(1); | ||||
|         } | ||||
|         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME); | ||||
|  | ||||
| @ -66,11 +66,24 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg) | ||||
|     QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { | ||||
|         dev = (VIOsPAPRDevice *)qdev; | ||||
|         if (dev->reg == reg) { | ||||
|             break; | ||||
|             return dev; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return dev; | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static char *vio_format_dev_name(VIOsPAPRDevice *dev) | ||||
| { | ||||
|     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info; | ||||
|     char *name; | ||||
| 
 | ||||
|     /* Device tree style name device@reg */ | ||||
|     if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     return name; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_FDT | ||||
| @ -78,15 +91,21 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, | ||||
|                             void *fdt) | ||||
| { | ||||
|     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info; | ||||
|     int vdevice_off, node_off; | ||||
|     int ret; | ||||
|     int vdevice_off, node_off, ret; | ||||
|     char *dt_name; | ||||
| 
 | ||||
|     vdevice_off = fdt_path_offset(fdt, "/vdevice"); | ||||
|     if (vdevice_off < 0) { | ||||
|         return vdevice_off; | ||||
|     } | ||||
| 
 | ||||
|     node_off = fdt_add_subnode(fdt, vdevice_off, dev->qdev.id); | ||||
|     dt_name = vio_format_dev_name(dev); | ||||
|     if (!dt_name) { | ||||
|         return -ENOMEM; | ||||
|     } | ||||
| 
 | ||||
|     node_off = fdt_add_subnode(fdt, vdevice_off, dt_name); | ||||
|     free(dt_name); | ||||
|     if (node_off < 0) { | ||||
|         return node_off; | ||||
|     } | ||||
| @ -608,12 +627,15 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) | ||||
|     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; | ||||
|     char *id; | ||||
| 
 | ||||
|     if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) { | ||||
|         return -1; | ||||
|     /* Don't overwrite ids assigned on the command line */ | ||||
|     if (!dev->qdev.id) { | ||||
|         id = vio_format_dev_name(dev); | ||||
|         if (!id) { | ||||
|             return -1; | ||||
|         } | ||||
|         dev->qdev.id = id; | ||||
|     } | ||||
| 
 | ||||
|     dev->qdev.id = id; | ||||
| 
 | ||||
|     dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num); | ||||
|     if (!dev->qirq) { | ||||
|         return -1; | ||||
|  | ||||
| @ -58,12 +58,20 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev) | ||||
| { | ||||
|     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev; | ||||
| 
 | ||||
|     if (!dev->chardev) { | ||||
|         fprintf(stderr, "spapr-vty: Can't create vty without a chardev!\n"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     qemu_chr_add_handlers(dev->chardev, vty_can_receive, | ||||
|                           vty_receive, NULL, dev); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /* Forward declaration */ | ||||
| static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg); | ||||
| 
 | ||||
| static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr, | ||||
|                                     target_ulong opcode, target_ulong *args) | ||||
| { | ||||
| @ -71,9 +79,10 @@ static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr, | ||||
|     target_ulong len = args[1]; | ||||
|     target_ulong char0_7 = args[2]; | ||||
|     target_ulong char8_15 = args[3]; | ||||
|     VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); | ||||
|     VIOsPAPRDevice *sdev; | ||||
|     uint8_t buf[16]; | ||||
| 
 | ||||
|     sdev = vty_lookup(spapr, reg); | ||||
|     if (!sdev) { | ||||
|         return H_PARAMETER; | ||||
|     } | ||||
| @ -97,9 +106,10 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr, | ||||
|     target_ulong *len = args + 0; | ||||
|     target_ulong *char0_7 = args + 1; | ||||
|     target_ulong *char8_15 = args + 2; | ||||
|     VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); | ||||
|     VIOsPAPRDevice *sdev; | ||||
|     uint8_t buf[16]; | ||||
| 
 | ||||
|     sdev = vty_lookup(spapr, reg); | ||||
|     if (!sdev) { | ||||
|         return H_PARAMETER; | ||||
|     } | ||||
| @ -140,12 +150,35 @@ static VIOsPAPRDeviceInfo spapr_vty = { | ||||
|     .qdev.name = "spapr-vty", | ||||
|     .qdev.size = sizeof(VIOsPAPRVTYDevice), | ||||
|     .qdev.props = (Property[]) { | ||||
|         DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, 0, 0), | ||||
|         DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0), | ||||
|         DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev), | ||||
|         DEFINE_PROP_END_OF_LIST(), | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg) | ||||
| { | ||||
|     VIOsPAPRDevice *sdev; | ||||
| 
 | ||||
|     sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); | ||||
|     if (!sdev && reg == 0) { | ||||
|         DeviceState *qdev; | ||||
| 
 | ||||
|         /* Hack for kernel early debug, which always specifies reg==0.
 | ||||
|          * We search all VIO devices, and grab the first available vty | ||||
|          * device.  This attempts to mimic existing PowerVM behaviour | ||||
|          * (early debug does work there, despite having no vty with | ||||
|          * reg==0. */ | ||||
|         QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) { | ||||
|             if (qdev->info == &spapr_vty.qdev) { | ||||
|                 return DO_UPCAST(VIOsPAPRDevice, qdev, qdev); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return sdev; | ||||
| } | ||||
| 
 | ||||
| static void spapr_vty_register(void) | ||||
| { | ||||
|     spapr_vio_bus_register_withprop(&spapr_vty); | ||||
|  | ||||
| @ -298,8 +298,10 @@ static inline void gen_debug_exception(DisasContext *ctx) | ||||
| { | ||||
|     TCGv_i32 t0; | ||||
| 
 | ||||
|     if (ctx->exception != POWERPC_EXCP_BRANCH) | ||||
|     if ((ctx->exception != POWERPC_EXCP_BRANCH) && | ||||
|         (ctx->exception != POWERPC_EXCP_SYNC)) { | ||||
|         gen_update_nip(ctx, ctx->nip); | ||||
|     } | ||||
|     t0 = tcg_const_i32(EXCP_DEBUG); | ||||
|     gen_helper_raise_exception(t0); | ||||
|     tcg_temp_free_i32(t0); | ||||
|  | ||||
| @ -616,18 +616,19 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2, | ||||
| 
 | ||||
| static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) | ||||
| { | ||||
|     int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap; | ||||
|     int addr_reg, data_reg, r0, r1, rbase, bswap; | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|     int r2; | ||||
|     int r2, mem_index, s_bits; | ||||
|     void *label1_ptr, *label2_ptr; | ||||
| #endif | ||||
| 
 | ||||
|     data_reg = *args++; | ||||
|     addr_reg = *args++; | ||||
| 
 | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|     mem_index = *args; | ||||
|     s_bits = opc & 3; | ||||
| 
 | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|     r0 = 3; | ||||
|     r1 = 4; | ||||
|     r2 = 0; | ||||
| @ -763,17 +764,18 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) | ||||
| 
 | ||||
| static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) | ||||
| { | ||||
|     int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap; | ||||
|     int addr_reg, r0, r1, rbase, data_reg, bswap; | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|     int r2; | ||||
|     int r2, mem_index; | ||||
|     void *label1_ptr, *label2_ptr; | ||||
| #endif | ||||
| 
 | ||||
|     data_reg = *args++; | ||||
|     addr_reg = *args++; | ||||
|     mem_index = *args; | ||||
| 
 | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|     mem_index = *args; | ||||
| 
 | ||||
|     r0 = 3; | ||||
|     r1 = 4; | ||||
|     r2 = 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Blue Swirl
						Blue Swirl