From 51daecc236fbff0d1ed30a9c63a3af6e8b5c7392 Mon Sep 17 00:00:00 2001 From: Mike Nix Date: Wed, 27 May 2020 08:04:49 +0800 Subject: [PATCH] Xmc flash 2 (#7317) * Remove unnecessary XMC support from eboot eboot is always run with the flash access speed set to 20MHz, so there is no need for special treatment of XMC chips. * After eboot copies the new firmware into place, verify the copy. If the data written to flash is as expected, the line cmp:0 will be displayed after the usual @cp:0 from eboot. * Disable interrupts during the precached part of _SPICommand() For some reason this was an issue during the reboot after an OTA update. --- bootloaders/eboot/eboot.c | 98 +++++++---------------- bootloaders/eboot/eboot.elf | Bin 34780 -> 35800 bytes cores/esp8266/core_esp8266_spi_utils.cpp | 10 ++- 3 files changed, 38 insertions(+), 70 deletions(-) diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index edbd92aa54..be67b0b6fe 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -12,7 +12,6 @@ #include #include "flash.h" #include "eboot_command.h" -#include "spi_vendors.h" #include extern unsigned char _gzip_dict; @@ -115,10 +114,12 @@ int uzlib_flash_read_cb(struct uzlib_uncomp *m) } unsigned char gzip_dict[32768]; +uint8_t buffer2[FLASH_SECTOR_SIZE]; // no room for this on the stack int copy_raw(const uint32_t src_addr, const uint32_t dst_addr, - const uint32_t size) + const uint32_t size, + const bool verify) { // require regions to be aligned if ((src_addr & 0xfff) != 0 || @@ -158,8 +159,10 @@ int copy_raw(const uint32_t src_addr, gzip = true; } while (left > 0) { - if (SPIEraseSector(daddr/buffer_size)) { - return 2; + if (!verify) { + if (SPIEraseSector(daddr/buffer_size)) { + return 2; + } } if (!gzip) { if (SPIRead(saddr, buffer, buffer_size)) { @@ -179,8 +182,17 @@ int copy_raw(const uint32_t src_addr, buffer[i] = 0xff; } } - if (SPIWrite(daddr, buffer, buffer_size)) { - return 4; + if (verify) { + if (SPIRead(daddr, buffer2, buffer_size)) { + return 4; + } + if (memcmp(buffer, buffer2, buffer_size)) { + return 9; + } + } else { + if (SPIWrite(daddr, buffer, buffer_size)) { + return 4; + } } saddr += buffer_size; daddr += buffer_size; @@ -190,29 +202,6 @@ int copy_raw(const uint32_t src_addr, return 0; } -//#define XMC_SUPPORT -#ifdef XMC_SUPPORT -// Define a few SPI0 registers we need access to -#define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr))) -#define SPI0CMD ESP8266_REG(0x200) -#define SPI0CLK ESP8266_REG(0x218) -#define SPI0C ESP8266_REG(0x208) -#define SPI0W0 ESP8266_REG(0x240) - -#define SPICMDRDID (1 << 28) - -/* spi_flash_get_id() - Returns the flash chip ID - same as the SDK function. - We need our own version as the SDK isn't available here. - */ -uint32_t __attribute__((noinline)) spi_flash_get_id() { - SPI0W0=0; - SPI0CMD=SPICMDRDID; - while (SPI0CMD) {} - return SPI0W0; -} -#endif // XMC_SUPPORT - int main() { int res = 9; @@ -235,47 +224,20 @@ int main() if (cmd.action == ACTION_COPY_RAW) { ets_putc('c'); ets_putc('p'); ets_putc(':'); -#ifdef XMC_SUPPORT - // save the flash access speed registers - uint32_t spi0clk = SPI0CLK; - uint32_t spi0c = SPI0C; - - uint32_t vendor = spi_flash_get_id() & 0x000000ff; - if (vendor == SPI_FLASH_VENDOR_XMC) { - uint32_t flashinfo=0; - if (SPIRead(0, &flashinfo, 4)) { - // failed to read the configured flash speed. - // Do not change anything, - } else { - // select an appropriate flash speed - // Register values are those used by ROM - switch ((flashinfo >> 24) & 0x0f) { - case 0x0: // 40MHz, slow to 20 - case 0x1: // 26MHz, slow to 20 - SPI0CLK = 0x00003043; - SPI0C = 0x00EAA313; - break; - case 0x2: // 20MHz, no change - break; - case 0xf: // 80MHz, slow to 26 - SPI0CLK = 0x00002002; - SPI0C = 0x00EAA202; - break; - default: - break; - } - } - } -#endif // XMC_SUPPORT ets_wdt_disable(); - res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], false); ets_wdt_enable(); - -#ifdef XMC_SUPPORT - // restore the saved flash access speed registers - SPI0CLK = spi0clk; - SPI0C = spi0c; -#endif + + ets_putc('0'+res); ets_putc('\n'); + + // Verify the copy + ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':'); + if (res == 0) { + ets_wdt_disable(); + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], true); + ets_wdt_enable(); + } + ets_putc('0'+res); ets_putc('\n'); if (res == 0) { cmd.action = ACTION_LOAD_APP; diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index f9a641c2f37fa922c86ed25b7a6ec080d810b940..60329d847e6307f2211d8c762ff1a6f68c4da0d7 100755 GIT binary patch literal 35800 zcmeHwdtg=7mG?g9K5{QPc|%AbkekaR2_z)Bi4YJZx$-V5CIkV&>&**N^CAyHCkWL- zb+j$`o;Gd3)@kk6+WKgn>8DeqYPAEc&#Eo7YCBe~Sj5&U3itc{_CEXGa|1KenQ!Ks zKR%D{v)5XC?X}lld#(LA=j5_u@yaEJVF-Ph;xa*O!=EziYLKtJ0XLTrH6kE9qC{kh z3|aoXt}r^!6n|AY1PQV8^g@{c9@-~_m$K~ovix{voj_WZE(DXuQNC(2k+WQs`^oi* z1wOIBCl>g`0-spm6AOG|fln;(i3L8fz$X^?!~&mK;1dfZTOc#GPy~>0ZZ7zgsLMot zXsW35$#eAaAH{Y^_5-n4tnhd&wlJ0f9KfACo6GY%%Ta%YsQc!xMcqo|B1K#d;?6f_ zin`;KqHbS>sC#JAqi&H6`a7|aoy;@EABK=$e?-&;(Y_mLHc}tb9;EC?k5|1M^H)7p z^m5i=^O+Z8bIqb(#Oi+$D=i3?3*&{@0U=7#d{x0`GfUG-te3JThUQv9Q#@Ie{b**| zaZ&ZNSoWi@%nMqJZmfDL>fd5K#TtjrkImq|D}(i-tRYx$%r}Ge=KO1e^{(K)ZNYkX zZIN|Xu-=nd6gXJ#HU5b;cB3O!fp1H>^<*^r(Eub10l_a{d}Gy7)A}r$_is5E^}ZH$ z8{Z@Un%BHl_r(sI^Nt=fy<>$aPg`JEpMBGKGt2lU%Re^jzZI)BZalhTO8q^t;s?`< zz8M2BV@h$2%ZukM%d*PTjIWaO(ETM@Gmh>y(SC5ZS6HDX9x?Gy(C`<}zo+OcvD&Ih z<^tC~m$0&ZTb_)*bnzSY4*i~r9yWFfzg`XcoH21-0|V61P;Pah3hBB?Jo-(C4; z{fAZlEl)*XzIad8fm6mYGkACA$>3Zwba%n3z`)7sQdbCs>RMOjWr0Aj z`0lbU^W>rqckuA3$KR!h?dHj*zBUm&eERX@Y;2>+c2dhd$74s$$D<;AcV5x**vUo9 z+;5sit7BEGW6Lv^7uGk%N-N4UJP!!mz6z$2lZ)26A^qf{&B&&nTx2zFbFaBMd*{}y ztJ_6W*7`L&j~c&xq2ca4EBjT5?6h3Y=LDIlfLFeY8Vnw?bTrH;{k6Tx_NOR_EhAlo?~e*e&0Ce zd8@2+$MK55u88BDiFIM-N>Tk zn?lz4yC;gOiLr7Ev;xwGn|J3z&CHXFO56*qS1t?~b|9k;-NzEp@1aVaR3I|cU%Gdks9H27?^=(T8I@e?t`mnR?oz0x%PavB<1lOT5JL}`|l7TkBuvr*G{ zm*h9Htl{aC%_oXQa9@jYjHKYcUgIqS^Y1d=V6N`9RmdXk-7L`2n_CPGyahTbmAdd0NLLs z0ND>PKQ!MPiwRM5@9C<0Pag<~WoBhf0Qp?g`yuEn&bRXRe*3g{j1b~}jK!|zeLDj? zJP&z2JGWN$_6{5mX6?DFGPS99#x0je>(@*>J+XS}Eia@U$DA4n1;YD=g5QmqQP-}I zVm=HNXG_j$$Db;yy5n@7qMMg8?nBbCL)LiGQf(z*Rch_mlgn&|4)oym7)W!Cnw!AOzee*LP zZaHT9?|W+hcGpq&DNnf*+-YetDVKCw|&iZY@Y#UbL>N zBkL-|7^HDFXJHmxBDNW8tCkflE&G+_w#F5_)?2gZM59=7UdSaTE)qF);+*~SV#T-q z-gn=V`(N7o#%Dg*lKp5UdMf*Q*enVAt5QRAS01{#+*;f%O6OaBr7KJ3`>Fy}^>gP3 z0&d+8=={`vYV5!7<-L}5%sl1(NzP2r-;Cu6@{S!)CyyXE-NtT_w* z;Jfc+*-Lw$+@EL`?Lv-asowkVJ7peoU0@wJ5;(pn3xOVvipB58!bO?hv8;-fc`wgqnj9z*$ zy8hYdy2Iv)=q0<}i&>4<*rVowvH+%1>-=DJ)dj9{%LCYT%G~HG2+gZ+z|4YC{|myyaGNwDIxZ$3jIHpA0t_H7>1w%5t5&*lUW)!JW-Z zMd-&y@h$J2a)*m9Ub^se)aHV;#VepqL%3+wFRLD3E-ce5x)kO)ShW7xqIItotvyk6 z$(OR|@bH6!QS;fT@#t%(o_Y1u0;@dDT4bH$uiEuOtmrqVs(y3Inre-E{P|dLzZu+6 zQ1s#{%N4qyAQX04*M-7vt3MR>Shs}2UaKV(PO-ig3j3_aP}pxh5DJg6&JTrCtsjTN zmQ@`Jr&-U1!s*tOP&lK&ZT&VJ7NKxv!B{IN95zDXtb(c5d*QGd3TOMOo-BGPOGPC7 z<>kH4-u3mT_WSRn`yDoa`E1Fzr<)tXXnS?8w4HJJmh0VO{6E8Z;LQi;}m8PtXeIhdVQu9a#|$yT!a9eN`%d zi(6Wvt z&cbrFI9nXW=s%uCckop`9Sj5le{%AI5$p){!{)9GQScrnqoHTL1@O6YYgalZx*O-* zd<+88MEkY>0tZWjyx_i9ia-AnqN`=s`?2CKxaO`8VhcEb?)r0V&N0u@W4Y)&sAI&M zzS!=Muquo3UD?>JLxA6=0sM2!3I0EXY=NaOE_mv)&^>jqtRg_bt!5@Vfgu?pl6g?rROrnd=U6K3#Ph?`e@N z7y@U-m`fN#!ZJhvI4_{jhoER1LsiidI>!1kh{IOr3c*H-`r&G zG)j>3s(ClF?kmWZjDVZ-#^+sbo=7R`3&f`)@p>M-rN}iej!}^1PD8d6%aABTlGlmM zy7eg3e3>AoKRxCP?k{?jdT!QC%g}Q9UVIG%C>{40@zy`@lI@S~KXJYgfAG(lb+rIx zUxB|3JRi8W2l=R&YzMjT{midrDgf)+g__Q<-($laHgG#25HWW*sJqxK7F+)X>mxwCI+r1?CZJ5Wap#Abb??P}R`nOPQf2j>1`Q+vKv-8_qjmp+d#5ql7Xo1ZHf(s) z$C-6(YqVZ4qm)aY2f5SEIk>ysDW79zrd$VQ+=jOZRb0zKa%Eq_0>f7bire&5v*35UPfOsabMELH)%`=g(;X992ClfY(kB}ZD?DB0TJXJb@aDAFg(|!gL zyb_X1SuT9bVK2`Nn|D1MnmHLf{s*bGH)|8%F^ym}#{3u{gFHi|x*%YuH~;GtM&-N{ zl&}RLcqgvF-R;`}!QKMN;yVn-_f8@Yrf+5sf+g)f00rps4}qj-TyCb+9tGq(9|BY6 z5){5N+*9Tq!#yCZ^FSdeD`qJCH1JFcDl~*EgEi0n-ymfzhlXxX$^suqzAPXq3keEe z47Zee!fqdxOIb=&`?3e3n?%a;IViP!CrMvHIMdfm_<~0PkM&(eITsPm^Sy&wDHjti z@C9&BSxx?cuaZ1XKLI>7yRD~Pq^y|*&S}04l(UvjQ{oGge;wg6UlIA&vu>sD1nHNO zUgK+n`BFAeey#5T*4;>+`Mzt&e;MIA-*cp2P7^H3d4zD3@YhY)G#!nOy#!q2C@u&r zmp7F7A;9a-0pd2yd}QNWKsT-+pI%Rm;VV&)*9Eeyg`)h2v5uaL*c6&55+B9m=BC1U=8ocir4O8|6M1BCv@p`FJgSiDY$I`Vd+I}pg zN;mOBJ1Q}QlJ!z=3?BzgX*Yw~U5diMPXHKY3^+7X)Z5c9jB*OR7b%D&o)I8h**pUchE<+1FnZoEY7EVni#{2J?I-(RilMUEJdq<1w`9e0uA%u zc8HW_mF;_mg#Tl#2o}XPfmIsNCC0Cz0k_hC!rs>y!@o^IBX6^7TiHlIpozD#k!?gr zh;n8zt|EF4EHZH#nXhI&4)qkA1cY%dOP>Wg?IY0NApHXhx$X_1r-|M`w$D=XWUx*t z$IaM9>)%E+!qVMD4+0H%S^7CTxNGnC2B&<5qOPaqxhPEE59KN739N`keQg-tFSAdx zP*!*k%IFg-Q6^14Bntn*rd_US+eP7%Hf=!Dt`UX5uxZz8+740tE6}dMC>MSNpbxj5dHzekiEpZ@o#mkY!P z)}jt!e4i!TQ6lp9q3AA$$iho)CCkCfcCUeMgEp;R(+p9#0TmxY#dV72-LYqkcm6a{ zH~>1`c1Y6o44@p>z2nv~UQzfnn`OUZK@+N{BF3J&DM=K*2Bt%h^VnIL7{&P?g5?iV z_ti>}>1S!M!?c6mQX9jMVaujW_j4BP0n3y}=qXQA z)ayVCTDn?=@eJ2G*WTmTOdrB_ocp{%>^~+&;ZDX&tl0{5vdI4|OR>?Q8GUsahZ{i1 zM)}v1*>6$oUv{#??9=ZCVISCk=TDM;P_h@^YqS3XsBED{6h36r-qN&QQTQX9c3RWs ziQ>mWn+VMcp9a7Po`5DM7)?f{D1HefyrU6?ui6#o$g&1=s8STZY139HnlVolp0G)m z*=#=O@sUmI)3h#8=*E$Q*4V9S&@IiTeM!@x+c?mqZUF$)?IBs%L{BU(0Zl4bW!HS( zt_kJx=h`$_1B!|1tAHie+P+&7BKW+OJa-Hruorn${``udrzg6b+J# zw}8Zjqj1PBTd(=sMB!&`TDPXbMxVE7*V;5{dz($OwJjWg&A6D}ZMOq!Uky?zO!h-X zqRWZm6{xoeL}78&egQ>tTZ7%!j8YJc4!W^gac2M*#-};$fq>VVvWgEOqpIu>GbVDf z9r%l?f~iIZ%#1h(guX=?gZUsq210b^h3L6w>@<+Mq~=n3?mzHWhMRD#&z#pLi?TW3 zPw6f1LQ5%IIDN?thN{BtiI};FMORWHry{lgn7JISrSy@=X~rgUe)i;$$hkqbEoOcQ zPG2sGoDFihWmGq*(98_hk-HnZ-x>NQ!j@hKeS5%fdhpEmDrsLe;8drvLd023jbMGyWD(>f5%Om&Yo-EFGUb!##Cidkia$oMr ze+Py3p#jlF7_EBb`mFZlo&w1t_vM~R@?CC-U_H6k0z-f(rzvm>Zc9H@F3(_ zEqyI^!6Xkh3oCFlTr4@4XtqReK(%&2=~$jTl<^fJ%^leJd3S>K5uy;2(vPyYfQStD z-+-P;+*JG1)Spm;eAd>_H;m!KQUgxg`2!7QMeKU^#c)OxB-2&mdK;)Bs|wE~J|{K8JPSgGo8y*Ah733Fx&Oi@xZcal82%ZAC^agn z#yxR0&QWUg)9ACw^#Y2<>xz%qZO@_5_hs8GN^YAH^61^heEs0Y7#2T*>$}Bw;MTU6 zZ$x!^c^(w!bra@d+sn`D+AihVZspqa$+Nn)n}=Ul`7&8955KmDdE5Z51=;JS-=htl z$h>ZD-%@;+o9@~Jfc!iby5|xUejW?m^PUD65M!_=2!g3shYaV&K6Sm-|Y ztH9FKvCzHX4-nwzvCzGcprD5ccRgXZpT|P?(o~fC(s?X&FK4GLKaYj(6@)YWJQlhy z_*=kZ{X7=BFCv`he}`>dOt`=wz}>x?`~g3Yh3=+3fTyPOSm<8E)~ES-EOf7}2ff4} zCjUCZW&R@auV>v#KaYj(OG&Ts^H}KKK>4-)2UvF_dFK0hEOcK+xXw>UcVGT0;6)ic z7P_N^<+1QxpqaFCRy}SWRLbTJ)_z;w-$%I}b~&5r;s?oWECkP3#M(hJkITI>+9`~m zQ370${%>^YCw<27cfgYOGfAYHW3WrhE0HKmW)rQVI6$PbD1 z58@Ci(G+ZSpeILr!rxKAo%)HPF`NghPegp)Nx*0*c$gCJ-kI*KANm9N{N-8Mn zpcI9`b1x{tOi-p^4r2IY@Sme*@3MRPd8IM@0EAA1b>F3RA4R2nIYGWh&5i+`?#1Ip z>Y?QnKSn7YgADp{rZKz(u2BLp9)of+5Va+;>mGy6oeR8Fj)THC0G}ZTGDXU{9(Z6j z8Y%?yOuSAJh9wKWfr6P^X|^=MklT%~(5nHA4Ql&Rh zvjn3w-rz8e8v_O8@aD@}+-%Kg8N?F;g^v*LZ0pweZ-7t7`-phEJJ@UnEm0!{=!dX4 z-GfL=)W~LYv3n@#M7uSz-7wMCINA-gO!~_lgY{f{_iUf}9y?PjyUU%;%!?BE|04cf zwyMg1O8n+T`5VAzz^~@Y+9?(=ISLA&4}7Lv8Wnyi@bV|ok?%voOztO)6|&+83Z@t1 zQ7)Zh3Z4^GPB9vdYV85D8c>ASm!ce1X7pbL4__mVa6cR1BXr{uqYUN0BA!ottt_96 zcNH@qP2dZFS6m8V^qv9;Lo*mryPfG@k87YjxZ({A09Cp`vf>A$uaP}#M2 zl^3P{y<)ovj_EZDAjGwIEozRTSq#iAa(%!=WSIK#zA^0c!6swz)Sk2Rs}Mc~Cp~xw9+jczm~dz}XfwUY=3zO;W3>@NxyQv1 zBEjNu@#{z-s=65SAydB>Fou_+fe>sEGO4lAP#sVlpMj1>V|6Lb7BbbuDr!C;y2IFl zN@E#qI~e3+8E6v9Mejbt-idRbBj+EaI~w`hLtQtbeDhKbsBTDZ_j=TUOw>S~=@~S;<<(+QYK;92q!Yk+2YRc{IUN zM59|;28oR0r(w& zia8L)+2_kri$>SbV_KPt5fpK@`EEkNif`KNPbqde3&<``f5PV0s*8#rVi34Y{n1hX z3D77r4Fk(ykP|B+Ldm!tz2&Nf5_^70r~?c7MF!HRQCPu3&Odic4b||G#!2fR6ErzRkf!@9 zD>5K{onVr*>!IKYn+6Y)6~6%*E7IfSl$Zm8+(J(h=j~>U%w@kkE`CET_t-TKh9cTw z-c-rJ53J8CWQ_%?2IrIWhDbP1ad4)QZEV#dvc-9PB5Krak|Ox6_QH!maNn>Q`cSv* zI{;*Ja>*u1)cphk-8T{*T_k>v;dG07n8H57{05?Ugt;EB$Lnf5p3{dCbso15EoVK~ zxJx0)l+QhqPv>}Z_#mX&=N9|a;&F4ruum=SnW*Y2x(F06Pc9DuNKq#jf+9toTz&#D zfVW%72>N?)%TV}B0LKtdoLp`Lma0!Kuc1pR>f}ODq^Oe%VRwo;xtIujpQTPN)4*b- zsFMrf%oKHU;VLyYMV(v-=cTBV3*my40PgP94SGpR znEdMqm!+ta3+q;f}P6`6=q;LbxtPom^;wMQQ5fLKr6(kNXXD zFufjF2E~00ER#2s{8rwN0kKamS#Au1QK4Tr8^aev;cNtG1#4W75X+WZvIWB1Z+?b&J#Xc-AD#Q1k@HL4R#<4rKJ<)scWRjO973o>nB5=Tx9#`gEw70m&XMIa3y)3t6&moSuyqeM(KXnB!0Y z%wwlRAbet+QJk-u$n{9d_*urneAPdeWEt7sy1YBW`P3rM6BlX1Ciyp9Yrs@hD4FoL z*BZji+Z)cqSr}ZleaKZ%lcXOvc841Y?^G&EQGr>x;D84aE4w2<9cM9cTIX z4Vs8sw=-_f2v)|G&ly*KN5DXJoHbRPq-tAQI`Gnx11~)}@G=~75O~^NiNM2IgQ1w? zw88S6fSfkQCdNdX3-fbg954gV!tgW3i}RI9ZchZNjvv@LKT(HfpD?%Oih9dIG%yRZ8X#f$Z@%Vt*aR3py!c(z zE0Ups*)hq`cRVses0yFsB(w8Fr7#jiGg~jgjm$1ba*ORBL`Dc5lo%T#^ca#MHZprA zUZ6G5BHf~IXJCXOM6!XyF^eAC<*T!w;8^${G#K{wTo>%uXRC+lAjBO+bQOn4N=70-GULuScfUUY*1ck_=7E7E7>!nXSU`7y`Abnc*=6 z<{{ZC5WHHK5g4+|21Jlx6YK=_hQ|!#SdQjgR;2wo%&i4XkZ8ab%3j5xImyuC;! zUL7-MJrics7t2431V`eBS6@>gvwM+J5gn_i#0pcz@d+a&d>_e+;qk>Lj1YcE;#W$X zmh?hAL@~>h8q!&d0kK^aIGZKE?H1%kcW)h|Sta6R{go#o;^|o= zQ_LM<{-TuEz$}P2;|Nk_#S&~_)~~3{u2fWJ_baMXD!+$fFPZaWCsS07Fz2UDq%&95 z;^V+?1zuD_neoLvf>sM<=>bVJdWZwGep$ z5Q6U+jlsBk{um`sBDsWb=Li9cHpCjO!9N3iMv^XJ_B@gY?sw6&5rT^O63t9uBynEQ z7n}Y73B6)=N`j5dJb3A!JQeXPgM1|LGHa0F24qpVH6H;B0^|e|IT8n7tvv%b5KUDY-s*ua^vs%)TnYOPFci#AHd{ zTP4G4X0J`4hmm}%aoxIwfI>_b9{HB>^?+raDvDPlFVqew0> zuw#S(<-r@ZrO5i0Bt40L;()k`bSCZmU$T!d*O3fRXO~9)=NMu%slq@kFlsqH` zN!5fAf@E^I6kkNwD-yGa1TSOOj+88oyyr=VMrN8JG4csvt0^ohc_Yj;Z(`&%FRe}H zjgmR;zHESGEac3Zki4P_lZE^P327e9!g)>eIMx)t&)z8|G%$Nuf)QqqA|>}M!P`jQ zdnE5=%)V#yHjWUwUllOZLK3~#Lf9ip`MPA@$n5Wtym+UH<$Q!NWx*K}BI7ggXd%}r z&RdX;C~!YA%1Ejo_v_L1_e#zU%qYVphIWh)_<^EpKjT~Y-%C;hvp4Zd7EZS2H66wk~URv+scRt}Jd~_O=uix5bAbol>RD?8>Wj zWjDBevPJ{56%vd`^F=`Ux*fjG%&r`_ldjCcV(om%+Q@9W1eCvTGH1 z6S83i>bjbd>XCC75@F_K=SEsrBc0X1hUA#8609LdaeP@%v`{TupafG?J6Pk!&`LQv z;t0-UkJ7wUO2bL@;**~)HAPLF6Fz;76WI|*GyolGeRg&6)>BOM1JN| zC0sSae1?QWBg`u$Ts^{kwuEa&n9rB+IU~%&5}rN6e3^vjj4)p%;mQ%_84ZV6Y9FyA8Kni1w#O8A@+=G!D(Il}w~B!@M=1(a{JVNX5MeC?et zNpY8X2&5mXip+j5!3eWIAmL<@@Rz4R_-9$(!0hJ|YhHdmt>uW*N~l1;99h_9?4;a zZ=&SKs#J^PyZKKk(jc`{@#8;>AIKqrL8k3tDjd@LMd_?~ZA^@Q1X zCAg6p-`yo^k>G74?{|>oLZ(|_jmMB6p4rP1+`x?Q>yl;t1eB*FLjyCu>q9q~{TwM( zkMVX<6dxT5IWGAcnDxr-+y-V_k&?xa2W5g}XkgYU!MMR@0j)wxK{I1wI5ZQfmV|yq z&|O*t0I%9`;j;!@`fvR7pX%|!&{sg`bC^;x;8@GQUFUILn=WK4cwoZUFd+ z@#sr`5T(Cc(x2{(=HttDQ~YJ3ZlA7D0-Aoo%dxq`QE3hAu@;FByncYBi->PP;`6tA z9rWw%6Zw4DjYoOSPkZx$Anna3eY7_p&(Yp|!X@nue%hOdXk9NC_TfR0r@1mDO{d*y zb0!`&X?GqYX&NTlown8d+=zsbxC`NaK-0g1S$`kWw~#iY?}JEJBkA&4i1j}q>4`$q zDVs+ijvG%f95nLN$aO`j@un*o8z_wiQ~qlOPA~RI8GcR zCXNvkqeYj08*e#GaR}86<0HKI!M{6Ti!drS_jI*Ybai)ZtElg59qj1tsn{ItYuy^{ zYpZDM@2w5Zp54;ZrNN4Uo}SMBifsdJ-Tl$>&TUndv&-8$+bcRdnkzQ7w47N`Gplx1 zsG_60rE{>gP5jq1c1G*A_=>J*%jS;m|L$hQtXUQKUsR1A;BxlxDV z*f0fXm`y1=Y?HlHwpOLvWsh9`bnvKBA9>g({IxKJDR8@gA~-z$T-*(53q5X1RgQTw zC3O_V#8~RF(O$#ODzDK#Ny?DygQ6%;c1l)WqdhA}wn82HWKT4mK9OPfjpOH$tq;jD zQN75Lb{zC)p)@&CRF7yiLwbxF8n^8?$|NSO0~S~Zpwv&>4As48Pt_j_DN19vKO3-{ zt&-EV!9Nptsg$~2YU+`9zr0(Lo+iBqf5R+efGeQuu))qSxc)|($s@a@4C=B6hM}MW zMR$N*(nh3-RT%b2cgV7xf-+721l+YRVzB^4O(-;z;h!q+%0Mc>$)lth(v*52)l{H( z$ghG@OQtiKQd^flC}qN2a4vN8CCrbexbwenz51VCLjG$O!oPCW9kr&&)#;2C3AT=} zNNRObs~1+Mvn)wmd$`FOXHS-D8s2ILEdx&nAw5k`?1YssDPO&cqb~#D8tDge5`!ly zSLf!ysnGEBXk7UGKx z*I-vATZMSkZ`T_U~Aylq&bOugTa^E0_R?gcJk`67Qgp0|Q$)<6__0Z+8V^A)@-M{Nj zIajOAf>e*eA#BG7LC)6@A(vX|kA4|NF1@lKVla=Mp#tVgdvW$+3!_#cNs*nthV!tN ziXM5D_roGeH6BP@2cep52L0t!t=3r;tX_Ku$IXc|lvCtVpx0kW=C|~6W#ZY!^)5uZ z<+A78p6RuL%b{B~rREE@J#%rK;(Ht(ja<7-w#uMYY zEANFir<&?b7*Fqh} zdREqRx16uzv$CxC`hTJ#PvWjG!kDll+S)D$))_Ev>8@%p)#f$DHX4noLx`sS&%s-y zH0ft9W!Ow<>MipA*VE-d$5%T(Sa98sZmGphhN69&qhgECC0sv( zm~m3eE2K^;w#GSJLG4XVX+gQ_x*i;oqpN~W8-{MKwh4xRyljyRyWu|vcb6Y?BuW!| z>L0oMJOC&M<~*VgJ$rV@&8Xf4bAHyoL_ap=5W4MwOvIyGs;6|hb%(zKtZG!%$g2=h zdsvSwRXcG_QO)F`mI@b-y~9<9CN`rEoaz9jrZJ_WOL~x+g_P?X{wgU)9h#`Ls-=vx zQTFw2IUX{K8QJ@#Fm?J-v7=Wd83LyBcADt4TAxtqb<$H-E5MNxO7?VZIJ=d zvbnA03jRg>*%+G#+uKERdq+2Zdm$3Rv&?~7RH;9I_411@jGTYbs&$cu`b*AMQ?zvt z^j#%7d%8CTQ&N)-k#cASo|r1TcJ@SD1%A(=rDqUUOyaZ~lfy67$FCpo2M_2I z&^Yc7^2w?_09`$J)U5nN^-T_h>_fW(2M1b2M^|){HVte?v#73gv~CkiFKh~&ACM2P z1La+GiI!+*XFuTXp7MdVZ3E@@;FNcE47Bw{S+proei1U9q8DuH9-KQjP~Hyaj_yu8 zk}hwDCLDY)v};()Agwhz5RK!aD`G3YdijM*BC8t~FBXw7p1h0rsI=fAz35kwA;*jU zhaPpbhym$r&i+eFC3_Qk{2x41^2s&_3QkZVhe!<+CO74Fkl51M7VV4h2ZEf&71B{u zY&2gr&<2l%veIFtFDhs6YU^t0>J^QvmM`v$_O~@6R(kq~UeX5(+aoLco8%u6*`__( z(tTAVDThS$1_Y02>FK>H(ihz-TBQW(v3!sokI>eRerdI6-==<;v7=jbwzUt4fga_l z>~|#E+Z$=`>*><76UA-Clln7!7A6^`W3;nnkmueAeh;cTG^%u~>>x@agS~JA^tGe2 zGlHK|7;Fvc-323Q|p$PY}#6tq5=)rDk|~q9otaGMv@y)6s;Otk&}co&Hy!uT(f5OgK79Lq{C_Nhlv_*(_I~&2YbN_vT;G>nELSY1^hXM zvtRtT#&BW7pvv(ENa6Arrf9gk_#(@3x$Jk~n&c9A_~5u)0xu;UmrLM*p5ww-$qtP2 zxuZ;6E|ILUOJD=xxbV;OXpJS+E#8eeB@pL3d3_O|3WSfDu0w9(zq!cuyLaNtf$Mkg z#G8QYckskpf$Mki#J2+1@8pT!09;>e?^YoE?S9fSfqxCTepjCj{(FIE;NN`H<%a+` z`F{aC(;gPqcVh_no>=oACt&|uaeN?j5~%*>fb!E(SHI&Y&R?~5%AW!J4g6bj6hryd zz!UOKF%LL@`(QH4DSruYzLKQFP~L0M$0=_;%K7ir;V$KM0C$!T0AJ?N|3={1MZuuv zzXv#f2O$Rpw)X-Kp!|30b@}&D?zG2GfmfVJ*za}Vg${Z02kXUg>EG<%1h};Pcl02T z_!Qty{dk(;zpJO)n-BaD^wIb-;QY7zG`>m1oaOv2?nvDK zOi@Jt;_r9c_M8WtZ=v}u5cwN`^M^aMej9*0?RPbBXa8>m&VS<()n)tq*=_zfDKqx( zy8!raHUgF9|HJ~vc)wsK%lo-3PmJ%Yz@6EP*NyLjOrUTdC^sqnY0p}Zj zeoI7rCGZjS7bx^G#ah)sbtgghwsE$$J#ZVUrU3414vBG~*y7_s}@EwK{i} z5$sXBqP>w8d}h)X9T@1tE`6{cdlk8R!l7-TMpikKZ!2~q+^{5$a7i7uH?dMJ$GWd1 zs-qf@lD#~(MA~@#NZO&P&6e6=%YL^skKRYiPAN%|$lBGB#cR)Byh8#Q)VBJt7n$M9yq-Ab`N&qpx)Yx^JXPG%Y&4C zG>vckrRE$6eVEo;b)IV31P`)$pFhf~qqf~=>H!_&UF6=JyY92An_xSe`4(Teh$ggq z($~Yix2>8cI!OBDAL+npqB6qqlzyX~IKIU@!{4?xM;(ScOR+Zj=wmdZ@&L_IxwlNZ+l-NXL58K*tWq(KYnJ2`Sehe@E ziP5vTHVz?pUh=P=$m9Wu`kbXJ%?{%wqTCT+e9X~))<)IIGx>Rr?xGx8cF;MXcCejg zjJp5LF@#GdLZe^Cx;>bD{FC%NC;6!i&ZccRh4n^T+7jp8GmQZGDquP4@~MpypBNVP z6i9bYhb8+bX5o;BsS)`=pUO9DNFFz5NquLvwlxoKfo ziMn!W1zLoJZKFD^aIXozRrn1QeQCa85Xh&mRoIl2=t2-RSOeI}w=IaDI4jh(5@mIx z_`+c!`0I80(lRa_#rH2O@Z(_FnkylXYr3w((wp#|bghG+!Of%i9>XW*-_(VUvMU`h zK+$f%uHs;$(u(YAxwr>0trcm2mwKo;Z0F72`>$dlNY3h1d{O3f}~iq zt&f6_*4w5HSn1=|+g59D+k4xuNUIfZY^}CdEwt8JTdlT;Z&c>{|Mxz7=1idX_Ure! zzu))s{Mcu&wf5R;uf6tK`*F_6uy^swC5B-LeVJmTAol!g*|pWkoA%>o2~jPA!YfKd zw#bs@zt9zi=h@=#Du*B;`p+(q3Ekwluf5?KGAriTN;@k(aGfs)B$KtsU zJUcgJFS@bncr38Z_z%{2)O^nj9oiA96J_th*;(W88Rh#l*U=#i!n%S^Up&0MjN; zt+sr4zOpQ*Ji|Cd&Y}BCa;BZU-bDMM>wUrwFY$_kp^y=nI`6B+gYlZG@#cK%kR|L~ z|F(x?PhIw>I+uROV~?7E%)T|JV21atc>R&WGpoagZd~S_otp>AXF?_B zv*DwmBl&D#$uhCxr=g+u_P-7hleU;=W_DPiq4)Q{7LOb$++&_u)YB?LLudD&W(ylo zyxvMLd+=4**t=Flj*Kj>kDpnz%=4mIydhq-A-+6o`GmTrcxgp>*5a=S+-?I?@XVrh zp2(3&XBKTnR(NKS-LT8Eraq&8XU;Y4Vs*~tYx;+bM;@#{GSbdHv%1v#&@a(g_L-SA zR%Kb8u|f`PeE^M}SrnNhUjA6!tay3mWAlT?1+vKW*Moa?iMOsYK0m`)K;r0#XGwt& z#bxoQqfd9ww|{b~Y?zB^j`saAcv%IT?G)|58&CrtK;`r{@AHqYoxf>#j zMZwIex4p6C#rSi-$v$@Cl(bce`BGS#Z;tt;Li3>~WLBkYOv8++#UhOied0n~y4 z{pV5wc<9hp!%tw|U51aj;pM%iYFS-L@&0EpI)*9v zhANG-XHjC`WxU6H=qAbz6Wf zhQQFFHsjAEpvf0y0c8J?0A&Ax`OrLHJPw;bd$#J?vqytsnORvKL_Wv#y#xA+g?9eI z-<^t$n9LIS1~lOkcfq+HF_H>efs?TQGC!ZNJPo zg}Epg4n_{`4t*nT#;pDC#{DoUXBo}~r;Zm_9X}g97K|M~TYUU17|`N6YwpSqFIw;U z5JvH@<@ST`#;fi>yUwmVcD8bLww<^1juDZv3BgH6ZBMZJI)4?0O3z#0Icu8`P-<0u zmt82e*#2X-@9Bdte)OGfub6>*k00J+o%Fo#E%#x_KYUSWp(tqo)s#01pSSJD79D+N zqt7oMX)CwqXDlyXU)7OwwPAdj#@U>M*<*>=Wvr`OR=l+A*S5zVRruW2>I0`6#EOf; zmMB;x@@mBehv&wp-u_4by$>IL>foO~`u4Wm2P)B1+0RGKl1QK`Jv?XS(5>b6;x17- z&+aK*Su)RG6|Ab8GcOqQ=zc)wS9+ zZ^k3Vm>8!mn)3az&z2ns=ZeZjN9Ue=^8WW%T>R|w2SP>JoWplNKDMmY?a$yz}EZb z2CFbUx2}GXidEaY#E*u;hpfmUQEu1A8utG+USHf$x9seS3uxZebE_~`Z{2aCJafKL zSiQIbuD{C8dL|T#UACl9pp9oQ3O;x${^?wQ_)yO5+^WKfvvYmz_f2@nfQ#R6_g?Q8 zLko64z9e6y*PWTvYzn*Dp7@X@&RkY-X=t%{XaorJJ+`mhZjLoP_{Vs-__8yR=HiB> zGmqQWnag~psNCM)yi|mLWK6y7wf8-d;>(sUxPjVSoUwQXw5g92uX?8H!R5j>&EhLy zo@2$AKVH24x#D%Fi`RZOhYk-vI2JP>j~Ne)Jp1#!v-9op411A%L7-~?FXP2IXRC6~ z+LP>25B?$^I&6lT3X210Z7Y0nVK`#h*M%b6e+;Ye1Y$NqgJBEpgE!jX1fBw~akIfaw#*CG)! z9Le=pJzV@$j*3Y5%hLxRzw7SfhXeQ0{T?-+dA#JFDW>V0LksVJA|C2Yw~b60U!386BEBY6RC3Qv_kB7t{)Mo)Bq$#0 z5#monYyJm(cJWLRJRPJXhedxV=geuiaahbZ%WcGAm8da5oEzSKx-wi@S^4_x3FbpB zq9Fdx(2FZehSEc&L!kHw0aEhb)I8Hy z4}*p}vwf>DotN2b>Zu=E_WmdywkMCCD0~;gYVoO)W-RLr2Kx#c*LQ{%iFGfJ_U1$& zueG@|d&Ocq(i6*GF6pc}F?y1xpniSl+-fuzj);<%2Ts!p3nQJ` z%TBC_L_A_{h`uV7zs(~pQF5Z@y@F8biP^V~w9V2JODr)r>{Rary;GSOv!d92-}Pyt z}xvt&0_xFqf~Fo|(}H;2z;a&CS)Cx9L4qZXq4vGU;lk>c1;e9gSL zS&XH{2@ddKbwc<)orC3SajrOt(SI<9?%=O_EEEg|Uw89@5$p){N6r0NqVP3LM!O&P z6~gDr?fsdU=x&^S>njkDA=>x-0S=Y{d7(qkPQCdlL|4oHH{(;cz%}>39iPwnbN?Ih z*{^t)zA_q}2X%y4(-Xh`U98Gt%$8j2av>n#&;Y&>w?moRH2W~c2HOwxj1~nuQMmMumuzo6T+zG5d-=BJwc_%go-wF$ zO?&%;f5Bw!L!BOr+JVg{;a-xqL> z8B5YcP1!(R$euiOtlU0oiBH!HxH1-GJ2$j)veH@a5uiq7^6ocn@A}C4`#SDgetOPx z_08Gqk8wWje;@BPk!%MG}ZV(6~fWFN_=FZP=@Wd=TGvX8p` zk3$}gaDupdY-ra3^nC#3*8x`gRC>7l-)zwYvX|_gV14p_<-P3MF7i^T%%IeT^n8qc z9qG>aI`*b0sSC%2e8D%fYb(y>OAGIFe_a}(@34rRKHhf(h}bW)EM`-@uXvU7kpOz(OY z9OrH9WEM{Zzco(E@O!^OR)5+a7JP{CsFei&gH_Ag2u`N>@~tfMc<+~4S^(;KJy2mE zaG%F%?-Eo>^LxkUp@zQ&h<6-Ig#Rwwyaj{}e+8=+5jOolAU#Cb^6w-(NjibB4v=Z` zPeFpbk_D7EmZVaa3;$Hu%R9~C?Po*Ni@+23Cu;4>*#vk*0~n1F_XA{*XNmOJ0rvaG z-i=Hu=NqSl%>cnyumX3Fe**;j3MGsGYjAwuc=BNCW=2^V_W~#snOB-=HBVAf2m3sS zpzx2!J#Fp_xCe!O5hw&@jVy(~1w4xqCK$rHfHg0q(CoSBo5!0r-vG&P0!dpyQ25`% zEv=5Q$A1Sn)0P&KC8sa8Nu({GjZ)kHXVO;?&h|GDzW4#aBmIMvb1C6`{}ZT{b{XM9 ze-QVyM)C*!#pGH26Tp*l+Pd3C+M220ob11ta@NsXO8gP>uP0pQ&n5rmtXt`SiS#Q- zul6s5-O`#Uzs67NrEMV3JpbL~-$=OD|6|gxqzM+~ew}cPFgSdkG&GvG7F;7Kt^n95 z-cUkg_&hcck6|uAHo66Lqmz7k5j6(7Q7~o;$g&oS^6$sunTfy}YcyITMD|#t!3!Qd z2o^n%mgAAzDxqZ%!u+E}CB_nJ{Z@jy`I=VNUxmnzkp+fXx)qHWqf1J;vn z;uE9$02|XOS+DQLz>Ae453o!1OQ_e z>2D%U%*Snlhy9<+m_koN3@f9SVn=}zqQ@E$Izb7bqRr5mX8bn@W4CJ9t!)77P0Sei zw>rfR4$86w#bK5yoaU0rnpPMDh+6f(bY8IP8v{eW{iQ4rJ<3N?AlH?(hF$Z?QCQh(Lth| zQjDvK(&a)yq8}wX5$L4PK)@W*PqEfM%Da^4CbC^eQQbrvz;Aqv=Kc%O`7GTphZzME z%2;|m#ajozxjpoGin@WOjv`Iob2_`0g1(8hFWA$D@%$`1!4;xtKg#F?vrtA`@7^tn zZg*%aG;NP4y4#^`)U<0w(R~gLn_^XWubA>3&@RHT7X1pqVgQ4(kfGAALIuzM+0b4L z=?U;$>G&;hQOpg51q*~a*}tz*%R|soDg7@*zr_w+hrQuwAg3Wa*ddJjSn_j}i2SQj zwB04LDB>tN24dOnwa~4}p-tB`LlhOG;wMpYp`!Wr9vI=9H(3FC|gV|^iYE1MI7X*oSnbu#VwCeNi)0n6gAgdU1Q*T0o~bWWC6Mqx(hes*Bs1A zs8P_erBxUwxDHtdPhC6N#FiJ0iyZ6?3U7b|7{6yt0d%~`AA!>UA$6-a{k5=M76>^g zu1#gHQ0zfBJNhIkeAe+FUVZ zDQG`~W>Z!HV318&2jEFiiee7?aff|(rO5AaXlTZm3&r|@FNR__z+kR!zlAE8GC$#P zr=wIV)+vf^b!ZbbtyL6#&Y^`B4U(rE28okq(LGMtrJBD@6y5L8S~P90DEfgz+v(7# z?Sl@@(YELvxCj@L&pPc?ilR73C(+w)C=$m~Ot}X2-Ude;U01)v0OICS5QDv_vS*Nk5X+0z|o*d$DK=kI3$XJnW zi)pWrIEq9%={X7|-I<;Og)W9d#+d1kqJlAc+9PP(SIpX{S(`U3=!}eVo*8@-#|!Zs zBEloq@~(Ekcc6qj;5)(0s}><@x^}o`E_-IG9j>W%xTdoab~eh~#7jPw zTutJ6^xY}}loIr3h1m@kuhKtt$4Q96XLg&y1z_+7lBzNJ)RO)mT(5QX@btq#$CzARE zs3Io@jkvF)61zdj^057EGGuvpAN?aX!Iev1#=uV@M5$3pHU0=ON{tJY8of07EOO<+ z`NrsqKXBTfO`+8&5jiYMZJQGE>D|UW{jk9p5I?l(+8*WF^vUzOwuc8ct9+R(mj^b-!@M2<`#|=2IG3Oe9@u;yZbZ`jSDK!hqksZD z(Rk(%6ak)SJaZod7!)Hgr3-@T*Wi|=@ZSNniQ`1$;fcm`;TM2qs1uE6J`X1WZh1Tl z2#Ua4xOwUbdjfaxzBC=B{!E@|Jj>ZBJ0MF}5Y7%Xkmur00v;LQiNTvU- zQZ8?>_RI4ACd!?#%flA{!Z=1|V*z+ZBG!(PdDQ3~u})$9loH^ASHfM4E&Az{F~Da9 z`S(a7)m#QB-zQO)^byUXNiwFiFbOq+AF}CMd;W@VpF4s1}roPWWT+ z@1xruHEK2;!8c_V9*I#8EobUol;SnWpdY~*154l< zB@p8^DCc5SERkLJ8f@-r;H7dL6wdwBG&zuIQqDubgY9T&0$V+cn_KcHaxYML!W z;(qK2rtAVEZ9$E$1+SQT6FJ7nru5T3W8eplN@Ju-Q&F=7qcq0gFf{<1CT%`e)gs=q z9fwmUG45=v#+q(YAHZJI5Y-M!927?wQRN#6-zqNZnbQ;pJ;0W zy$5KS^q1KN>sbd6?3w;^O0ALI{STB+FHhnx62F=DSLJ>@)SJFFSw02$H2BpVS$i=t zISLBDhTL*#RQNvuFMk*v`8Fg>zlCB~$ciUXFlFsq*|l_zi8$g`PBa>fnc4$p>_ZV= zw~2C8nbvzXJbaBb!YMZJ9OwA8219qO4g4+Q>tuNo@j!gasu zlrBUmhlAyCvI+}NRayRsD#uYjm0?Pz!vK3(2Uqz}8aOESh|q|wMj?b)2iKwI2%5z} zl*#o0&l@Ud(i|r?gRC!Opb-p{;X)@EOJ9PK#>!av4Y?jCiXr|j+2=pMk8 z>1fD!Aywp;9g#0kTZ;A2wNpE^~JN z9fVIbR?|c9lm|V>euH*{Hd8Khcvz0{Xf(no_geh$4J=-ZU%?4c#jUy#HubY?V_+#7 z2*U5j&|V4sCH{wzavHa0h2lLIuWMn=hBWH8jc!oDjQ^+&P(ovMBSvjpqkDeKQ- z!*|LspT(9HII2d@`kzy>X0Y~vtUX%>&gUg8#2lVIu+&jW{Q%z>C__MTE?FRr@O2E$ z+({hVCFb)m>xIvPd76AI5|I`E1crGuob^t2?Z2WBWAHKPIDZ3Z^BZsr>XPD3z}^Kv zYS3!Wpa$nsBW6}%l9{j%v_KXr=z`*#Kq&-e#&5wo53CcwSNs`JD?ly&B7n;QR6LJj zy5kFIm`;GLXT>WH?Tm}|mP6ws3WslsIFq{8Oeq~k5c4=@>p@tY)*q}a$KZ1 zIMc{Bc4`s1;-cGV%Gym*1i#5$z@^OdiOtZ5y5)WbKrSbjT#`iX5eW3$NO*XW_!)-N zBj&*r&JpGZ5XB?R$KiUseu~qOK9s2QxN~SZ@43d421(}VGE_`Go#SoS{UoZBv2$wi zdN^S?rxs5DRjuMnLGkhA@*Mza>f}ODq^Xn3PXGpmpDhp!bmNw#@TUNdAf7zA+yN|I zpIn|pm(tY9g`h}NCl|t=G<9-esoz#7m&stU)6~g@aCVwHxp0*lnWj!Ig!9v$pb;-4 zT$mQb-P1_^V46C)TnBiPtxhg}$e*01PA)S+FG-7#e?8%{G<9-e-O99=NWX&g>NIt7 zq5PUOb#fukyfk%kAzYiLPA)XTq6~F%Aq)<$=TGQhW*x9BihB=OHg72Ty}Z8y#5uX- zJV)26&@V}ifyLF!%=ThLN&uxzeY6% zzUoM+rj%TG)aV^Jic|56fQ)&=k#Q&3C&z{RKwP}R7Q?dn&r#sC|pb{A6a zHp*@9+=O7N1J~z)=C8$DS}qe4z&MtVt&P=e_21cQ6Ux}VOhDHJ=(AdDoC9T1jr3-o-<^dP;^$zWuNm|}P(5SUj zPmJSP)6>Zwt5Fq3jxjkiFWt&4$Xq=p$H*Ro(VZmH(=ST5ux?nRg_Sus{lfI+d8p^m zaqjZseJbWTA2SxEHL#~4AWF?dqCgm^B znSz%t47x->VsW~$dJNe@E;i67l8#BDT2w=Gwmmr=`sMn_I|cHE zQg*7e7-%JKT~c~lnv}d?tO*sSC0S_}rTFw2B5A96_yVEK&82wClO%HdXKn@eIj>v6 z-Mp!;;?u4I_j0??a0k<#GeUb#dQzKnM%PXq-Hg;>%uF4FEbZXg%8_#P@WInuzL1x+ zV9YT#w2240p+4x`kuS2FN&Rp8~N4oy(b7$cKoBF%;POpXHrat4N97RgqunDDR-t91A$;bf+&4 zTINF0wQ}v2Gm_3%p><$SD^rIm#R^r4GU%965_V~bR&eH*V@Dl;Rwu2YhW-L~R~2bi zQi2e(lU>4wCfNg=5!@;aGws|FPOCXs>ai+u!kjnW8On9(>%HvXe2yeG6^>9WWNH#z zkPr-q)01HBaN_@7OmYqKx#KX+6+ehWzmCIzjzcxMA+*%GnOFer)Huv=$pLewio>jA z9A>LH%yIW8WdISVdPQXz=)5lJdLKd+gK z1kuduCAfjvIwX(S^LBKQ(7#EH4H5c2k|8!QJDw=e8fcLo(bFFsq|~L7y`C8*Ln;ag zQ5NKAk*Yw;(MsSiI}$1wqDdETL*0Y2euJCzagZ`Zuc-adq>znI-hNn?FbzMq`K7E; z&+Ly9Y-08XQmS3})l4ovy?|Yq<=_>#AvQ954(VLpBFWpptPIH%J%agMBui{NFoHm* zMDVEvfi5Jk*bBZ8K}xm+%G^yfBvhw5bzn0@BQvc-V}hX=)FG)EzVkXCHJ+8AHiCC8 zl8J|v%vsMA+q4x0%R7)@Y<`ZjSAonviIfg^Yn&LLkSYZ)MguNe)Y zK`l^nxJ6P?IvR7<0>kYiT->+gk&e3fAG!qG}yjpC8z;6U_Pbj47%Hne$s2 z(wVDj8xqw(O2cboG{uZ>yj>mREBI4LhG<|m2Bj9h8yh5`Sd;pr`~}I{$c*falEy(o zv<~b;Qi(NGLe*5k<{RBria|@~3*04=l$b5}>b6vBUe9cW1e=&$ij*qxB2bng zF-WS$4H6`i%cb}Rcbg(H`;-JXGW#@Asx*g1;#x)H8cof>CC#BBk~$ z$=g8QrzP)3X3sjj4TFT9Qw7YlkYw+*5cY^tej%ARFnbcohxN5jga!#y7Mw9D@*J(T zkZ&o@A0hjh0)LK-GE(X%{Cc<&4@k}?W|U!x-FpWKyrAgXSbTjw25&&&8O+AwH3cRc zW>b(-jYZxx$=kqeg5=%EO!FpfLSC=rZDd9UQyg5Un=JyZSQghaE0m%VwkQRuT$M6& zDzDO&t3j(##mugeU?Q6L0_A&Z^oW^LIbkPVnRaIF<&w35*%}G1ZbjCoK;5F2$x262 z^pGr0$mIL#7bK~k*~>`W3H6G?LBfAUO5?JJP2M1p(=GG zp8~&+Y)FB+u4bfqMJ1XIj(u_lb6 zm2!2&6`ZLarFp58hEwV#CO=(jis}R>eEM29vNwTf?i5)G_xgXM17GHzkbYgy?3;Kf zkH}(n9}>$h=>|m4nQ0MuNJ` z?r_M=@04)WAoI^jI6TPw3lg3=$o#N`s|T5XNx~NlGXIK%D+if>56NYXXMplmuxney z_r=R4Dd94I1lLQdBC|2FG|H?12|N3wzr2I;cNHtMxC9&cQre4TBYbeGshPA*_(BOE zqXIX}vDNbqLHZvqKVWV)kXERPjqeSs@wfnGHxVVX%!rV@PReW<(q(WFjq+(5nc# zON#*D9ThIT+s38;u1o)U79Xp89&|p%C`Hak0x#jY9uIzJS;4vHAvcAIr)Nrz{*1a1 z`(HjxszJ^d#`@CV=4yO508{Y85>=m@@asU+pFira6N6ajD?nd`dCjDkqzsc0~E`c3ZA@On1*O4@xcq0;@UVX_$ zUk7{f?5&UGnxFRO<22fv&&g=5rU?n}=v!Zwc(fgCI|HO-PzfyVK@O zJZjSJJVw$qOtd>~tNFPRX-48Mg!=(ae-vxTV@S^+-3eP9LHcJTUA_^qJ_)#-IQK93v)< z5fh_Dm(RmH0#p78vSGZ7*CzNuc1MI!vAKIoTg9f>_Lj}Dp4N)iwjC91y<2O-vt}jo zzV7bM-ilp)ZC$;w^3GjVm9xs*I@>EcJDMvtwX~dDP(7n&M!2G*tEF>$Yn%AT8#t#$ zM`Xp8Sj*;)uKydN#f%vh_@{c@+j>>S_G{Qpeu^*Jn!CIEW&psS@Ab8|wzbdLOlOJ$ zif!-gi}qc;wXGL4Oe84B-%10RKheM+XGn@6VK+zbkFsq>xiy{A zDP^~;?~(W2lHv*YrF8bmk~-~?rTk+R&F__R_d1$U*9=)}m(vGwj*$F*N%!J2J4&;0 zZdArswfX{Embc#M_JFK(8LEpG+}ZGw87L+QWZH& z3FC8Gv)%z&1jgX*flLY@W2S8NYI#p{VA3_rrj#9aNq%K(Rk}y^$O>eFN0s`?!#?@Y z6twX{*(oSBqy_Y7DFr#wsg(3#6cZz;M@0JyyQq9cdm<^jrRIvF{MRj6`HJ?ZJlP6$ z=#lzsI(;L{=@CcG3Xqc?Y*;yg9Nf1D#^RnD8LBU|Qfib?D^*wfG$^o)Nz1_96ezXS z_JSxMYz^Nh#o81Y4H-q!<65O&9tr12c$d6qOAo=Ho=QLGs%1T87?xKuenc9@>-Y&3 zvLw7$4u%Q_L%OvxoZDn7)Vk%6=ePzw6c{HvrUI11BNawhX&^l$DwGuu4WxofduahE zrqsa-gk&w451mCP?#G;FiayMC{|DEP|BmVXA770A&ed+%94}Xkb5;o0F|k6Z)k3W% zSS`-8MBt+olN*{*&P1lB$em7TF+6mrDCbVzP3dncM6Y(dn}NbCxVs${DW zk4cAj1*u+p!%QMF!y+0}rlHCV`1PR?pHIcG-91RO^|@HZa@iLRmd z6PQXgA1v?iO#p+l*7)Q^CD(59!KKt%YbG4Tbh(mTCnVn<>8M_|#gF5q19C@g-6`i% zM+ntp5V)pqOZz&@q~8Uk!j{tys(`srHX>ukX%4+)4YcROHp1z%Bj1O(!CVSX$s-p9 zX*4vhRO2S!ItJBbGw2bgTea#bd-w57u;t=lD>B}=!;`viy6*|5NP zqa3~Du3c)F*uz*GB=;QIRr(e+;}$_~3)BLSseluLbwau?Mi<`ByE+!=*_YiTRnE(a z*;iJ4;UB2T)2;O>7*p+k_Q-*C2aMVftHD%T$u!4kG_?*Pn))Auw@GQz&n#uwY-#Fk z^8WYJ)f%afH9V|a_n}*A5tE?^b8=MO+d91|Q*?Dlw-7cews_XJeh4w6q?T7nom6a% zlERe6Ds)Xbta5d=?%yp(R|TCm4BcF92Ml@EFr=}Kzy+XNoFh>>Qr>CKAF55Za$vPx zR!55id*y~wZ&JCD(7wb8%9K()&Oj#P(IeGUy4=1uPytpos%qp_h^W1XSC*=svZknJ z@=;5Li&riTmfVOdld40XI?kwBMX6}X2~W*J%Jq#vm6W57FjQLAQpVXJr|2VcY-AM4 z`3@T|viC}1>MWvSM^8>N1kPftgez)P?6~i8*P^1wxhsmgD|b#xfL$xOA#f$;#lYz8H zPTXE8$M4L4YI$LRDMyrZkKEfu<@2U!Pg|@t+R_}2wYK7&XvZ~e(LT|#xvk|Y{u%c9 z7@N1Zw~OZXjxPMce>A!skFRP_rEX#4@=Gs?F1&Qr`e=RK+Vj;EZC!mmSBuW>u1!IC z+uqgNv8k)AHOQX}#BXUR9XOZ*e~T0CZQHa3ReD`D$f(qonzr|}Z4+&Mz0sYmebKhA zSaWBa=xuB1>*(%^c67D2?Gl~WTuN=BavOTry}hTUE!x?!1-~_-`8K2fC}XS9){d4w z(bp5}>UDZHGmNgqq(G-fl5cCQr?)NY)NJPCJki<){d@ajJ$(-2_AWfW+ls#e?S(3A zZ*zA~UofT1TYJ!-D1N)G7Yb|bobeFUCCXlk*1n#$Hf`XQm)0$c)~#A4Iwdvb6e!11 z;1Q%UWM_A*Rp3_xTDrHxY$=>hV{*Ku`uH1r{#iYp02(J8Kt8H;EWV{1&uEoHsJ=22fkOO`|%>lZH;(FmS%i^Nd!dAR6R@goPBUWy)dw1__G zl5V3(^QQV9dMxdM8BDnv2rZp$v7RV@dd6)VA)P}7K=ajoZSYdGC7o3IpYrU6Rm&Im z#CqEr5DDEq0_fTvSjHJfsb`8aL}g>n&`Mub@uIvB)$0)=qNRK5)zO~VPSGkQNcV*Q zZc4;oYe%o_ZLDWgFS_5+B|6*M5l-F8Ejjej*w(Gl_MYx7dhVgPop{cDj)TG$!*q;w zwruC=HHx1Yni(Eex>I%#CDH9$F?{H2M`vdgf1SU*O>}hafNO8++blW}483qHM5+U| z^sR)~x3+cm#pLlA=9EX|Xme+G%T-Z&g4oOos&rFZU$nDL&UsKl4J&DKEVjgYuX2RL z_~<;_R1Ixb1H%J&w0V0+XKPdjZ+ClpuM*ta)`IAY;!n?;;aQ!{6rjYb-pZOL?8zb@eBye6(e=Tw^xF{kq`rEev+0nxnMzb~#d7OCbM+2F_MMR_MJ7b2`VS zSL|XNT8bRNs#(q)Uo{Kywshgbxxo@lHKl5%5m>cF5Q&dJ*2x!I(dAw3-C}ja;%Hr@ z;nJ0>8y81cE^l01U$?She&vX|$nyF83;n-w;n&hwg8hJEz{?bc%hQyi;coFgkn6IX z*Snfz2|Pn^U6#Q6I@e_hJb!at_+ZzCQ9d_@$;%R{Dq8~k1J{NBqC{&fsUGoa+%17P zUsvmk_#_~FT67(9yy6yfkn7jd#Fqotuce9elTH14ns_U4{hFHiPT=}=HStdX*B9Hn z9SDEFoV0AeLMF?Hkh}SxB;6Sn)_)H}!dIvuOa4;?IDY;7 z0WCwE0jgieQ+_7u>et`I`Rl%J`O|>^3I7ijs!4e>fhXmgVlHt0J$(_%DSruYzTKn4 zP#*sV+b!>Ml=J_&!d=Si0PZg5!}nb-{ci-GTO0~${;vY(-`3}W!1f-(IgejCeIR8&B-QGOlL(oU#%YgI$ z|I+v>;_xT>8ST*pJcLV^<0sC=dvUG5DeeI7?k|5G#%&M&PMTZa-w(szl=!4tE&ruq z^>H{zeC9xXMgw=-gTE{`;nk$QE(6XdesvH?{(ptN-TGXKayPycxc(f3{QHK<`vP$N zc?iqz1e1T>1}xt{8tb&-SMS=L=hY219=SjX!_vLF>ogTy)#(D&X$^ z?*=|JDcSxF!1;TW%qag50RDe&K&5`)V1dj3eu;j#PKqXo%xa^F%lP+yp4}!TbhXfA+)jdf-9mq{?57ce32& zuRDP2&uz%hAI)<2C$Tw9*$`oa#O2I+o-bE6we%+!To+MpH}vwyMO4DW*4NZch~#ic z$&G}wyhfXGtdW~r9J^ZGTgT{@Hhi?OHQItNFWO>#eLdJdZ|}usL~f68_UfyaRnFzx ziR}h=B*~LlN{5|Ys#MFhuq%n`;Kh^RR-PxKZ9EsGY{ArSN^PBGzgwEQGj?y3Wv7&+ zXmnj;bn&`{i&x20?V`mE3mc+QaUP{{aPI8HMzaGuWVMAkFO%%qxh2h8ac1n{sq@@2 z*aJt=tzFwYan5etiqm5yJIfP}bI?re?4{-$2z?gTdvTso*#wWJdLuu~s>Alx=js6+ z6J6xyo7?L1tD9sypZOMFvWO;hdeYO)&9$SNCb~%-I3`p^IgZj_wDTtRZs+*f&gPiQ zVCN~;rXIF$A2!yFb&-{ep{VOHajs1;HqN-ET9clYa63A)JO?FD9J-@U?~}2U+!kY3 z+S;+Bw`1nHhrO0wjAxHN8Kn3!jum*$@i)&{^2kGd&eN4!;Z!DKA-%HVcJk&kUs9>=6URKaPp4d<$@v6i;v z3HDqgK)#Alj=Fs4qQobMMLopPozrp1{)rhlwqY(r-q)k@%^H#i$Qe@K8Le&2+c!a< z*p@coAeg|rH5_Yh?rGbhF&sZN7{l|ZO*q0hby6`t(9k7lRLtNvV|ZvLW~f)pGh`ET z?fH9d`0pa+i9v1=xaY;1K6D^iQ!b@Ii;=JmRHqNFmEhwq)ags}O$C8``syE#9|O^a zAZoB0u$%90G;l39EY79NYJqE*MWI?DzTi6I=(0;treT2M=rSSxfOnDl(q&x3HO#Uj zmt$|`B4}{)Fus%ce+|B(3teS9TrfbfADT(Z=_>nx6RvdVSK;q^b6rO_mNDJz z1) return SPI_RESULT_ERR; @@ -69,8 +69,11 @@ _SPICommand(volatile uint32_t spiIfNum, volatile SpiFlashChip *fchip=flashchip; volatile uint32_t spicmdusr=SPICMDUSR; + uint32_t saved_ps=0; + if (!spiIfNum) { - // Only need to precache when using SPI0 + // Only need to disable interrupts and precache when using SPI0 + saved_ps = xt_rsil(15); PRECACHE_START(); Wait_SPI_Idlep((SpiFlashChip *)fchip); } @@ -116,6 +119,9 @@ _SPICommand(volatile uint32_t spiIfNum, SPIREG(SPI0C) = oldSPI0C; PRECACHE_END(); + if (!spiIfNum) { + xt_wsr_ps(saved_ps); + } return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT); }