add iommu version to sparc32
PATCH 1/1 add iommu version to sparc32
Add iommu version to sparc32. Also reset iommu after initialization.
Index: hw/iommu.c
===================================================================
RCS file: /sources/qemu/qemu/hw/iommu.c,v
retrieving revision 1.17
iommu.c +7 -4
@@ -37,7 +37,6 @@ do { printf("IOMMU: " fmt , ##args); } w#define IOMMU_CTRL (0x0000 >> 2)#define IOMMU_CTRL_IMPL 0xf0000000/* Implementation */ #define IOMMU_CTRL_VERS 0x0f000000/* Version */ -#define IOMMU_VERSION 0x04000000#define IOMMU_CTRL_RNGE 0x0000001c/* Mapping RANGE */ #define IOMMU_RNGE_16MB 0x00000000/* 0xff000000 -> 0xffffffff */ #define IOMMU_RNGE_32MB 0x00000004/* 0xfe000000 -> 0xffffffff */
@@ -104,6 +103,7 @@ typedef struct IOMMUState {target_phys_addr_t addr;uint32_t regs[IOMMU_NREGS ];target_phys_addr_t iostart; +uint32_t version; } IOMMUState;static uint32_t iommu_mem_readw (void *opaque,target_phys_addr_t addr)
@@ -158,7 +158,7 @@ static void iommu_mem_writew(void *opaqubreak ; }DPRINTF ("iostart = " TARGET_FMT_plx"\n" , s->iostart); - s->regs[saddr] = ((val &IOMMU_CTRL_MASK ) |IOMMU_VERSION ); + s->regs[saddr] = ((val &IOMMU_CTRL_MASK ) | s->version);break ;case IOMMU_BASE : s->regs[saddr] = val &IOMMU_BASE_MASK ;
@@ -308,10 +308,11 @@ static void iommu_reset(void *opaque)memset (s->regs,0 ,IOMMU_NREGS *4 ); s->iostart =0 ; - s->regs[IOMMU_CTRL ] =IOMMU_VERSION ; + s->regs[IOMMU_CTRL ] = s->version; + s->regs[IOMMU_ARBEN ] =IOMMU_MID ; } -void *iommu_init (target_phys_addr_t addr) +void *iommu_init (target_phys_addr_t addr,uint32_t version) {IOMMUState *s;int iommu_io_memory;
@@ -321,12 +322,14 @@ void *iommu_init(target_phys_addr_t addrreturn NULL ; s->addr = addr; + s->version = version; iommu_io_memory =cpu_register_io_memory (0 , iommu_mem_read, iommu_mem_write, s);cpu_register_physical_memory (addr,IOMMU_NREGS *4 , iommu_io_memory);register_savevm ("iommu" , addr,2 , iommu_save, iommu_load, s);qemu_register_reset (iommu_reset, s); +iommu_reset (s);return s; }
Index: hw/sun4m.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.60
sun4m.c +5 -1
@@ -69,6 +69,7 @@ struct hwdef {int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;int machine_id;// For NVRAM +uint32_t iommu_version;uint32_t intbit_to_level[32 ]; };
@@ -343,7 +344,7 @@ static void *sun4m_hw_init(const struct/* allocate RAM */ cpu_register_physical_memory (0 , RAM_size,0 ); - iommu =iommu_init (hwdef->iommu_base); + iommu =iommu_init (hwdef->iommu_base, hwdef->iommu_version); slavio_intctl = slavio_intctl_init(hwdef->intctl_base, hwdef->intctl_base + 0x10000ULL, &hwdef->intbit_to_level[0],
@@ -509,6 +510,7 @@ static const struct hwdef hwdefs[] = { .me_irq = 30, .cs_irq = 5, .machine_id = 0x80, + .iommu_version = 0x04000000, .intbit_to_level = {2 ,3 ,5 ,7 ,9 ,11 ,0 ,14 ,3 ,5 ,7 ,9 ,11 ,13 ,12 ,12 , 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
@@ -542,6 +544,7 @@ static const struct hwdef hwdefs[] = { .me_irq = 30, .cs_irq = -1, .machine_id = 0x72, + .iommu_version = 0x03000000, .intbit_to_level = {2 ,3 ,5 ,7 ,9 ,11 ,0 ,14 ,3 ,5 ,7 ,9 ,11 ,13 ,12 ,12 , 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
@@ -575,6 +578,7 @@ static const struct hwdef hwdefs[] = { .me_irq = 30, .cs_irq = -1, .machine_id = 0x71, + .iommu_version = 0x01000000, .intbit_to_level = {2 ,3 ,5 ,7 ,9 ,11 ,0 ,14 ,3 ,5 ,7 ,9 ,11 ,13 ,12 ,12 , 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
Quoted 1 line · Robert Reif
Add iommu version to sparc32. Also reset iommu after initialization.
Should the version be tied to CPU model instead of machine type? At least for Turbosparc this seems to be the case. Older CPUs may have separate chips for IU and IOMMU.
Otherwise the patch looks good, thanks.
Quoted 9 lines
Quoted 4 lines
Add iommu version to sparc32. Also reset iommu after initialization.
Should the version be tied to CPU model instead of machine type? At least for Turbosparc this seems to be the case.
On SMP systems the IOMMU is on the system board in a separate ASIC. On single CPU systems the IOMMU is integrated into the CPU. Without checking the FEH, the SS 5 was the only single CPU system that shipped with more than one family of CPUs (MicroSparc II and TurboSparc and they do have different IOMMU versions). That could be special cased.
Unfortunately QEMU will allow you to specify unrealistic systems. We should probably add allowable CPU types to specific machine types to catch this.
Quoted 9 lines · Robert Reif
Quoted 9 lines
Quoted 4 lines
Add iommu version to sparc32. Also reset iommu after initialization.
Should the version be tied to CPU model instead of machine type? At least for Turbosparc this seems to be the case.
Quoted 5 lines
On SMP systems the IOMMU is on the system board in a separate ASIC. On single CPU systems the IOMMU is integrated into the CPU. Without checking the FEH, the SS 5 was the only single CPU system that shipped with more than one family of CPUs (MicroSparc II and TurboSparc and they do have different IOMMU versions). That could be special cased.
OK, then the machine is more correct place.
Thanks, patch applied.
Quoted 3 lines
Unfortunately QEMU will allow you to specify unrealistic systems. We should
probably add allowable CPU types to specific machine types to catch this.
Well, there are plenty of things that can be unrealistic, for example memory size. For the IOMMU case, Linux does not make any checks for the version, same with NetBSD. I don't think it matters too much.