Skip to contentSkip to conversation

add iommu version to sparc32

PATCH In review Robert Reif 2 participants 4 messages Nov 12, 2007 – Nov 17, 2007

lore
Share & tools
lore
#0 lore raw

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
diff -p -u -r1.17 iommu.c
@@ -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 *opaqu
             break;
         }
         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 addr
         return 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
diff -p -u -r1.60 sun4m.c
@@ -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,
#1 lore raw
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.

#2 lore raw
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.

#3 lore raw
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.