The SS-10, SS-20 and SPARCserver 600MP accept -m up to 60 GiB, and the
LX, SS-4, SPARCclassic and Voyager accept 256 MiB, more than any of
these machines could hold. On the SS-10, SS-20 and 600MP, sizes above
the hardware limit fall into three ranges:

- Up to 4 GiB, QEMU maps the RAM, but no real machine could hold it.
- From 4 GiB, the size wraps around in the firmware. QEMU passes it as
  an 8-byte fw_cfg item, but the sparc32 OpenBIOS reads only its low
  32 bits, so -m 5120 boots as if it were -m 1024.
- Above about 56 GiB, the RAM also overlaps the SBus devices, which
  start at 0xe20000000 (TCX).

Set each limit from the real hardware:

- The SS-10 and SS-20 memory controllers (EMC and SMC) decode eight
  SIMM slots as 64 MiB windows from 29 DRAM address bits, 512 MiB in
  total (Sun patent EP0571099).
- The SPARCserver 600MP takes at max 1 GiB, onboard plus expansion
  boards (SPARCsystem 600MP service manual, 800-5318).
- The SS-4 takes at most 160 MiB in its five SIMM slots.
- The LX and SPARCclassic use the microSPARC-I on-chip controller,
  which decodes four 32 MiB banks, 128 MiB.
- The Voyager has 16 MiB onboard and two slots for 16 or 32 MiB cards,
  80 MiB. Its default RAM size becomes 80 MiB, so -M Voyager without
  -m still starts.
- The SPARCbook model gets 128 MiB, the decode limit of its
  microSPARC-I. This keeps QEMU's default -m of 128 MiB working and
  does not describe a real SPARCbook configuration.

Machines without ECC map an empty slot so that accesses to missing RAM
do not fault. It now ends at iommu_base, where memory decode ends on
those machines, rather than at max_mem.

Update the maximum memory sizes in docs/system/target-sparc.rst.

Signed-off-by: Imre Kaloz <[email protected]>
---
 docs/system/target-sparc.rst |  6 ++++--
 hw/sparc/sun4m.c             | 24 ++++++++++++++----------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/docs/system/target-sparc.rst b/docs/system/target-sparc.rst
index 4116cac493..de0acc76dc 100644
--- a/docs/system/target-sparc.rst
+++ b/docs/system/target-sparc.rst
@@ -52,8 +52,10 @@ QEMU emulates the following sun4m peripherals:
 -  CS4231 sound device (only on SS-5, not working yet)
 
 The number of peripherals is fixed in the architecture. Maximum memory
-size depends on the machine type, for SS-5 it is 256MB and for others
-2047MB.
+size depends on the machine type: 512 MiB for the SS-10 and SS-20,
+256 MiB for the SS-5, 160 MiB for the SS-4, 128 MiB for the LX,
+SPARCclassic and SPARCbook, 80 MiB for the Voyager, and 1 GiB for the
+SPARCserver 600MP.
 
 Since version 0.8.2, QEMU uses OpenBIOS https://www.openbios.org/.
 OpenBIOS is a free (GPL v2) portable firmware implementation. The goal
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 550acdff6d..c586b1c44e 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -840,10 +840,13 @@ static void sun4m_hw_init(MachineState *machine)
     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0);
 
-    /* models without ECC don't trap when missing ram is accessed */
+    /*
+     * models without ECC don't trap when missing ram is accessed,
+     * up to the end of memory decode at iommu_base
+     */
     if (!hwdef->ecc_base) {
         empty_slot_init("ecc", machine->ram_size,
-                        hwdef->max_mem - machine->ram_size);
+                        hwdef->iommu_base - machine->ram_size);
     }
 
     prom_init(hwdef->slavio_base, machine->firmware);
@@ -1174,7 +1177,7 @@ static void ss10_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x72,
         .machine_id = ss10_id,
         .iommu_version = 0x03000000,
-        .max_mem = 0xf00000000ULL,
+        .max_mem = 0x20000000, /* 512M: EMC has 29 DRAM address bits */
     };
 
     mc->desc = "Sun4m platform, SPARCstation 10";
@@ -1207,7 +1210,7 @@ static void ss600mp_class_init(ObjectClass *oc, const 
void *data)
         .nvram_machine_id = 0x71,
         .machine_id = ss600mp_id,
         .iommu_version = 0x01000000,
-        .max_mem = 0xf00000000ULL,
+        .max_mem = 0x40000000, /* 1G: onboard plus expansion boards */
     };
 
     mc->desc = "Sun4m platform, SPARCserver 600MP";
@@ -1258,7 +1261,7 @@ static void ss20_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x72,
         .machine_id = ss20_id,
         .iommu_version = 0x13000000,
-        .max_mem = 0xf00000000ULL,
+        .max_mem = 0x20000000, /* 512M: SMC has 29 DRAM address bits */
     };
 
     mc->desc = "Sun4m platform, SPARCstation 20";
@@ -1291,11 +1294,12 @@ static void voyager_class_init(ObjectClass *oc, const 
void *data)
         .nvram_machine_id = 0x80,
         .machine_id = vger_id,
         .iommu_version = 0x05000000,
-        .max_mem = 0x10000000,
+        .max_mem = 0x05000000, /* 80M: 16M onboard plus two 32M cards */
     };
 
     mc->desc = "Sun4m platform, SPARCstation Voyager";
     mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
+    mc->default_ram_size = 80 * MiB;
     smc->hwdef = &voyager_hwdef;
 }
 
@@ -1324,7 +1328,7 @@ static void ss_lx_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x80,
         .machine_id = lx_id,
         .iommu_version = 0x04000000,
-        .max_mem = 0x10000000,
+        .max_mem = 0x08000000, /* 128M: microSPARC-I on-chip controller */
     };
 
     mc->desc = "Sun4m platform, SPARCstation LX";
@@ -1357,7 +1361,7 @@ static void ss4_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x80,
         .machine_id = ss4_id,
         .iommu_version = 0x05000000,
-        .max_mem = 0x10000000,
+        .max_mem = 0x0a000000, /* 160M: 5 SIMM slots */
     };
 
     mc->desc = "Sun4m platform, SPARCstation 4";
@@ -1389,7 +1393,7 @@ static void scls_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x80,
         .machine_id = scls_id,
         .iommu_version = 0x05000000,
-        .max_mem = 0x10000000,
+        .max_mem = 0x08000000, /* 128M: microSPARC-I on-chip controller */
     };
 
     mc->desc = "Sun4m platform, SPARCClassic";
@@ -1421,7 +1425,7 @@ static void sbook_class_init(ObjectClass *oc, const void 
*data)
         .nvram_machine_id = 0x80,
         .machine_id = sbook_id,
         .iommu_version = 0x05000000,
-        .max_mem = 0x10000000,
+        .max_mem = 0x08000000, /* 128M: microSPARC-I on-chip controller */
     };
 
     mc->desc = "Sun4m platform, SPARCbook";
-- 
2.47.3


Reply via email to