All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 06/54] hw/misc/iotkit-sysctl: Remove is_sse200 flag
Date: Mon,  8 Mar 2021 17:31:56 +0000	[thread overview]
Message-ID: <20210308173244.20710-7-peter.maydell@linaro.org> (raw)
In-Reply-To: <20210308173244.20710-1-peter.maydell@linaro.org>

Remove the is_sse200 flag in favour of just directly testing the new
sse_version field.

Since some of these registers exist in the SSE-300 but some do not or
have different behaviour, we expand out the if() statements in the
read and write functions into switch()es, so we have an easy place to
put SSE-300 specific behaviour.

(Until we do add the SSE-300 behaviour, the thing preventing us
reaching the "unreachable" default cases is that armsse.c doesn't
yet pass us an ARMSSE_SSE300 version.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210219144617.4782-7-peter.maydell@linaro.org
---
 include/hw/misc/iotkit-sysctl.h |   2 -
 hw/misc/iotkit-sysctl.c         | 256 +++++++++++++++++++++++---------
 2 files changed, 187 insertions(+), 71 deletions(-)

diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index 7cdafea3e25..980c2ddfd3c 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -64,8 +64,6 @@ struct IoTKitSysCtl {
     uint32_t cpuwait_rst;
     uint32_t initsvtor0_rst;
     uint32_t initsvtor1_rst;
-
-    bool is_sse200;
 };
 
 #endif
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 34b37fe8824..c67f5b320ab 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -101,28 +101,48 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         r = s->secure_debug;
         break;
     case A_SCSECCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->scsecctrl;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->scsecctrl;
         break;
     case A_FCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->fclk_div;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->fclk_div;
         break;
     case A_SYSCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->sysclk_div;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->sysclk_div;
         break;
     case A_CLOCK_FORCE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->clock_force;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->clock_force;
         break;
     case A_RESET_SYNDROME:
         r = s->reset_syndrome;
@@ -137,60 +157,100 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
         r = s->initsvtor0;
         break;
     case A_INITSVTOR1:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->initsvtor1;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->initsvtor1;
         break;
     case A_CPUWAIT:
         r = s->cpuwait;
         break;
     case A_NMI_ENABLE:
-        /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
+            /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */
             r = 0;
             break;
+        case ARMSSE_SSE200:
+            r = s->nmi_enable;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->nmi_enable;
         break;
     case A_WICCTRL:
         r = s->wicctrl;
         break;
     case A_EWCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->ewctrl;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->ewctrl;
         break;
     case A_PDCM_PD_SYS_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sys_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sys_sense;
         break;
     case A_PDCM_PD_SRAM0_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram0_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram0_sense;
         break;
     case A_PDCM_PD_SRAM1_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram1_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram1_sense;
         break;
     case A_PDCM_PD_SRAM2_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram2_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram2_sense;
         break;
     case A_PDCM_PD_SRAM3_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            r = s->pdcm_pd_sram3_sense;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        r = s->pdcm_pd_sram3_sense;
         break;
     case A_PID4 ... A_CID3:
         r = sysctl_id[(offset - A_PID4) / 4];
@@ -284,94 +344,154 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
         }
         break;
     case A_SCSECCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
+            s->scsecctrl = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
-        s->scsecctrl = value;
         break;
     case A_FCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
+            s->fclk_div = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
-        s->fclk_div = value;
         break;
     case A_SYSCLK_DIV:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
+            s->sysclk_div = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
-        s->sysclk_div = value;
         break;
     case A_CLOCK_FORCE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
+            s->clock_force = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
-        s->clock_force = value;
         break;
     case A_INITSVTOR1:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            s->initsvtor1 = value;
+            set_init_vtor(1, s->initsvtor1);
+            break;
+        default:
+            g_assert_not_reached();
         }
-        s->initsvtor1 = value;
-        set_init_vtor(1, s->initsvtor1);
         break;
     case A_EWCTRL:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
+            s->ewctrl = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
-        s->ewctrl = value;
         break;
     case A_PDCM_PD_SYS_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
+            s->pdcm_pd_sys_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
-        s->pdcm_pd_sys_sense = value;
         break;
     case A_PDCM_PD_SRAM0_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
+            s->pdcm_pd_sram0_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
-        s->pdcm_pd_sram0_sense = value;
         break;
     case A_PDCM_PD_SRAM1_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
+            s->pdcm_pd_sram1_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
-        s->pdcm_pd_sram1_sense = value;
         break;
     case A_PDCM_PD_SRAM2_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
+            s->pdcm_pd_sram2_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
-        s->pdcm_pd_sram2_sense = value;
         break;
     case A_PDCM_PD_SRAM3_SENSE:
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto bad_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP,
+                          "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
+            s->pdcm_pd_sram3_sense = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP,
-                      "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
-        s->pdcm_pd_sram3_sense = value;
         break;
     case A_NMI_ENABLE:
         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
-        if (!s->is_sse200) {
+        switch (s->sse_version) {
+        case ARMSSE_IOTKIT:
             goto ro_offset;
+        case ARMSSE_SSE200:
+            qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
+            s->nmi_enable = value;
+            break;
+        default:
+            g_assert_not_reached();
         }
-        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
-        s->nmi_enable = value;
         break;
     case A_SECDBGSTAT:
     case A_PID4 ... A_CID3:
@@ -443,15 +563,13 @@ static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "invalid sse-version value %d", s->sse_version);
         return;
     }
-
-    s->is_sse200 = s->sse_version == ARMSSE_SSE200;
 }
 
 static bool sse200_needed(void *opaque)
 {
     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
 
-    return s->is_sse200;
+    return s->sse_version == ARMSSE_SSE200;
 }
 
 static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
-- 
2.20.1



  parent reply	other threads:[~2021-03-08 17:50 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-08 17:31 [PULL 00/54] target-arm queue Peter Maydell
2021-03-08 17:31 ` [PULL 01/54] clock: Add ClockEvent parameter to callbacks Peter Maydell
2021-03-08 17:31 ` [PULL 02/54] clock: Add ClockPreUpdate callback event type Peter Maydell
2021-03-08 17:31 ` [PULL 03/54] clock: Add clock_ns_to_ticks() function Peter Maydell
2021-03-08 17:31 ` [PULL 04/54] hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks() Peter Maydell
2021-03-08 17:31 ` [PULL 05/54] hw/arm/armsse: Introduce SSE subsystem version property Peter Maydell
2021-03-08 17:31 ` Peter Maydell [this message]
2021-03-08 17:31 ` [PULL 07/54] hw/misc/iotkit-secctl.c: Implement SSE-300 PID register values Peter Maydell
2021-03-08 17:31 ` [PULL 08/54] hw/misc/iotkit-sysinfo.c: " Peter Maydell
2021-03-08 17:31 ` [PULL 09/54] hw/arm/armsse.c: Use correct SYS_CONFIG0 register value for SSE-300 Peter Maydell
2021-03-08 17:32 ` [PULL 10/54] hw/misc/iotkit-sysinfo.c: Implement SYS_CONFIG1 and IIDR Peter Maydell
2021-03-08 17:32 ` [PULL 11/54] hw/timer/sse-counter: Model the SSE Subsystem System Counter Peter Maydell
2021-03-08 17:32 ` [PULL 12/54] hw/timer/sse-timer: Model the SSE Subsystem System Timer Peter Maydell
2021-03-08 17:32 ` [PULL 13/54] hw/misc/iotkit-sysctl: Add SSE-300 cases which match SSE-200 behaviour Peter Maydell
2021-03-08 17:32 ` [PULL 14/54] hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 Peter Maydell
2021-03-08 17:32 ` [PULL 15/54] hw/misc/iotkit-sysctl: Handle INITSVTOR* " Peter Maydell
2021-03-08 17:32 ` [PULL 16/54] hw/misc/iotkit-sysctl: Implement dummy version of SSE-300 PWRCTRL register Peter Maydell
2021-03-08 17:32 ` [PULL 17/54] hw/misc/iotkit-sysctl: Handle SSE-300 changes to PDCM_PD_*_SENSE registers Peter Maydell
2021-03-08 17:32 ` [PULL 18/54] hw/misc/iotkit-sysctl: Implement SSE-200 and SSE-300 PID register values Peter Maydell
2021-03-08 17:32 ` [PULL 19/54] hw/arm/Kconfig: Move ARMSSE_CPUID and ARMSSE_MHU stanzas to hw/misc Peter Maydell
2021-03-08 17:32 ` [PULL 20/54] hw/misc/sse-cpu-pwrctrl: Implement SSE-300 CPU<N>_PWRCTRL register block Peter Maydell
2021-03-08 17:32 ` [PULL 21/54] hw/arm/armsse: Use an array for apb_ppc fields in the state structure Peter Maydell
2021-03-08 17:32 ` [PULL 22/54] hw/arm/armsse: Add a define for number of IRQs used by the SSE itself Peter Maydell
2021-03-08 17:32 ` [PULL 23/54] hw/arm/armsse: Add framework for data-driven device placement Peter Maydell
2021-03-08 17:32 ` [PULL 24/54] hw/arm/armsse: Move dual-timer device into data-driven framework Peter Maydell
2021-03-08 17:32 ` [PULL 25/54] hw/arm/armsse: Move watchdogs " Peter Maydell
2021-03-08 17:32 ` [PULL 26/54] hw/arm/armsse: Move s32ktimer " Peter Maydell
2021-03-08 17:32 ` [PULL 27/54] hw/arm/armsse: Move sysinfo register block " Peter Maydell
2021-03-08 17:32 ` [PULL 28/54] hw/arm/armsse: Move sysctl " Peter Maydell
2021-03-08 17:32 ` [PULL 29/54] hw/arm/armsse: Move PPUs " Peter Maydell
2021-03-08 17:32 ` [PULL 30/54] hw/arm/armsse: Add missing SSE-200 SYS_PPU Peter Maydell
2021-03-08 17:32 ` [PULL 31/54] hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo Peter Maydell
2021-03-08 17:32 ` [PULL 32/54] hw/arm/armsse: Add support for SSE variants with a system counter Peter Maydell
2021-03-08 17:32 ` [PULL 33/54] hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo Peter Maydell
2021-03-08 17:32 ` [PULL 34/54] hw/arm/armsse: Support variants with ARMSSE_CPU_PWRCTRL block Peter Maydell
2021-03-08 17:32 ` [PULL 35/54] hw/arm/armsse: Add SSE-300 support Peter Maydell
2021-03-08 17:32 ` [PULL 36/54] hw/arm/mps2-tz: Make UART overflow IRQ board-specific Peter Maydell
2021-03-08 17:32 ` [PULL 37/54] hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate Peter Maydell
2021-03-08 17:32 ` [PULL 38/54] hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register Peter Maydell
2021-03-08 17:32 ` [PULL 39/54] hw/misc/mps2-scc: Implement changes for AN547 Peter Maydell
2021-03-08 17:32 ` [PULL 40/54] hw/arm/mps2-tz: Support running APB peripherals on different clock Peter Maydell
2021-03-08 17:32 ` [PULL 41/54] hw/arm/mps2-tz: Make initsvtor0 setting board-specific Peter Maydell
2021-03-08 17:32 ` [PULL 42/54] hw/arm/mps2-tz: Add new mps3-an547 board Peter Maydell
2021-03-08 17:32 ` [PULL 43/54] docs/system/arm/mps2.rst: Document the " Peter Maydell
2021-03-08 17:32 ` [PULL 44/54] tests/qtest/sse-timer-test: Add simple test of the SSE counter Peter Maydell
2021-03-08 17:32 ` [PULL 45/54] tests/qtest/sse-timer-test: Test the system timer Peter Maydell
2021-03-08 17:32 ` [PULL 46/54] tests/qtest/sse-timer-test: Test counter scaling changes Peter Maydell
2021-03-08 17:32 ` [PULL 47/54] target/arm: Restrict v7A TCG cpus to TCG accel Peter Maydell
2021-03-08 17:32 ` [PULL 48/54] hw/dma: Implement a Xilinx CSU DMA model Peter Maydell
2021-03-08 17:32 ` [PULL 49/54] hw/arm: xlnx-zynqmp: Clean up coding convention issues Peter Maydell
2021-03-08 17:32 ` [PULL 50/54] hw/arm: xlnx-zynqmp: Connect a Xilinx CSU DMA module for QSPI Peter Maydell
2021-03-08 17:32 ` [PULL 51/54] hw/ssi: xilinx_spips: Clean up coding convention issues Peter Maydell
2021-03-08 17:32 ` [PULL 52/54] hw/ssi: xilinx_spips: Remove DMA related dead codes from zynqmp_spips Peter Maydell
2021-03-08 17:32 ` [PULL 53/54] hw/timer/renesas_tmr: Prefix constants for CSS values with CSS_ Peter Maydell
2021-03-08 17:32 ` [PULL 54/54] hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt() Peter Maydell
2021-03-08 18:49 ` [PULL 00/54] target-arm queue no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210308173244.20710-7-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.