ppc/pnv: add a OCC model for POWER9
The OCC on POWER9 is very similar to the one found on POWER8. Provide the same routines with P9 values for the registers and IRQ number. Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190307223548.20516-10-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
		
							parent
							
								
									3233838cd1
								
							
						
					
					
						commit
						6598a70d00
					
				
							
								
								
									
										13
									
								
								hw/ppc/pnv.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								hw/ppc/pnv.c
									
									
									
									
									
								
							@ -956,6 +956,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
 | 
			
		||||
                            TYPE_PNV9_LPC, &error_abort, NULL);
 | 
			
		||||
    object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
 | 
			
		||||
                                   OBJECT(&chip9->psi), &error_abort);
 | 
			
		||||
 | 
			
		||||
    object_initialize_child(obj, "occ",  &chip9->occ, sizeof(chip9->occ),
 | 
			
		||||
                            TYPE_PNV9_OCC, &error_abort, NULL);
 | 
			
		||||
    object_property_add_const_link(OBJECT(&chip9->occ), "psi",
 | 
			
		||||
                                   OBJECT(&chip9->psi), &error_abort);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
 | 
			
		||||
@ -1012,6 +1017,14 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
 | 
			
		||||
 | 
			
		||||
    chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
 | 
			
		||||
                                            (uint64_t) PNV9_LPCM_BASE(chip));
 | 
			
		||||
 | 
			
		||||
    /* Create the simplified OCC model */
 | 
			
		||||
    object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
 | 
			
		||||
@ -109,6 +109,77 @@ static const TypeInfo pnv_occ_power8_type_info = {
 | 
			
		||||
    .class_init    = pnv_occ_power8_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define P9_OCB_OCI_OCCMISC              0x6080
 | 
			
		||||
#define P9_OCB_OCI_OCCMISC_CLEAR        0x6081
 | 
			
		||||
#define P9_OCB_OCI_OCCMISC_OR           0x6082
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
 | 
			
		||||
                                          unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PnvOCC *occ = PNV_OCC(opaque);
 | 
			
		||||
    uint32_t offset = addr >> 3;
 | 
			
		||||
    uint64_t val = 0;
 | 
			
		||||
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case P9_OCB_OCI_OCCMISC:
 | 
			
		||||
        val = occ->occmisc;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
 | 
			
		||||
                      HWADDR_PRIx "\n", addr >> 3);
 | 
			
		||||
    }
 | 
			
		||||
    return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
 | 
			
		||||
                                       uint64_t val, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PnvOCC *occ = PNV_OCC(opaque);
 | 
			
		||||
    uint32_t offset = addr >> 3;
 | 
			
		||||
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case P9_OCB_OCI_OCCMISC_CLEAR:
 | 
			
		||||
        pnv_occ_set_misc(occ, 0);
 | 
			
		||||
        break;
 | 
			
		||||
    case P9_OCB_OCI_OCCMISC_OR:
 | 
			
		||||
        pnv_occ_set_misc(occ, occ->occmisc | val);
 | 
			
		||||
        break;
 | 
			
		||||
    case P9_OCB_OCI_OCCMISC:
 | 
			
		||||
        pnv_occ_set_misc(occ, val);
 | 
			
		||||
       break;
 | 
			
		||||
    default:
 | 
			
		||||
        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
 | 
			
		||||
                      HWADDR_PRIx "\n", addr >> 3);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
 | 
			
		||||
    .read = pnv_occ_power9_xscom_read,
 | 
			
		||||
    .write = pnv_occ_power9_xscom_write,
 | 
			
		||||
    .valid.min_access_size = 8,
 | 
			
		||||
    .valid.max_access_size = 8,
 | 
			
		||||
    .impl.min_access_size = 8,
 | 
			
		||||
    .impl.max_access_size = 8,
 | 
			
		||||
    .endianness = DEVICE_BIG_ENDIAN,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
{
 | 
			
		||||
    PnvOCCClass *poc = PNV_OCC_CLASS(klass);
 | 
			
		||||
 | 
			
		||||
    poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
 | 
			
		||||
    poc->xscom_ops = &pnv_occ_power9_xscom_ops;
 | 
			
		||||
    poc->psi_irq = PSIHB9_IRQ_OCC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo pnv_occ_power9_type_info = {
 | 
			
		||||
    .name          = TYPE_PNV9_OCC,
 | 
			
		||||
    .parent        = TYPE_PNV_OCC,
 | 
			
		||||
    .instance_size = sizeof(PnvOCC),
 | 
			
		||||
    .class_init    = pnv_occ_power9_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void pnv_occ_realize(DeviceState *dev, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    PnvOCC *occ = PNV_OCC(dev);
 | 
			
		||||
@ -152,6 +223,7 @@ static void pnv_occ_register_types(void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static(&pnv_occ_type_info);
 | 
			
		||||
    type_register_static(&pnv_occ_power8_type_info);
 | 
			
		||||
    type_register_static(&pnv_occ_power9_type_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init(pnv_occ_register_types);
 | 
			
		||||
 | 
			
		||||
@ -88,6 +88,7 @@ typedef struct Pnv9Chip {
 | 
			
		||||
    PnvXive      xive;
 | 
			
		||||
    Pnv9Psi      psi;
 | 
			
		||||
    PnvLpcController lpc;
 | 
			
		||||
    PnvOCC       occ;
 | 
			
		||||
} Pnv9Chip;
 | 
			
		||||
 | 
			
		||||
typedef struct PnvChipClass {
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,8 @@
 | 
			
		||||
#define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
 | 
			
		||||
#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
 | 
			
		||||
#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
 | 
			
		||||
#define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
 | 
			
		||||
#define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
 | 
			
		||||
 | 
			
		||||
typedef struct PnvOCC {
 | 
			
		||||
    DeviceState xd;
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,9 @@ typedef struct PnvXScomInterfaceClass {
 | 
			
		||||
#define PNV_XSCOM_OCC_BASE        0x0066000
 | 
			
		||||
#define PNV_XSCOM_OCC_SIZE        0x6000
 | 
			
		||||
 | 
			
		||||
#define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
 | 
			
		||||
#define PNV9_XSCOM_OCC_SIZE       0x8000
 | 
			
		||||
 | 
			
		||||
#define PNV9_XSCOM_PSIHB_BASE     0x5012900
 | 
			
		||||
#define PNV9_XSCOM_PSIHB_SIZE     0x100
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user