From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38845) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xvs9D-0003d4-1o for qemu-devel@nongnu.org; Tue, 02 Dec 2014 13:26:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Xvs96-0003X9-Uq for qemu-devel@nongnu.org; Tue, 02 Dec 2014 13:26:02 -0500 Received: from mail-wg0-x22b.google.com ([2a00:1450:400c:c00::22b]:47358) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xvs96-0003Ww-IS for qemu-devel@nongnu.org; Tue, 02 Dec 2014 13:25:56 -0500 Received: by mail-wg0-f43.google.com with SMTP id l18so17690925wgh.30 for ; Tue, 02 Dec 2014 10:25:55 -0800 (PST) Message-ID: <547E042F.7010201@gmail.com> Date: Tue, 02 Dec 2014 19:25:51 +0100 From: Adam Hoka MIME-Version: 1.0 References: <1414590171-16912-1-git-send-email-adam.hoka@gmail.com> <20141130223134.GC14637@redhat.com> In-Reply-To: <20141130223134.GC14637@redhat.com> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms010201070103030609070505" Subject: Re: [Qemu-devel] [PATCH] i6300esb: fix reading config registers and accept writes of all length List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Richard W.M. Jones" Cc: qemu-devel@nongnu.org This is a cryptographically signed message in MIME format. --------------ms010201070103030609070505 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Hi, On 11/30/2014 11:31 PM, Richard W.M. Jones wrote: > On Wed, Oct 29, 2014 at 02:42:51PM +0100, Adam Hoka wrote: >> Don't require configuration register write to be off a certain length,= >> as some PCI implementations always access them in 32bit only. This is >> because it's in fact the only kind of access supported by the standard= , >> anything else is implementation dependent. >> >> Add support for reading back the configuration register values. >> >> Unify the MMIO register implementation into a common read and write >> function. This makes driver testing in QEMU less surprising. >> >> Missing: interrupt register is still not implemented as interrupting >> itself is absent. It's unclear from the 6300ESB ICH specs where >> the IRQ line is connected in real hardware. >> >> Signed-off-by: Adam Hoka > I don't really have any opinion on this patch. All I care is that it > doesn't break the Linux device driver (the Intel-supplied 32 bit > Windows device driver is unfortunately a lost cause). Did you test it > against Linux? I wrote a small test harness that makes testing the > qemu watchdog simple: > > http://git.annexia.org/?p=3Dwatchdog-test-framework.git;a=3Dsummary > > Rich. Thanks for the feedback. I guess I could test it on Linux. Should I just = run this utility? What's wrong with the Intel/Win driver? BTW, could you ever find some=20 documentation on where the hell is the IRQ line is connected on real HW? >> hw/watchdog/wdt_i6300esb.c | 134 ++++++++++++++++++-----------------= ---------- >> 1 file changed, 53 insertions(+), 81 deletions(-) >> >> diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c >> index 687c8b1..8512a91 100644 >> --- a/hw/watchdog/wdt_i6300esb.c >> +++ b/hw/watchdog/wdt_i6300esb.c >> @@ -212,12 +212,12 @@ static void i6300esb_config_write(PCIDevice *dev= , uint32_t addr, >> =20 >> i6300esb_debug("addr =3D %x, data =3D %x, len =3D %d\n", addr, d= ata, len); >> =20 >> - if (addr =3D=3D ESB_CONFIG_REG && len =3D=3D 2) { >> + if (addr =3D=3D ESB_CONFIG_REG) { >> d->reboot_enabled =3D (data & ESB_WDT_REBOOT) =3D=3D 0; >> d->clock_scale =3D >> (data & ESB_WDT_FREQ) !=3D 0 ? CLOCK_SCALE_1MHZ : CLOCK_= SCALE_1KHZ; >> d->int_type =3D (data & ESB_WDT_INTTYPE); >> - } else if (addr =3D=3D ESB_LOCK_REG && len =3D=3D 1) { >> + } else if (addr =3D=3D ESB_LOCK_REG) { >> if (!d->locked) { >> d->locked =3D (data & ESB_WDT_LOCK) !=3D 0; >> d->free_run =3D (data & ESB_WDT_FUNC) !=3D 0; >> @@ -240,13 +240,13 @@ static uint32_t i6300esb_config_read(PCIDevice *= dev, uint32_t addr, int len) >> =20 >> i6300esb_debug ("addr =3D %x, len =3D %d\n", addr, len); >> =20 >> - if (addr =3D=3D ESB_CONFIG_REG && len =3D=3D 2) { >> + if (addr =3D=3D ESB_CONFIG_REG) { >> data =3D >> (d->reboot_enabled ? 0 : ESB_WDT_REBOOT) | >> (d->clock_scale =3D=3D CLOCK_SCALE_1MHZ ? ESB_WDT_FREQ := 0) | >> d->int_type; >> return data; >> - } else if (addr =3D=3D ESB_LOCK_REG && len =3D=3D 1) { >> + } else if (addr =3D=3D ESB_LOCK_REG) { >> data =3D >> (d->free_run ? ESB_WDT_FUNC : 0) | >> (d->locked ? ESB_WDT_LOCK : 0) | >> @@ -257,116 +257,88 @@ static uint32_t i6300esb_config_read(PCIDevice = *dev, uint32_t addr, int len) >> } >> } >> =20 >> -static uint32_t i6300esb_mem_readb(void *vp, hwaddr addr) >> +static uint32_t i6300esb_mem_read(void *vp, hwaddr addr) >> { >> - i6300esb_debug ("addr =3D %x\n", (int) addr); >> - >> - return 0; >> -} >> - >> -static uint32_t i6300esb_mem_readw(void *vp, hwaddr addr) >> -{ >> - uint32_t data =3D 0; >> I6300State *d =3D vp; >> =20 >> - i6300esb_debug("addr =3D %x\n", (int) addr); >> + i6300esb_debug("addr =3D %p\n", (void *)addr); >> =20 >> - if (addr =3D=3D 0xc) { >> + switch (addr) { >> + case 0x00: >> + return d->timer1_preload; >> + case 0x04: >> + return d->timer2_preload; >> + case 0x0c: >> /* The previous reboot flag is really bit 9, but there is >> * a bug in the Linux driver where it thinks it's bit 12. >> * Set both. >> */ >> - data =3D d->previous_reboot_flag ? 0x1200 : 0; >> + return d->previous_reboot_flag ? 0x1200 : 0; >> } >> =20 >> - return data; >> -} >> - >> -static uint32_t i6300esb_mem_readl(void *vp, hwaddr addr) >> -{ >> - i6300esb_debug("addr =3D %x\n", (int) addr); >> - >> return 0; >> } >> =20 >> -static void i6300esb_mem_writeb(void *vp, hwaddr addr, uint32_t val) >> +static void i6300esb_mem_write(void *vp, hwaddr addr, uint32_t val) >> { >> I6300State *d =3D vp; >> =20 >> - i6300esb_debug("addr =3D %x, val =3D %x\n", (int) addr, val); >> + i6300esb_debug("addr =3D %p, val =3D 0x%x\n", (void *)addr, val);= >> =20 >> - if (addr =3D=3D 0xc && val =3D=3D 0x80) >> + /* register lock */ >> + if (addr =3D=3D 0xc && val =3D=3D 0x80) { >> d->unlock_state =3D 1; >> - else if (addr =3D=3D 0xc && val =3D=3D 0x86 && d->unlock_state =3D= =3D 1) >> + return; >> + } else if (addr =3D=3D 0xc && val =3D=3D 0x86 && d->unlock_state = =3D=3D 1) { >> d->unlock_state =3D 2; >> -} >> + return; >> + } else if (d->unlock_state =3D=3D 0) { >> + return; >> + } >> =20 >> -static void i6300esb_mem_writew(void *vp, hwaddr addr, uint32_t val) >> -{ >> - I6300State *d =3D vp; >> + switch (addr) { >> + case 0x00: >> + d->timer1_preload =3D val & 0xfffff; >> + break; >> =20 >> - i6300esb_debug("addr =3D %x, val =3D %x\n", (int) addr, val); >> + case 0x04: >> + d->timer2_preload =3D val & 0xfffff; >> + break; >> =20 >> - if (addr =3D=3D 0xc && val =3D=3D 0x80) >> - d->unlock_state =3D 1; >> - else if (addr =3D=3D 0xc && val =3D=3D 0x86 && d->unlock_state =3D= =3D 1) >> - d->unlock_state =3D 2; >> - else { >> - if (d->unlock_state =3D=3D 2) { >> - if (addr =3D=3D 0xc) { >> - if ((val & 0x100) !=3D 0) >> - /* This is the "ping" from the userspace watchdog= in >> - * the guest ... >> - */ >> - i6300esb_restart_timer(d, 1); >> - >> - /* Setting bit 9 resets the previous reboot flag. >> - * There's a bug in the Linux driver where it sets >> - * bit 12 instead. >> - */ >> - if ((val & 0x200) !=3D 0 || (val & 0x1000) !=3D 0) { >> - d->previous_reboot_flag =3D 0; >> - } >> - } >> - >> - d->unlock_state =3D 0; >> + case 0x0c: >> + if ((val & 0x100) !=3D 0) { >> + /* This is the "ping" from the userspace watchdog in >> + * the guest ... >> + */ >> + i6300esb_restart_timer(d, 1); >> } >> - } >> -} >> - >> -static void i6300esb_mem_writel(void *vp, hwaddr addr, uint32_t val) >> -{ >> - I6300State *d =3D vp; >> =20 >> - i6300esb_debug ("addr =3D %x, val =3D %x\n", (int) addr, val); >> - >> - if (addr =3D=3D 0xc && val =3D=3D 0x80) >> - d->unlock_state =3D 1; >> - else if (addr =3D=3D 0xc && val =3D=3D 0x86 && d->unlock_state =3D= =3D 1) >> - d->unlock_state =3D 2; >> - else { >> - if (d->unlock_state =3D=3D 2) { >> - if (addr =3D=3D 0) >> - d->timer1_preload =3D val & 0xfffff; >> - else if (addr =3D=3D 4) >> - d->timer2_preload =3D val & 0xfffff; >> - >> - d->unlock_state =3D 0; >> + /* Setting bit 9 resets the previous reboot flag. >> + * There's a bug in the Linux driver where it sets >> + * bit 12 instead. >> + */ >> + if ((val & 0x200) !=3D 0 || (val & 0x1000) !=3D 0) { >> + d->previous_reboot_flag =3D 0; >> } >> + >> + break; >> } >> + >> + /* re-lock registers */ >> + d->unlock_state =3D 0; >> } >> =20 >> static const MemoryRegionOps i6300esb_ops =3D { >> .old_mmio =3D { >> .read =3D { >> - i6300esb_mem_readb, >> - i6300esb_mem_readw, >> - i6300esb_mem_readl, >> + i6300esb_mem_read, >> + i6300esb_mem_read, >> + i6300esb_mem_read, >> }, >> .write =3D { >> - i6300esb_mem_writeb, >> - i6300esb_mem_writew, >> - i6300esb_mem_writel, >> + i6300esb_mem_write, >> + i6300esb_mem_write, >> + i6300esb_mem_write, >> }, >> }, >> .endianness =3D DEVICE_NATIVE_ENDIAN, >> --=20 >> 2.1.1 >> Regards, Adam --------------ms010201070103030609070505 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIMfjCC BjQwggQcoAMCAQICAR4wDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoT DVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNp Z25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA3 MTAyNDIxMDE1NVoXDTE3MTAyNDIxMDE1NVowgYwxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1T dGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWdu aW5nMTgwNgYDVQQDEy9TdGFydENvbSBDbGFzcyAxIFByaW1hcnkgSW50ZXJtZWRpYXRlIENs aWVudCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcJg8zOLdgasSmkLhOr lr6KMoOMpohBllVHrdRvEg/q6r8jR+EK75xCGhR8ToREoqe7zM9/UnC6TS2y9UKTpT1v7RSM zR0t6ndl0TWBuUr/UXBhPk+Kmy7bI4yW4urC+y7P3/1/X7U8ocb8VpH/Clt+4iq7nirMcNh6 qJR+xjOhV+VHzQMALuGYn5KZmc1NbJQYclsGkDxDz2UbFqE2+6vIZoL+jb9x4Pa5gNf1TwSD kOkikZB1xtB4ZqtXThaABSONdfmv/Z1pua3FYxnCFmdr/+N2JLKutIxMYqQOJebr/f/h5t95 m4JgrM3Y/w7YX9d7YAL9jvN4SydHsU6n65cCAwEAAaOCAa0wggGpMA8GA1UdEwEB/wQFMAMB Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRTcu2SnODaywFcfH6WNU7y1LhRgjAfBgNV HSMEGDAWgBROC+8apEBbpRdphzDKNGhD0EGu8jBmBggrBgEFBQcBAQRaMFgwJwYIKwYBBQUH MAGGG2h0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9jYTAtBggrBgEFBQcwAoYhaHR0cDovL3d3 dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6AloCOGIWh0dHA6Ly93d3cu c3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0cDovL2NybC5zdGFydHNzbC5jb20v c2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysGAQQBgbU3AQIBMGYwLgYIKwYBBQUHAgEWImh0 dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93 d3cuc3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwDQYJKoZIhvcNAQEFBQADggIBAAqD CH14qywGXLhjjF6uHLkjd02hcdh9hrw+VUsv+q1eeQWB21jWj3kJ96AUlPCoEGZ/ynJNScWy 6QMVQjbbMXltUfO4n4bGGdKo3awPWp61tjAFgraLJgDk+DsSvUD6EowjMTNx25GQgyYJ5RPI zKKR9tQW8gGK+2+RHxkUCTbYFnL6kl8Ch507rUdPPipJ9CgJFws3kDS3gOS5WFMxcjO5DwKf KSETEPrHh7p5shuuNktvsv6hxHTLhiMKX893gxdT3XLS9OKmCv87vkINQcNEcIIoFWbP9HOR z9v3vQwR4e3ksLc2JZOAFK+ssS5XMEoznzpihEP0PLc4dCBYjbvSD7kxgDwZ+Aj8Q9PkbvE9 sIPP7ON0fz095HdThKjiVJe6vofq+n6b1NBc8XdrQvBmunwxD5nvtTW4vtN6VY7mUCmxsCie uoBJ9OlqmsVWQvifIYf40dJPZkk9YgGTzWLpXDSfLSplbY2LL9C9U0ptvjcDjefLTvqSFc7t w1sEhF0n/qpA2r0GpvkLRDmcSwVyPvmjFBGqUp/pNy8ZuPGQmHwFi2/14+xeSUDG2bwnsYJQ G2EdJCB6luQ57GEnTA/yKZSTKI8dDQa8Sd3zfXb19mOgSF0bBdXbuKhEpuP9wirslFe6fQ1t 5j5R0xi72MZ8ikMu1RQZKCyDbMwazlHiMIIGQjCCBSqgAwIBAgIDCuV7MA0GCSqGSIb3DQEB BQUAMIGMMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20g Q2xhc3MgMSBQcmltYXJ5IEludGVybWVkaWF0ZSBDbGllbnQgQ0EwHhcNMTQwODIwMDAzNTQ4 WhcNMTUwODIxMDc0MzM5WjBdMRkwFwYDVQQNExBKaHhrRDE4bUtTQXRRdzBwMRwwGgYDVQQD DBNhZGFtLmhva2FAZ21haWwuY29tMSIwIAYJKoZIhvcNAQkBFhNhZGFtLmhva2FAZ21haWwu Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqLxgDs6fBmS12hz3dI7/IfhR jYKA8RlbAy2rAQWlXszd8pTyBFIHfIuvJDrvDXr9RdXjLK27eKdY5e5EI4hPp0NYg8KMPNOW pRgHxDftrLGZH0MfmYgYUhowMnO/hgAPw5CvO62nkG8sicy7rxE2ZonOPTpddFOQESJtiO4F QsAuiEGd1wcCzFNKwo7fT1sfRpzooHKF4AtGxDf6ivauK7t3I4zTEw2MkKDu0eWuVYQMFqnp eC4OHxRTWdVrwbZ4VtajKDauA5kox0GuKO+FrmRFg6Rn5acHvUcWWqgX65709eX7sAz3ouVj 3t876sdvZtBn/35sn+cIV8wQMI7aUQIDAQABo4IC2TCCAtUwCQYDVR0TBAIwADALBgNVHQ8E BAMCBLAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBQwDrJh6leH +ZkArOeY1pL/KCCV5jAfBgNVHSMEGDAWgBRTcu2SnODaywFcfH6WNU7y1LhRgjAeBgNVHREE FzAVgRNhZGFtLmhva2FAZ21haWwuY29tMIIBTAYDVR0gBIIBQzCCAT8wggE7BgsrBgEEAYG1 NwECAzCCASowLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w ZGYwgfcGCCsGAQUFBwICMIHqMCcWIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MAMCAQEagb5UaGlzIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3JkaW5nIHRvIHRoZSBD bGFzcyAxIFZhbGlkYXRpb24gcmVxdWlyZW1lbnRzIG9mIHRoZSBTdGFydENvbSBDQSBwb2xp Y3ksIHJlbGlhbmNlIG9ubHkgZm9yIHRoZSBpbnRlbmRlZCBwdXJwb3NlIGluIGNvbXBsaWFu Y2Ugb2YgdGhlIHJlbHlpbmcgcGFydHkgb2JsaWdhdGlvbnMuMDYGA1UdHwQvMC0wK6ApoCeG JWh0dHA6Ly9jcmwuc3RhcnRzc2wuY29tL2NydHUxLWNybC5jcmwwgY4GCCsGAQUFBwEBBIGB MH8wOQYIKwYBBQUHMAGGLWh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9zdWIvY2xhc3MxL2Ns aWVudC9jYTBCBggrBgEFBQcwAoY2aHR0cDovL2FpYS5zdGFydHNzbC5jb20vY2VydHMvc3Vi LmNsYXNzMS5jbGllbnQuY2EuY3J0MCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wu Y29tLzANBgkqhkiG9w0BAQUFAAOCAQEAEKkx26T7co8xfwGmT5IKZHwyi/Bzv7tcREuKD04M 58ovevgoX3gWY/qg1udOUEBGvATfryAQ5inCqu8iQtNIul9m3srk54ffLn3HjtuTaGWo7He1 TekVhtvRuwOK6w1bBsPh5kmaKruDWqFvUN3NnTqo+KZkY2ADvUo2t1W30/Ml9OY8Y4hXdZlW Fzkjn5uEgTB3nQa3hdTb7COyKZW+WXc1eZ6NrP+KCMRw4kelGJEPy7BX9hia/kGZcOBSyXWY paz6lZVur0UnLkzgdGCmAuBnrM1Z4eqMvuiuAPXUK2twNGWnixGESiEbtQjA6FOXdKwfFpPK 1VgtAA7J9tRRMzGCA90wggPZAgEBMIGUMIGMMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3Rh cnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu ZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3MgMSBQcmltYXJ5IEludGVybWVkaWF0ZSBDbGll bnQgQ0ECAwrlezAJBgUrDgMCGgUAoIICHTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG CSqGSIb3DQEJBTEPFw0xNDEyMDIxODI1NTFaMCMGCSqGSIb3DQEJBDEWBBRULxvOyxBmQT+r LSIVRWu3ZBChyDBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjALBglghkgBZQMEAQIw CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0G CCqGSIb3DQMCAgEoMIGlBgkrBgEEAYI3EAQxgZcwgZQwgYwxCzAJBgNVBAYTAklMMRYwFAYD VQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0 ZSBTaWduaW5nMTgwNgYDVQQDEy9TdGFydENvbSBDbGFzcyAxIFByaW1hcnkgSW50ZXJtZWRp YXRlIENsaWVudCBDQQIDCuV7MIGnBgsqhkiG9w0BCRACCzGBl6CBlDCBjDELMAkGA1UEBhMC SUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENl cnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJ bnRlcm1lZGlhdGUgQ2xpZW50IENBAgMK5XswDQYJKoZIhvcNAQEBBQAEggEAdesfkb68jHkD 4aYkcYUqAsL7XZ2DET4ty6PxL7t/D9oRIXKRvpXJYPb/AbZpztG5c6SIF8PesY0P3hiMGpH8 e9Cwf+nOU6WXbWPybgsuVu1ds4WPWNJcgNveQ7hFZm1N2BmRGUsTCx24tOwC8nWxfVSpMVQI BGRZCOLaWLNFvW4QUyaUPZFpp0MDx9ZSnQPPWfaLLdTj0bbAgBAcpOtWYlsLl78GdVEytq+d SpuKfDudO9X7IL6RkKgoSZb/EM84hhspCd5KQRz3DXcG+SEci18ec/Uojuedu4f3mautRfhF LW0TeQ8Ti79g3/Qh4C2YkJ4IkK9Yinym6EQvC7j/GwAAAAAAAA== --------------ms010201070103030609070505--