qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller
@ 2019-12-10  0:52 Andrew Jeffery
  2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10  0:52 UTC (permalink / raw)
  To: qemu-arm; +Cc: qemu-devel, peter.maydell, clg, joel

Hello,

The AST2600 has an additional SDHCI intended for use as an eMMC boot source.
These two patches rework the existing ASPEED SDHCI model to accommodate the
single-slot nature of the eMMC controller and wire it into the AST2600 SoC.

Please review!

Andrew

Andrew Jeffery (2):
  hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
  hw/arm: ast2600: Wire up the eMMC controller

 hw/arm/aspeed.c              | 15 ++++++++++++++-
 hw/arm/aspeed_ast2600.c      | 23 +++++++++++++++++++++++
 hw/arm/aspeed_soc.c          |  3 +++
 hw/sd/aspeed_sdhci.c         | 11 +++++++++--
 include/hw/arm/aspeed_soc.h  |  2 ++
 include/hw/sd/aspeed_sdhci.h |  1 +
 6 files changed, 52 insertions(+), 3 deletions(-)

base-commit: 6a4ef4e5d1084ce41fafa7d470a644b0fd3d9317
-- 
git-series 0.9.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
  2019-12-10  0:52 [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller Andrew Jeffery
@ 2019-12-10  0:52 ` Andrew Jeffery
  2019-12-10  7:49   ` Philippe Mathieu-Daudé
  2019-12-10  8:56   ` Cédric Le Goater
  2019-12-10  0:52 ` [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller Andrew Jeffery
  2019-12-10  8:53 ` [PATCH 0/2] hw/arm: ast2600: Wire up " Cédric Le Goater
  2 siblings, 2 replies; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10  0:52 UTC (permalink / raw)
  To: qemu-arm; +Cc: qemu-devel, peter.maydell, clg, joel

The AST2600 includes a second cut-down version of the SD/MMC controller
found in the AST2500, named the eMMC controller. It's cut down in the
sense that it only supports one slot rather than two, but it brings the
total number of slots supported by the AST2600 to three.

The existing code assumed that the SD controller always provided two
slots. Rework the SDHCI object to expose the number of slots as a
property to be set by the SoC configuration.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 hw/arm/aspeed.c              |  2 +-
 hw/arm/aspeed_ast2600.c      |  2 ++
 hw/arm/aspeed_soc.c          |  3 +++
 hw/sd/aspeed_sdhci.c         | 11 +++++++++--
 include/hw/sd/aspeed_sdhci.h |  1 +
 5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 028191ff36fc..862549b1f3a9 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -259,7 +259,7 @@ static void aspeed_board_init(MachineState *machine,
         cfg->i2c_init(bmc);
     }
 
-    for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
+    for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
         SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
         DriveInfo *dinfo = drive_get_next(IF_SD);
         BlockBackend *blk;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 931887ac681f..931ee5aae183 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -208,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
     sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
                           TYPE_ASPEED_SDHCI);
 
+    object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
+
     /* Init sd card slot class here so that they're under the correct parent */
     for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
         sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index f4fe243458fd..3498f55603f2 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -215,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
     sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
                           TYPE_ASPEED_SDHCI);
 
+    object_property_set_int(OBJECT(&s->sdhci), ASPEED_SDHCI_NUM_SLOTS,
+                            "num-slots", &error_abort);
+
     /* Init sd card slot class here so that they're under the correct parent */
     for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
         sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
index cff3eb7dd21e..939d1510dedb 100644
--- a/hw/sd/aspeed_sdhci.c
+++ b/hw/sd/aspeed_sdhci.c
@@ -13,6 +13,7 @@
 #include "qapi/error.h"
 #include "hw/irq.h"
 #include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
 
 #define ASPEED_SDHCI_INFO            0x00
 #define  ASPEED_SDHCI_INFO_RESET     0x00030000
@@ -120,14 +121,14 @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
 
     /* Create input irqs for the slots */
     qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq,
-                                        sdhci, NULL, ASPEED_SDHCI_NUM_SLOTS);
+                                        sdhci, NULL, sdhci->num_slots);
 
     sysbus_init_irq(sbd, &sdhci->irq);
     memory_region_init_io(&sdhci->iomem, OBJECT(sdhci), &aspeed_sdhci_ops,
                           sdhci, TYPE_ASPEED_SDHCI, 0x1000);
     sysbus_init_mmio(sbd, &sdhci->iomem);
 
-    for (int i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+    for (int i = 0; i < sdhci->num_slots; ++i) {
         Object *sdhci_slot = OBJECT(&sdhci->slots[i]);
         SysBusDevice *sbd_slot = SYS_BUS_DEVICE(&sdhci->slots[i]);
 
@@ -174,6 +175,11 @@ static const VMStateDescription vmstate_aspeed_sdhci = {
     },
 };
 
+static Property aspeed_sdhci_properties[] = {
+    DEFINE_PROP_UINT8("num-slots", AspeedSDHCIState, num_slots, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(classp);
@@ -181,6 +187,7 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
     dc->realize = aspeed_sdhci_realize;
     dc->reset = aspeed_sdhci_reset;
     dc->vmsd = &vmstate_aspeed_sdhci;
+    dc->props = aspeed_sdhci_properties;
 }
 
 static TypeInfo aspeed_sdhci_info = {
diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
index dfdab4379021..dffbb46946b9 100644
--- a/include/hw/sd/aspeed_sdhci.h
+++ b/include/hw/sd/aspeed_sdhci.h
@@ -24,6 +24,7 @@ typedef struct AspeedSDHCIState {
     SysBusDevice parent;
 
     SDHCIState slots[ASPEED_SDHCI_NUM_SLOTS];
+    uint8_t num_slots;
 
     MemoryRegion iomem;
     qemu_irq irq;
-- 
git-series 0.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller
  2019-12-10  0:52 [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller Andrew Jeffery
  2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
@ 2019-12-10  0:52 ` Andrew Jeffery
  2019-12-10 12:52   ` Cédric Le Goater
  2019-12-10  8:53 ` [PATCH 0/2] hw/arm: ast2600: Wire up " Cédric Le Goater
  2 siblings, 1 reply; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10  0:52 UTC (permalink / raw)
  To: qemu-arm; +Cc: qemu-devel, peter.maydell, clg, joel

Initialise another SDHCI model instance for the AST2600's eMMC
controller and use the SDHCI's num_slots value introduced previously to
determine whether we should create an SD card instance for the new slot.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 hw/arm/aspeed.c             | 13 +++++++++++++
 hw/arm/aspeed_ast2600.c     | 21 +++++++++++++++++++++
 include/hw/arm/aspeed_soc.h |  2 ++
 3 files changed, 36 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 862549b1f3a9..0e08d62e9ff3 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -272,6 +272,19 @@ static void aspeed_board_init(MachineState *machine,
         object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
     }
 
+    if (bmc->soc.emmc.num_slots) {
+        SDHCIState *emmc = &bmc->soc.emmc.slots[0];
+        DriveInfo *dinfo = drive_get_next(IF_SD);
+        BlockBackend *blk;
+        DeviceState *card;
+
+        blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
+        card = qdev_create(qdev_get_child_bus(DEVICE(emmc), "sd-bus"),
+                           TYPE_SD_CARD);
+        qdev_prop_set_drive(card, "drive", blk, &error_fatal);
+        object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
+    }
+
     arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
 }
 
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 931ee5aae183..723c8196c8a5 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -46,6 +46,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
     [ASPEED_ADC]       = 0x1E6E9000,
     [ASPEED_VIDEO]     = 0x1E700000,
     [ASPEED_SDHCI]     = 0x1E740000,
+    [ASPEED_EMMC]      = 0x1E750000,
     [ASPEED_GPIO]      = 0x1E780000,
     [ASPEED_GPIO_1_8V] = 0x1E780800,
     [ASPEED_RTC]       = 0x1E781000,
@@ -64,6 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_SOC_AST2600_MAX_IRQ 128
 
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
     [ASPEED_UART1]     = 47,
     [ASPEED_UART2]     = 48,
@@ -77,6 +79,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
     [ASPEED_ADC]       = 78,
     [ASPEED_XDMA]      = 6,
     [ASPEED_SDHCI]     = 43,
+    [ASPEED_EMMC]      = 15,
     [ASPEED_GPIO]      = 40,
     [ASPEED_GPIO_1_8V] = 11,
     [ASPEED_RTC]       = 13,
@@ -215,6 +218,14 @@ static void aspeed_soc_ast2600_init(Object *obj)
         sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
                               sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
     }
+
+    sysbus_init_child_obj(obj, "emmc", OBJECT(&s->emmc), sizeof(s->emmc),
+                          TYPE_ASPEED_SDHCI);
+
+    object_property_set_int(OBJECT(&s->emmc), 1, "num-slots", &error_abort);
+
+    sysbus_init_child_obj(obj, "emmc[*]", OBJECT(&s->emmc.slots[0]),
+            sizeof(s->emmc.slots[0]), TYPE_SYSBUS_SDHCI);
 }
 
 /*
@@ -487,6 +498,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
                     sc->memmap[ASPEED_SDHCI]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
                        aspeed_soc_get_irq(s, ASPEED_SDHCI));
+
+    /* eMMC */
+    object_property_set_bool(OBJECT(&s->emmc), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->emmc), 0, sc->memmap[ASPEED_EMMC]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0,
+                       aspeed_soc_get_irq(s, ASPEED_EMMC));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 495c08be1b84..911443f4c071 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -56,6 +56,7 @@ typedef struct AspeedSoCState {
     AspeedGPIOState gpio;
     AspeedGPIOState gpio_1_8v;
     AspeedSDHCIState sdhci;
+    AspeedSDHCIState emmc;
 } AspeedSoCState;
 
 #define TYPE_ASPEED_SOC "aspeed-soc"
@@ -125,6 +126,7 @@ enum {
     ASPEED_MII4,
     ASPEED_SDRAM,
     ASPEED_XDMA,
+    ASPEED_EMMC,
 };
 
 #endif /* ASPEED_SOC_H */
-- 
git-series 0.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
  2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
@ 2019-12-10  7:49   ` Philippe Mathieu-Daudé
  2019-12-10  8:56   ` Cédric Le Goater
  1 sibling, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-12-10  7:49 UTC (permalink / raw)
  To: Andrew Jeffery, qemu-arm; +Cc: peter.maydell, joel, qemu-devel, clg

On 12/10/19 1:52 AM, Andrew Jeffery wrote:
> The AST2600 includes a second cut-down version of the SD/MMC controller
> found in the AST2500, named the eMMC controller. It's cut down in the
> sense that it only supports one slot rather than two, but it brings the
> total number of slots supported by the AST2600 to three.
> 
> The existing code assumed that the SD controller always provided two
> slots. Rework the SDHCI object to expose the number of slots as a
> property to be set by the SoC configuration.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>   hw/arm/aspeed.c              |  2 +-
>   hw/arm/aspeed_ast2600.c      |  2 ++
>   hw/arm/aspeed_soc.c          |  3 +++
>   hw/sd/aspeed_sdhci.c         | 11 +++++++++--
>   include/hw/sd/aspeed_sdhci.h |  1 +
>   5 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 028191ff36fc..862549b1f3a9 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -259,7 +259,7 @@ static void aspeed_board_init(MachineState *machine,
>           cfg->i2c_init(bmc);
>       }
>   
> -    for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
> +    for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
>           SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
>           DriveInfo *dinfo = drive_get_next(IF_SD);
>           BlockBackend *blk;
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 931887ac681f..931ee5aae183 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -208,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
>       sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
>                             TYPE_ASPEED_SDHCI);
>   
> +    object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
> +
>       /* Init sd card slot class here so that they're under the correct parent */
>       for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
>           sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index f4fe243458fd..3498f55603f2 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -215,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
>       sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
>                             TYPE_ASPEED_SDHCI);
>   
> +    object_property_set_int(OBJECT(&s->sdhci), ASPEED_SDHCI_NUM_SLOTS,
> +                            "num-slots", &error_abort);
> +
>       /* Init sd card slot class here so that they're under the correct parent */
>       for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
>           sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
> diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
> index cff3eb7dd21e..939d1510dedb 100644
> --- a/hw/sd/aspeed_sdhci.c
> +++ b/hw/sd/aspeed_sdhci.c
> @@ -13,6 +13,7 @@
>   #include "qapi/error.h"
>   #include "hw/irq.h"
>   #include "migration/vmstate.h"
> +#include "hw/qdev-properties.h"
>   
>   #define ASPEED_SDHCI_INFO            0x00
>   #define  ASPEED_SDHCI_INFO_RESET     0x00030000
> @@ -120,14 +121,14 @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
>   
>       /* Create input irqs for the slots */
>       qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq,
> -                                        sdhci, NULL, ASPEED_SDHCI_NUM_SLOTS);
> +                                        sdhci, NULL, sdhci->num_slots);
>   
>       sysbus_init_irq(sbd, &sdhci->irq);
>       memory_region_init_io(&sdhci->iomem, OBJECT(sdhci), &aspeed_sdhci_ops,
>                             sdhci, TYPE_ASPEED_SDHCI, 0x1000);
>       sysbus_init_mmio(sbd, &sdhci->iomem);
>   
> -    for (int i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
> +    for (int i = 0; i < sdhci->num_slots; ++i) {
>           Object *sdhci_slot = OBJECT(&sdhci->slots[i]);
>           SysBusDevice *sbd_slot = SYS_BUS_DEVICE(&sdhci->slots[i]);
>   
> @@ -174,6 +175,11 @@ static const VMStateDescription vmstate_aspeed_sdhci = {
>       },
>   };
>   
> +static Property aspeed_sdhci_properties[] = {
> +    DEFINE_PROP_UINT8("num-slots", AspeedSDHCIState, num_slots, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
>   static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
>   {
>       DeviceClass *dc = DEVICE_CLASS(classp);
> @@ -181,6 +187,7 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
>       dc->realize = aspeed_sdhci_realize;
>       dc->reset = aspeed_sdhci_reset;
>       dc->vmsd = &vmstate_aspeed_sdhci;
> +    dc->props = aspeed_sdhci_properties;
>   }
>   
>   static TypeInfo aspeed_sdhci_info = {
> diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
> index dfdab4379021..dffbb46946b9 100644
> --- a/include/hw/sd/aspeed_sdhci.h
> +++ b/include/hw/sd/aspeed_sdhci.h
> @@ -24,6 +24,7 @@ typedef struct AspeedSDHCIState {
>       SysBusDevice parent;
>   
>       SDHCIState slots[ASPEED_SDHCI_NUM_SLOTS];
> +    uint8_t num_slots;
>   
>       MemoryRegion iomem;
>       qemu_irq irq;
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller
  2019-12-10  0:52 [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller Andrew Jeffery
  2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
  2019-12-10  0:52 ` [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller Andrew Jeffery
@ 2019-12-10  8:53 ` Cédric Le Goater
  2019-12-10 22:19   ` Andrew Jeffery
  2 siblings, 1 reply; 10+ messages in thread
From: Cédric Le Goater @ 2019-12-10  8:53 UTC (permalink / raw)
  To: Andrew Jeffery, qemu-arm; +Cc: peter.maydell, joel, qemu-devel

On 10/12/2019 01:52, Andrew Jeffery wrote:
> Hello,
> 
> The AST2600 has an additional SDHCI intended for use as an eMMC boot source.

Have you also considered booting the QEMU Aspeed AST2600 machine 
from the eMMC device ?

C.

> These two patches rework the existing ASPEED SDHCI model to accommodate the
> single-slot nature of the eMMC controller and wire it into the AST2600 SoC.
> 
> Please review!
> 
> Andrew
> 
> Andrew Jeffery (2):
>   hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
>   hw/arm: ast2600: Wire up the eMMC controller
> 
>  hw/arm/aspeed.c              | 15 ++++++++++++++-
>  hw/arm/aspeed_ast2600.c      | 23 +++++++++++++++++++++++
>  hw/arm/aspeed_soc.c          |  3 +++
>  hw/sd/aspeed_sdhci.c         | 11 +++++++++--
>  include/hw/arm/aspeed_soc.h  |  2 ++
>  include/hw/sd/aspeed_sdhci.h |  1 +
>  6 files changed, 52 insertions(+), 3 deletions(-)
> 
> base-commit: 6a4ef4e5d1084ce41fafa7d470a644b0fd3d9317
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
  2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
  2019-12-10  7:49   ` Philippe Mathieu-Daudé
@ 2019-12-10  8:56   ` Cédric Le Goater
  2019-12-10 22:17     ` Andrew Jeffery
  1 sibling, 1 reply; 10+ messages in thread
From: Cédric Le Goater @ 2019-12-10  8:56 UTC (permalink / raw)
  To: Andrew Jeffery, qemu-arm; +Cc: peter.maydell, joel, qemu-devel

On 10/12/2019 01:52, Andrew Jeffery wrote:
> The AST2600 includes a second cut-down version of the SD/MMC controller
> found in the AST2500, named the eMMC controller. It's cut down in the
> sense that it only supports one slot rather than two, but it brings the
> total number of slots supported by the AST2600 to three.
> 
> The existing code assumed that the SD controller always provided two
> slots. Rework the SDHCI object to expose the number of slots as a
> property to be set by the SoC configuration.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Reviewed-by: Cédric Le Goater <clg@kaod.org>

One minor question below.


> ---
>  hw/arm/aspeed.c              |  2 +-
>  hw/arm/aspeed_ast2600.c      |  2 ++
>  hw/arm/aspeed_soc.c          |  3 +++
>  hw/sd/aspeed_sdhci.c         | 11 +++++++++--
>  include/hw/sd/aspeed_sdhci.h |  1 +
>  5 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 028191ff36fc..862549b1f3a9 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -259,7 +259,7 @@ static void aspeed_board_init(MachineState *machine,
>          cfg->i2c_init(bmc);
>      }
>  
> -    for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
> +    for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
>          SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
>          DriveInfo *dinfo = drive_get_next(IF_SD);
>          BlockBackend *blk;
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 931887ac681f..931ee5aae183 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -208,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
>      sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
>                            TYPE_ASPEED_SDHCI);
>  
> +    object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);

OK. This defines 2 SDHCI slots for the ast2600 SoC, but

> +
>      /* Init sd card slot class here so that they're under the correct parent */
>      for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
>          sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index f4fe243458fd..3498f55603f2 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -215,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
>      sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
>                            TYPE_ASPEED_SDHCI);
>  
> +    object_property_set_int(OBJECT(&s->sdhci), ASPEED_SDHCI_NUM_SLOTS,
> +                            "num-slots", &error_abort);


why use ASPEED_SDHCI_NUM_SLOTS here ?

C.

>      /* Init sd card slot class here so that they're under the correct parent */
>      for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
>          sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
> diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
> index cff3eb7dd21e..939d1510dedb 100644
> --- a/hw/sd/aspeed_sdhci.c
> +++ b/hw/sd/aspeed_sdhci.c
> @@ -13,6 +13,7 @@
>  #include "qapi/error.h"
>  #include "hw/irq.h"
>  #include "migration/vmstate.h"
> +#include "hw/qdev-properties.h"
>  
>  #define ASPEED_SDHCI_INFO            0x00
>  #define  ASPEED_SDHCI_INFO_RESET     0x00030000
> @@ -120,14 +121,14 @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
>  
>      /* Create input irqs for the slots */
>      qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq,
> -                                        sdhci, NULL, ASPEED_SDHCI_NUM_SLOTS);
> +                                        sdhci, NULL, sdhci->num_slots);
>  
>      sysbus_init_irq(sbd, &sdhci->irq);
>      memory_region_init_io(&sdhci->iomem, OBJECT(sdhci), &aspeed_sdhci_ops,
>                            sdhci, TYPE_ASPEED_SDHCI, 0x1000);
>      sysbus_init_mmio(sbd, &sdhci->iomem);
>  
> -    for (int i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
> +    for (int i = 0; i < sdhci->num_slots; ++i) {
>          Object *sdhci_slot = OBJECT(&sdhci->slots[i]);
>          SysBusDevice *sbd_slot = SYS_BUS_DEVICE(&sdhci->slots[i]);
>  
> @@ -174,6 +175,11 @@ static const VMStateDescription vmstate_aspeed_sdhci = {
>      },
>  };
>  
> +static Property aspeed_sdhci_properties[] = {
> +    DEFINE_PROP_UINT8("num-slots", AspeedSDHCIState, num_slots, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(classp);
> @@ -181,6 +187,7 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
>      dc->realize = aspeed_sdhci_realize;
>      dc->reset = aspeed_sdhci_reset;
>      dc->vmsd = &vmstate_aspeed_sdhci;
> +    dc->props = aspeed_sdhci_properties;
>  }
>  
>  static TypeInfo aspeed_sdhci_info = {
> diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
> index dfdab4379021..dffbb46946b9 100644
> --- a/include/hw/sd/aspeed_sdhci.h
> +++ b/include/hw/sd/aspeed_sdhci.h
> @@ -24,6 +24,7 @@ typedef struct AspeedSDHCIState {
>      SysBusDevice parent;
>  
>      SDHCIState slots[ASPEED_SDHCI_NUM_SLOTS];
> +    uint8_t num_slots;
>  
>      MemoryRegion iomem;
>      qemu_irq irq;
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller
  2019-12-10  0:52 ` [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller Andrew Jeffery
@ 2019-12-10 12:52   ` Cédric Le Goater
  2019-12-10 22:15     ` Andrew Jeffery
  0 siblings, 1 reply; 10+ messages in thread
From: Cédric Le Goater @ 2019-12-10 12:52 UTC (permalink / raw)
  To: Andrew Jeffery, qemu-arm; +Cc: peter.maydell, joel, qemu-devel

On 10/12/2019 01:52, Andrew Jeffery wrote:
> Initialise another SDHCI model instance for the AST2600's eMMC
> controller and use the SDHCI's num_slots value introduced previously to
> determine whether we should create an SD card instance for the new slot.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

LGTM. One comment.

> ---
>  hw/arm/aspeed.c             | 13 +++++++++++++
>  hw/arm/aspeed_ast2600.c     | 21 +++++++++++++++++++++
>  include/hw/arm/aspeed_soc.h |  2 ++
>  3 files changed, 36 insertions(+)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 862549b1f3a9..0e08d62e9ff3 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -272,6 +272,19 @@ static void aspeed_board_init(MachineState *machine,
>          object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
>      }
>  
> +    if (bmc->soc.emmc.num_slots) {
> +        SDHCIState *emmc = &bmc->soc.emmc.slots[0];
> +        DriveInfo *dinfo = drive_get_next(IF_SD);
> +        BlockBackend *blk;
> +        DeviceState *card;
> +
> +        blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> +        card = qdev_create(qdev_get_child_bus(DEVICE(emmc), "sd-bus"),
> +                           TYPE_SD_CARD);
> +        qdev_prop_set_drive(card, "drive", blk, &error_fatal);
> +        object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
> +    }

I think we could use a function for the above ^

C.

>      arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
>  }
>  
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 931ee5aae183..723c8196c8a5 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -46,6 +46,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
>      [ASPEED_ADC]       = 0x1E6E9000,
>      [ASPEED_VIDEO]     = 0x1E700000,
>      [ASPEED_SDHCI]     = 0x1E740000,
> +    [ASPEED_EMMC]      = 0x1E750000,
>      [ASPEED_GPIO]      = 0x1E780000,
>      [ASPEED_GPIO_1_8V] = 0x1E780800,
>      [ASPEED_RTC]       = 0x1E781000,
> @@ -64,6 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
>  
>  #define ASPEED_SOC_AST2600_MAX_IRQ 128
>  
> +/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
>  static const int aspeed_soc_ast2600_irqmap[] = {
>      [ASPEED_UART1]     = 47,
>      [ASPEED_UART2]     = 48,
> @@ -77,6 +79,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
>      [ASPEED_ADC]       = 78,
>      [ASPEED_XDMA]      = 6,
>      [ASPEED_SDHCI]     = 43,
> +    [ASPEED_EMMC]      = 15,
>      [ASPEED_GPIO]      = 40,
>      [ASPEED_GPIO_1_8V] = 11,
>      [ASPEED_RTC]       = 13,
> @@ -215,6 +218,14 @@ static void aspeed_soc_ast2600_init(Object *obj)
>          sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
>                                sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
>      }
> +
> +    sysbus_init_child_obj(obj, "emmc", OBJECT(&s->emmc), sizeof(s->emmc),
> +                          TYPE_ASPEED_SDHCI);
> +
> +    object_property_set_int(OBJECT(&s->emmc), 1, "num-slots", &error_abort);
> +
> +    sysbus_init_child_obj(obj, "emmc[*]", OBJECT(&s->emmc.slots[0]),
> +            sizeof(s->emmc.slots[0]), TYPE_SYSBUS_SDHCI);
>  }
>  
>  /*
> @@ -487,6 +498,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
>                      sc->memmap[ASPEED_SDHCI]);
>      sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
>                         aspeed_soc_get_irq(s, ASPEED_SDHCI));
> +
> +    /* eMMC */
> +    object_property_set_bool(OBJECT(&s->emmc), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->emmc), 0, sc->memmap[ASPEED_EMMC]);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0,
> +                       aspeed_soc_get_irq(s, ASPEED_EMMC));
>  }
>  
>  static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 495c08be1b84..911443f4c071 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -56,6 +56,7 @@ typedef struct AspeedSoCState {
>      AspeedGPIOState gpio;
>      AspeedGPIOState gpio_1_8v;
>      AspeedSDHCIState sdhci;
> +    AspeedSDHCIState emmc;
>  } AspeedSoCState;
>  
>  #define TYPE_ASPEED_SOC "aspeed-soc"
> @@ -125,6 +126,7 @@ enum {
>      ASPEED_MII4,
>      ASPEED_SDRAM,
>      ASPEED_XDMA,
> +    ASPEED_EMMC,
>  };
>  
>  #endif /* ASPEED_SOC_H */
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller
  2019-12-10 12:52   ` Cédric Le Goater
@ 2019-12-10 22:15     ` Andrew Jeffery
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10 22:15 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-arm; +Cc: Peter Maydell, Joel Stanley, qemu-devel



On Tue, 10 Dec 2019, at 23:22, Cédric Le Goater wrote:
> On 10/12/2019 01:52, Andrew Jeffery wrote:
> > Initialise another SDHCI model instance for the AST2600's eMMC
> > controller and use the SDHCI's num_slots value introduced previously to
> > determine whether we should create an SD card instance for the new slot.
> > 
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> 
> LGTM. One comment.
> 
> > ---
> >  hw/arm/aspeed.c             | 13 +++++++++++++
> >  hw/arm/aspeed_ast2600.c     | 21 +++++++++++++++++++++
> >  include/hw/arm/aspeed_soc.h |  2 ++
> >  3 files changed, 36 insertions(+)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index 862549b1f3a9..0e08d62e9ff3 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -272,6 +272,19 @@ static void aspeed_board_init(MachineState *machine,
> >          object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
> >      }
> >  
> > +    if (bmc->soc.emmc.num_slots) {
> > +        SDHCIState *emmc = &bmc->soc.emmc.slots[0];
> > +        DriveInfo *dinfo = drive_get_next(IF_SD);
> > +        BlockBackend *blk;
> > +        DeviceState *card;
> > +
> > +        blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> > +        card = qdev_create(qdev_get_child_bus(DEVICE(emmc), "sd-bus"),
> > +                           TYPE_SD_CARD);
> > +        qdev_prop_set_drive(card, "drive", blk, &error_fatal);
> > +        object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
> > +    }
> 
> I think we could use a function for the above ^

Yep, I'll refactor that.

Andrew


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
  2019-12-10  8:56   ` Cédric Le Goater
@ 2019-12-10 22:17     ` Andrew Jeffery
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10 22:17 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-arm; +Cc: Peter Maydell, Joel Stanley, qemu-devel



On Tue, 10 Dec 2019, at 19:26, Cédric Le Goater wrote:
> On 10/12/2019 01:52, Andrew Jeffery wrote:
> > The AST2600 includes a second cut-down version of the SD/MMC controller
> > found in the AST2500, named the eMMC controller. It's cut down in the
> > sense that it only supports one slot rather than two, but it brings the
> > total number of slots supported by the AST2600 to three.
> > 
> > The existing code assumed that the SD controller always provided two
> > slots. Rework the SDHCI object to expose the number of slots as a
> > property to be set by the SoC configuration.
> > 
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> 
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> 
> One minor question below.
> 
> 
> > ---
> >  hw/arm/aspeed.c              |  2 +-
> >  hw/arm/aspeed_ast2600.c      |  2 ++
> >  hw/arm/aspeed_soc.c          |  3 +++
> >  hw/sd/aspeed_sdhci.c         | 11 +++++++++--
> >  include/hw/sd/aspeed_sdhci.h |  1 +
> >  5 files changed, 16 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index 028191ff36fc..862549b1f3a9 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -259,7 +259,7 @@ static void aspeed_board_init(MachineState *machine,
> >          cfg->i2c_init(bmc);
> >      }
> >  
> > -    for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
> > +    for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
> >          SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
> >          DriveInfo *dinfo = drive_get_next(IF_SD);
> >          BlockBackend *blk;
> > diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> > index 931887ac681f..931ee5aae183 100644
> > --- a/hw/arm/aspeed_ast2600.c
> > +++ b/hw/arm/aspeed_ast2600.c
> > @@ -208,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
> >      sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
> >                            TYPE_ASPEED_SDHCI);
> >  
> > +    object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
> 
> OK. This defines 2 SDHCI slots for the ast2600 SoC, but
> 
> > +
> >      /* Init sd card slot class here so that they're under the correct parent */
> >      for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
> >          sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
> > diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> > index f4fe243458fd..3498f55603f2 100644
> > --- a/hw/arm/aspeed_soc.c
> > +++ b/hw/arm/aspeed_soc.c
> > @@ -215,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
> >      sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
> >                            TYPE_ASPEED_SDHCI);
> >  
> > +    object_property_set_int(OBJECT(&s->sdhci), ASPEED_SDHCI_NUM_SLOTS,
> > +                            "num-slots", &error_abort);
> 
> 
> why use ASPEED_SDHCI_NUM_SLOTS here ?

No good reason. I'll just switch it to '2' like in the 2600.

Andrew


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller
  2019-12-10  8:53 ` [PATCH 0/2] hw/arm: ast2600: Wire up " Cédric Le Goater
@ 2019-12-10 22:19   ` Andrew Jeffery
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Jeffery @ 2019-12-10 22:19 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-arm; +Cc: Peter Maydell, Joel Stanley, qemu-devel



On Tue, 10 Dec 2019, at 19:23, Cédric Le Goater wrote:
> On 10/12/2019 01:52, Andrew Jeffery wrote:
> > Hello,
> > 
> > The AST2600 has an additional SDHCI intended for use as an eMMC boot source.
> 
> Have you also considered booting the QEMU Aspeed AST2600 machine 
> from the eMMC device ?
> 

I hadn't got that far. I was surprised we hadn't yet wired up the eMMC controller at
all, so I solved that problem first :)

Andrew


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-12-10 22:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-10  0:52 [PATCH 0/2] hw/arm: ast2600: Wire up eMMC controller Andrew Jeffery
2019-12-10  0:52 ` [PATCH 1/2] hw/sd: Configure number of slots exposed by the ASPEED SDHCI model Andrew Jeffery
2019-12-10  7:49   ` Philippe Mathieu-Daudé
2019-12-10  8:56   ` Cédric Le Goater
2019-12-10 22:17     ` Andrew Jeffery
2019-12-10  0:52 ` [PATCH 2/2] hw/arm: ast2600: Wire up the eMMC controller Andrew Jeffery
2019-12-10 12:52   ` Cédric Le Goater
2019-12-10 22:15     ` Andrew Jeffery
2019-12-10  8:53 ` [PATCH 0/2] hw/arm: ast2600: Wire up " Cédric Le Goater
2019-12-10 22:19   ` Andrew Jeffery

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).