From e01226016beccd02aeabd8f5e0c95804ac5b300d Mon Sep 17 00:00:00 2001 From: Xindong Xu Date: Fri, 12 Jan 2018 08:30:31 +0000 Subject: ref_device_common: sync to 8.1 trunk 2c9d1cfd8f [2/10] PD# 158649 1. bug 157786 add tv related code 2. bug 158467 move recovery code to vendor Change-Id: Ied3a58eab6362981d903f068fa8462801a9a9e03 --- diff --git a/audio.mk b/audio.mk index 3a66e68..9c42fd4 100644 --- a/audio.mk +++ b/audio.mk @@ -21,20 +21,7 @@ PRODUCT_PACKAGES += \ audio.r_submix.default \ acoustics.default \ audio_firmware \ - libparameter \ - libamadec_omx_api \ - libfaad \ - libape \ - libmad \ - libflac \ - libcook \ - libraac \ - libamr \ - libpcm \ - libadpcm \ - libpcm_wfd \ - libaac_helix \ - libamadec_wfd_out + libparameter #PRODUCT_COPY_FILES += \ # $(TARGET_PRODUCT_DIR)/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf \ diff --git a/hdcp_rx22/arm_tools/aictool b/hdcp_rx22/arm_tools/aictool index b9e2f51..4ad79a4 100644 --- a/hdcp_rx22/arm_tools/aictool +++ b/hdcp_rx22/arm_tools/aictool @@ -1,162 +1,177 @@ -ELF -&x0;hQ`Rx0: * +ELF +&x0;hQ`Rx0: *  - hFF Z)FF + hFF )FF   -L1FF -'R;0;h09 ) - -FD,< +L1FF +'R;0;h09 ) +FD,< -GHD@WO - +GXDXWO O3 -hO`O -hбOPShOh +hO`O +*hбOPShOh - -  -Cy D@XGh{ G\wGLrT ,* KFCF*SFT9)*FF 8F)FFFXFTFT F,F4Fgh8FQF ``a^a`(a ,OPShOhdh -F<&Fci +( +  +Cy DXXH0  H$HT ,* KFCF*SFT9)*FF 8F)FFFXFTFT F,F4Fgh8FQF ``a^a`(a ,OPShOhdh +FOp ++ +|0hZ`|0h +D`#bo(h! `ohSoH<Op ++ +|0hZ`|0h +D`oI0!Op ++ +D`@ ++ +D`Op ++ +|0hZ`|0h +D`|0Zh`00$l ++ +|0hZ`|0h +D`ohZ`oI|!Op ++ +|0hZ`|0h +D`oh:`Z`noI!xOp ++ +|0hZ`|0h +D`kF " -0`#h"+@ @̈́oI!nO3MOp -+ -D`o(h)j `ohPoH<Op -+ -D`I@Ch0 0+j+ nQxX)2f;+bo+j3Y(h11 `ohSoH<Op -$4D q+jOp -+ -D`|0i2`|0ha|0"`Z`FTF 0  R!l D< -+ -D`|0i2`|0ha|0 `X`_'FCFFTF -+ -D`|0i2`|0ha|0!`Y` 0  R!l D< -+ -D` -+ -D`#boiD`ohao`S`@FTF 0  R!l D< -+ -D` -+ -D`DP|Sb@OjOIO( h+c@K@S@  -0 @  -MXBOnL`2ŲMXBOlL`2 MXBR'L`1MXEN$_MXA -ZFMXN"E h)MXA E z +0 @  +MpBOnLx2ŲMpBOlLx2 MpBR'Lx1MpEN$_MpA +ZFMpN"E h)MpA E z YhfP@VJ hh   U@e@On_ Oi Ol_ B /² N % "PZTW@B i E*b B( *     ZiJ V -MXHz@ 3U@ l@ : +MpHz@ 3U@ l@ : %  F 0p P @ @.c@BK@S@  -0 @  -FbAFXbF(RFp -OEEeE +0 @  +FbAFXbF(hRFp +OEEeE  N -i 2^l +i 2^l %F -L`;  +Lx;  @@ `@ -s, lj -0 0 0{ 0c0K03D6B(F }O0OB +s, lj +0 0 0{ 0c0K03D6B(F }O0O B s`o09F  pl p#ip}+qkqci @@ -200,7 +215,7 @@ FbAFXbF(RFp t#jt'0+ukucj ucju+0+vckvj vjv/0+wkwj -wjwOpPO2 +wjwOPO2 ^ 0 ADL7DOqH _iOHkID(O O{LJdDLFiNDO~I @@ -399,29 +414,29 @@ pD|k u:6iE pDDX x90Dqn Y8DH - @PDG DD rDD + @PDG DD rDD  - "D + "D (  - - + + `†_2b"Ol  -\†^2|,2]"\"aS@`",202S@$"02T2S@X"$2(2S@(2 -DpR-$";$2YF0F +\†^2|,2]"\"aS@`",202S@$"02T2S@X"$2(2S@(2 +DpR-$";$2YF0F Y$‰ )2Z„% *2[&" +2\"'],2(-S@^",2 ./2-_ *„+." 0a"`”12) bS@c23"/ -1223"0 +1223"0 ObOCXO,ZU" X"a2(2WO.TV‚ $"T2`bc,0"`2($S@02 -+]" @N. +^" @G/ +_" @:0 +`" @91+a" @,2+b" "ٔ3"c2K@0)F - O\pOHr -+{ٔ."^2S@r3h +vٔ/"_2S@r3h +kٔ0"`2S@+s3h +nٔ1"a2S@ks3h+cٔ2"b2S@s3h+bٔ3#c"J@s3`HF ++]" @N. +^" @G/ +_" @:0 +`" @91+a" @,2+b" "ٔ3"c2K@0)F + OtpO`r ++{ٔ."^2S@r3h +vٔ/"_2S@r3h +kٔ0"`2S@+s3h +nٔ1"a2S@ks3h+cٔ2"b2S@s3h+bٔ3#c"J@s3`HF # # # -" " "# #" "# +" " "# #" "#    -     B +     B  {]{{{ z$   )2* @@ -432,131 +447,131 @@ ObOCXO,ZU" X"a2(2WO.TV‚ $"  2   FpXp pp qq - rqrs]sss + rqrs]sss {{) ('%$#"    D OT OQ OR OSg LY nEPZ[ \N G F ED@ -$%l@ %'l@ '(l@ ()l@)l@l@l@l@l@l@!l@!&l@&____X_%z۲Ҳ_ɲ$([ ,0  -FPBshR$ -F@Oph -+h -At`XD0D@D00DsB -O  `F -o -  -4X?(F1F:FGLEѽ -1 -KOPSh ->O# -.2.)'%   +$%l@ %'l@ '(l@ ()l@)l@l@l@l@l@l@!l@!&l@&____X_%z۲Ҳ_ɲ$([ ,0  +FBshR$ +FOph +At`XD0D@D0DsB +O  `F +o +  +4X?(F1F:FGLEѽ + +OPSh +O# +.2.)'%    J+FUFSFUS IF= - + E -d Yh i1D - -PF(yhFRF6+F P$/#p -мi@ -}j -Db UF4Fo - -P5PP.h` +؂DѹKK"{DhI KK"{DhI F ?0~kX>o + +P5PP.h` % #` 60# <8d9kzkC# B :kB;j3-0#<6 D#8j-:m{l -1F*F FiGB~OssB~KK"{DhI --$h 0FQFRFFm -1F*F FiGB~MOssB +1F*F FiGB~OssB~KK"{DhI +-$h 0FQFRFgFm +1F*F FiGB~MOssB +i [B;c` 6 -<%6 &>dkQF8k*FX>sBsAuF --%h!0FQFRFF&`zi -%m4#` +<%6 &>dkQF8k*FX>sBsAF +-%h!0FQFRFaF&`zi +%m4#` ` C@m 60# @@ -568,207 +583,205 @@ D#m-:;nn CnC2 ) ~@KK"{DhI n 1F*F FiGB}OssB 0}o*D -X --cl +X +-cl 6 -<%4 &f`QFj*FX>sBsAFɹ --"l -` +<%4 &f`QFj*FX>sBsAFɹ +-"l +` # %lͱP` [B`bJ F%!0=~mPV`5P3h -%H%F -~ - F+!`0h9n -O FT&P!FSD& +#(hhY`B# +#hF:> FT&P!FcD& 1q `8mF - mZ + mZ v `o+! F3AHBHA -O -` F ! -ݸo -cdFV \Vxo +O +` F ! +ݸo +cdFV \Vxo "ze` Eѹ Л - OI EFghFfh + OI EFghFfh  011`m P;i;;aj@;i O ~d{e0)i0) -^ +^ DZ,p+h "ze -HDjBF +HDjBF 3  FvEٲ -{ecr0iB f"3{b UxjYF8bpi: "zb;{dFi3bJ.h00 +{ecr0iB f"3{b UxjYF8bpi: "zb;{dFi3bJ.h00 Z -ݻoO S C+BgŻ & -EKX+B9llkk -`:` - 8DIB|x FScap𱁸  F  q{ig+ -  }biiB?P !`ap ! FAHBHA +  }biiB?P !`ap ! FAHBHA _a / F-!CXBXA i -ǹ) +ǹ)  %Fz` zhF F0!0  -YF:k0FBF8ksf)оk:k +iF:k0FF8ksf)оk:k :@ -`7 +`7 FFF^ -`{+!0FAHBHA -B +`{+!0FAHBHA +B ;C # )@Կ `W0F ! -"9F F - - - +"9F F + + +  . -C +C - -8` -л08FI  -л08FI  -Fo#sC(#xhO1!c` + +8` +л08FI  +л08FI  +Fo#sC#xhO1!c` F#`?%C `USx0; +@&b*F6%C`` F#{PC#soSxh+#{c{ F2CC#scs]#{ FC#sV#{C#sSxl+ FK"{DOrbPDO -Ѓ%!`a oa(Fj -ACa;hB8F;`2ixS!0 -3# iF+x3 ?2D?B@FzhF 7FCpG@F)F/OPS +Ѓ%!`a a(Fj +ACa;hB8F;`2ixS!0 +3# iF+x3 ?2D?B@FzhF 7FCpG@F)F/OPS xr* -B8F!Fn%)' C^OpF -F@s+j*Kp/! -F@ s0 F9F FhF#h0F#S# C%`UBOј -F -00F9F"F-O<S[`@HP +>F-O<S[`@`P O _O - + X   Rh -\E +\E  -BC -#'` 0#hF(FC&`#h JpzDhX * -p0FAF"0Bx +i@XD]KpGp?c2Z?(O3B4 ++8 FO3 2h_CR +"+F% +B'Qx )"цB, +Bg  O "' T (;(CH|'ND|" ] (" LH LDCH|CD,( "1FT JH|' 9(FO 5JFGHS < B - +  G3h*&ܜBO  -C`C C,!C S +C`C( CD!C8S  -CpgFFLF +CpgFFLF 3  , EkSF ? 3 h2 -` C$0C!CS +` C<0C!CS h! 2 `((eF !D-OFhF $ @@ -1089,11 +1105,11 @@ h! 2 BF=F #E%FFx+o2+`B*`  @5B9  G(@E@ - )!)@!PB"FO 4  -     ٝ@0+ A -ФF` A`$! .տ  $@ο`C`O3ؿ@sȿD`ؿ`` AA` 𽡱 +@$O C@s9C[`A` `` -! +! D0F!FBFG 3Fxx sEѴB\FУE4FDvF^E BB8FSS<; @@ -1222,11 +1238,11 @@ A`$! EخFFpE1FsF/Fx B pFٮB #Fxx B!FBFG -#Fxx B FIFBFG - -B`! -" lF*F1F F=%yih -*F0*"*8 F9Fs\ FEF9F9LF +#Fxx B FIFBFG + +B `! +" lF*F1F F=%yih +*F0*"*8 F9Fs\ FEF9F9PF ) )  @@ -1253,7 +1269,7 @@ b B F)FK -BKD(F 0 +BKD(F 0 J @@ -1275,260 +1291,253 @@ J  F d  -XFl - +XFl #~o -D3l ):;m -&`P4!`a -!z`P FV!0 -!,+`@zhF -!z`\P FV!0 -!,+`@"zhF +D3l ):;m +&`P4!`a +!z`P FV!0 +!,+`@zhF +!z``P FV!0 +!,+`@&zhF &g~m4# ` -C@~iBgo.Bc.0# Ek FV!0.FoE9ozhF +&*F`F +.4.#. RFFFFFeF Foz`>k FV!0.FoE9szhF *~9>30F)F -&*FgF)&`yn - - [B`;b F+!L0k -PFeAPF - x[B~eba F%!]0~[>k[jv\30nfF -> -!z`.F` F\!0 -!E9WzhF -7 -~et:i~{)F ;oFr&`[ .Fe츙KK"{DhI ! -!z`.Fx0 F\!0 -!E9@zhF -hF +&*FguF)&`yn + [B`;b F+!<0k +PFeAPF + x[B~eba F%!M0~[>k[jv\30nfF +!z`.F` F\!0 +!E9[zhF +~et:i~{)F ;oFr&`[ .Fe츙KK"{DhI ! +!z`.F|0 F\!0 +!E9DzhF +hF F#`?3C `*F``F#{C#shp#{ -Ѓ%!`a -"b" #C;+#h - - +Ѓ%!`a +"b" #C;+#h + +    -# Dbb3hui+O$ h]@(F@O -,30F0 -+BX -F +# Dbb3hui+O$ h]@(F@O +,30F0 ++BX +F 3hB&  F FqC(FD#F2F (@ FUF# -  -E - DDOI DO OU4L EFgfffHU  93 F Od &O{eBB I">  .8vFD5%(FE22DFH2H2.[ٺDD<P,BQ2DBFBOBDiiaDaBh +  +E,  + DDOI DO OU4L EFgfffHU  93 F Od &O{eBB I">  .8vFD5%(FE22DFH2H2.[ٺDD<P,BQ2DBFBOBDiiaDaBh ,+5+xJ+ -"h]E?ch+ -" -Z(Q#; +?Kc;+?E+?AhDT kx0; +93 - -D +"h]E?ch+ +" +Z(Q#; +?Kc;+?E+?AhDT kx0; +93 + +D ?EjO 3kJF C8chB -Ya`xB РhchB F`-Ahsjj2kCE RDQ`<`O4O4b9lB,FE&XF?FK@{DhX0 -,i~􎪻k +k. D"F|d +, +:8l(F>b9lB,FE&XF?FK@{DhX0 +,i~􎪻k  - -CF $"F0,F xeFD - -- + + +- yn8Oz -# kFE +# kFE  -kS"0y+K@,0(Ѓ&0.n-n}m{mC3!h@O5 -  &&XFFFL&}n +kS"0y+K@,0(Ѓ&0.n-n}m{mC3!h@O5 +  &&XFFFL&}n #00$O @>b{d`e -0d +d :CU <;DKF 5 - + 2𹃊E=@ -1FPF,FPF1F RIIE  3E D@KA +1FPF0FPF1F VIIE  3E D@KA ` sx8Q#0x+ -  -: -T0EF -tF;F F" +  +: +T0EF +tF;F F" ,` z -U+@1;F0F" +U+@1;F0F" 3DSH@#D SH|) @! E - FeF {D@&DDLFFHBO6W(FQFPQFF(F xP, CCB -1瀝B>@[QFF.FQFF RBAB + FeF {D@&DDLFFHBO6W(FQFTQFF(F |P, CCB +1瀝B>@[QFF2FQFF VBAB 2€B=@EF#BE8;B[ B63F Y` - -tF+F F" -,` { -CFB  -CB +>` + +tF+F F" +,` { +CFB  +CB 0X 0Jo   @FW+p^,`D @˃L5( " " -E -YFPF FPFYFGAE I0iҊEIcH @#FB +E +YFPF FPFYF GAE I0iҊEIcH @#FB a F!  EO5Y -HF8F -HF] X,  @AB +HF<F +HFa X,  @AB ى0B;@ -HF@F -HF 7BAEى2e҉E=`EE #B8;KEX+B 5+F@F X*0B @FAFSF +HF@F +HF ;BAEى2e҉E=`EE #B8;KEX+B 5+F@F X*0B @FAFSF 8Ӊ % -O +O !X* L(?Z! Tcs2O -" +" 3x0+?0+?9F$HFRF f$ -" +" 3F (` - - -ԀlpfhB"_P + + + +ԀlpfhB"_P FB? -*D<F,7FOChB7+F - : BAB  3ҍB AD -HFGAE 3E= - Z: BAE  3E AD@)FF - )FF8GAE - 3E - OCCAB  3𦀌B AD@ )FF - +*D<F,7FOChB7+F + : BAB  3ҍB AD +HFGAE 3E= + ^: BAE  3E AD@)FF + )FF@F @ - ; CAB  2ـB @Ҁ AFXFyFAF -XFGAE 3𽀢E=@E @1F @"%&@@HOI8F CIFGFIF -8F/ -1FIFF -@#E  ! - FOCCAB  39ҍB 3MAF(FF(F -AFKAB 3ҍB>  +IF + 0EҊB AD? IF`F + &; CAB +  2ҎB  +@FGAE 3E>@F @ + ; CAB  2ـB @Ҁ AFXF}FAF +XFGAE 3𽀢E=@E @1F @"%&@@HOI8F CIFKFIF +8F/ +1FIFF +@#E  ! + FOCCAB  39ҍB 3MAF(FF(F +AFKAB 3ҍB>  GD?khFhZ -( - O  +( + O  F h{D  DGE  X - + -D FB -@+P+0+F@{+ о& +D FB +@+P+0+F@{+ о  -Bج -@ - {DhXh@ -,Fh hh F +Bج +@ + {DhXh@ +,Fh hh F @@ -1950,7 +1957,7 @@ D FB - + input. the source ROM image. @@ -1974,13 +1981,13 @@ For more information, see the man page. - -  - -  + +  +  +     !"#$ - + @@ -1990,7 +1997,7 @@ For more information, see the man page. - + @@ -2063,7 +2070,7 @@ d\h![T6$:. -XXXXEEEE,,,,????kkkk::::AAAAOOOOggggꗗ𴴴sssstttt""""筭55557777uuuunnnnGGGGqqqq))))ʼnoooobbbbVVVV>>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<X`3Q}$Jv)Cb4o= x&u/3V8[%L.A aהlކ{ňv̢UXO᰽B =0'*z>>>ffffHHHHaaaa5555WWWWiiiiَUUUU((((ߌ BBBBhhhhAAAA----TTTTsrc/cipher/aes/aes.c +IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNNllllVVVVeeeezzzzxxxx%%%%....ttttKKKKpppp>>>>ffffHHHHaaaa5555WWWWiiiiَUUUU((((ߌ BBBBhhhhAAAA----TTTTsrc/cipher/aes/aes.c ^ f(n0v8~8@9;:?H><=6P7541X023$`%'&&#h" !.*p+)(6-x,./>pqBsrwvJt u~R}|yxZz{lmbo$nkjjh,ibcra4`edzf @@ -2136,7 +2148,7 @@ LLMFGETDA@B\CTU"WdVSR*PlQZ[2YtX]\:^|_ - + @@ -2149,12 +2161,12 @@ LLMFGETDA@B\CTU"WdVSR*PlQZ[2YtX]\:^|_ WARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1. - +   -  - - +  + + @@ -2338,100 +2350,19 @@ $ - - - - - - - + + + + +  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ }L,D4fl}C}Ο+#U>#`e!Q4\Ycɟ+1*ZibBtz["؊4س?ŏmk1Ke6ukG܉ـ( f13j~{j6h߸ +] + +u + + - -4 - - - - -# - - - - -Vs -c: - - - - - - - - - - - - - - - - - -0 - - - - - - - - -v +^ +y +L +S +Z +a +h +\ + + +Rs +a: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +7 + + + + + + + + +v - - - - - - - - - - - - - - - - - - - - - -# - - -# - -E - -v + + +Z + + + + + + + + + + + + + + + + + + +Q +R +  + + +# + + + +E + +v - - - - -B -V -c - - - - - - - - - - - - - - - -$Qt -8 -8$Q0$Pt - --$Q - - - - - - - - -$Q0$Pu - - - - - - - - -k + + += +R( +a + + + + + + + + + + + + + + + + + +$Qt +8 +8$Q0$Pt + +;$Q + + + + + + + +$Q0$Pu + + + + + + + + +k - - - - - - - - + + + + + + + + - - - - - - - - - -3} - - + + + + + + + + +k +3} k -k - +k +  @@ -2767,1508 +2712,1492 @@ c  - - + + - - + +  - +  - -.1<~t2Z=ggL=. -.!>>l!u< ./K1nty f?@gZ\=[ -mtI-eR-# - / -.*C'K +.!0>l!u< ./K1nty f?@gZ\=[ < -J[s0 tL$Y0 0$ -.vJ#./ =>! -h! +hyfe -B -$B - - - - - - - - - +<}J$K!u?YOY!u=1K!uK=1!#1 +f!;#ugg/k.<Xo<"g>yfe +B +$B + + + + + + + + + $A B R -$B B - +$B B + $A M X $A B q -$A B - A B -$A B - +$A B + A B +$A B + $A B w $A B B -$A B -$B ^$ +$A B +$B ^$ $B ] -$B -B -  +$B +B +   - + A P -A , +A ,  -$B - B -$B +$B + B +$B $A B I -$A B -$B +$A B +$B $B I -$B +$B $B F -$B +$B G   ,A BP$B L -,A BP$B +,A BP$B B G -B +B A i A R A L -A +A ,A BP$B a -,B BP$B -A +,B BP$B +A ,BP$B X ,BP$B Y -,BP$K - -  -A +,BP$K + +  +A B -B +B B M -B -$A B A +B +$A B A B l -B - -B +B + +B A G -A -B -B - B -A +A +B +B + B +A APA H -0A B A -A Q +0A B A +A Q B G -B -$B +B +$B B D -B - -$B B$ - - - - -A +B + +$B B$ + + + + +A $B U $B N $B K -$B +$B $B W $B  $B a -$B , +$B , A B -A - B +A + B  - + A M -A +A $B B -$B - A -B +$B + A +B $B  $B O $B H -$B -$B -A ( -B +$B +$B +A ( +B B R -B -A -A E +B +A +A E +  $A B B $A B  $W B y -$A B +$A B  - - -A -$B -A -A - - + + +A +$B +A +A + + A D -A  - - - -$B -$B - - -  +A  + + + +$B +$B + + +  $B N $B f -$B +$B B U B i B E -B -A -$B +B +A +$B A j -A L -$B ^ - +A L +$B ^ + $B Z -$B +$B $B  $B J -$B $ - +$B $ +  - +  - -$B - + +$B +   - +  - +  - - - - B -B -  - - -$B -B -$B + + + + B +B +  + + +$B +B +$B A z -A +A  - - - + + + B } -B -P +B +P  - +  - + $B C -$B +$B $B v $B B -$B -[ +$B +[  B B - B -VJ P f ~ Z ~ Z ~ - + B +VJ P f ~ Z ~ Z ~ + T | PDDHDDH -rFF`DDF +rFF`DDF  ^ -D +D  ^ -rFFZDDF +rFFZDDF B ^ -B -$B - +B +$B + A C -A B - B +A B + B A T A i -B +B $A B Z $A B G $B B  -$B B -B -C -C -C -B A -B A -C +$B B +B +C +C +C +B A +B A +C $B Y $B I -$B -G CAA -L CC - +$B +G CAA +L CC +  - + $B B -$B B$ +$B B$ $A B  -$A B -  -A -$A B -A -A K -B +$A B +  +A +$A B +A +A K +B B U -B +B A A D -A A BA -$B -$B +A A BA +$B +$B B f -B -$B - - +B +$B + + A G -A - -$C B +A + +$C B $B B $B k -$B - - - - +$B + + + + $A B / -$A B ( +$A B ( A Q -A -$B - -$A B ( - -$A B < +A +$B + +$A B ( + +$A B < $D B  -$B B -$B +$B B +$B $B H $B  $B \ -$B -$B +$B +$B $B K $B  $B S -$B +$B $B E $B d $B Q $B ^ $B V -$B +$B $B D $B  $B A $B L $B o $B  -$B P +$B P $B L $B  $B S $B Q $B  -$B +$B $B J $B  $B  $B x $B U $B | -$B H +$B H $B P $B t $B E $B  -$B $T +$B $T $B L $B  $B  $B K $B  $B { -$B H +$B H $B O $B n $B E $B  -$B ~$T +$B ~$T $B  $B j $B  $B o $B D $B u -$B +$B $B  $B Q -$B ( - B -$B F$ - B B +$B ( + B +$B F$ + B B B C -B , -A MA -$B +B , +A MA +$B B g -B +B $B E $B I -$B +$B $A B  $A B f -$C B -$A B -$A B  - +$C B +$A B +$A B  + $A B H -$A B - - -A +$A B + + +A  A -s r q pon -n m l kji -L K J IHG -N M L KJI - +s r q pon +n m l kji +L K J IHG +N M L KJI + $B E $B  $B  -$B +$B $A B B $A B ` -$F B -  +$F B +  $B  -$B -  +$B +  $B  -$B +$B  A A C - A A -$B + A A +$B $A B f -$A B - +$A B + $B  -$B +$B $B  -$B - -,A BP$B -B +$B + +,A BP$B +B B M -B -A -$B +B +A +$B $B d -$B  +$B  B B -B B +B B A B -A B +A B B B -B B -$B -A - +B B +$B +A +  - + A f -A +A $B Z -$B -A -$B -$A B +$B +A +$B +$A B  - -A - -$A B -$B -$B - -A + +A + +$A B +$B +$B + +A C  - B -BA -BA -B - A W - -$B + B +BA +BA +B + A W + +$B $A B  -$A B +$A B $A B ] -$D B +$D B $A B A -$A B , -$B +$A B , +$B  - +  B Z B G -B +B B D - B 4 + B 4 $B J -$B -A +$B +A $B S -$B -$A B - -$B - B - -$A B +$B +$A B + +$B + B + +$A B $B B q -$H B -B - A - -$A B $ -A -$A B L -$B - - +$H B +B + A + +$A B $ +A +$A B L +$B + + A E A P -A -A B -$A B +A +A B +$A B $A B  -$A B - -DB +$A B + +DB    - + $B # -$B -A J -B B - -B B -B B +$B +A J +B B + +B B +B B A [ -A  - +A  + $A B ! -$A B -A +$A B +A A O -A +A A w A e -A - -A +A + +A   - -A -B B + +A +B B B C B L -B +B $B D -$B +$B B ] -B -$A E - B -$B -$A B -$A B -$A B +B +$A E + B +$B +$A B +$A B +$A B $A B ^ -$A B  +$A B  $B J -$B +$B $B J -$B +$B B T B Q -B -  -$B +B +  +$B  B W  B d - B $ -  + B $ +  $B ] $B  -$B - -B -A -B B -A -A - -$A B -$B +$B + +B +A +B B +A +A + +$A B +$B $B a $B _ -$B +$B $B H -$B +$B  A E  A D  A D - A  + A  $B p -$B -B +$B +B  - +  - -$B -B -B - + +$B +B +B +   - -A i + +A i  B B - B - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + B + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  - +  - +  - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + +2 + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -X - - -[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +6 + + +7 + + +; + + + + + +A + + + + + + + +L + + + + + + + +O + + + + + + + + + + + +Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +x + + + + + + + + + + + + + + + + + + + + + + +  - + diff --git a/hdcp_rx22/arm_tools/hdcprxkeys b/hdcp_rx22/arm_tools/hdcprxkeys index 68cec2b..36ebe0b 100644 --- a/hdcp_rx22/arm_tools/hdcprxkeys +++ b/hdcp_rx22/arm_tools/hdcprxkeys @@ -1,371 +1,325 @@ -ELF -h+Ѩg# +Yп_T -F -h FBF -FO  -o -h" -&x0;hQ`Rx0: * +ELF +h+Ѩg# +Yп_T +F +h FBF +FO  +o +h" +&x0;hQ`Rx0: *  - hFF/)FF + hFF-)FF   -L1FF -1FF, 3vIFFO -'R;0;h09 ) -FD,< +L1FF +1FF, 1vIFFO +'R;0;h09 ) +FD,< ? -9 0@ - - - oo - io +60@ + + oh + ih     pt - Xo - 0@"i + Xh  -  -@"4 -,^3 - -8ׯ(  - -@` +  +,^3 + +8ׯ(  +$ + +@` 0 -ȍ +Ȇ 00 - - ᄈ -@ -6 -R - ( 2 -  -  -@@ M< -8P - - -< - - -8  - + + + + ᄁ + +@ +/ +6 + + R +H + ( 2 +H + +  + +  + +, + + +(  (@0@ -) * -W@ P@ -( - -&( -<0@(  - -㸧㌹ +) * + +&! +?0@(  + 0  -" -@@@ - -| @@ - - - - - - - - - -\' - - +" + + + + + + + + + +* + + - - - - - - - - - - - - -N - - - -p - - - p + + + + + + + + + + + + +N + + + +p + + +p - - B0 -p - -90@ -8P0@$(9 @ - - - - - - - - - - -"n( - -0 -  - - - -" -   -0P8P@< 90p - -$0 - - 00@, @ + + 0&O T" + +&V + +" +  + +5 + +  +  + PP - -& + +&  -P +P 1 -p - +p + -O -  - - -, - -< -@@0P - - -0 =0 +O +  + + +, + +? +@a +0P + +30#: 4 + +0=0 2 2 -3/ +3/ 2 -90@) +60@& 2 -,:0@) +70@&  -p <0@L-0@ @ -4 0@- +;<*0@ @ +$0@-  - + ЍD  d 0  -GD?khFJ#pF - pGO2 -h -BOSؿ -3`)h -FMsh R$ -FI#h -Mxt`XD0D@D0DsB -O  `F -o -  -4X?(F1F:FGLEѽ - -9Ih -vIc +GD?khFGspF + pGO2 +h +BOSؿ +3`)h +FKpCh R$ +FFsh +K`D`XD0D@D0DsB +O  `F +o +  +4X?(F1F:FGLEѽ + +9Gch +vGx3 .2.)'%    J+FUFSFUS IF= > E -d Yh i1D +d Yh i1D -PFfyhFRF+F P$/#p -мi@ -}j +PFfyhFRF+F P$/#p +мi@ +}j #Db UF4Fo - -P5PP.h` +؂DѹKK"{DhI KK"{DhI F 0~kX>o + +P5PP.h` % #` 60# <8d9kzkC# @@ -1247,13 +1171,13 @@ $Fy :kB;j3-0#<6 D#8j-:m{l 1F*F FiGB~OssB~KK"{DhI --$h 0FQFRFFm -1F*F FiGB~MOssB +-$h 0FQFRFFm +1F*F FiGB~MOssB [B;c` 6 <%6 &>dkQF8k*FX>sBsAYF --%h!0FQFRFF&`zi -%m4#` +-%h!0FQFRFF&`zi +%m4#` ` C@m 60# @@ -1266,36 +1190,35 @@ D#m-:;nn CnC2 ) 1F*F FiGB}OssB 0}o*D X --cl +-cl 6 <%4 &f`QFj*FX>sBsAlFɹ --"l -` +-"l +` # %lͱP` [B`bJ F%!j0=~mPV`5P3h -%H%F -~ - - F+!`.0h9n -O FT&P!FD& +#hF:> FT&P!FD& 1q `8mF - mZ + mZ v `o+! FAHBHA -O +O ` F ! -ݸo -cdFV \Vxo +ݸo +cdFV \Vxo "ze` Eѹ Л - OI EFghFfh + OI EFghFfh  011`m P;i;;aj@;i O ~d{e0)i0) @@ -1308,10 +1231,10 @@ D#m-:;nn CnC2 ) Z ݻoO S C+BgŻ & EKX+B9ll}kkx -`:` +`:`  8DIB|x FS < B - +  G3h*&ܜBO  -C`M +C`KK !K  -CpgFFLF +CpgFFLF 3  , EkSF ? 3 h2 -` M`MQMs +` K0K!KC h! 2 `((eF !D-OFhF $ H -k +k BF=F #E%FFx+o2+`B*`  @5B9  G(@E@ - )!)@!PB"FO 4  -     ٝ@0+ A -ФFO4O4b9lB,FEv&XF?FK@{DhX0 -,i~􎪻k +:8l(F>b9lB,FEv&XF?FK@{DhX0 +,i~􎪻k  - + - yn8Oz -# kFE +# kFE  kS"0y+K@,0(Ѓ&0.n-n}m{mC3!h@O5 -  &&XFFFL&}n +  &&XFFFL&}n #00$O @>b{d`ek FV!0.FoE9zhF *~9>30F)F -&*FgF)&`yn - [B`;b F+!h0k -PFAPF - x[B~eba F%!y0~[>k[jv\30nfF +&*FgF)&`yn + [B`;b F+!h0k +PFAPF + x[B~eba F%!y0~[>k[jv\30nfF !z`.F` F\!0 -!E9gzhF -~et:i~{)F ;oFr&`[ .Fe츙KK"{DhI ! +!E9gzhF +~et:i~{)F ;oFr&`[ .Fe츙KK"{DhI ! !z`.F0 F\!0 -!E9PzhF -hF +!E9PzhF +hF F#`?3C `*F``F#{C#shp#{ -Ѓ%!`aa(Fj -"b" #C;+#h -ԀlpfhB"_P +Ѓ%!`aa(Fj +"b" #C;+#h +ԀlpfhB"_P  -  -# Dbb3hui+I! h]@(F$O -,30F0 +  +# Dbb3hui+Fq h]@(F$O +,30F0 +BX -F -p yD hX0hwi +F +p yD hX0hwi 3hB&  F FQC(FD#F2F (@ FUF# -  -@L<  - DDOI DO OU4L EFgfffHU  93 F Od &O{eBB I">  .8vFD5%(FE22DFH2H2.[ٺDD<P,BQ2DBFBOBDiiaDaBh +  +N<   + DDOI DO OU4L EFgfffHU  93 F Od &O{eBB I">  .8vFD5%(FE22DFH2H2.[ٺDD<P,BQ2DBFBOBDiiaDaBh ,+5+xJ+ -"Th]E?ch+ -" -^(Q#; +?Kc;+?E+?AhDT kx0; +93 -D +"Th]E?ch+ +" +^(Q#; +?Kc;+?E+?AhDT kx0; +93 +D ?EjO 3kJF C8chB -Ya`xB РhchB F`KAhsjj2kCE RDQ`<` -d +d :uU <;DKF 5 @@ -2374,13 +2300,13 @@ A3xB@$FFCE@? sx8Q#0x+ -  +  : -T0EF -tOa;F F" +T0EF +tM1;F F" ,` z -U+Ja;F0F"v +U+H1;F0F"v 3DSH@#D SH|[ @@ -2395,22 +2321,22 @@ A3xB@$FFCE@? RF0F -`f KDFF +`f IFF RFMF$ F8UlPF %:DP[FFFPOD' -[F +[F 1@S` - -tOa+F F"o +>` + +tM1+F F"o ,` { CFB  -CB +CB 0X 0Jo   @FW+p^,`t @˃L5( @@ -2497,25 +2423,25 @@ YFPF FPFYFGAE I0iҊEIcH @#FB % -O +O !X* L(?Z! Tcs2O -" +" 3x0+?0+?9F$HFRF f$ -" +" 3F (` - - -F -FF\ + + +F +FF\ xKxS FqPF OyF # 8FlOO -   O{ -F!ʼO"!ü +   O{ +F!ʼLlr!ü  ,   @msu:D @@ -2523,7 +2449,7 @@ F!ʼO"!ü   OsDES C{  -O +O E gO@mFBr#7:(%  @@ -2541,55 +2467,56 @@ E # FH #GfB8OFuBO B -# -X:e`Nd4L `ja|c\1"4O -FTj\EF?OZ1 +# +X:e`LTL `ja|c\1"4O +FTj\EF?OZ1  FD&>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<< @@ -2720,7 +2634,7 @@ IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNN - + @@ -2733,11 +2647,11 @@ IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNN WARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1. - +   -  - +  + @@ -2921,20 +2835,15 @@ $ - +  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ }L,D4fl}C}Ο+#U>#`e!Q4\Ycɟ+1*ZibBtz["؊4س?ŏmk1Ke6ukG܉ـ( f13j~{j6h߸ -.x,A8M&V-#2am%ʖɳ+v,VL0aCWao/}6蘾͑ʛw2W_!2mn}6 U`'_tأir&<1ahA`.WQIb6 81 +ND QXLnQm |?[Kc99k:oׅ[Pb^ +ZHٓ?-]v~ k!0* +0Zo +.x,A8M&V7Vˑ@Q֐ %ʖɳ+v,VL0aCWao/}6蘾͑ʛw2W_!2mn}6 U`'_tأir&<1ahA`.WQIb6 81 ،.\mG -`Ƌ C.) ̗h'f 9!b _{y< Vn=L-W}Z$-8VĦ4OƦ_0Tҏ' -C"YJy:h;Ŗ*H p@'Ȑk\_a.:RVRەLF=r yf%&b>$E؂{3\ 0~{鑠#ۑeЃ'S[ZAO"wtT݀޲ sA=`*j^ŕҫ[|YݻrjD)4E[M8U?eIX hc gԮ'I4ϭ1/IQ5;} +`Ƌ C.) ̗h'f 9!b _{y< Vn=L-W}Z$-8VĦ4OƦ_0Tҏ' +CYJx:h;Ŗ*ZK uə@\_a.:RVRەLF=r yf%&b>$E؂{3\ 0~{鑠#ۑeЃ'S[ZAO"wtT݀޲ sA=`*j^ŕҫ[|YݻrjD)4E[M8U?eIX hc gԮ'I4ϭ1/IQ5;} KSa+was2IYY/Twfo' qJ+6"ynh@5] e+ Ήik5-`$iRU7M/3 Np=7$ׂk{Ⱦ /NZ;P~3q|So8ixRjg+ -:􃘤oeQ4+ d AY.ۅ.6uVy) - 9Wn&#T3sD(}%5'k^yRȘ*[#2= -e'i@&lo\;㣴;S."t&${s42i TZZX۶ "lrޚC~Ad&ؾ̢$DU%@Q幞(/Z#4>^s3᳇ ؝JeMͼ}̌!F*6Hl\"uI5e8|Vh&*~|;bp8c㌊x]^Y:#UrZ#x/cMŋe/&yMKǂ+znrʍ2>s 'eK +:􃘤oeQ4+ d AY.ۅ.6ILaӢm+M8vI31rMH}{\*{a}|W[`=Y .M.4 +2^nOsع(.9h"抄2͚ +FGHCd1e`+eo<lʺň:<ڿphG90<Ȕ# ƙD xr 4DrۀjfUEdT%(?*B9W{ƍg@PoKο|k;.FXH+'/r?0Q&ϋ01|0p@܁Y[u@tĆ0hN:,9O/D֔B Hx;4$]k_` + 8Wn&"U}3s@ )}&4&n}_/ꭎ:.Bzth@#nn]?⢴;X+!v%%{u70h W[[Xְ!+iqM(j!+~]`vٿ˦&E +U$NT溜),Y#4.OU >k[2$K&@QSۺ710zL͵8/+yci92 6B3%4:2~]r3D[*L&qt2k+*[:ʘ\$Z5+Ci#=kzIh-}Y࠾NoQ)U S<%nPY޷b&Ľ|qy5a/H#EFVyT43cd[%Mκ4ؿ~s$_ʙ[;ujX5V$wW\`%2#zQ:-9fhHO @@ -33,7 +37,22 @@ T{A(1C?dOfObvTp~%®a|ܙ΍!;KGmh{ ]B6PQ ,i U ѤףD(&kkA1F'4`82y:s Xt#X;p:D-^^LPJ, UFm!N92v Ʌºb\0ǖ $gPBug@R``d*͸8t?kͥr_kNR=~ߡ0+un@PM8`>sn0&^t'@ϲ}q(+~*3ӄ Bi\ZP"-9wy6FطeZ)#jܑd9v'i3oa&\N΋u_i2u FIw~(4}Xq=wGYw!ҴGj#Hm6,b -^[w)!z3şsk+Db| +^[w)!z3şsk+Db|P5b +pm%V>%#DͫRNj59vieSO;t?gDUi$]!W3X] K)>L[Nr'4k3!GJ+Gn/&8 +6G`/ Q7dz̳J|Nv!gfݙ +:H?> ZYmPcu\b4fkb܄$;y*pyO=-pkDhgfJH'#w蔅5Jp2N} +զK{D'y|$#fH*=L_dJzɗWxN|? |3`nd >TԷOua]Ҟ`XmKQ{0 +wųDj,Gzm4We؎)w B| +3-CJ0!~,}l +,va&HAM*jl aؒ G0Uwp +` zYr8a2y=6Gw ~v +ˀO@V"^GX%ڇ܏KvyE= +b6$t1J=Ag + Gi\+ t/'*ܻO[6禜Gl|WFwM!/8 E/w$smͨ6AS&xZvAGd' MK`;Aq7bM//a:8u~rAVV 2hm6 .gsm't^<Ev9[:RVsI*%" \:!AD(t& z:qѻАBξ +I 4;g;9SқҫM片Saܙk3 +G^T`U|"?섓!m76!B8rUr-|)ϓU2P(@>|7fyX gۺجOCΦx(.bt.wEzF^iX뮣^4h6=uSջ:Z*>XQ2ZؓR-0gV'\e0{ b(F/ UoوBMļ!#?k(@C vS7da3H-Q]ƉkOVYa5.CSv'O=R!c i n 975biDZ\Q]̔VlvdzufX):\pX`e8Kwok8qD,+޳Φ.MaXN6qL /%A4$~& IG0O}Ns U?O΍ŎO\dv.z˵։3XIXakCaA#cśt@xQD5ŞB,bmXҸgR kHb4b -ܫbլtbU$~ -'&wp`f[? :#z Oi8-4V -wov;B6ٝ$ps/jwGPބgL𱫦I:n! 3C)d0o#pϢV V="I4)ZZ -^nS~9zM}Mh`ZgZ`>#w_Xcto\-3G5'QRHd 4 O#ZAKrmEF0gR<\jӉ -?Ob)RV?Sk.9NlC.`\q[LUY=&S: -ߐu_z'.Q1h=4^XQ&yzF&hL)t{8:'RCv2GsjP!\P-"ƅA =>߃w|e/v"ŪL|n4"aLfMrf9ȿ9P>w 2mPQuKv#%ܗߺ3re29nrPz{|l)\EK`Ya5=~dmDSWEe&}~fC¢ey -tw BĻ -Jʛ iU^Քw5 -F'0 Wg¼]Pyrncm}j-~TG*wfˤÖ>HcQ$sU`Ȇh}I -zdhX >62bg8^׮͊A,8IӼ!vL-L!1=46۸꺗BUVͶؗi<[_q/MϷ"iUf_7!"wHS6μ ^"nU*&v7qg|4Yp$HåȖ "Zyi²gr~t$S,diJUJ DknN(킙B$iCpv^_/D~M3 -˷% - ^_O>:7X2vAA -~,DJc_q*f -ymN,a>FChǤA</G %XpٟY=:25$Tܳ3')28 DpsiX -3Xy9cޔמ% -)ABьjnڧ+f;_Oշ__[,Oaqք>arnЋ}"emxDa! v;(5GCPⶨ\KU;Y -![n@WM-kɱ%=,54;e3x6(|W :$p3 hrb|PI؋M4*#cU6^M^j9u|:B=L2ҷlI!/0ȳ- %Br<^(#.#v7w 69«\-ȓl w% /@K]t9)>\G -Ѵ9Ae@xZhH -ȸЛ2 p - . v8*PVdB|N`Jæ`>}Ȗ `M $\v>OYfpU$ҏ YI1=(j".( -- ׇH`"G45:CuzdUH~$@-H~cu`yPGҜ~Tϔ_ɮ vD1ȝx6{2 ++% ^&ӴŠ<N -EL,2+6HGk$GC9lٝɅ=$:*H|:'D*.l^h=W,@R 9 -ľa6j ݑms笗EKgV5rMLPkQx;o!)54AߓvkHzmqN>̩~eߞ -U͠}*՘ gP}Vh՟v~]bA7?m;^4Q&CHZ,/$D -WG[ -g"Er]4Mtq~*˟ԙų#=f;だ\QynX|R}z& 63sLn/Is(ji2wzkkI3S$4!VUzj^C]2@$H0!?>4Wyj!m<^Ac|F0|n@H^ k~ b<$0qBP*z0³vY<o梧0@3`C+5xAԢxdTQ3MFKZ"C -OYe~cAIXeb7}#u>p@x -p -"GqoMoch#{Gؑ5UUԎ?)!EȜQzCՍ>T,ᚳcb' ܣ-!BC@T7,~ ap9smYIw8й -j첳}#*Ҫ=I1PlfRvNY (܇}혽Xv%ڕb{2ve1xK3Yw}op_:=R+uB -?V06Sqa[܂ FQ3KH  %њ$c+QZ24#/) Ej]k )VdG|.ɶ: iLtbh>*O'WMmbXN{7ZRE\onGB^bĜ^[%UfYL3HX[ pMd 8:_2R5VUY2+e 8!}1hphIezS-XtieOwK?>H6.索$C|V@Z9ґX1r3 jɥ d{3x^ -R+rp -kw&WYU;fLoNFPl0v1T*J$ Șa31@1:? -ž}K*M-T\KgL{NˇCe|g3cLWӂ#<8[* -vSF/#שQETn?}ڐ -/Kf0jmCF72EȨän?mCSXu9coHP^Z$17 ~{5c.[} -!y^[P&5vG^G섔yݾm+ k~݅B٨oD+Up٫IƱMhR댱`6{J|RҎAEiV6xH5E45t(~*jAQAWԟkCNi~ɇ!LɑbXûGSKtmr -(iVxAcxlg`} {1/h#0tJ9n{ |G"͇﵉ ~X [['6 -[_(៑VGCM^ꞬpyFc7?$&H-#Z[Wc&+8* bDZ8ndLW(N !)\`ƅQE9 4MAMY -'F -e2hkfd!f^T393KW%=+pk(Heuu5Ut|1 dF_~wUAW[RP>I\ -iϯ8K oɄUB2WT%N}ꯐp|2!ZlFyqBk R%'#9 -ɤ(˖`Cs8 -&i6PFeF[}r -yIfཉ -W09K3hYRKbWKwC8.f{R?mJK -#1Y$5䠢Wi:cT@f|@@]|U䞵|I9a<'f7:Y -2sU@):9& R -&x{3>Th0/(hbHfVJ m)Oj9P*]O4K@0:+Vhh 6>1 b^ZPkC'SKlm Tz_bp >pޜ*簖sqX,,* F{󍺳Pښoyr4|}mG8H5Iyں ڏ'RGU&ށ$n 0=KxN?Ox˽(sx&l8Ͼ!zx b0Wk#?*ה_5T_fp~3I.vyB*a/^΀*Wn[j#Dĭ -kQ.E&=,aƥ .tb`1zA}OLޅLݭ%O1S%-):#给5P` U2(+Qdla7qCv`H4UL0ͣr787h/=.+e H2D<ϡ\N #ab$Jz֌d[^'\{sU^'!ԶmBܡ@ HݎIPi(e:i LQJD>_c(yBSuh -_@b(6:U_07yu#_fA([Y`dNri~28Y5\of+҈=~Wh[6}`] -io٤k[nTِ⹸=HcuZͅhF D}GlFބo؞+^|{`Xa-2dZ9.{k5Év]M4Y6,-(qwlwtȐ,,-MCͫ0jLmVkF/O4V%؆祙K -z9'2$:u@_Rt)wM'憫AV7 Y'̠rH ! N%!\Cm" ÆLh) -GdO+*jA(&LfW7$S^bUG9HQoj\R u=-Z3Sp -8dc#+B:C9{x~5Hlf"䬁_@sFNv4C-Anwx_:ԃEh}7ry<ƶdf8_G>/S/a?vZ ܂");^Mܸ׆C7AVK@ȃ ]j )T?K5^Ȃ(HɓRxR_nXoJ^K&ctbI#PªgBj1EL|4jԓrux fo*Ǫ6f%ӌ91+rP6ob -ыjUs.2Bnס$kS&g}!gjǸǿ%RJ':];K>8kM3˄F_C@a N,>% L]T{դ:ܪ"Ki` /JPffknxd,(ÊHz Z`b:F $oYGbH*evecglk -*<NjY`Uw[3 -:OM3f*U7#UvOSګ& -{*Y\W+'Nb4iMJ4?(Ϊ'<\wD$d,ۄ|povՊzS^^Qڪ.d1 fC;,<|3VS3O6rxshQ]I役w'ξ0-@;z+UAԎ -XQ2frdJDK/ ďG~fPY ?.eQP :uȒ`eB` -;)l-H -/ Ai@RS;5PNrI?09IfiM|a}Ckcެ:J -jbᆬ= -70 -ȡsi :)'d&bE@8MY:h_TDQ-b3ɖg8ɎDYPAHDD4L,tW#8 (|rӭ?+u7P`27h& -n#)V&ZVk9j7r;0{&[ãݧDS:iw3P79F36߫6ռ -lNװʭ]"U~S: -4ȴlK,Ѳz -`+[3`o"3XWHC=qvVd7Pz`7˱qOGkO0P۬#۵]. %Kri,yE&K -ҵi00f]ف}fsn3<%zjs<8VS V/4޺!5g"id[UOzTr{j@.d!lWYα̶[?WJ{*ÝN6<@H$r۹<βVk'{|@?7?;w@%T a/~]gCu72,u[w=G~t̺ѱL'?+|1 -Ra -&*| ,`JO-d"Vu"IR@IR8|BtL&.^g blyqcl\Ubn5!kݗ H`&0PoI.q5M&;~qT5Rp[sPabj*&T$:H'c/_PQLkj3+(Jeg8!~I*f3~4^nc@ʜ8 ~ Rg), C[%}|q ^SDϪ+.zE<)8`xki!UZ #wbH b=?AOMQLMzn{mY6$@Q‗i-m@yбdё%y{GuONЕuuu6(c9M3&gS,M4qP3|85-!+,7Od -Pm$G<]t̩Yr -1r<ﵐ47 Ck[&x`+",}Cu -}42&N 1^HGvh޸dkac˰ÔcS ~47.~}SW?#9R&Fс#m`ﮑ"c56m~=0%Oe0^%W~_0HV7m;T1p"$*7ƨэ$Ѡ>* *k~#(آWrŰRI]U<\u4><ِS 'u -:o`ٴ7+y4/y϶1rUXE/n{]̹_gXR7<^)סE,Yh#0&OvAwy2<>p 8D -6*lh1]L-5.8e = Gv YK*M!V\ JK!A4Urk4 (6.ד0x$򕿉`S"ڻaoF%fJ>;u p$MK~UF?@lۊ"X arc^qPM_f$L7%M9ZU1UbtT܀fp\(R ɂlIb%ܕ3(`.o^7ܔרeVd $I6vy|۽{L|}rhcܠ,> _h]kwF{=L$Rio4ޗMh -r*qV60l+Yn79q:ӫ\&x ak-}9拾".ܞ"qPME,72?:-o!|+aY;d # W.#H?F.PD6kB qjZ%.G-mDzgEhI,hU"E=VY-ϔ}} nߍ0w -n|E$t^ڴwxCHulj`М_`nRhiI9T̶q/a4)?9no, Wf0ѿkW+ -/FqQlyE;-ڈ~Z|(x'zi" N,ErZw{+l6@>J [)n*XkWAi#Bi=8 -(/^=EyYC!TejQ{SBȟ+P9 -K*C-9% #VFbJ:+@<9H,ҷMDŽ<(Y?DXU?;UW!hCY8PKQ3g9 (li8bm?B -ygX~3CW|Cl+! 此*),"­_hم0!qL5e J?N|%@v(pѠ_Ib[,J8[b|<\Cu9$=OY7ĪW=L dk"e -L5lI>X=ga#26uCQV]t${@uh3v;Su -A폘xZ0PO{3B@kqhituhL_\V\ZHuݟPG6 X.R9<$B`W:1:`t+ ' q"(ȓ>5 - AJ_ǀ$8do?Ü8Ԉ5:=#@2>x_mrFOdkbTO}D_ՂPJo| -1p6 - -\H/\}trta)/ H*+&Rߝ[VjU|}5)K3ocM=sIU4|gIH0Ϩ -5X.) W Rt#d\!!O+1N~s\r6hbe-Cg -*XxZU_B"Nt{NC|Sfw=&!]&vE94C k|^}IiH3@]qcfEVTM(^{ܐK`'GCYo_WMnSY58h,v$uS) gaMn1bQ%oso^&"L\D4o^lX]`$[˜$H# 7L_mK~zZܞLwXw99➱ަ'+$I4*+z,xJ~ҦB n|@ꟊ?Z xo3a,5P.VDX%) ZȪM$9S1ϟ}]//>%Hc^T˞oJmv2z[SL׳k~X- e}uZ!,aT$t378$iDI4UR( UOuܨ{7]T"&; U59+ "}oEP45m֚bfLQ!N'VVqRq-jσئX˻z!Zq iEK`%ո`f  dçM\f)銌.{(SMDwpݥw:iG^M5n`ġZ]094S&`BFzkT™ -s/PL~˽-Lz@i嘾m%( m+#z KLm -wջX".)vt[}~19 A 9bJc@CcSo4 D]rkr -F'Է3-yx5:0JGbpZ?F6v9boq4«֩8 WkfJ.WAN3yBPLn6p |ʯw?(|jxgr0Osa -󈡕f&TA9fCe$m -y w% 2b,OA4' 06siUc\<܂r AmkWlɉsbk"؅ט/|cѕiJN1{hάl/hOM;ir-Uˌ,O!C~{q<0z [8V*#,7D߯A~*LI;.[ Cm &GKbʋhسC)lzG:tLqU7Ȥዑ)Vs=ǁ0 ;3`?7$\Q%˓="̭8{#LU;!evxܸ3'WEwUw"N\b~q5[AN{>_7ޓ|Xl֕vOb$уoR -a@KTM&B8<*=b78"'b6?q9JW.RZfpSۡ$OK\ha&RV<Θg|ݭRDJI[`R'}ڊw1KUЂ s_"-"䃆.El_䭑FTS%cgSvl%%$ -wbFPP-i3A,``fͫks&ՂCM#|V{Uu>x5yq%k@DQ\##W""oSlz֮ <['A)E,dyӞN{2ѝgH{Pp4OzؕajmYS@ TnL1=g60t%06.7F0 A?0bdlc!WdX}b(Dx,H0?ۑh`/[42j.3❼Qjb(RY"Yx㣜LW(Eb,ȝP"`vqYYn_5pZl_;xF DL[Dam۽|3&r A1·j΍.xĪJ}>z4{2S -g*9'6ʭXob -'I5,_lX2u=G| pjVMڨ=p hj90G˹|ZY :\({_ʫ-vN)?F<ʊnV)@H`FqOnZ]r,S4x>CTwdl?H74[`E%-Dy]4%EjqNo qhu/z|qhw)ȳ^іFL -(WHYU05Sb^KЙ.kw:Sg+:6<0ٗaQ_e]/oSy"ZIax8z)W9nȇ8B>m|i@0?" -!1Eq)B}(H~\JǷ){(~D*+^Z`gZxLCV R-K\bԌ}DO/pO[kGĞL. <4 -WM|H̡ޓH+Ȉt!B8/})Lg>~#>m -Rpr5vј,>#Q?Oe`3t@u]_* }T-=l؂.eJ5xکl@jn($J -lK| -${m4U`Jb!v0Wlg!1w:5fa> GZHMc3ǟ&}E;P@;iGƄ -i}I Wm.LHد Vиvs?#OX9CGN' cɞdGr[̤!;7ޓSJ| y_e@~pM_n7dﶁTEIw*23 qE -^Cu !lw#ݝz/xиdT $P~ޫT֩Ḯ jv\)!+{"jj ߆޸Cu\;?[t('~F_v];F'Šbo:3YԃFȄ - -*)XdaP -'n[ [xq -h:=չrޝ@sL cMnnjՐ5 -vy1Hȫ`(f?M߯ӀL_.ABS ȼP~q8q2>TWRF}Ky&q@*խU-yQjJdH"LL-"!l%>Q`.P @pի ۶k^E8=Z.Ȋ3QO -!sgT,~4+eBC1ϱ%%Jw\lZgfo]ղ"Àoe)Kg諂͵i ק4W]%!,&u()]7 ']zDƣK{bT.%<Ԫ.$>KAv2Gq٬Nh V@!!a[GJN%oqAA$٩ѻ[²'su[YP0=u#[.]8̫_0y?h_`hG9MeS5ZTr&>. ee`jj9 ܀bE5jQ\ߊc^^QUϡ &{g&S['_ 9_vn6/9V^+)z2X*d5PPIymn T4^/AwdL[7=6 - JVǯT)}NqW=>RcJy='TiҲ@+~zptJ<`g`D3M!@Bt)C?֐k`03hWӺ4}}X;U?PUpQ.ߴw8JxDC!v'IʵZTI8$24 vD&u#%nG C/,ulemm[$2IÕ螵 -XA-68 ^JgLSK0ޘSψ&`܂{g)FI7 bV=tt @SOA&VQfNj?)t&PJo%͋9m1Kk/n]ob|]%{@LBf5m& Be[M%@Hc~\RPK• -xRoI$;m"4ZɮcRD3/#IbQ&(OMk65--jz;n,5U % ]TF}+WA~' o@DeL/ヱpF>C[6< %p{E(𡗀@tqqPlęyՒ8 (wa4! '7S.&U sk9QrTEٽZp\ˬkޅURT' [}&BJG-%6IG}&UWӃ iP/@}:]ol\cuHWkE'b%]RG$HN;F4 -xv8irf%i~=7*{-RٝL'B: -16rd˞|mz7ؓ]pwdi]ïLë3MW,7vm"A,v|+p4C9Dũ9_ sW1)5mݷFgUq;&dᲷ׾ֈB(BnhMuLJϳKr9 Ǖ2)3u{w6}(\oL6Pl ?ª)W4Gm=|ߢ=]4Kb_.d({~ !FGьTHJ%4`ZlUĨ6 -VLi`<=;t5ͽ"'3:/^_Q&ѤfތA"+$ :entvt7F2E`r|V,JIƪi>2Vih ɼ~-[::F'1z[&Gi}c\I|Qd9)+>6k5(}E=d#}zRX~sMv_j˛2#vL#Eeq9|* ov 6.|eǗ |ݵ)աK;_@0gI!m{߿nEHܩ[@Bn~*sdvQG -@bP3ʌ}kd\`iep\^duj{Jmz+lpRSj{ -~#iʘV&81d|=ӷ>`UĎfuqk8UFp(b/=JSrID+ Pڅx#c@ Ȁ|=8tGN[~d8XK`kUKKJ$i C>\u$Q!2dM-E\Mhj+Z[hJ;"ZkUw8Glvy^],|;&6GhlU]ȼ3Jj'&[cywC~aMJpK^]vJMDs -Q ǺCMꬿ19VRɔ-@mw3<GGp)}2l?/Pō -gD_n+BXAK -#߯oFm֛|oj -x+Yƶt(XdO{ERFuFb@Ym,^JA+8DtԪ> -_:Mr\U;Oӊ g"gULȳ @Wc$`AݠJoJ涭 Rة9;?ApH@rÓMqX W2&֬g āKg kZT<폆M\SSkd * -ļ<#/u=jW#KahCgقS.A9ʃgGokZ_)_6nW@>1^(*7Q@CCA3gܒLx -#+5L}8 JC_4HBps;T,w1$Ti^;zi:e5FPV7xHSE8ֻ=c6ZIՉ8y- Qлz TGru'޺hr %+fNy2-%B{Y}P|:(:L$,f -p2hy`3}Ed&,hJ%J>{\aN"Rp]*j+q7VVm.BQW:{8N8]*n*lU*:;!G0FY-Kиs#%} &?87.]pjlwaEbKQ wHbE1Ĵ-`r8ޢ !C F6GdzO.je2 cis -ۺ|G dcHH'/Wf[yVϷ.k3%WQf7Q.Ip.hN6,ESوnH(QJ~x|P+n%9 +bI ;0RX hB FR܇a+;P (ϊcJo;>̡Y =Ld-BVQI:'׊N2!_@nTM2v/j[h̴ϏD' 1 9!n6ò,7";qV+eŲkĺ2MRy_R;YU{<]0l5j@EBep"f04TObPnS߼f`?Ãigly't!+%fL_&0&w;|E"t2%EVA_OJ4s_{1g%݆%¦ j -B^ߛLb@a މpUܚQQ?jNOBpV(Y?(?r>71rD^6z]'[I!&G&rVPlt| -csvEûQxK)G^/hGZr*V 'luA`7JK -Jl$# 1Gmύ]}7@xRRK u>Vk`8N1/Wׄo*|Xը _A2 Js+ h!N Dj{"OµcZK#\6s,4] O P0: 'DT 10k"}S\ޢYn7t_2) -SF]wJE?(TG}J'E4%4<|YF̊v4k. GMkDܿc4tSfYL)e[=,vMQzxCLW]oE)zQ!- -N><,٬q9qC/Vo)(^4`6bQ|*ou{8ڽ@05 n< iLv5&kE*(L3U)T0 U2ev|7F. -bfdT% 3z*xa2laLv8[ǕJӳQ -q-ह ->2oZXQ;sS`WuZw5Ml WsHc q]m7?W+Ty^lviwۄ,'j qmš3fE0J{Jz}ʻl!z™𚟻Z۾*: p5uP5#W܋g8֥-{)Zis5e -N -Ⱦf ɻp?P89#W?zÝأ]N=Z7A=^lzd'R?S!ئ<SXߒ!~XC -zbјC_ˆy)B6w]}S_h˘˶1A{L}A dfM@7 -J`d#÷ջm"¨B7ebOA|{7`q -d_B|GYe-!G"Kc\ 9`=njٻ!~^+,l<3NPsuNb1rI:g@4aT6~jWtR\±x7+}Svb88qe_Mn19eQ\h^Ⱥ&-vJ1+ڻsaS2> Ȟif`Wuclmy5SP%aasDI9Pl_9&nT`b Oė|`|m_=? -UeB;8CbHuK'Җ>g35-W^q^)dl1q0bERGnp>|C~]eeƦ.~#{CRַ+>ѵqc j9 o9oV_t -9|/ePAXroxңl_ Ť fG'ֲĵ[ -2{C!~$6O^)!>q1T]=sQ碔/P)7AX};iߑH_nS 5"K)xMzW@JR`h9 -+ޚo6vPxeU I"p 긙Yģr"+R0 6&w>ѭg/kAֹN^$ -9DJWG}YY($zï -ϿxHn*acUĚ-G^Ůp\~B` -<̾)Mos<^b ڰ$l{\;[0^q 0cCǡsZ{v ټ"n't?%~w񰐼=w,{ -퀾pR9/W~?hE+^@NjJ[]Huv x1#ܵEp@ZUxߠT=;S(1D<['\Y$FBUɟ.(̙{VCu@M*ܔz஑t'Oq5/PZtC{w60M$9fz>('o -fr}|i9L]zTjru3*_ڒzbX)=90vI -+nc\ȭ6lD\5AfFdJ߆|j^D,'|k*Wi*8՘Gӌ=԰G,WSiO^g}&2YWCNO -uS2k5os0|I$ܱ;9Pׯq jIspH͐[74!Oj(h__l^!URZ'k;D(^3e+3$MF?2<%6g^_7[tHM{|™b@oҴk1ZI.Ň``i,*TQ2jP tFђ6)_Q΄߱U]imI,^i4T&3O9yw@YH.p.u_dh~03Cdb#UP 6k8/o.OD,MAI8Ar\&Qe8 -pTb*V{ ZxG2غKඃ. -hI,e -?hmӭu+s*JNn< $w0Ί܏K ->tv - 3Λ܎Z{.џ.|G!6P;͎h x!!{F B<]Ϳ!E,8?R*Nrf)f頵av*:Vі9n4|*N$")2 -y.;\-ԴԡW,uz?^i n/dyq(4v81.[=C8VYlkk߄p?)n #+p<&V&Rf5kF?gE_QAac'yW1(=ޓS w-> I7m -4 X.2k - Vv? y.RLf:f!St(̍] ObQn L=׽tlޫu0X GlaxLA>G>S5X!߼MMAO'~@b0?:'R2[U]U2 -eG8O/6&Ak\CnT[&6At -Mv0ȾRɟTT_>ٛC!K5 põgxZ8'Q*3U̒qk BsPA P^.V. -G~`8;޸1Y汁>DpkƳGi!׳NN -w>tzRjp~^^RKƃѭHd+.S3p&\x䓁|( EQԚ~Lȴ9 qd]Fp U=JFL -8hLPHf -Ύ,Ht[Pzi%+TؒǡS`x}sSz$aUD5ZGZM;)pZ<t˙Sch{+[pb9\7yapy-LuUr -YU]Z -!AٴOlIi6? -ae>tl 70V9ɻYl='Zh6QJ[ZPUѿB^f}j9-fNO<cu̬ -iy{Gf2(E E,4b -;v -chBi?(_ hATWj/F!J_Y<>oe=yJTU`b7XW`9534DOn;kɃd ARw+蒖28;׺:^͍α$kn0:Ams:fi-@iYLYUpY MbUS$MLTX{fqq6YNPBfK$P`" vNBXpXc֖v8I<~0*ȂB }4PD:C}Su8fPNCO-ZOlnWU!l ->ࠎb~b̯~DTdO P_;ױo~ʫ8h5CU {t1ttvxP_H0N\%=;ԁV2ܱE_9!aP'\%w[<uZ/>L@ -QKF:/*lfFmĈ+|„1 #q w!C$Dtf +>~?t3` .=hg Wj(vދ0bxaMO+ {RK&|7]+.?Ħ?N%fij09sv' [Ç./600g25~бVjjn6p+K*,'Yy(zgBXNe;FW@GE1|LFJ!z#}b:^~dd&5WG?b` n1ݔSx1hy!ad%֗X-ֹjve} yS$ZRA{LC>OSr!,~RLZ>"Y$ElH(̡ J4C.fU:baD[8 -s"9h -5rŭGXX.:z3>چPm8Ǹ -JB;y wN{ Ag1'[ےB?XR R$\d3*L&GܸC -+y -n)lJZum5ng6_AB{oPBGRx/4U%f|Yq -vw^L',{tƴe Azr!K#ub8+u܋=t(¶jašpmrLn1:F-/S37eV o T/mC-U29N&ܖAZ3oe<+$\4Ms3W썯~gCjB( @ vnwzU{P)xE)VͯinD;.\CY\$:8խ}=S>)6i]:ϣ|& Dz'`u治 Odj-gA<aYl<ٌ -fKD3L-*xf]{I2A+8+d4KY#@.W1S@.WTarLա5F)"PЕo 1Iw(k -{k?E"yŅ@r[ 64i.44DF9\^KR*kTw,:';k!N>XpLrpI|)0a'8uc9Nu/]%GPA,A1QU]1E[u"8}xӫعf -2PM^3kQk3C,dyTE Q W=8oCAn:xn3gōeXesu># vI=MhD0^CAvZ;Uʢ^rCgo*q (_\KRʅ8;q1PmP4ATcy] ZYp֓=H6j"k4`1خݕU*f h65& - c - ~{T>\sIV1lz|O0k[W~ȂҐ>KŠӖ1@F:vex>6W ڣkaLNtw8y'fn6%v_z Md^_E2@\pOPC `3y*a^x }/]L^ovH9UKz{}W\)A f#Y2I۠a' E_L`)S-j0r -gYXG?ju} }&WϖpIC:K;=i]O#4x c -b~d=Qr{lTȉ* ]qeoҹUZC},ۛ5ǭ"qŔI2ps O͉YG;(IiZa/+̹# v ķ -JZݓTL 7$O,E?]H.qyM& }+1 '\0[+>? * -=|cv\h.G곬,'a$fLaiD2 u(~j!') %'›ޮ?!->n璨"r{zG,R7 )nRӧ<~,_3ЊJDK*<[`w@4da!V .LLH.#a -tEkgV$q*ʰgZVLo 7{C#G)b\#G/6uXE'`AeA$k2w |C7l߸vpD1Ъ96\K.#dW]{趇RBZ/{va C從-&?_8(%e d+_o&p[zVSBgdy3;#nr,ܔv!c36F@sy773Wɤb4wVβẄg,,} 5.u NJxΠ o T^ǏJ6ŗ$wN MͥU %wOnnk\4H\"aGQk 9Wv -秆lMWui14 _؏^ *yRI |׳kn~5X7-XNTGqN/l1|ÄjK}/B @"۪ؤקšK/پ2 -rfU:Tm e-xqx"eK=L;htn4 e|zGA7 s7Q=Y̜~o.Kٴ9̻du'fg,Wx@)/,ڇ֡D}/N Ʀ -ؙmi -7 rv|Y"Wʏ*\X؂d==&[(x$-_K犔LKɥ y-[AI)f %v-OOi=, 菭b2.gZԳ 3*,Vˆs!2 CWrB/6CK'>??icZ,TxSL3 nt66 -H._}eUUo-[+%S$pi k=_瑏RU=پm6c^*M A6)$i!NND$Epݮ^%EЛ95{ =2·HN2( јá*LJ0<"|keؿ }wV Lakcui2Tߠ !h[A^F(ݝ˸V=6Αrݜ[y{mILʟf\Lx]ԟWt۝9DZh.10u:µN`tіU4nQBYVo:du=]q#*MC0[gzFPb0I[+XoWg7rU.1u涻T+lag2RooST?#62Q,'4gF =JaX}?TaZHmT!I(AQuyALPT(O0ris 4 \7H} -,o͎~ˋϧyCV3-|4se~kyOԢ^j:Z).Xb ژjs(ooy=a1p疐~ -*p"{@doR7U8Rp9aB:Zr;2#ӴK}31J=IRD;,F1S@}k9&36Ǟ.]x/u;n -wq"uVNo?"&C)+Vj;>@?D*FdbH`H+7#S/Q\ - !dC2 C'UrU*=xv5A˕AܰSĩ2[Llj7̅XH?FC11IV]p1zLX&J~xu߯es0p0ݙ;Y`ʠ;6La؇@[XY9 -m+L 8uDՅ?>@b3'rތ;'S=r -.[ M1bpQEs"Mk هsz9"<U.K>:R8ՑEԓ S'4^UKQZ-_}P5#Z<2vP$Is'ۛ4[꧛2"~9BSZlzHÃ㔜v2'oO- -%%vԌxxǂI{_J)v\EOr}n^o3;s}_Qu(=G}Sx|, -1=ب?rg (.>(6- z WTUCtǦEF -[A~-<J쒧L9/ݕN#ଙ>rDg/^xW9BS@JΣlYM%=- #-Q5S%N^y -ɢ|=y$~$- LM;2 -o{A#a=Z^>j*5YJK6' PBES^f;R" -ZlN6 -:mK~ R+wz%pLSr`ɺ=ΆYFh8HA.h+iD׻v rEќ&y0U^olj:m;B/|?HNT"z7^fȞXWBW`%\r$s -ܢqF^sYwj$y.#[g l,@ P z֎Bxҭo!y,j~bNQmη. T4t>' -|dTD$Jp׾Ah?ȶ0RBЖ̀JfR" fF/j7 QOm`6@Ỳ8 yV3dy}%6Mtu@ З-jP(} -Q D.sYv}/UMb1#k j')zS+7ϋ0$6z^ 7.g·B櫆Q/p dq߈{:ՙu -gi[2b[=`}v?T3rN؆uz=` r2]>IS3_n[Ed;3qy;BÖ, 3ڐ&f[ŽIJE~g\vI5P ̵?vUc~5[,B -]lƮ,H$WW7īw۰! nGjдlDaE1h`xɺKM$T `CwgMߢ -'qnH=a5I{li -QMa I?ϭȎ5v/ -z ̝b֮q{ }*3k|a.Q fP344$KeTEfji'YQ} : TDžgEnɌ‹SA;"x1\6B2 -b(S\Z:UQ]?G9r ~š!F_@C,'̽qmS3CwGFXA*.Ysש$98wyQ5LiڱϢ}eot$xtb6"5)\dp˞t(. -va'H(np>Z9e[0ZQSٍcZwsCA &'` \jRo;D -Uh{bmo|dV:z'3y:Qާ$QF{i=.40n+ezmw=y:o7| NՌS/V>9ncB] i$@)\AQ<RG}`30%EgFDʀBT`ߜBVSTCnfW}T@4&Sպβ 7(M٩N &u_8X_, ,.SصmeG6?SўRyȲ#u=h9V}?'a)"ւu/O&)Z+/9Qڧ!g鼒i} 1bb߼ Ec>__AX ~JdK27^G4 !=DvRRw]^Kos*{SEuҹDhWȍ)G8x5N\%oCi:UB.gosHISF^5moցgCk VU%P!B4EfIy?R9j&tYh;o&p=' -k*W&> "x -#|&mVg6``3ǾVF^<(){887N4Nٟ4}{Lf׵vyMm  -ǥݠ͆Uf[E&yZf M$nHiU[XQnk}BtԻxd i0Nt -|]ꞠS~4N>m{NЙX^5~NNL gť[T(=1jA\֪Jl`&{*ڎdB7uL/˜v2YszlU<5rH5.G*r8ԯJ~=:XDˊ}&YYlRҬ;ӱ[K7R&xƙW˜YA4F\ [/FVG&{զɆT6#q?B5P.Xuc-l2J<~ri|FZrbq<*q4|;;s`5oo8 -C~eZa**uGsF cc7v~i&wE`D%Id'aBЊEQ~;>Kwca|3ux9lk\i`[0q -O!5 PtՕѶW(1 ّ#¥e?BF*$fy{ -}@؋ԓ7Ê>OR.dѤJ^7롕Ly`1_t$3 G zX.So*!X߃~Xv|Y702(|E-B P,1'UV>1ЪuZmv3Cީ'Y%)o'EpqS_u?z_K>PCL&-"x\3CVuq"8Ud2 -_3 2ﱵ(aoMPxso_Z@͔ư͐"&}#Q| QCR>Yg luD֣,ʍrK-vyݐf9h#jwzR֖xr'Z(y SͲ>U_FkB(C6d@y@4"..mN֎A_ɦe:p% 'N˿ٷCPIdt>HM-*sCv&ETƽpK^u-q~ě=foyUUkzPt9ME[-?oM /BiFH(a&k6Ag?VԘw[kOxPv_:I >~yƲlc#jpͷsHM- $GB3ÝE9wxהۯ_>AM)o ef~Q +OTWv[`ppX낂7n!5M ͻ^PIXg9 k - -˫Mgq6SBS^ta~u3-Sh, -Hr1#өJpdY6 qUD5Xppw[Vk{14Uj|@>_~5 %m( -pJn`3n6|;: ]b@J"xyZ2;s-Re%+Ղ2x>H} N=} -{bcp5rV oM#'7-_<LV<,yY'tv0.T"O)# -]UKP+>I=zMd\fV'm6KRu]ј *Hwsj$cPz-T)bXyx-uY^tY?FLmK9/OJ6^=`z=GWО/ IwbljZeDL7 Y]v=d2?J*η#" ~` - ?8d>y/ە]]} -0(zyzd*Qʍ.X*$tү]#nbNdb2s_\x=+t -e?#±!3,ӬXwN0B1 H0yę46*\9\؅ST t~± ϐ3}юTRIGEx;tbkE~wh5x2Stp|jK7^䍩z䈴B?3c 9k[0 ϶drRU}& {^+ΫZ ӪGb z/h^sGIJt -[W4ٸ@aԁ% A k,䷪W~سD_CC}ڛF1A2YNKuW=2Ezg'塴mNQ#M#~Xq6Hzܒ+// Pn-rU0À-mTW}5ʂI81e_- rN~Å1;I9)7\E/rCSj.'G])JkM}=\zC̕$uo G{*I"t`╥4jg2E_LQFI4f"fr.:YQ 6梈L۳Ϳ'~!㇃d#My"xq[Mi~)?DUxлْt - ~?T6st}ej`~V i@D,| - (߾#&ͮ^ *iYW&R7YBZDP$ !4˄ˍG9b qW>> -Hղ mW -mh6lUsX(}`㏓OM29.2VU?ƫ;ggcrUƺǬ5Mg1~mz?6$<(*x.d_לw<] x#/ÅR{ދ<^\KajQһUq/0 .r *t2[%#RhOlޱU2R$ζ#`ↂ"(XT]&sÉCEnSw4 )c)F5ڎ0"7Na7E]^9!0&7wB!~q w}ɇO _^yl̿osKr1Q)0>MtfC5X4Mc8B2 -@-|H m޷^JTcjD8OXwDm*Eq~T=_8RV⚗<@K IލqnOwD[: jxqK&0ydE Xy[XG|"ߏ#޶c>B??uIav3O;[)^+=F<5wXīٍN}df5vb[4ۄZWڠ*!T4'`R-y6-EucX(r0hf <[_ wkktj.!&5wZ -jsk7I[xҔ{* f6.[Iu+\.q4^*_[+l |LfMudi ,cCps{`3Ә!a]^IpswdL_8, -ߺ?X@ и:p+dtG!„}oѤڀoO{3iǜ +L{n/ۡk-ǢBUq-I(Oa2γYB NTLSdE98dY n74@Eeݷx -TrT<& J=n)ٱ"lLPtI+)ds!1% (B~ -VK4Q1,aqT3Ӣ1_\ћ|GNڐwa#=ls^z4b@ꞙ8*|$ݸheIЃzd]W;5dY2ۃM?` 6Жڂ'yxtHH,U7gbLTpUMlj|l)چr]~*635E\z0W;U),jL:{ / -CTڻo.T)}ܚ[yG!Zo<U`END6[m,ANp -66z V --cйК[V])P/mMFj{i7 5H]6}:fHޯ0 -a%/%(_Qe#Icp -\oj$G 7G /rnI;֙$6&#S>dw|.s2y|3rGy+>^iM^m*&΅_*0ؿvG?u׺'%djuXq1h!?gWpS{\-ӊҊ2^fӟ٧b(T?TӮ$q8 Fg {18 3ޕڷØ8g%H+5y8p(QKzX'4G0#e[+AzGF?JB+l]"|"ѧo(3+n6Dfznh0> [r'% $8WKҬ'pQ+˔+nĤð~I(QMeae3(*#;Zn%|$<3ŠITfE_g\ J\2˯sZcaY yME!d'[4]w_<":Q[tWϤv&?)lkյMW~FJNᄞݔ$fly`s5>yל1\i+kғ@]LT䡽{^ RPJ϶ -|.Kby3M;N -n|Fzϲӄm%I:$!?s#JFR<~(` -$u%r6ȹl5^@ݮjt`P5*-ZPӂ -nNu&5_ 3sNFM٥vIzL؆&0)m6 n_5qqSiN7NP_u 3I4\J@PjTV@87/j\X0a,QAVb(L!90;f2C/&7>otM FbC*,|UO$f_=ȸd6S? ,B:HiwЬ8ba5yUpվ6p]1B%`wLk? ^S8܆Ksa$ºR̴Hazat"74ժv`a,5uCP|!m5%H6J|$|9\N"=X"%+D\,G UZk$x#@o^bY?/vo,ECQ -wp(ݬ"%ϋ7ʗ7( ;r +QTuq"Y7UZپf!fz[!Zt8&@jy(l8O?li?_ey!iGD4dS&$ŲN n~5cR{?fZ5m; MDŽ -D buL5GP}*EXo -B7Vx3BK%g#5Mq$ޅ=.sƬ̱N%mhL-W肺!ÓE+Fv;Ożi -Y>p@"UOoO?T0i Mt I|Sp4eSBu MEr9@Hd9!ܭFN} -Sn~ H=ྫ.nl}\ƚå'|\vW铆V2f -Sws2H]ꀒFγ~!XD&dtLtvdǤ\ -NV -oؖ -F+ - -u~2s3Us: -`(@iVU׎{ϲgHޤn6sMl|0EԕJ7k>I+[2 S+ǽ -iQh݅lFOl#㙇p1ͦb~P<秉b\qz]nLMSkRӾAm]sm؟]>~9ty.|Tɸ -K3VHD"͙}Dr ;eʨh 0>;ZT3~(.q#~ E@狛h7fhQ@#O0B~c0N)d 45XIͧ7ݘZc{CtGH Fy, en^rw! n"id#38kaƮO}N+2+ -EK<%a߇ZO@U׷ϑQIz||zZ( ~߭0\qr -E -!A)t|E>jAjD%0:5gV ̮`.}z9ٺ*dED3okEnOF#sw ڰtWv3LB@8`^a`PɂCj{Mhb[XX.Iol]dJOfj%u~gON+in4¿t2]ǢmTXgB-o68 - ȇl-atgSl *wannŋ6Pf4cU8k3 R -wJDL>Sʟ-KBH3LkJ(NBjyj$C? -zY1BV]r/* 2MPqAFVN5V5{R5^!AB2 iL=i{IFtW^h͏Y"2΅a, KfI(kp 3(Pja^xX466M{eֶ-p~l]c7ZHgXsK6J%Ho ^"8-Iā|WL -cIS-5w|ϴݚr~&tPkEfW> -*:"Yxm0[7Xdb -]N4-Y>W9CU%U4%¡xOs5TUe\hoI޻߱Ky5SV-4ΰn`!1X3kϼO.c~$`<ϋ8ώZPvU\ -esQJ>EUB.[XPn|/@ x,P!T#-ص2:ieN9"G.# --ju9Ǻf gwcL-LT|s VUGxXDK %;a0>:Sl6zLs6\k጑H^@jk ~;>$l}&e dM:&Hf%)dt.hS9iruybR6<0J*b@UEJn6u ОΣ M}bȧaz&׷ +IoXk{P50X d +tNr;Z% >; +Ů:<嗂o?dk-\'zmK3^ 55@N累QgO7$̦>B}ٖip +DXAQJA.>̓}q`KGHUj2${du}T2b@/8Ҝ*ŊmQ> Vb97g:e/~Ǭ@> .;)Y [9=bR#N%3l4n̦cxi&4ptE&qC@6VEX|ćj  36[[sq:|[93E~ +1nŷ(ml@Ճq{…N(?]m5n.ώ^u0cn$ +1ES6ty|[lӳ:p:Lkn-ĨsXY!p +V2< *¨ʿǶk@{/)Aka73Sr`1/RM'v+c cb>T^.5싻{HU u sRޕ4kwZ +'RJ[R z +7M_Kff χ +R:wH\Qra7J'N{A-J܎a-#O{㠶c#(QK`72j:w1E1%P21xv`q93A`'cLeaw@rLm \~}u +((^qԙ= tL&pHv$2RQ'K7GdyUcWLJ@L0};QX < }FonswӋƯA%YMh bɔTY04;+W!xҙc CGC,)3%0hgurrk\Ox0nSr4 3is* +2w/. +RuVk%yB% ݯ.𹎜}%T}1t6䆒e/0Y#S( ֤0(-5"jQ'a3/EQpc@fl] Dٵ]2 ` +ɟ$v=:Fab4R}JvPP|~>In]X(uDQ]ɬÖa$v ԗΟD,8 s|i4cXAD2չ1b /EaSfaLS4N _t1"X~]`C {x]?:,U +/W>d #6^rbрP4ظ_|dCxT~?B?-pL Ld^@Τ8Ze321M.e׉] +]Y\;3 +!|kzot[*?Cqr|BD~c˷O܂: w3brߓY7M:Ȯ~ȭ(aJ?.5l2>p+/+nϚPK.[iOF!rei]B +%QEp6R޳aBU6 +N&~N6U#~}۞]}`VY'v6LQs|I􀡤 -&7R^a)*>ܫOpDh79h>Nk0mےq]=AO&/ ya7r:er9ŏ5b`R sa>`Oazt +y@rLtPdQGKNOQ(:1L*r֎Qů, +Ԙq+0-y3sEI=fLk>'C,.7YI + )~+# 12 ŴB/vh`Ψf6IƉ T1[X)I8rN,AD"fbO"HO3_Ep܅{fqbBt5Uά3Z^5ͫ +\SDw-* HVLc-0g!5 V+`w@01ȈoϮ)*2>zKA!>%[K#P\|zG5<`,>GYtt?B(VGWGdGKJS3`/A[b/I abVNz@t96|c 柈 ;$*6R_=oΫǧ!`4n g΀yCM0"Z? +H*{faf o>%6OҢ|*B%: +Զ7\Y +ĤV@+|Uߖtg(I _̐;wk?+[Ka ~hcy᜕vi͢::6 6Dm\SEyL]8g{fNhmCk*H_ u݀ TJȨ_K̿wO}ָhmXP, /`LnYgVidn |hUd ;N;W 'rP8}QXgڮt&9 RfhbFx!R2TC &.(׺ZCf4-8ePn4Iގٓ_/;ad_r|`1ۥC ߽3aE޹ɊY3]`#LOI +4vpwZhm1Z;sHC^sf`4D~ӿj+yU,D8=AӶyCV .Y4 @cuxe1"Ɖ˟חNva_V@}d>ϨXu>FJPD]G +kSPzNyP 6FZvAq=E F}Y.i6mp]mP6j"iZ3c{o Ȧb #T5mp>(@Sc8Ȣʫ}/E +E8ZdUsqOaQ +9'z$<#1pGo~t]8nF%!ˈJ3Q'VpEZD>gX_JdA +lV۷tE^1k!7S|a{½\YuB$DUyWضlkDUs[?Wo0DFfG|C://8B_E&*{( A+@1F%it`5h H{˳ wi݄j_fr?ڛ0 + +#|`(Pm6͌_ً;1څWN>m]\='Yr9Ll@TkMDxr'QvN;;y5s^#d0z aC~:w6 +IJ ʩ8+/$f3" =76Ww yDmoSncFaMq1R#)a$E Gx7;,P 4aU*<-Ӏ +9QiY1 Fܖkw/Db}/MV ?Y[&뒗dzG9r4= +~A5֝]K[{Pvt}Xwl Z.78(vʞ2h +[RrqH,S2?*=NM2ڬtVu njZP*Nr7Kj]D'iS03c}E8P@]^ "x.[;u4 G4ށ!*0Xsֵwa7\u/0z +9,~?顿dac=F5ҵeՐsw5MM%( h.g/¤<9AI8 'T/r6=_XHOGBߢ]FZ5KR馜`3+q>q,~Op$  hq]C~+!|\G9r݃tpv2J![KD +\De + ^J}2* [OGc>J +볟 3`b'~Eo-rت waK($l?9fmrzxk%GZ;/ +5Qfe./|:6R '"`DƊ9@'7Hk!.pd=6IХ`RCƷF!x*nʫz⭞ !\1E:2%pN|l.~|| /O%8yJ +2s} k,L'v WBl=ֽ涕% m +)ZseC Sx~O i>imrYGnTfY `M޴.Bj]*?ͫPEn2>>5: SжVgY*5&zTIPI@.GaieMh,B=w#jCb[|@*d Ey,Ck}Ɯa@{~7!qqb%q|s3F<8ϸE||#:lԃ=C.b\ښ]uESne,ҁAþ/[dHϋDq㙂'R-p]݁˵Up27wBgJs߽I1諲'<&H_H%qlN_Y.o>8+`iWyIl3 j!0MŊ^~1Z:Fi/79\z'7-7\&& 1'cԭG >܃Q` }V +;}5YIvnZ{8w[>^h)M(75ȄsRx.rc\5I-喛KT%A+CI?*Qf7PAq´AJ7󄿽H{~ |b07ֳȩ}z^;`l^w˱­Q@ xfM mGkIYn +; ]DKڕ5gѦx'ac!ej-#S$j@8NT&'ohOPvd ?F/Mm(%B9C#Xnyg&+l$ <_ +~hra ~=ӝxA9Ed^8) +1mY>Zɿ% +l8ܜ}Jjt7^%#5 lX'*ͺqgfw#{mvB^bv읔WKt`!>c:%5"V+^omt5`@`vy׸r+YUa6CD7pCM + + e|=h + +r-)`iAb~n=.nMh>QBW1 +hgse(2񳝍 F\pHX_ +`>8̸2+NGu20(%ǤEG=|jRz\i\j J;6|Gjz#}k^W诺JtT)\;92Mm_/Wah׶<dY1}@Tͫ#]dgOA ܲJ0 +Hz}k@R oV5:x Ri_7nrQx*iKd7=xc2bKk 'B!>nۅk`Z4lquqb,tv Ewq8dubr".e1qQF ۖ\PL zL:I|*E>9M-+?'A& +\CuO2R,$^n;SֽksZESX)"]=xFl2>6 +̷D(S:[yw{oE;?lIKUY%C #UzIu!*nvڔNjѺ P\ho4+> +$4wa{%vU!OCqE RbZATCoFme]ttus\8- +Bj5  @.znks-+^v և{x&ش>6:`o6Hftw'W(ɸdG:QI +II˿Wo훮5}n{cϪŒ#<]jld +w#E{`WɂK3)d 2(6Mo8^K0,ʂ:AP*Vbo9Ԁ Hi~y}_JX|Rl,N)-.Ox`)K$upzx-r (xy'@-?կԀ mk驙I3`ĒL zZ~z6XxϞqͅHr%-3Zş ZE=!? +'Sm @)KTd$@[lF\B jOO֓nS}HF߾ +j' }L? .5dlQ@O,p7%> +ZyӜy,#䵽V!5{k}?+$5/^=td΅#:$sXjb1hwF)06\a}=n8a6Scd@A+hܛC݁m0 +^к2|y(H gS=A/01f*JK|OPPG#tkr"א +FOž ,} +&YZ:|} V}!]^_&U+L_Wx)'sƷ> +0mT*, 4Q]?J9~xaE#wfY +TeXu?v_s,,;CehHG̮O%KhZ: +o'- +H-nVKfc,K&i|\T@MUWJI7jHFy?TVH:beF6]|֚gёwtvl}xh X\? 7&f͗b(7' wM)z+.Hkڨk +vDQύ^=̖Y:o0&Dkxk*w i=N_ɱa%@M r,HwrKH")0 C*=Pv$ښR'vQbq~Iu,{3&|VC.->d gc>AcQ;ڶPjx^OCXP3٘?^ AƁ(C}}Nٮ0x5;F* +?MbdF(T\7XȏQqU{"24N3*Yg2d(N|Ăr*|@sf//5 $?7/)8k;᜙C[i' 7%OM8h yk"Q +;ŪIvcUscZ?T4 oIY\YHdH9g%;(PeLk|56.:#H SѠ(W%EL3KnTyۣ +L:PގcNK-{O25Uؚ)S%<"ZpM +6iK!3Wvy_lx9Ѱ'm^Q}Ha)XïQiY1o{_6^Ϭ яLC8#k +Hq) +l Db|sG(︀+MG(,NFwC! +C +]C $hC^ŽЗKmT_0"&vjba\jp:#%uDuuOÛAyT Ph7G +po3=|; u5`F(HXA +"0Z"Qhv_[S8MgKՒah FgjJP{QL7zv \ːH%7F +ِ>c3XSs㾔`9GœHeɑRn >c1kZ҈" y929SnP1daߪ>||B GS(gͻƣ&]5w95aOھ;LQ_2G]<X'-V`bnU[;I" +>P dx ,z[((GQi (k7̡s اJp[ MĄsC6GVVE*ą]; }M\Fw +8j, ,hH +Nh$&R%+R&RK1p(7mW?q{/ρuW1TX* O0.Ǵ +{>- b4/\ŵ/U:tq/"B"$f gZV\wk\s'Z8˵Dus>TUkZr8u v0ڹΰbZ aR)S~GHB.w RQrw[lM@0"1gd{\&@ }+(w!+=h@  g>ciU鍬0]SO ١Wu+:[ݣ*mi,VǴWCV2t&G9^$IK Zhp3NFf:t[*UOɇ0L}U@:kcV]F[Ϭ〤th*r_]GҮXiQf{-! fwʏt,:cvK]]~HG9t|f}F!ZC# +NUN aAs6DG}T zb{or9ɛv+<9{64lźSwn~ sAl7^NR=oԏt mKfJm81 [X,6{,jQ-ZJFZCX<6 As=KY[N:"#~gC̡.ܡ!{'tq +'Qjhj߿=*"7XƟ'Dqȉ^ѻq,9R"zGp΋[r@NÜtU -HPu0@~TlCTKj~} $Kt͏j$ep])ܻFWR;7i 4ՐT//Z +JBqtqI[0n褉R6H@)n:E a* +ݩ%8WܿhTAu|| .!=)#+MKwĊ4"W@N?˙K8v +tH0(X9@:S˫f:#ZK6#h{ÿsٕ[`hŇ"Ux5Ct~:' ,-qRs]` ӺFm9BQ-։n(2:xJW +gIbfrr狽tc%zBw>f6$0DiXc2ҳ"^\xV4ZD?x6@u5ev%<ިM:>;46叟UmeRfGN!ec惠8n [$8=;ʙt=)[LbKM,y<5ꟷr]q8>#גpj>q;Um&'>Z2Q4݀'F [#hYh擼`fB,ޗO(DzʃfIҩ?)؂6"52LM*x +%!@ ?<7o-d]#ƴy\۳[^!>QFX.ڸih0B%`/ +jȐqOX/@8@3B,NtJ:]!q3֤{2 Pg",c_CO&Ŭ)(L5eVBȱc2wM^+57Ա3>_&JۭWD~WͳbT^`59"$n.G#W`"K\ YrBĬkt5ĦNh 7xGϐ#G$ө[Db#>׎k?Y.%8mC~ln" n07/VjEN1Ub)V(VnEe^@]pg Lx,V\KtywqF tz<|ʻhh׵(JYqԤǩGNAp/-* $2}ٺY38%BrN uIݭF4_yS/ ꇙP=yO q'ʋb,n8^YD$@.x;euݝ,],Nch/~H{ɽXI +z9YgF¨Z$]tH hI'%{0Xp|2OKJbaoSAizP$ QFFa;t ⬬/ ZyG$ +K2ұrbpq + +ײB+;g"@# !.G2 Nt )gQn=~~V|@J`*-go j݉sLH軒 +_?̭hcAY-E$?{Y=S +TSR +O5E"VPS+έ$^lR1D=Z@o +I&:]G |^sf([xX`~ }S@xbZ<\kqzAI +RxƜ|]`9Nޏ + =~)D=3Pm!cL)]P7[|oX;eZ3uH]Wp~A[PU[K);#g`sPq0} vJ0<҈%ȡrײ7De2L<[2h IAjM%}URT/W8(БN]:C3duT>"WH_7p($%R t(`6^}O7ѵ{/v蛎f*E k4:n9RQD!<ٍ^pk%0N/;m R>f:!GZS0bGǫ*xbI/?w{żw_\Q |M*ɖ)4I!kx(gae-8fI9rD]ߔQO:落O}-'DVUpﺣF_pBkU7BYw__.2vE(kЯ +j,2ʄ>^WKC8[P'E”i{wfX{&#fF&X_T(٦4{mG;2p%dM7} +hnLVfC +*8{ubEAˇr]wN_C`wWrEI>?iWС)T"U@ RAƖF8m=(ԗ^:w;Vs-sQodr+KI{T0:I04ʼn^$s6'7%)ь5^gϘ# ^٩vq-H3b][·.2]C#pib^1<NZ}.fC×v@݇5)lMM!z oC;Eӑ[m2MDRW|qv©/;Oh: +ڻe"ӈ)a<9Ѓ&Fl3ӄ=7EyO# Evƫ[ cKxVqB>pahLX׬bs)Vwv<[7PC}*BX 9X icf۲l5Z0 t,X}5v[jG~'DQ}vuQ$p[Ѣ}J!Cv1L~4&<{:ͷi*6pX#>WWa)[ 9B~e +4] #]'e 2 v iEuvS cY6n\ Ž]\hL[rMYEpS9V Ϡ(H1t; x!+{E$!w5}yʶf +[m5n^ o_ՌϞ '*f`erUWUeIz&HM6#~*" ` +Q쑚6!eZ4;Jvrm9Xuьc v\,p.j ۦWeERibq 3{zY"팗7g]K;(kjp6ٛ&w .#u'DdP"BZ`,P;CLGI9~$[K%/HI\Ȟ΀ӡòd=%א5;O̿jpi6 +%K8^dam=&%ޔ`n"չIK;g#2)[ݟ'xs'713C0}i6p48@V ΰ"Eכ " bnnu}_Jl +}N\*{Au5&NN ;5θ峒/yҪ>~ڲ)޹_93K̉Rl657r +> ŀ8>"0xtw(B)GdޤS zMd9.%Mf էnjsQ0ԶFωjzT҄ 93|IִL(h^+{OmOae CYd4\6Wp`c Ԇr$;3/1)GU낖M"׍<'ogR # ͖H͚d @'Qy{U});g +JY`Mvm:\f=MDۓJb ~+͑adc*ELj{xemB_^h#e~sb-I$ZIH`T]0T!檯*%"DJ"*Oxђ:7k;gQ~tתZ9gR7 X0o9+Gc̒^qcK'6iG)ϴɽ5~4}B +>{ǟMh?/ ,GW8βhjE^O.C=[zA$g?{Ʃ|lUMVJP&G"SI)̊{0 cYGky>uF_{ +M,XLD||&J +% \(E#7vHB̞ =,ZH +x8f^݀pEjdթ4 @ 9+ŔYnlZCv"DXݬ,ЎHK\HbU#]ǯȝнI ey>RAM=@ Z1~,M-)y=wyT۠LSץƜTZ_3e;hq7)mzWh`!0cY&LcHl}Üiל7m|u|us6ޤWthLt}BH5j3OtR+VLNPr ,9A (_|i +>+XĹZ6>a/?sjHp0p%/(ۄޖ܄mAVȬ]\Ty'jbjFXEp0eD+WNg)v=t@T5fuzm)Ӿޔہ>e'(<ĸIb98wн'Dc<YӌAq؈H.dP3EWӊYM1H`b' +ґNk}57Ʊ3h£>$9ߍ|s2'0ݞH[QǪcR,[x>L +yE!&"W^R^'; 4[!DD!5d +;HWpt]n|[#~fD'3LI,UU/ N߅ny$l%-%ի NAs!Bޗp1 v9oD4~}PYV2/fT#/crw2#lFw?),ep/uP|rXkx_#*ܱb b(㋛`HPV )nf„YI2.սq +# ~A`lL|+T) G5 6Ga@ D ;x\XS="\oEoV & +&n-Fi?ORZ}iPAK|SX??AryN/I)jMjqlpA {i=8溳 FrhŃ@oFCEۭmf#2EDAF`_2^9 +ًؒг`R7j4j?r2.ћl၌Ḭ3Z70?*yv#juA\Fɂr_+ n%Jf`JgR퇰x9 [U/wnG)lzeV&:nt,s}^+H VuSl$V@#KgEτ>D\o1=wdm`Ƴx7٤aK*/,wb޲gF}ҡruhQDMc%5Dog~ O&ibOx&̡R:ߞ٘cK8@l*)8ڀ8_X&̹d菊IuMYNJhB + pOh X?"wqƀ2 n*naf`k@nLtSDfIuSU٩%Z[uY +Ѳ %WVc (5i/lB8;I16cM7}6Ug5Ed~)*ҫH +)e>]܋NHz*Mv@_y6<k{<mnFa +LPi|:ŒG5r4UqƂ+WIZ %EW`H +(ݰ~|0^D!Pg"역0c>SETD;kU4t(@7E/6](RWtx)*'^]W%hM;wO`_T,ȿ 9:CdJ>‰,YIP}e05"wXI܍xXslvƔ)U, +1~F>@W +3e:{BM!s(+:g7f)e ++濏vr +4ݠQ<'%&L<doyer@Bqc(FM+TғfZpf.>ƻfqM8.<ӫJ2\_@5@bpnɄB/zY_4ZDD!G5o%t⒴ Ls'n܋-o}/VLxuKF/F2(]:Iˀ.$ Ml}\R$rJrF5a(I293DKÆ29I8?=Ds<{\ʺx0+CKʇxi'8uY҇| \}|_5 Tg +gFώ>b؇82 -K!"j~<ʅ-XPV_J h@;g3iQ+^lD\2$t5$<չ1Qkh +BB4 ^EZ/ێsDHC k)/nԆ~OgyF_aEi>s3w~h#n[" 8!Y'C*h~8=Kϸriܻ +f`aF8ݼ͈7ŏC^F:֗af%acP@*BI ?]C, V6Qna L{et_|$EW{n`T#07> \s9bEB'gVW\ʀ&"zu{;*ZŗBΓ\k~]5}J6IJT'0Ylpq-x\$`+֎S_m-5x8UnAF D2Sdvw$gz&6BlI2 QXEz ͧ*\%(yQ"mǎ2xdLvyH'[Wv A/4 ?KUL QiкjNaqz˴ẻ 5Śb6P,!oy( +鶀lAcJUf;>= $ #k5m۽i90oVAdE +t>l +tJكڏCW?Q7/̟tT.{25o5 %*+[-M/ke &C7utuɯcB9M>m|EzX:vg‚ZE2@;+'$@ꋕCXm4&!kƞy_^{Dw𸮭WFҼyrBC eO*gh#+W@ۓEqޛ +DK{/xcIm43QWjny +0j24 zqzp+ 0 ?6 ftO:Br +s&0=8ƽkOS\s + +8>5skȆ? 4ZilgN `jI|~~BӌJz`GE׷ +܏ Szg% ʰDP+봎W{&C4@[`!ʖmW^"02RDy  FM)'ui[7Sým߫S46HZ҉cdW$Vq58ymFc} 6+KW'+Q ݝȅ;/~guni@v,]Ek(,EyϲCm"̾*Y+U +#Au]t@D |y +sJ j҅MG=;!]BԫES]^~OȺ*ù „'d=ZTwrO]x}D ##) K+ضf: {փC+)ߐqdq~ 9`INBVbzon +4B*o^! +R0Hem\Ȉm@}è$PT5(tɝCb5JDKIs +چYq=8 +_9ѴHq޵)p^ȴV)*49S?DQv[ +唇Ҿ2χȔʚ^[JӊqSS<` +ܻ*Y}VH~4'%k$Xx*XgW$8yYziww@o kjcÉ9]9fՉ^i,m0SCٯ 1\·]ʇfY0&F7_os)B>f̥Q蒡3~=(#YK^Ԃi0W*˭SGFSQp^P~]H:f+6b$Jҙ}%ދZ4:W$-§.0@)~^w.GBsl[׽Z}kwᜍЎm 9EǏjr,a֡x}+$#FՔ}Ul_ Z_;/pxRKJK^_KTMS^(,]{wVԈ7qV]&ؙ9:zɻL6@\lj'S3sA2?7%_/nG @#eDX5ӓtٗ/4ּ4 GZ}I8u7㆘C>{S +YYhMK$ ۼY!$ 6{mufuRB}ϤH/թ@v}F1L3\D>kxS_}<02YƊenl S BIuC+|I?؅&Kon)-e4 ;\yjp>tlnwٿDo+e՚{Q[ι(w)2sԌރoR( b1si + +`L!ĚAq#N조 U!$6aFد„xgA)_7{9'|[8-C9a[$lIlʣ~f5GdE0Fel!A<%qbYvMEad8DՀdtu/;4ۘpk/gJ:%Găԟ" D{x!qCNHLwWscd幦  +ZhnpOj52+3a +C`!Iy=t4 ymaK1KXV,qaʾ՚0#^REFe)ަm6ehW= +Z',;M0;}w1>|MڍQXk%T)BZ#h!kD5 +KvvMkgc8zSsz+ ^JT28d[acJ$jsmf@Z@k#^EWm`)5C¡z1) +V:Fꩂd:`g*M=]A_x@ 6Gx)0~c” ofC9NeL($M'0唪J] N-ׂ.Qp >ݢ + +pPtJQ[Hh򜳐P{_%>G(\99{FXóIڟ1Pf#HAOeyfJy3~\R<C<:G΄m~?LWVC +XW~rZ}׵`OLqYUa,XMW&2:+aiF Mx / IKlu Һ#̪dX +2nanq @)o0FwBK;p?yӷfv%W) ^3N"0D>,GI=!*?%?_.͚Gba$]RĎm$QmZC~(&_2KrHTZn@Bh-X7,>t4bv'D'>εj|z^eA"t!GI@SEegm"f|Xߨ85^!?19mRxȴN +0oiȘ4\>9tKfg{x=*o&;36y40l.dIÒ/8oJ][vOnF%6o;j:M62d[UdJQbdeVQyM;>bVN9:ahzH;Up 5*xVyP ,zEt^VrKm9@ ߜy'/#D {hP.Q! -IR &uyty3;CA^De;|o[e0gP!یI +KL1QZdsb`G=K`ajTl^3-?lg5~Pb SƄiiWg`U F&NDfw&kҬZTwbg_6⮲Y5ta{Al#\k?%Do"M$DIHn ^AΝ4ZYTSBVr b.I1B "S!:cC :V Z]F7wݩ˖jbYީbFױJKd<R S_m/iIIyW1ù9M)J 9^N{ҁt"^SN4^/fI4WgߨJ[G^wavI KەG6GUnx*+,EpUf9`%ޘ"gWX!bAݟL<~]z殝q>mX` 7ֆs5*7[6!AgCfe̙b'i̴Q67 +u3OR0|!{ZRp($tPQӪ[I'WZ 5FAlkE3UA5(3V(2t\;YRCȏ=jsn +4sF,;&/!y̫9,rr;o#֡S{~s8c ۗM׳Ís`< n+үK; vZ jl/V{+exQgG,%o *g"S ~S +hK!U7k̔>W.c_r!}$KpR\gy$Xͦ=}n)O:yBy8%:n=5-~ecCglW|YS Jر9ֵ)@wUI4X UǪj$JKMiA܅"$1л.-p,ZE=WX.Y1i}4Q,D/mOxgCLZ՟ʭPٺ+i3,mN3!)jǾc۠( Қ ׌AB< +H%¶;ŽA+wĻP;mtru3u0P=s_Ij>Š X\[IqBH)vX\l+QDR3'tsI.r'B{[DZ?Z g$G皙 }//f&!Q1WS'dH[yЦD˳7ti r,"h80o'G_5ggJ~ p=ueUku}r%hkڨ&0; +2IM`;L?Wx +Hv(wApع`&+^3 V͈ RR8YuZp@Fkds|s]u&a]t +~!L _1^զV ++s M g}jf6ɭ?>h&8;&ަmHOI ,e٠$g׼k>1 rf[:͹KMd4 +aB'C01DNEabDPb.:}J .=c0^E#%Ha8{t6R@#*F; +vR r+z7p>?԰ĆNIAO +ڰą`RO/*|8*EĨM2x^hUcd9'o7qf36~q&˯b;9ZB@""փ@ 72L @95g(2qT*Q/Ya:&BJae yun(@ٹ +_ YIc!W#.C'F7jΤ֍¸s,\v,Ƥ1Kg^+SRdqOs^qᄗ:A{H6{^K4vZ+rσyTEɏO_[aIJ]Y]LJ>пgDW0\FΩz+,US L Kj7$r`P[9ItU:r ̬ԴG}.%@sl .S|\%Jtܝ5>L܏ʖ01:$nW]/9"KzɷaCXVQ$$$4gNb6AIW]+hIcqbĠ66~ 蓯)qn_ <]KpO +0{= bqT;}"TO4Gy-\r hr uh*J*\ 6є[㍃qԆvnH rcLg\O^dq)vk/[ZTz1"-n+ęeK3SM'6~=QdlE> T~5x/s[+5wH=@QG=GA|PW !AOwiraN̽{6e&G*c?4]B 6aG9K)ف}^OzZ0PwlR5=} + Ga-HXV Za`6\hik>"+FM,1/" ]u6qNDxPȲF#1C4(=z>uG$;'I\Qa2çѐ#oh>NGmvĦ3۔^,UmW d6E7'}}3#5)((WLƟcnEl-תOS@`hFbծZdPPc4NJzFivlub*i{חաjKm+DAYl{4y?HN@?y9PdvyW[Ӈ=bh?LpKgNKqS]d'R&K`5L<DAb͚x`(0Bے>Aƹ2Qo@Bmr&lg u $gGh1^0yj4>)_Me^Dueaeoaҝ36|9V %|'qHwJLr += +|XzKw@pgD/ J;@ԙkbSzyħ#4 +;δ?I +2ax=Q$)nIi=(2KE'nE/m"zjBx=0VbNo},hcR)DҖ|bޅɛ^d:an@9ZT s70`M3z;#w:~g ꩛pz1+ܳ,=:0/ +/x=vqx0JAI~ +{mKCrKKlq$,N] 5cWBs舞/erͳ`I0 MɈ;ARܪ'[C9rџ|?,r9Fb#ج}s.P&@pcL M5*Ϸ\J%Qz+t/E'#؜~iHi΄ +!a>%%%BNc l|ֻGѶ=Y@΀+c;' ۼk +AT-BYt%UX1O;O1 E/ [tpLc}HŮt[SD)fX>427(jݿ{%Um̳0U¶"uyufɣ43 ̩<h' }P4INog{.z5ie䘷m,0a;I|ȗL!N0 -n3HP\W4Q_ʃ~ ڠQCfS3. +ݴDh?: ,s <)O#k搤^XgDY:)0ÛIIBh Ȍqtuv ^bf4=GkYr +| |$K'[^` }7tXFYms +k *E/^KbsYg@1 agfo^Uؗ +y'V(MJn MjSjyB?VtJuLqaC,VT%Ļ0,І3}/5ۤAe<6v|ɧDbgf'G8i?ls +*#gc7eW5\b~e<(Bl/#td8l5V*tHRUZhzAafNJlw,n0*C{b}<$z, C>RBô#Bq`_|PQJuKVJr9tڹ@oX'skdZEn\e"$ZQ.8ΛQ˔`ˏ1g\Y93A|{# %8VgqO @}o9b5 +LDYqу?BC]s N㼑/ 9 i-u#NQ? # }hcpڳM3z>2X NDX^R&%g r}掎7 Ky桵$0B{QGsyQ, +g!omzY1RwfTg}NqßzIVD25W/oC1cӿ0֍f0dmɇ, pi{-/vO7p7֫Pgꡠg Rn/ИOS%3|:%޹7tt%k> +-yW3W21~!RO¸* +|zXyR3:ڗ?7|Y~35($9*=f%Z$_Ōg X%)^(p蛯Qʾ>vm++F.}cFL!.&[ J{u.:=Rb|jwAٙ w}[[겡Ӟ x z>m 9#/ +Qڐ?f#sW]z{!b*d|QU1.ąɸ"uKn. O1s 9yяKp)\1WT"y-LMf 󹩒[]ƨ׀7}?1 +ңdDZNC$3Ab1;`lZk]k`n qmW<'%ɝ +x,]#[ڹ4P .Tx]J.[R /fn[p+~:j)i\y.>qS횋Nh̹IͿިͯ`+'g0"+x!~Ə|$8jJ^x QU]NSE6Yv0CL-聴=1Em|?%$+~ 9pulne +|6?N,w&f`S2EhPI@'SqE:M!rc";{ +Z%I 6.c+mB lmW)`Ҭv ӎ9эsPJY9y]ch3x9o.:XY؈E`"-'(U.J">s XʥyЧ!Sٿ*!4^i >"TAXPjG_w%m2b3D4e[PIڋ.1ЯPj}5 +(p~Qa4Lqж}ŭ@8,69!PN'@SQMfx߈ +qbԱ&o߻3X`9 QE;=_BV+K#3!l=8|q"PYF#ӻ~bԽEeN3%'Li(N!H2+Dqq[!Ɛ5MEQB,փuE|~1c| 4(u&ZǮ#9О3dgM|}e1ݙBr0*4ljnDjZM`7um|ͧcD0|T"Ӟ:'<*SFY%S&dCV5뢇 +< ;MH+(FF6(0Ϯ'ֶH z78 ) +i2oq7t=g7?3:EkdFi(| +G7K5RPMCi@0]=3apY>a ݰx;X{yxIsx + 02{ҍI]ĔX0z +Փqo +VxQT\+l܊ +G(Z֒ hVrʈ rJ_6a5JVAVj9̞$Nŀ@ix.y5SFt{l1sQo?0 hY4 CU$ߍ4΂M«>mYjwE Lkv7^Ռ"h +yjyDja`hZ(7bK +ʙVZzm3uf /6HqT22[ȥMj",*]vK3j F3 U<[yR^ Ӕe ż8OSZ4062PWS h pmx-)wO7")L@2 Y+3{jnRp=6OK@_䌥%@ +RdnC\sC2ϰA^Փ?6- Mt1L*,(ip^!`o?Z*qQ; p +\b c۴\ŭ LBIT/"MK-޷*彭p̏Dh9rB ݶVjFɴP$@M`+a +{!pk!zQby#\4[V _Numt2tp p=70b7+}<ѨLs2WιH#9|sYFdkYu5lH(uU\y fp*' +ѧP;:i<=Slg+(H<-OQ8޶'J=f14u:15J:=\F@4kLsV[.(| &V*&~n"*xY]3 t⊤.wl\xo}#]'ۏj rl"duΖ&`{yaPb>X5: ZJ*J,8V[ +FFc|7V|}q2`h<([4݀,)ΨOm!7 a1Sʙ]cMa +[-Zފ9S&7:CҸE] ԠQt!zYK~v V=|RsMɿm#MpBe׺Scg7}! +RѦ_/:ȉax\Ć* +!?Hf6¡<gKBOq6 +`t`P!5q]_:ӴQK)aKXS'Qnv懺SraL&dYފgWRB…;Id)L3%L0cMK{4#> +VOc$JhBCO=+9+ 66*/lJ<Q$@,^'gqW>!(ˏ_PJXSweN z f4?LH}{!b E̍ &^fFʶOpېw uȻ $>7UV3ʗ2v.00w\A"Pb/'\󾇂qb o5j~1u%(\.A+X{Y>ҭ.8.w2h)l%3{E[lpaǥ[+Mık8ښ'hP~Αtd^ql*|<"tqEN )5yTIxv^s6S/8'BqkA|x!+8 +vd$_<׫21;ɻJ=9X`cr߭1[7A RzSϋl)a13FqE* ȟ6b~8@] +3%sA^f4UaU"ʞ iPfgVYX|=VK{BKȜ{<=!/~/Dw1GpU"̎vׂG(S=jyTLׂٷױ";n]XkS@ŁE?u^Ub ehmyb8DXS536Pi[%٦&EITeG4RF,BNg{E+$|ꃖm+q_]d +X$؏AW9~a$!aߎ )/0|>eA9$.tH7F͙p +bj{y qTΧ L#OR +Գ8]8wDůJϨ_ۄn%kÎDpy3cV7/P9э!)LZTXzޜ$J5Xl WN"N /6D'=0?D>'܉r8cm+4ϝ +-CqF|gfH +qQ0Nb93hKm%dL2âd/RQ>L&5}&lF'y$#`Nܰ`|#o +'3 e v݃F@گ]9V:U +]ԭӁ@H/-Zn(-HbIד}i?wNUjD!-Z>Z"CSYMri4sVhP:qgl͒+\Ńsh 0gA2GL;2h1SlS\24a$Tbiu%,r{}P}7Lr'T;hQ'ݽ[:y 3U2|q؃ cOP^L (>x*b)GVz0-N ~TE `QؕD k +#LL+aі>șTCX-(&Zy0z|hZn\+QgʽTF]LD ۻo#磤J["E :K8~ym͙뢲Bɧl}~G"HUߊk Qd^Fot}ꤥ(K*H` +'~D^LLœzK~\7p4# _yNISQ +l ^VlNf,2ԨsnGґqm'U--Ѱ{w7@ +CzdзVu<8PPGx&2^zQsc#Ut9bnU/- c,LkoZ!h3b9k_:B3n}w ¤egkNy1^svIkasj0 ?In]c돭wh9Iw=b"t`?/N?hHmH=+,mSA +fT?5 H"EXʒU ѣK +Sl E:ldn4 ,ˮ;ܬaTfJUm +|)iGhjM:ֿRؚsF"YOU#g%ib>h,)YŞ7N<[so+[No܍Nl9pHJ6ET.&Q30G@ kx4<I5*פؠ4}9"|5Id@X6{ R8e?K`2$Oap&݇oZZEcBܼf; x +|]`7Rf,(wK9G|]8ې(E\xPGZbD oKDRKVoE&J&6H*-:+n/!k`Ëj@aNxoVҲEs82<GHT}'l%H!l @wbe3]RD9 +LYuHsմp%䷐1RbE|@Q$V$o>EhwG}k3 zxy!@$:WT`2Kרs +18xQAݰ4T}#6LJ<.Y#v=-A7I FW]>gk{@,3NT 9b `Ǔ,oDLo%0|B;XNU98ٯҟ$=:*չ7gٕGM)bv>{EØ"#_nc?JjAB!\w`^pcŭ aL"95kIrДsgwiJ5~6"y;<|A\ds%M)68Q|iI.@g@ҁ&v%QP􀌆k\&&%,qGr$MA>8m(?A@V2s9?5Iե(=cd%koLR<tТeKQO*"N9yNfr}k"Tä2s|77`q?;Tw܇o74?>A>T}`QH΅qԥA#MBW/AI3,Ar!DŽTۃk<Ǔ1.@W+%u7F#EivRg0 +ރiY|Qp֘ygӓ4`mlՄ31BtT:ĥE4!6NbnXkL!!A)raf9ws#{hW՞Es +HkTb,o}:6 iaƞKrz.A'{s|*+_/!߼HR/vT'%jK8rvTֺ)N;9E(6q~iN}`(J߅ *<9#udZm<75z%LSC~ES1܏jCtm{gq$.%e@ق?<47zz`z\#ׇb1ēKv "{mL8>\N +qB*εO +n.\ Ӣŏ➍DCD= s%qt}lm@ .'{2?7,ďҊ{OeNWݩZO85唾L:YpD" mK_e'$5IzxgTp!ߣ^iK|(-|EgA}EIW^Z#mZ8 +)4<3: TVku$i0Qٶ{|0H¨0hX2 ]QQEŢDK DЖ@|<3ΠB(`I+ۆ+TdO·T-6m[R_H +v\0 .HԈd1^$T:_8i5nN)U +Է&&6,veǼ֕;.L>!0+􍈈I( 4hZ Ѽ*,iNgO6(PߝP.g$piS/Bw@Ϩ94fOoyD4JBd6q!D:>vme`Pi/ U7>9} 0?YPMȨ +k2Qx ozwj"k{J+LF0M|I^2簶ZHw2'a`VFչ2Gٚ2xz7-,TK►_% E/]::]BTQRx*J%W5q}B9ߩlOfۥ'c)AZ3lc9U҂PA)y +h Z*nuYk3M&_y(*O݆T3Z +sxFǟ/;dX&V)QY%uf`7OYQ;M=x,zh.% nTzGGeǝO*/m1Ev$-  ;+;UŮyv:Ϊf;3yW +g[>ʼ˼|y: +!JDb}CC+g@ /`Ty%=iAl9. +ql]茤 7`*׆IxCD%coi]m3rurBT@}43-&̻A:&Xw9mRGPeOA!ԓW&#gjςxɻs~{ַ0o$ ,$av]0Zd1 +pt +,\ƥ\|zJv N5l$4̮7y_-7ȰӱIp\} _1&Sq*lt}>Q6S?o jajDZoY-gv,km.rt^i]3!0Z[/n 5 Og>Q&XG%k441+ +hfid +STT\g/x Tai+l#e[3X:&YӺ7GL2"_m +_azˠɚս+AJØ+L\:&S~r3JS_4_aR>;,mX{ +m +8]I}'LL0E{aW\{uAi"RdIۙzEլ*0TW5>rad?8!;_Hf :^Zs V[d +l|'.v0_²3L2ļ ݦK VquSA6J7&^XKLJkM2 I`W6x<ҋ)zfVh%=ɍޥ/ +3nĈFRPzohkO(Gڼ^jH#i&WmLӦpҔ`n,"ۀ& 7,e3% u]={)ur/ۯ@&iDT{QyN`0ݤmv@clϮ`qju}=_;3 ߅CAѭt\DY5!h.߹hOݎN-iqg*`qH/ƪ3yBP&]@m 1LwIhIs!!\`R r#צ1C)%pڽ Lْˊ-[+ +ex,(re mqɱ;MBB?ha> \fĦJ9.9,osZ4WaY +ꡎ|gHωa/31-#qʱhbODRSm8TU (!VmSH9=GtFצ:J2Ў*0IҡZQ'%|пaC+/·np bnXyLA9 EX5T`~Q Y ^mYM'qe^[!]#U]}W:p쫹=ux +m߀:s[T*Y쇿|6VZ2JڈF+naj-I3$8Y])5aʤBv^u%dZ>cJ滰;G*xyRսЏS0Kˡub'Шj2)Eؕ ϵ%&G)AqjfddI?&U7Yј~Іڪ,/!{ӳ^t<'sZ]}Eߓzm]Q)h}J=,QIC ׌2V(pRlI^-o?{g"2Z4MH^o7B0{$#]>p@ +sn|TY=hǏ"YN ۑx0eV.\";$WD㧥:Fb8SikJ vhNh "hc6:jOW'0Ni@↟miNG@5vȋLJK(Evwmܨ\,s\?\G +i΂:#<YnqhįLPT>9ߴf eeLTYN/ܙτY$)n`Ji_]D*fyXn7Zm?MΕ&T\P@[Pksm<}ufQȫ`8jy:0^v0@LL  +dGE:ɦߡAϿq~ʀt9ظL .F@ +0aUR'ŁA7IP+@ +^ړ;ftlG vejHJ'˷A#Pb|xe.qH +%ۅ!s3"y.fuHu, +s4U1IJ\Bs +VHN!1UC!eZa%JТ9xi&&NI4el p3z'y=j m5C%}~Q>3:jn6c5E՜t`1aVv3Fv^$u&9{VHV +F38✟B3N1It6Y͎Ʉ} +Np# $</TO@W8pTk|U,8HXg=q4]w="Q`蛈u;t +ۋؓ+a S},FJ'}8֊ūH\Uiq Χj\PVal,A:zj[:)"E1~X#1ʴ +\um4F| Q0/H x6L#ɟ">,(3n +^I*FB%}Usz ezp`x&&/ +nԜVFW姨.V):{ 5!>7%Ix , +I/k-6NX}1iWnC?i>b*^UN:Q\JZr=(䈜8OVl/ /bKiYdab v$T{ +jiZXQ a~]ILM~Y_/(^PAWT~h|h~aٲV-aLGa240, +:cv +=#6郷t&rVf|ED<#\0?؆#E]iDpz>+UD{SІ;;oo1==Z.N)I ΟzNzw7}_4XϝY޽_R&Ndᴢ)1IFOD& ;1i uF]"Mtle唯QWh':.dHBe;8V'rOhj 11@–sY1ƙm!R6_yHge +0ۆihJZaEC#H9g:Y#}Da^I{wgH,"T_# F%Iyi@!Tv֪P0uù.۴scu +39rׯTq,+ ْz0+n9]^sS%l9_{c}"2"0)NPI7lR+(8;?-{:)T~Gf`F0<#Ǿ/ +7.e>GluE"wlZ@1^'pRaH>4ddi'$Y-nɖٕLYE/L3H9k{v98}C2s ZY[3 BV#\hMtC=ˇ1]3}EX& >lÑFٳ#,z u̲ssjև 8d(CgC+xC)DM5P;@-) *Y569ŇuHM>6y/roHNaQ%`kOL'ۆhg-xxPGa)c%]/<"+oqzz\,>+Ak ${_{.g ) 6^\ٖ KP䳲wR3 L )]`rmkF~%rKIFan7~Q]mm}zauLq,僲gx70DÆB$ +gEf : *P#|F{V +PdL_2t}Oɨ]SB UǠ`󑋴 t_z 3r:vy>^_p?vߥ!E!Y5G^mL+xpZC+@c03Ϩ hF#Kv.3UV"h"8VftҀ?w]ҥ9lV Y~PNM%|.meo7_T:|FCaYGIkpѪԈ% .l5h0X+)a;c/U* W~b*4#Tw7"y?ZoAw A͙|mTD(=o2ORWe[yndefl'\: 69[eXq^"<'[/.8] )ul_u-%Ͽ4sQEh@KS QЖѱo05AHŲ|CmC:EڤY|i"F![ _^Q%4q۰Pv_r,xW YILi oO濍dÒPLH؋&C]l*oO΋@:)Q + W][e;YMW>$ +ךX0u&*yǢYq^m"Ƶ,fQL,C+)tJ;Ү,<{.x٥=1IS:A]j 2 P!~6s>WYt9lb8uak ᡡLDUqB]mM-zW+y*xa?P>pn GFmջJ дwoɜ2ҨVBxrpRҵ(f-1?#/|pv[jvK!qd{S!?IjlLQeiz@>yrkA:]|92LštSF?ypOg$AWxľwzE_;S[BhۚH,d 4c]ئ? ^ u%H-oRr$Dsh8oآ OYR'pƺl]V]V(A#c!L82x$pU#|%T}>"!C=Nnv Tq~ +~iSdO  _wb`M=t9b)68ҕ=ر(Ѡ#F~KnJ?VQ_Z6+^#c1K%J?4E?3I?f #~Co uj\  g((㨘 +ud$en7 +A) +F'6z*/qɯ- (nY"w-^v _iyJY]V}m * IڣJ }k' lvI0'̓ H_⹁WxoW7G/)_sb"2Xť~ӽ!Y\a]~9AWbwzlkFd{PЄ7\C,#5U{uΞ c)h&VJ$ zYzZ3#uGo6I=zO6BefOOcl{dDz1  7u3G8Prpjմڮp8TέSAw&+7o5_ diff --git a/hdcp_rx22/hdcp_rx22 b/hdcp_rx22/hdcp_rx22 index 5f29150..430c07f 100644 --- a/hdcp_rx22/hdcp_rx22 +++ b/hdcp_rx22/hdcp_rx22 @@ -1,78 +1,123 @@ -ELF - - -K \ -}DJO -FHrIU0yD -\*I yD} -03/K -!C-*FO6" - -KJ {D -8F -FQF2F 8F -0 F -JFGHFu78F1F2F -MBbhDh+FJFG - -) -,@ - -!! 7   -DO0 - -SDQFC`"F 0 -!hf B -i9DhjF$#G - -% {bh$!Wih2FGh"O#"JD -OsRFi -F!XW#'}D -! -IhRk OBD9((I J - 9FZC - - -3HV`xD8R" -bFK]{D T - 3YTHFD -F  -FxD F8@ -F#FxDz I yDz F8@ -F#FxDH I yDH F8@ -Fh -F  -F  -F  -FxDr F8@ -F  -FxD F8@ -F  -F  -FxDh F8@ -OpOpOpOp -!`t!t -l h|p - +ELF + +03/K +i +FOy +4 +JC +O0 +O0e +O0 +(B7'{D!h + f + c + L +@W eT +T +iGahhhi@!G8B вJK!hzD{D +I +" +!" +K +VE + + + +8 +bFN + +FE +)BxxxC"`@ F +& +O1 F1FF  +i + + +O  0 O  +Z +6]DfE +ahhKiX!GOqB'J'K!hzD{D + +?I ?JyDzDbH !@q` +.HxD +I JyD + +IF +J + F@PF? +IF +J + +IF +J +Fd +IF +J +DO + +j F F +H +xD +O +P + + (H + IF0FDD H! +HxD HxD + +p!! + )$܀)6А)OР)@ +"1O@ + +6 +A + + + + +xD +!F +(FoBF +HxD + GpGF + h)F2Fi FG? +Nreu h +- - е?D + +pJ +OT + FoG  +p + bh^h +B& +xD + dxDpGp($ +HxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpG}HxDpG{HxDpGxHxDpGvHxDpGsHxDpGqHxDpGnHxDpGlHxDpGiHxDpGgHxDpGdHxDpGbHxDpG_HxDpG]HxDpGZHxDpGXHxDpGUHxDpGSHxDpGPHxDpGMHxDpGJHxDpGHHxDpGEHxDpGCHxDpG@HxDpG>HxDpG;HxDpG9HxDpG6HxDpG4HxDpG1HxDpG/HxDpG,HxDpG*HxDpG'HxDpG%HxDpG"HxDpG HxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpG HxDpG HxDpGHxDpGHxDpGHxDpG% +?o/o C02 +@-@ +$hXX   &(  +D + + + - - + + + + + + - - - - - - - - - + + + + + + - - - @@ -80,15 +125,20 @@ FxDh F8@ + + + + + + - - - + + @@ -96,9 +146,15 @@ FxDh F8@ - - - + + + + + + + + + A  - "Dhdcp_rx22 + "&Dhdcp_rx22 diff --git a/hdcp_tx22/hdcp_tx22.contenttype1 b/hdcp_tx22/hdcp_tx22.contenttype1 deleted file mode 100644 index 72b964f..0000000 --- a/hdcp_tx22/hdcp_tx22.contenttype1 +++ b/dev/null @@ -1,165 +0,0 @@ -ELF - -03/K -i -bhhiGOqB@ -O{@nBٴ"R 5C/ɲf Fah$#"nhiRFG  $>$Ѹ -yD h h -O0 -J K!hzD{D -O0 - f - c - L -@[ eT -Q -iGahhhi@!G8B вKJ{D!h -J K!hzD{D -" -!" -K -VE - - - -8 -bFN - -FE -)BxxxC"`@ F -& -O1 F1FF  -i - - -O  0 O  -Z -6]DfE -B  -ahhKiX!GOqB%J%K!hzD{D -J -K!hzD{D -.HxD -I JyD - - -8h -GYIFYJ yDzDb -!FzDEJ !FzD2 -7 - -c -/йJzD'vhI(FyDF - - - -(EAF=JChzD <AF1JhzD xO - QFP8F LD I JyDzD4 -HxD -I -JyDzD - - )$܀)6А)OР)@ -"1O@ - -6 -A - - -W - - -xD -!F -(FoBF -HxD -- - GpGF - h)F2Fi FG? -Nreu h -- - е?D - -pJ -OT - FoG  -p - bh^h -B& -xD - dxDpGp($ -HxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpG}HxDpG{HxDpGxHxDpGvHxDpGsHxDpGqHxDpGnHxDpGlHxDpGiHxDpGgHxDpGdHxDpGbHxDpG_HxDpG]HxDpGZHxDpGXHxDpGUHxDpGSHxDpGPHxDpGMHxDpGJHxDpGHHxDpGEHxDpGCHxDpG@HxDpG>HxDpG;HxDpG9HxDpG6HxDpG4HxDpG1HxDpG/HxDpG,HxDpG*HxDpG'HxDpG%HxDpG"HxDpG HxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpGHxDpG HxDpG HxDpGHxDpGHxDpGHxDpG& -% -?o/o C02 -@-@ -бԱ ܲT  -| @DL8N\vx HT - \ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -A  - "&Dhdcp_tx2201 diff --git a/patch/frameworks#base#0001.patch b/patch/frameworks#base#0001.patch deleted file mode 100644 index 5df96a5..0000000 --- a/patch/frameworks#base#0001.patch +++ b/dev/null @@ -1,41 +0,0 @@ -From 787a233d2b30b7aecc795d7a46d20b649cdbd033 Mon Sep 17 00:00:00 2001 -From: Chaomin Zheng -Date: Wed, 5 Jul 2017 18:59:38 +0800 -Subject: [PATCH] PD #146924:remove HDMI/SPDIF device from fixed volume - devices - -Change-Id: Ib61a667204ebde2f4daa7f2043ebd6eecd18783c ---- - .../com/android/server/audio/AudioService.java | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java -index e5c3106..f1c9255 100644 ---- a/services/core/java/com/android/server/audio/AudioService.java -+++ b/services/core/java/com/android/server/audio/AudioService.java -@@ -546,11 +546,11 @@ public class AudioService extends IAudioService.Stub - = new RemoteCallbackList(); - - // Devices for which the volume is fixed and VolumePanel slider should be disabled -- int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI | -+ int mFixedVolumeDevices = //AudioSystem.DEVICE_OUT_HDMI | - AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | - AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | - AudioSystem.DEVICE_OUT_HDMI_ARC | -- AudioSystem.DEVICE_OUT_SPDIF | -+ //AudioSystem.DEVICE_OUT_SPDIF | - AudioSystem.DEVICE_OUT_AUX_LINE; - int mFullVolumeDevices = 0; - -@@ -5402,7 +5402,7 @@ public class AudioService extends IAudioService.Stub - } - // Television devices without CEC service apply software volume on HDMI output - if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) { -- mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI; -+ //mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI; - checkAllFixedVolumeDevices(); - if (mHdmiManager != null) { - synchronized (mHdmiManager) { --- -1.7.9.5 - diff --git a/products/tv/init.amlogic.rc b/products/tv/init.amlogic.rc index ad50075..914b594 100644 --- a/products/tv/init.amlogic.rc +++ b/products/tv/init.amlogic.rc @@ -428,6 +428,13 @@ service hdcp_tx22 /vendor/bin/hdcp_tx22 \ disabled oneshot +service hdcp_rx22 /vendor/bin/hdcp_rx22 \ + -f /vendor/etc/firmware/firmware.le + class main + disabled + oneshot + seclabel u:r:hdcp_rx22:s0 + service ddrtest /vendor/bin/ddrtest.sh class main user root diff --git a/products/tv/product_tv.mk b/products/tv/product_tv.mk index 3b499d1..4174f12 100644 --- a/products/tv/product_tv.mk +++ b/products/tv/product_tv.mk @@ -2,44 +2,47 @@ $(call inherit-product, device/amlogic/common/core_amlogic.mk) #TV input HAL -#PRODUCT_PACKAGES += \ -# android.hardware.tv.input@1.0-impl \ -# android.hardware.tv.input@1.0-service \ -# tv_input.amlogic +PRODUCT_PACKAGES += \ + android.hardware.tv.input@1.0-impl \ + android.hardware.tv.input@1.0-service \ + tv_input.amlogic # TV -#PRODUCT_PACKAGES += \ -# libtv \ -# libtv_linker \ -# libtvbinder \ -# libtv_jni \ -# tvserver \ -# libtvplay \ -# libTVaudio \ -# libntsc_decode \ -# libtinyxml \ -# libzvbi \ -# tv_input.amlogic \ -# droidlogic-tv \ -# TvProvider \ -# DroidLogicTvInput \ -# DroidLogicTvSource \ -# libhpeq.so \ -# libjnidtvsubtitle \ -# libjnidtvepgscanner -# -## DTV -#PRODUCT_PACKAGES += \ -# libam_adp \ -# libam_mw \ -# libam_ver \ -# libam_sysfs +PRODUCT_PACKAGES += \ + libtv \ + libtv_linker \ + libtvbinder \ + libtv_jni \ + tvserver \ + libtvplay \ + libTVaudio \ + libntsc_decode \ + libtinyxml \ + libzvbi \ + droidlogic-tv \ + TvProvider \ + DroidLogicTvInput \ + DroidLogicTvSource \ + DroidLogicFactoryMenu \ + libjnidtvsubtitle \ + libjnidtvepgscanner + +# DTV +PRODUCT_PACKAGES += \ + libam_adp \ + libam_mw \ + libam_ver \ + libam_sysfs PRODUCT_PACKAGES += \ imageserver \ busybox \ utility_busybox +# LiveTv +PRODUCT_PACKAGES += \ + DroidLiveTv + # DLNA ifneq ($(TARGET_BUILD_GOOGLE_ATV), true) PRODUCT_PACKAGES += \ @@ -75,12 +78,6 @@ PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=0 PRODUCT_PACKAGES += \ TvSettings - -#USB PM -PRODUCT_PACKAGES += \ - usbtestpm \ - usbpower - PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.software.live_tv.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.live_tv.xml \ frameworks/native/data/etc/android.software.app_widgets.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.app_widgets.xml \ @@ -89,6 +86,7 @@ PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.location.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.location.xml \ device/amlogic/common/android.software.leanback.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.leanback.xml \ frameworks/native/data/etc/android.hardware.hdmi.cec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.hdmi.cec.xml + #copy lowmemorykiller.txt ifeq ($(BUILD_WITH_LOWMEM_COMMON_CONFIG),true) PRODUCT_COPY_FILES += \ @@ -97,10 +95,6 @@ PRODUCT_COPY_FILES += \ device/amlogic/common/config/lowmemorykiller_512M.txt:$(TARGET_COPY_OUT_VENDOR)/etc/lowmemorykiller_512M.txt endif -#DDR LOG -PRODUCT_COPY_FILES += \ - device/amlogic/common/ddrtest.sh:$(TARGET_COPY_OUT_VENDOR)/bin/ddrtest.sh - # USB PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml \ @@ -110,9 +104,16 @@ custom_keylayouts := $(wildcard device/amlogic/common/keyboards/*.kl) PRODUCT_COPY_FILES += $(foreach file,$(custom_keylayouts),\ $(file):$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/$(notdir $(file))) -# hdcp_tx22 +# hdcp_rx key tools and firmware PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/../../hdcp_tx22/hdcp_tx22:$(TARGET_COPY_OUT_VENDOR)/bin/hdcp_tx22 + device/amlogic/common/hdcp_rx22/hdcp_rx22:$(TARGET_COPY_OUT_VENDOR)/bin/hdcp_rx22 \ + device/amlogic/common/hdcp_rx22/arm_tools/aictool:$(TARGET_COPY_OUT_VENDOR)/bin/aictool \ + device/amlogic/common/hdcp_rx22/arm_tools/esm_swap:$(TARGET_COPY_OUT_VENDOR)/bin/esm_swap \ + device/amlogic/common/hdcp_rx22/arm_tools/hdcprxkeys:$(TARGET_COPY_OUT_VENDOR)/bin/hdcprxkeys \ + device/amlogic/common/hdcp_rx22/firmware/esm_config.i:$(TARGET_COPY_OUT_VENDOR)/etc/firmware/hdcp_rx22/esm_config.i \ + device/amlogic/common/hdcp_rx22/firmware/firmware.rom:$(TARGET_COPY_OUT_VENDOR)/etc/firmware/hdcp_rx22/firmware.rom \ + device/amlogic/common/hdcp_rx22/firmware/firmware.aic:$(TARGET_COPY_OUT_VENDOR)/etc/firmware/hdcp_rx22/firmware.aic \ + device/amlogic/common/hdcp_rx22/firmware/firmware.le:$(TARGET_COPY_OUT_VENDOR)/etc/firmware/hdcp_rx22/firmware.le # bootanimation PRODUCT_COPY_FILES += \ @@ -122,10 +123,18 @@ PRODUCT_COPY_FILES += \ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/tv.mp4:$(TARGET_COPY_OUT_VENDOR)/etc/bootvideo +# TV EQ +PRODUCT_COPY_FILES += \ + $(BOARD_AML_VENDOR_PATH)/external/libaudioeffect/EQ/lib/libhpeq.so:$(TARGET_COPY_OUT_VENDOR)lib/soundfx/libhpeq.so \ + $(BOARD_AML_VENDOR_PATH)/external/libaudioeffect/EQ/lib64/libhpeq.so:$(TARGET_COPY_OUT_VENDOR)/lib64/soundfx/libhpeq.so + # default wallpaper for mbox to fix bug 106225 PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/default_wallpaper.png:$(TARGET_COPY_OUT_VENDOR)/etc/default_wallpaper.png +#ADDITIONAL_BUILD_PROPERTIES += \ +# ro.config.wallpaper=$(TARGET_COPY_OUT_VENDOR)/etc/default_wallpaper.png + # Include BUILD_NUMBER if defined VERSION_ID=$(shell find device/*/$(TARGET_PRODUCT) -name version_id.mk) $(call inherit-product, $(VERSION_ID)) @@ -134,8 +143,4 @@ DISPLAY_BUILD_NUMBER := true # default timezone PRODUCT_PROPERTY_OVERRIDES += \ - persist.sys.timezone=Asia/Shanghai - -#TV project,set omx to video layer,or PQ hasn't effect -PRODUCT_PROPERTY_OVERRIDES += \ - media.omx.display_mode=1 \ No newline at end of file + persist.sys.timezone=Asia/Shanghai \ No newline at end of file diff --git a/recovery/Android.mk b/recovery/Android.mk deleted file mode 100644 index 3c93256..0000000 --- a/recovery/Android.mk +++ b/dev/null @@ -1,8 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(LOCAL_PATH)/recovery_extra/Android.mk \ - $(LOCAL_PATH)/ubootenv/Android.mk \ - $(LOCAL_PATH)/fdt/Android.mk \ - $(LOCAL_PATH)/check/Android.mk \ - $(LOCAL_PATH)/ui/Android.mk \ - $(LOCAL_PATH)/updater_extra/Android.mk \ No newline at end of file diff --git a/recovery/check/Android.mk b/recovery/check/Android.mk deleted file mode 100644 index 0f1921f..0000000 --- a/recovery/check/Android.mk +++ b/dev/null @@ -1,27 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := security.cpp dtbcheck.cpp - -LOCAL_MODULE := libsecurity - -LOCAL_C_INCLUDES += bootable/recovery - -LOCAL_C_INCLUDES += \ - system/core/base/include \ - system/core/libziparchive/include - -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ - -LOCAL_STATIC_LIBRARIES := libcutils libselinux - -LOCAL_CLANG := true - -LOCAL_CFLAGS += -Wall - -ifeq ($(OTA_UP_PART_NUM_CHANGED), true) -LOCAL_CFLAGS += -DSUPPORT_PARTNUM_CHANGE -endif - -include $(BUILD_STATIC_LIBRARY) diff --git a/recovery/check/dtbcheck.cpp b/recovery/check/dtbcheck.cpp deleted file mode 100644 index 9d13bee..0000000 --- a/recovery/check/dtbcheck.cpp +++ b/dev/null @@ -1,860 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dtbcheck.h" - - -extern "C" { -#include "fdt/libfdt.h" -} - - - -#define MAX_LEVEL 32 /* how deeply nested we will go */ -#define CONFIG_CMD_FDT_MAX_DUMP 64 - -#define DT_HEADER_MAGIC 0xedfe0dd0 /*header of dtb file*/ -#define AML_DT_HEADER_MAGIC 0x5f4c4d41 /*"AML_", multi dtbs supported*/ - -#define AML_DT_ID_VARI_TOTAL 3 //Total 3 strings -/*Latest version: v2*/ -#define AML_DT_VERSION_OFFSET 4 -#define AML_DT_TOTAL_DTB_OFFSET 8 -#define AML_DT_FIRST_DTB_OFFSET 12 - -#define AML_DT_DTB_DT_INFO_OFFSET 0 - -#define ENV_DTB "aml_dt" -#define CMDLINE "/proc/cmdline" -#define STORE_DEVICE "/sys/class/aml_store/store_device" -#define DEVICE_NAND 2 -#define DEVICE_EMMC 1 - -extern int IsPlatformEncrypted(void); - -extern int DtbImgEncrypted( - const char *imageName, - const unsigned char *imageBuffer, - const int imageSize, - const char *flag, - unsigned char *encryptedbuf); - -struct fdt_header *working_fdt; - -static Dtb_Partition_S dtb_zip[24]; -static Dtb_Partition_S dtb_dev[24]; - -unsigned int recovery_size1 = 32*1024*1024; //default value 32M - -static int isEncrypted = 0; - -struct Dtb_header { - unsigned int dt_magic; - unsigned int dt_tool_version; - unsigned int dt_total; - char data[0]; -}; - - -/****************************************************************************/ - - -unsigned int -STRTOU32(unsigned char* p){ - return (p[3]<<24)|(p[2]<<16)|(p[1]<<8)|p[0]; -} - -int GetDeviceType() -{ - FILE *p = NULL; - int len = 0; - char buffer[32] = {0}; - int type = 0; - - p = fopen(STORE_DEVICE, "r"); - if (p == NULL) { - printf("open failed!\n"); - return -1; - } - - len = fread(buffer, 1, 32, p); - if (len <= 0) { - printf("fread failed!\n"); - fclose(p); - return -1; - } - fclose(p); - - printf("buffer:%s\n",buffer); - - type = atoi(buffer); - printf("type=%d\n",type); - return type; -} - -signed int -GetDtbId(char *pdt){ - FILE *p = NULL; - int len = 0; - char buffer[1024] = {0}; - - if (pdt == NULL) { - printf("param error!\n"); - return -1; - } - - p = fopen(CMDLINE, "r"); - if (p == NULL) { - printf("open failed!\n"); - return -1; - } - - len = fread(buffer, 1, 1023, p); - if (len <= 0) { - printf("fread failed!\n"); - fclose(p); - return -1; - } - fclose(p); - - char *paddr=strstr(buffer, ENV_DTB); - if (paddr == NULL) { - printf("not find env:aml_dt !\n"); - return -1; - } - - paddr = strtok(paddr, " "); - - paddr = paddr+strlen(ENV_DTB)+1; - //printf("cmdline, aml_dt=%s\n", paddr); - - strcpy(pdt, paddr); - return 0; -} - - -/* - * Heuristic to guess if this is a string or concatenated strings. - */ - -static int -is_printable_string(const void *data, int len){ - const char *s = (char *)data; - - /* zero length is not */ - if (len == 0) - return 0; - - /* must terminate with zero or '\n' */ - if (s[len - 1] != '\0' && s[len - 1] != '\n') - return 0; - - /* printable or a null byte (concatenated strings) */ - while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) { - /* - * If we see a null, there are three possibilities: - * 1) If len == 1, it is the end of the string, printable - * 2) Next character also a null, not printable. - * 3) Next character not a null, continue to check. - */ - if (s[0] == '\0') { - if (len == 1) - return 1; - if (s[1] == '\0') - return 0; - } - s++; - len--; - } - - /* Not the null termination, or not done yet: not printable */ - if (*s != '\0' || (len != 0)) - return 0; - - return 1; -} - - - -/* - * Print the property in the best format, a heuristic guess. Print as - * a string, concatenated strings, a byte, word, double word, or (if all - * else fails) it is printed as a stream of bytes. - */ -static void print_data(const void *data, int len, int *index, int flag) -{ - int j; - - char *pd = (char *)data; - - /* no data, don't print */ - if (len == 0) - return; - - /* - * It is a string, but it may have multiple strings (embedded '\0's). - */ - if (is_printable_string(pd, len)) { - j = 0; - while (j < len) { - if (flag == 0) { - strcpy(dtb_zip[*index].partition_name, pd); - } else { - strcpy(dtb_dev[*index].partition_name, pd); - } - j += strlen(pd) + 1; - pd += strlen(pd) + 1; - } - return; - } - - if ((len %4) == 0) { - if (len > CONFIG_CMD_FDT_MAX_DUMP) - ; - else if (len == 8){ - const __be32 *p; - p = (__be32 *)pd; - if (flag == 0) - { - dtb_zip[*index].partition_size = fdt32_to_cpu(p[1]) - fdt32_to_cpu(p[0]); - } - else - { - dtb_dev[*index].partition_size = fdt32_to_cpu(p[1]) - fdt32_to_cpu(p[0]); - } - (*index)++; - } - } else { /* anything else... hexdump */ - if (len > CONFIG_CMD_FDT_MAX_DUMP) - ; - else { - const unsigned char *s; - } - } -} - - -int -GetPartitionFromDtb(const char *pathp, int depth, int *partition_num, int flag){ - static char tabs[MAX_LEVEL+1] = - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; - const void *nodep; /* property node pointer */ - int nodeoffset; /* node offset from libfdt */ - int index = 0; - int nextoffset; /* next node offset from libfdt */ - uint32_t tag; /* tag */ - int len; /* length of the property */ - int level = 0; /* keep track of nesting level */ - const struct fdt_property *fdt_prop; - - nodeoffset = fdt_path_offset (working_fdt, pathp); - if (nodeoffset < 0) { - /* - * Not found or something else bad happened. - */ - printf ("libfdt fdt_path_offset() returned %s\n", - fdt_strerror(nodeoffset)); - return 1; - } - - - /* - * The user passed in a node path and no property, - * print the node and all subnodes. - */ - while (level >= 0) { - tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset); - switch (tag) { - case FDT_BEGIN_NODE: - pathp = fdt_get_name(working_fdt, nodeoffset, NULL); - if (level <= depth) { - if (pathp == NULL) - pathp = "/* NULL pointer error */"; - if (*pathp == '\0') - pathp = "/"; /* root is nameless */ - } - level++; - if (level >= MAX_LEVEL) { - printf("Nested too deep, aborting.\n"); - return 1; - } - break; - case FDT_END_NODE: - level--; - if (level <= depth) - ; - if (level == 0) { - level = -1; /* exit the loop */ - } - break; - case FDT_PROP: - fdt_prop = (struct fdt_property *)fdt_offset_ptr(working_fdt, nodeoffset, - sizeof(*fdt_prop)); - pathp = fdt_string(working_fdt, - fdt32_to_cpu(fdt_prop->nameoff)); - len = fdt32_to_cpu(fdt_prop->len); - nodep = fdt_prop->data; - if (len < 0) { - printf ("libfdt fdt_getprop(): %s\n", - fdt_strerror(len)); - return 1; - } else if (len == 0) { - /* the property has no value */ - if (level <= depth) - ; - } else { - if (level <= depth) { - print_data (nodep, len, &index, flag); - } - } - break; - case FDT_NOP: - printf("%s/* NOP */\n", &tabs[MAX_LEVEL - level]); - break; - case FDT_END: - return 1; - default: - if (level <= depth) - printf("Unknown tag 0x%08X\n", tag); - return 1; - } - nodeoffset = nextoffset; - } - - *partition_num = index; - return 0; -} - -unsigned char * -GetMultiDtbEntry(unsigned char *fdt_addr, int *plen){ - unsigned int dt_magic = STRTOU32(fdt_addr); - signed int dt_total = 0; - unsigned int dt_tool_version = 0; - - //printf(" Amlogic multi-dtb tool\n"); - if (dt_magic == DT_HEADER_MAGIC) {/*normal dtb*/ - printf(" Single dtb detected\n"); - return fdt_addr; - } - else if (dt_magic == AML_DT_HEADER_MAGIC) {/*multi dtb*/ - printf(" Multi dtb detected\n"); - /* check and set aml_dt */ - int i = 0; - char *aml_dt_buf; - aml_dt_buf = (char *)malloc(sizeof(char)*64); - memset(aml_dt_buf, 0, sizeof(aml_dt_buf)); - - GetDtbId(aml_dt_buf); - //printf("aml_dt_buf:%s\n", aml_dt_buf); - - unsigned int aml_dt_len = aml_dt_buf ? strlen(aml_dt_buf) : 0; - if (aml_dt_len <= 0) { - printf("Get env aml_dt failed!Ignore dtb check !\n"); - *plen = 0; - return fdt_addr; - } - - /*version control, compatible with v1*/ - dt_tool_version = STRTOU32(fdt_addr + AML_DT_VERSION_OFFSET); - unsigned int aml_each_id_length=0; - unsigned int aml_dtb_offset_offset; - unsigned int aml_dtb_header_size; - - if (dt_tool_version == 1) - aml_each_id_length = 4; - else if(dt_tool_version == 2) - aml_each_id_length = 16; - - aml_dtb_offset_offset = aml_each_id_length * AML_DT_ID_VARI_TOTAL; - aml_dtb_header_size = 8+(aml_each_id_length * AML_DT_ID_VARI_TOTAL); - //printf(" Multi dtb tool version: v%d .\n", dt_tool_version); - - /*fdt_addr + 0x8: num of dtbs*/ - dt_total = STRTOU32(fdt_addr + AML_DT_TOTAL_DTB_OFFSET); - //printf(" Support %d dtbs.\n", dt_total); - - /* split aml_dt to 3 strings */ - char *tokens[3] = {NULL, NULL, NULL}; - for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++) { - tokens[i] = strsep(&aml_dt_buf, "_"); - } - - if (aml_dt_buf) - free(aml_dt_buf); - //printf(" aml_dt soc: %s platform: %s variant: %s\n", tokens[0], tokens[1], tokens[2]); - - /*match and print result*/ - char **dt_info; - dt_info = (char **)malloc(sizeof(char *)*AML_DT_ID_VARI_TOTAL); - for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++) - dt_info[i] = (char *)malloc(sizeof(char)*aml_each_id_length); - - unsigned int dtb_match_num = 0xffff; - unsigned int x = 0, y = 0, z = 0; //loop counter - unsigned int read_data; - for (i = 0; i < dt_total; i++) { - for (x = 0; x < AML_DT_ID_VARI_TOTAL; x++) { - for (y = 0; y < aml_each_id_length; y+=4) { - read_data = STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \ - i * aml_dtb_header_size + AML_DT_DTB_DT_INFO_OFFSET + \ - (x * aml_each_id_length) + y); - dt_info[x][y+0] = (read_data >> 24) & 0xff; - dt_info[x][y+1] = (read_data >> 16) & 0xff; - dt_info[x][y+2] = (read_data >> 8) & 0xff; - dt_info[x][y+3] = (read_data >> 0) & 0xff; - } - - for (z=0; z0: get image data successful - */ -static unsigned char *s_pDtbBuffer = NULL; -static int -GetZipDtbImage(const ZipArchiveHandle za, const char *imageName, int *imageSize){ - int len = 0; - int ret = 0; - unsigned char *paddr = NULL; - - ZipString zip_path(imageName); - ZipEntry entry; - if (FindEntry(za, zip_path, &entry) != 0) { - printf("no %s in package!\n", imageName); - return 0; - } - - *imageSize = entry.uncompressed_length; - if (*imageSize <= 0) { - printf("can't get package entry uncomp len(%d) (%s)\n",*imageSize, strerror(errno)); - return -1; - } - - len = *imageSize; - - unsigned char* buffer = (unsigned char *)calloc(len, sizeof(unsigned char)); - if (!buffer) { - printf("can't malloc %d size space (%s)\n",len, strerror(errno)); - return -1; - } - - ret = ExtractToMemory(za, &entry, buffer, entry.uncompressed_length); - if (ret != 0) { - printf("can't extract package entry to image buffer\n"); - free(buffer); - return -1; - } - - - if (isEncrypted == 1) { - ret = DtbImgEncrypted(DTB_IMG, buffer, len, "1", buffer); - if (ret == 2) { - printf("no decrypt_dtb and no support!"); - free(buffer); - return 2; - }else if (ret <= 0) { - printf("dtb.img encrypt from zip failed!\n"); - free(buffer); - return -1; - } - } - - paddr = GetMultiDtbEntry(buffer, &len); - if (paddr == NULL) - { - printf("Cannot find legal dtb from zip \n"); - free(buffer); - return -1; - } else if (len == 0) { - printf("No need to check dtb \n"); - free(buffer); - return 2; - } - - if (s_pDtbBuffer != NULL) { - free(s_pDtbBuffer); - s_pDtbBuffer = NULL; - } - - s_pDtbBuffer = (unsigned char *)calloc(len, sizeof(unsigned char)); - if (!s_pDtbBuffer) { - printf("can't malloc %d size space (%s)\n",len, strerror(errno)); - free(buffer); - return -1; - } - - memcpy(s_pDtbBuffer, paddr, len); - free(buffer); - - return 1; -} - -static int -GetDevDtbImage(){ - int fd = 0; - int len = 0; - int ret = 0; - unsigned char *paddr = NULL; - const char *DTB_DEV= "/dev/dtb"; - const int DTB_DATA_MAX = 256*1024; - - unsigned char* buffer = (unsigned char *)calloc(DTB_DATA_MAX+256, sizeof(unsigned char)); - if (buffer == NULL) { - printf("malloc %d failed!\n", DTB_DATA_MAX+256); - return -1; - } - - fd = open(DTB_DEV, O_RDONLY); - if (fd < 0) { - printf("open %s failed!\n", DTB_DEV); - free(buffer); - return -1; - } - - len = read(fd, buffer, DTB_DATA_MAX); - if (len < 0) { - printf("read failed len = %d\n", len); - close(fd); - free(buffer); - return -1; - } - - close(fd); - - if (isEncrypted == 1) { - ret = DtbImgEncrypted(DTB_IMG, buffer, len, "1", buffer); - if (ret <= 0) { - printf("dtb.img encrypt from dev failed!\n"); - free(buffer); - return -1; - } - } - paddr = GetMultiDtbEntry(buffer, &len); - if (paddr == NULL) { - printf("Cannot find legal dtb from dev block \n"); - free(buffer); - return -1; - } - - if (s_pDtbBuffer != NULL) { - free(s_pDtbBuffer); - s_pDtbBuffer = NULL; - } - - s_pDtbBuffer = (unsigned char *)calloc(len, sizeof(unsigned char)); - if (s_pDtbBuffer == NULL) { - printf("malloc %d failed!\n", len); - free(buffer); - return -1; - } - - memcpy(s_pDtbBuffer, paddr, len); - free(buffer); - - return 0; -} - -int -GetEnvPartitionOffset(const ZipArchiveHandle za) { - int i = 0; - int find = 0; - int ret = -1; - int offset = 116*1024*1024; //bootloader(4M) GAP(32M) reserved(64M) GAP(8M) cache(--) GAP(8M) - int imageSize = 0; - int partition_num_zip = 0; - - ret = GetZipDtbImage(za, DTB_IMG, &imageSize); - if ((ret == 0) || (ret == 2)) { - printf("no dtb.img in the update or no need check dtb, check dtb over!\n"); - return 0; - } else if (ret < 0) { - printf("get dtb.img from update.zip failed!\n"); - ret = -1; - goto END; - } - - working_fdt = (struct fdt_header *)s_pDtbBuffer; - - ret = GetPartitionFromDtb("/partitions", MAX_LEVEL, &partition_num_zip, 0); - if (ret != 0) { - printf("get partition map from dtb.img failed!\n"); - ret = -1; - goto END; - } - - for (i=0; i partition_num_dev ? partition_num_zip : partition_num_dev; - #else - printf("partition num don't match zip:%d, dev:%d, can not upgrade!\n",partition_num_zip, partition_num_dev); - ret = -1; - goto END; - #endif - } - printf("partition_num = %d \n",partition_num); - - for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common.h" -#include "cutils/properties.h" -#include "security.h" - -T_KernelVersion kernel_ver = KernelV_3_10; -/** - * --- judge platform whether match with zip image or not - * - * @platformEncryptStatus: 0: platform unencrypted, 1: platform encrypted - * @imageEncryptStatus: 0: image unencrypted, 1: image encrypted - * @imageName: image name - * @imageBuffer: image data address - * @imageSize: image data size - * - * return value: - * <0: failed - * =0: not match - * >0: match - */ -static int IsPlatformMachWithZipArchiveImage( - const int platformEncryptStatus, - const int imageEncryptStatus, - const char *imageName, - const unsigned char *imageBuffer, - const int imageSize) -{ - int fd = -1, ret = -1; - ssize_t result = -1; - - if (strcmp(imageName, BOOT_IMG) && - strcmp(imageName, RECOVERY_IMG) && - strcmp(imageName, BOOTLOADER_IMG)) { - printf("can't support %s at present\n", - imageName); - return -1; - } - - if (imageBuffer == NULL) { - printf("havn't malloc space for %s\n", - imageName); - return -1; - } - - if (imageSize <= 0) { - printf("%s size is %d\n", - imageName, imageSize); - return -1; - } - - switch (platformEncryptStatus) { - case 0: { - if (!imageEncryptStatus) { - ret = 1; - } else { - ret = 0; - } - break; - } - - case 1: { - if (!imageEncryptStatus) { - ret = 0; - } else { - fd = open(DEFEND_KEY, O_RDWR); - if (fd <= 0) { - printf("open %s failed (%s)\n", - DEFEND_KEY, strerror(errno)); - return -1; - } - result = write(fd, imageBuffer, imageSize);// check rsa - printf("write %s datas to %s. [imgsize:%d, result:%d, %s]\n", - imageName, DEFEND_KEY, imageSize, result, - (result == 1) ? "match" : - (result == -2) ? "not match" : "failed or not support"); - if (result == 1) { - ret = 1; - } else if(result == -2) { - ret = 0; - } else { // failed or not support - ret = -1; - } - close(fd); - fd = -1; - } - break; - } - } - - return ret; -} - -/** - * --- check bootloader.img whether encrypt or not - * - * @imageName: bootloader.img - * @imageBuffer: bootloader.img data address - * - * return value: - * <0: failed - * =0: unencrypted - * >0: encrypted - */ -static int IsBootloaderImageEncrypted( - const char *imageName, - const unsigned char *imageBuffer) -{ - int step0=1; - int step1=1; - int index=0; - unsigned char result= 0; - const unsigned char *pstart = NULL; - const unsigned char *pImageAddr = imageBuffer; - const unsigned char *pEncryptedBootloaderInfoBufAddr = NULL; - - // Don't modify. unencrypt bootloader info, for kernel version 3.10 - const int bootloaderEncryptInfoOffset = 0x1b0; - const unsigned char unencryptedBootloaderInfoBuf[] = - { 0x4D, 0x33, 0x48, 0x48, 0x52, 0x45, 0x56, 0x30 }; - - // Don't modify. unencrypt bootloader info, for kernel version 3.14 - const int newbootloaderEncryptInfoOffset = 0x10; - const int newbootloaderEncryptInfoOffset1 = 0x70; - const unsigned char newunencryptedBootloaderInfoBuf[] = { 0x40, 0x41, 0x4D, 0x4C}; - - if (strcmp(imageName, BOOTLOADER_IMG)) { - printf("this image must be %s,but it is %s\n", - BOOTLOADER_IMG, imageName); - return -1; - } - - if (imageBuffer == NULL) { - printf("havn't malloc space for %s\n", - imageName); - return -1; - } - - if (kernel_ver == KernelV_3_10) { - //check image whether encrypted for kernel 3.10 - pEncryptedBootloaderInfoBufAddr = pImageAddr + bootloaderEncryptInfoOffset; - if (!memcmp(unencryptedBootloaderInfoBuf, pEncryptedBootloaderInfoBufAddr, - ARRAY_SIZE(unencryptedBootloaderInfoBuf))) { - return 0; // unencrypted - } else { - return 1; - } - } - - //check image whether encrypted for kernel 3.14 - pEncryptedBootloaderInfoBufAddr = pImageAddr + newbootloaderEncryptInfoOffset; - if (!memcmp(newunencryptedBootloaderInfoBuf, pEncryptedBootloaderInfoBufAddr, - ARRAY_SIZE(newunencryptedBootloaderInfoBuf))) { - step0 = 0; - } - - pstart = pImageAddr + newbootloaderEncryptInfoOffset1; - for (index=0;index<16;index++) { - result ^= pstart[index]; - } - - if (result == 0) { - step1 = 0; - } - - if ((step0 == 1) && (step0 == 1)) { - return 1; // encrypted - } - - return 0;//unencrypted -} - -/* return value: - * <0: failed - * =0: not match - * >0: match - */ -int DtbImgEncrypted( - const char *imageName, - const unsigned char *imageBuffer, - const int imageSize, - const char *flag, - unsigned char *encryptedbuf) -{ - int len = 0; - ssize_t result = -1; - ssize_t readlen = -1; - int fd = -1, ret = -1; - - if ((imageBuffer == NULL) || (imageName == NULL)) { - printf("imageBuffer is null!\n"); - return -1; - } - - if (access(DECRYPT_DTB, F_OK) ||access(DEFEND_KEY, F_OK)) { - printf("doesn't support dtb secure check\n"); - return 2; // kernel doesn't support - } - - fd = open(DECRYPT_DTB, O_RDWR); - if (fd <= 0) { - printf("open %s failed!\n", DECRYPT_DTB); - return -1; - } - - len = write(fd, flag, 1); - if (len != 1) { - printf("write %s failed!\n", DECRYPT_DTB); - close(fd); - fd = -1; - return -1; - } - - close(fd); - fd = -1; - - fd = open(DEFEND_KEY, O_RDWR); - if (fd <= 0) { - printf("open %s failed (%s)\n",DEFEND_KEY, strerror(errno)); - return -1; - } - - result = write(fd, imageBuffer, imageSize);// check rsa - printf("write %s datas to %s. [imgsize:%d, result:%d, %s]\n", - imageName, DEFEND_KEY, imageSize, result, - (result == 1) ? "match" : - (result == -2) ? "not match" : "failed or not support"); - - if (!strcmp(flag, "1")) { - printf("dtb.img need to encrypted!\n"); - readlen = read(fd, encryptedbuf, imageSize); - if (readlen < 0) { - printf("read %s error!\n", DEFEND_KEY); - close(fd); - return -1; - } - - } - - if (result == 1) { - ret = 1; - } else if(result == -2) { - ret = 0; - } else { // failed or not support - ret = -1; - } - - close(fd); - fd = -1; - - return ret; -} - -/** - * --- check zip archive image whether encrypt or not - * image is bootloader.img/boot.img/recovery.img - * - * @imageName: image name - * @imageBuffer: image data address - * @imageSize: image data size - * - * return value: - * <0: failed - * =0: unencrypted - * >0: encrypted - */ -static int IsZipArchiveImageEncrypted( - const char *imageName, - const unsigned char *imageBuffer, - const int imageSize) -{ - int ret = -1; - const unsigned char *pImageAddr = imageBuffer; - - if (strcmp(imageName, BOOT_IMG) && - strcmp(imageName, RECOVERY_IMG) && - strcmp(imageName, BOOTLOADER_IMG)) { - printf("can't support %s at present\n", - imageName); - return -1; - } - - if (imageBuffer == NULL) { - printf("havn't malloc space for %s\n", - imageName); - return -1; - } - - if (imageSize <= 0) { - printf("%s size is %d\n", - imageName, imageSize); - return -1; - } - - if (!strcmp(imageName, BOOTLOADER_IMG)) { - return IsBootloaderImageEncrypted(imageName, imageBuffer); - } - - if (kernel_ver == KernelV_3_10) { - //check image whether encrypted for kernel 3.10 - const pT_SecureBootImgHdr encryptSecureBootImgHdr = - (const pT_SecureBootImgHdr)pImageAddr; - const pT_EncryptBootImgInfo encryptBootImgInfo = - &encryptSecureBootImgHdr->encryptBootImgInfo; - - secureDbg("magic:%s, version:0x%04x, totalLenAfterEncrypted:0x%0x\n", - encryptBootImgInfo->magic, encryptBootImgInfo->version, - encryptBootImgInfo->totalLenAfterEncrypted); - - ret = memcmp(encryptBootImgInfo->magic, SECUREBOOT_MAGIC, - strlen(SECUREBOOT_MAGIC)); - if (!ret && encryptBootImgInfo->version != 0x0) { - return 1; // encrypted - } - - return 0; - } - - //check image whether encrypted for kernel 3.14 - const AmlSecureBootImgHeader encryptSecureBootImgHeader = - (const AmlSecureBootImgHeader)pImageAddr; - const p_AmlEncryptBootImgInfo encryptBootImgHeader = - &encryptSecureBootImgHeader->encrypteImgInfo; - - secureDbg("magic:%s, version:0x%04x\n", - encryptBootImgHeader->magic, encryptBootImgHeader->version); - - ret = memcmp(encryptBootImgHeader->magic, SECUREBOOT_MAGIC, - strlen(SECUREBOOT_MAGIC)); - if (!ret && encryptBootImgHeader->version != 0x0) { - return 1; // encrypted - } - - return 0; // unencrypted - } - -/** - * --- check platform whether encrypt or not - * - * return value: - * <0: failed - * =0: unencrypted - * >0: encrypted - */ -int IsPlatformEncrypted(void) -{ - int fd = -1, ret = -1; - ssize_t count = 0; - char rBuf[128] = {0}; - char platform[PROPERTY_VALUE_MAX+1] = {0}; - - if (!(access(SECURE_CHECK, F_OK) || (access(SECURE_CHECK_BAK, F_OK))) \ - || access(DEFEND_KEY, F_OK)) { - printf("kernel doesn't support secure check\n"); - return 2; // kernel doesn't support - } - - fd = open(SECURE_CHECK, O_RDONLY); - if (fd <= 0) { - fd = open(SECURE_CHECK_BAK, O_RDONLY); - if (fd <= 0) { - printf("open %s failed (%s)\n", - SECURE_CHECK, strerror(errno)); - return -1; - } - kernel_ver = KernelV_3_14; - } - - property_get("ro.build.product", platform, "unknow"); - count = read(fd, rBuf, sizeof(rBuf) - 1); - if (count <= 0) { - printf("read %s failed (count:%d)\n", - SECURE_CHECK, count); - close(fd); - return -1; - } - rBuf[count] = '\0'; - - if (!strcmp(rBuf, s_pStatus[UNENCRYPT])) { - printf("check platform(%s): unencrypted\n", platform); - ret = 0; - } else if (!strcmp(rBuf, s_pStatus[ENCRYPT])) { - printf("check platform(%s): encrypted\n", platform); - ret = 1; - } else if (!strcmp(rBuf, s_pStatus[FAIL])) { - printf("check platform(%s): failed\n", platform); - } else { - printf("check platform(%s): %s\n", platform, rBuf); - } - - if (fd > 0) { - close(fd); - fd = -1; - } - - return ret; -} - -/** - * --- get upgrade package image data - * - * @zipArchive: zip archive object - * @imageName: upgrade package image's name - * @imageSize: upgrade package image's size - * - * return value: - * <0: failed - * =0: can't find image - * >0: get image data successful - */ -static unsigned char *s_pImageBuffer = NULL; -static int GetZipArchiveImage( - const ZipArchiveHandle za, - const char *imageName, - int *imageSize) -{ - ZipString zip_path(imageName); - ZipEntry entry; - if (FindEntry(za, zip_path, &entry) != 0) { - printf("no %s in package!\n", imageName); - return 0; - } - - *imageSize = entry.uncompressed_length; - if (*imageSize <= 0) { - printf("can't get package entry uncomp len(%d) (%s)\n", - *imageSize, strerror(errno)); - return -1; - } - - if (s_pImageBuffer != NULL) { - free(s_pImageBuffer); - s_pImageBuffer = NULL; - } - - s_pImageBuffer = (unsigned char *)calloc(*imageSize, sizeof(unsigned char)); - if (!s_pImageBuffer) { - printf("can't malloc %d size space (%s)\n", - *imageSize, strerror(errno)); - return -1; - } - - int32_t ret = ExtractToMemory(za, &entry, s_pImageBuffer, entry.uncompressed_length); - if (ret != 0) { - printf("can't extract package entry to image buffer\n"); - goto FREE_IMAGE_MEM; - } - - return 1; - - -FREE_IMAGE_MEM: - if (s_pImageBuffer != NULL) { - free(s_pImageBuffer); - s_pImageBuffer = NULL; - } - - return -1; -} - -/** - * --- check platform and upgrade package whether - * encrypted,if all encrypted,rsa whether all the same - * - * @ziparchive: Archive of Zip Package - * - * return value: - * =-1: failed; not allow upgrade - * = 0: check not match; not allow upgrade - * = 1: check match; allow upgrade - * = 2: kernel not support secure check; allow upgrade - */ -int RecoverySecureCheck(const ZipArchiveHandle zipArchive) -{ - int i = 0, ret = -1, err = -1; - int ret_dtb = 0; - int imageSize = 0; - int platformEncryptStatus = 0, imageEncryptStatus = 0; - const char *pImageName[] = { - BOOTLOADER_IMG, - BOOT_IMG, - RECOVERY_IMG }; - - platformEncryptStatus = IsPlatformEncrypted(); - if (platformEncryptStatus == 2) { - return 2;// kernel doesn't support - } - - if (platformEncryptStatus < 0) { - return -1; - } - - if (platformEncryptStatus >0 ) { - ret = GetZipArchiveImage(zipArchive, DTB_IMG, &imageSize); - if (ret > 0) { - ret_dtb = DtbImgEncrypted(DTB_IMG, s_pImageBuffer, imageSize, "0", NULL); - if (ret_dtb == 2) { - printf("dtb secure check not support!\n"); - } else if (ret_dtb > 0){ - printf("dtb secure check success!\n"); - - } else { - printf("dtb secure check error!\n"); - ret = -1; - goto ERR1; - } - } else if (ret == 0) { - printf("check %s: not find,skiping...\n", DTB_IMG); - } else { - printf("get %s datas failed\n", DTB_IMG); - goto ERR1; - } - } - - for (i = 0; i < ARRAY_SIZE(pImageName); i++) { - ret = GetZipArchiveImage(zipArchive, pImageName[i], &imageSize); - if (ret < 0) { - printf("get %s datas failed\n", pImageName[i]); - goto ERR1; - } else if (ret == 0) { - printf("check %s: not find,skiping...\n", pImageName[i]); - continue; - } else if (ret > 0) { - secureDbg("get %s datas(size:0x%0x, addr:0x%x) successful\n", - pImageName[i], imageSize, (int)s_pImageBuffer); - imageEncryptStatus = IsZipArchiveImageEncrypted(pImageName[i], s_pImageBuffer, imageSize); - - printf("check %s: %s\n", - pImageName[i], (imageEncryptStatus < 0) ? "failed" : - !imageEncryptStatus ? "unencrypted" : "encrypted"); - if (imageEncryptStatus < 0) { - ret = -1; - goto ERR1; - } - - ret = IsPlatformMachWithZipArchiveImage( - platformEncryptStatus, imageEncryptStatus, pImageName[i], - s_pImageBuffer, imageSize); - if (ret < 0) { - printf("%s match platform failed\n", pImageName[i]); - goto ERR1; - } else if (ret == 0) { // if one of image doesn't match with platform,exit - printf("%s doesn't match platform\n", pImageName[i]); - goto ERR1; - } else { - secureDbg("%s match platform\n", pImageName[i]); - } - - if (s_pImageBuffer != NULL) { - free(s_pImageBuffer); - s_pImageBuffer = NULL; - } - } - } - - return 1; - - -ERR1: - if (s_pImageBuffer != NULL) { - free(s_pImageBuffer); - s_pImageBuffer = NULL; - } - - return ret; -} diff --git a/recovery/check/security.h b/recovery/check/security.h deleted file mode 100644 index d42e412..0000000 --- a/recovery/check/security.h +++ b/dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SECURITY_H_ -#define _SECURITY_H_ - -#define DTB_IMG "dtb.img" -#define BOOT_IMG "boot.img" -#define RECOVERY_IMG "recovery.img" -#define BOOTLOADER_IMG "bootloader.img" -#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0])) - -#define NORMALBOOT_NAME_SIZE 16 -#define NORMALBOOT_ARGS_SIZE 512 -#define NORMALBOOT_MAGIC_SIZE 8 -#define NORMALBOOT_MAGIC "ANDROID!" - -#define SECUREBOOT_MAGIC "AMLSECU!" -#define SECUREBOOT_MAGIC_SIZE 16 -#define SECUREBOOT_MAGIC_VESRION 0x0801 - -#define DECRYPT_DTB "/sys/class/defendkey/decrypt_dtb" - -#define DEFEND_KEY \ - "/dev/defendkey" -#define SECURE_CHECK \ - "/sys/class/defendkey/defendkey/secure_check" - -#define SECURE_CHECK_BAK \ - "/sys/class/defendkey/secure_check" - - -#ifndef SECURITY_DEBUG -#define secureDbg(fmt ...) -#else -#define secureDbg(fmt ...) printf(fmt) -#endif - -typedef enum Kernel_version { - KernelV_3_10, - KernelV_3_14 -}T_KernelVersion; - -typedef enum SecureCheck { - FAIL, - ENCRYPT, - UNENCRYPT, - TYPE_MAX, -} T_SecureCheck; - -static const char *s_pStatus[TYPE_MAX] = { - "fail", - "encrypt", - "raw", -}; - -typedef struct NormalBootImgHdr { - unsigned char magic[NORMALBOOT_MAGIC_SIZE]; - unsigned kernel_size; - unsigned kernel_addr; - unsigned ramdisk_size; - unsigned ramdisk_addr; - unsigned second_size; - unsigned second_addr; - unsigned tags_addr; // physical addr for kernel tags - unsigned page_size; // flash page size we assume - unsigned unused[2]; - unsigned char name[NORMALBOOT_NAME_SIZE]; - unsigned char cmdline[NORMALBOOT_ARGS_SIZE]; - unsigned id[8]; -} T_NormalBootImgHdr; - -typedef struct EncryptBootImgInfo { - // magic to identify whether it is a encrypted boot image - unsigned char magic[SECUREBOOT_MAGIC_SIZE]; - - // version for this header struct - unsigned int version; - - // total length after encrypted with AMLETool (including the 2K header) - unsigned int totalLenAfterEncrypted; - - unsigned char unused[1024 - SECUREBOOT_MAGIC_SIZE - 2 * sizeof(unsigned int)]; -} T_EncryptBootImgInfo, *pT_EncryptBootImgInfo; - -typedef struct SecureBootImgHdr { - T_NormalBootImgHdr normalBootImgHdr; - unsigned char reserve4Other[1024 - sizeof(T_NormalBootImgHdr)]; - T_EncryptBootImgInfo encryptBootImgInfo; -} *pT_SecureBootImgHdr; - - -//S905 SECURE BOOT HEAD -#define AML_SECU_BOOT_IMG_HDR_MAGIC "AMLSECU!" -#define AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE (8) -#define AML_SECU_BOOT_IMG_HDR_VESRION (0x0905) - - -typedef struct __aml_enc_blk{ - unsigned int nOffset; - unsigned int nRawLength; - unsigned int nSigLength; - unsigned int nAlignment; - unsigned int nTotalLength; - unsigned char szPad[12]; - unsigned char szSHA2IMG[32]; - unsigned char szSHA2KeyID[32]; -}t_aml_enc_blk; - -typedef struct { - - unsigned char magic[AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE];//magic to identify whether it is a encrypted boot image - - unsigned int version; //ersion for this header struct - unsigned int nBlkCnt; - - unsigned char szTimeStamp[16]; - - t_aml_enc_blk amlKernel; - t_aml_enc_blk amlRamdisk; - t_aml_enc_blk amlDTB; - -}AmlEncryptBootImgInfo, *p_AmlEncryptBootImgInfo; - -typedef struct _boot_img_hdr_secure_boot -{ - unsigned char reserve4ImgHdr[1024]; - - AmlEncryptBootImgInfo encrypteImgInfo; - -}*AmlSecureBootImgHeader; - -int RecoverySecureCheck(const ZipArchiveHandle zipArchive); - -int DtbImgEncrypted( - const char *imageName, - const unsigned char *imageBuffer, - const int imageSize, - const char *flag, - unsigned char *encryptedbuf); - - -//extern RecoveryUI *ui; - -#endif /* _SECURITY_H_ */ diff --git a/recovery/fdt/Android.mk b/recovery/fdt/Android.mk deleted file mode 100644 index 5982389..0000000 --- a/recovery/fdt/Android.mk +++ b/dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - fdt.c \ - fdt_ro.c \ - fdt_wip.c \ - fdt_sw.c \ - fdt_rw.c \ - fdt_strerror.c \ - fdt_empty_tree.c - - -LOCAL_MODULE := libdtb - -LOCAL_CFLAGS += -Wall - -include $(BUILD_STATIC_LIBRARY) diff --git a/recovery/fdt/Makefile.libfdt b/recovery/fdt/Makefile.libfdt deleted file mode 100644 index 91126c0..0000000 --- a/recovery/fdt/Makefile.libfdt +++ b/dev/null @@ -1,10 +0,0 @@ -# Makefile.libfdt -# -# This is not a complete Makefile of itself. Instead, it is designed to -# be easily embeddable into other systems of Makefiles. -# -LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 -LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h -LIBFDT_VERSION = version.lds -LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c -LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) diff --git a/recovery/fdt/fdt.c b/recovery/fdt/fdt.c deleted file mode 100644 index e56833a..0000000 --- a/recovery/fdt/fdt.c +++ b/dev/null @@ -1,222 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -int fdt_check_header(const void *fdt) -{ - if (fdt_magic(fdt) == FDT_MAGIC) { - /* Complete tree */ - if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; - if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; - } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { - /* Unfinished sequential-write blob */ - if (fdt_size_dt_struct(fdt) == 0) - return -FDT_ERR_BADSTATE; - } else { - return -FDT_ERR_BADMAGIC; - } - - return 0; -} - -const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) -{ - const char *p; - - if (fdt_version(fdt) >= 0x11) - if (((offset + len) < offset) - || ((offset + len) > fdt_size_dt_struct(fdt))) - return NULL; - - p = _fdt_offset_ptr(fdt, offset); - - if (p + len < p) - return NULL; - return p; -} - -uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) -{ - const uint32_t *tagp, *lenp; - uint32_t tag; - int offset = startoffset; - const char *p; - - *nextoffset = -FDT_ERR_TRUNCATED; - tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); - if (!tagp) - return FDT_END; /* premature end */ - tag = fdt32_to_cpu(*tagp); - offset += FDT_TAGSIZE; - - *nextoffset = -FDT_ERR_BADSTRUCTURE; - switch (tag) { - case FDT_BEGIN_NODE: - /* skip name */ - do { - p = fdt_offset_ptr(fdt, offset++, 1); - } while (p && (*p != '\0')); - if (!p) - return FDT_END; /* premature end */ - break; - - case FDT_PROP: - lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); - if (!lenp) - return FDT_END; /* premature end */ - /* skip-name offset, length and value */ - offset += sizeof(struct fdt_property) - FDT_TAGSIZE - + fdt32_to_cpu(*lenp); - break; - - case FDT_END: - case FDT_END_NODE: - case FDT_NOP: - break; - - default: - return FDT_END; - } - - if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) - return FDT_END; /* premature end */ - - *nextoffset = FDT_TAGALIGN(offset); - return tag; -} - -int _fdt_check_node_offset(const void *fdt, int offset) -{ - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) - return -FDT_ERR_BADOFFSET; - - return offset; -} - -int _fdt_check_prop_offset(const void *fdt, int offset) -{ - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) - return -FDT_ERR_BADOFFSET; - - return offset; -} - -int fdt_next_node(const void *fdt, int offset, int *depth) -{ - int nextoffset = 0; - uint32_t tag; - - if (offset >= 0) - if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) - return nextoffset; - - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_PROP: - case FDT_NOP: - break; - - case FDT_BEGIN_NODE: - if (depth) - (*depth)++; - break; - - case FDT_END_NODE: - if (depth && ((--(*depth)) < 0)) - return nextoffset; - break; - - case FDT_END: - if ((nextoffset >= 0) - || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) - return -FDT_ERR_NOTFOUND; - else - return nextoffset; - } - } while (tag != FDT_BEGIN_NODE); - - return offset; -} - -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) -{ - int len = strlen(s) + 1; - const char *last = strtab + tabsize - len; - const char *p; - - for (p = strtab; p <= last; p++) - if (memcmp(p, s, len) == 0) - return p; - return NULL; -} - -int fdt_move(const void *fdt, void *buf, int bufsize) -{ - FDT_CHECK_HEADER(fdt); - - if (fdt_totalsize(fdt) > bufsize) - return -FDT_ERR_NOSPACE; - - memmove(buf, fdt, fdt_totalsize(fdt)); - return 0; -} diff --git a/recovery/fdt/fdt.h b/recovery/fdt/fdt.h deleted file mode 100644 index 48ccfd9..0000000 --- a/recovery/fdt/fdt.h +++ b/dev/null @@ -1,60 +0,0 @@ -#ifndef _FDT_H -#define _FDT_H - -#ifndef __ASSEMBLY__ - -struct fdt_header { - uint32_t magic; /* magic word FDT_MAGIC */ - uint32_t totalsize; /* total size of DT block */ - uint32_t off_dt_struct; /* offset to structure */ - uint32_t off_dt_strings; /* offset to strings */ - uint32_t off_mem_rsvmap; /* offset to memory reserve map */ - uint32_t version; /* format version */ - uint32_t last_comp_version; /* last compatible version */ - - /* version 2 fields below */ - uint32_t boot_cpuid_phys; /* Which physical CPU id we're - booting on */ - /* version 3 fields below */ - uint32_t size_dt_strings; /* size of the strings block */ - - /* version 17 fields below */ - uint32_t size_dt_struct; /* size of the structure block */ -}; - -struct fdt_reserve_entry { - uint64_t address; - uint64_t size; -}; - -struct fdt_node_header { - uint32_t tag; - char name[0]; -}; - -struct fdt_property { - uint32_t tag; - uint32_t len; - uint32_t nameoff; - char data[0]; -}; - -#endif /* !__ASSEMBLY */ - -#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -#define FDT_TAGSIZE sizeof(uint32_t) - -#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ -#define FDT_END_NODE 0x2 /* End node */ -#define FDT_PROP 0x3 /* Property: name off, - size, content */ -#define FDT_NOP 0x4 /* nop */ -#define FDT_END 0x9 - -#define FDT_V1_SIZE (7*sizeof(uint32_t)) -#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) -#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) -#define FDT_V16_SIZE FDT_V3_SIZE -#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) - -#endif /* _FDT_H */ diff --git a/recovery/fdt/fdt_empty_tree.c b/recovery/fdt/fdt_empty_tree.c deleted file mode 100644 index f72d13b..0000000 --- a/recovery/fdt/fdt_empty_tree.c +++ b/dev/null @@ -1,84 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2012 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -int fdt_create_empty_tree(void *buf, int bufsize) -{ - int err; - - err = fdt_create(buf, bufsize); - if (err) - return err; - - err = fdt_finish_reservemap(buf); - if (err) - return err; - - err = fdt_begin_node(buf, ""); - if (err) - return err; - - err = fdt_end_node(buf); - if (err) - return err; - - err = fdt_finish(buf); - if (err) - return err; - - return fdt_open_into(buf, buf, bufsize); -} - diff --git a/recovery/fdt/fdt_ro.c b/recovery/fdt/fdt_ro.c deleted file mode 100644 index 02b6d68..0000000 --- a/recovery/fdt/fdt_ro.c +++ b/dev/null @@ -1,574 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -static int _fdt_nodename_eq(const void *fdt, int offset, - const char *s, int len) -{ - const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); - - if (! p) - /* short match */ - return 0; - - if (memcmp(p, s, len) != 0) - return 0; - - if (p[len] == '\0') - return 1; - else if (!memchr(s, '@', len) && (p[len] == '@')) - return 1; - else - return 0; -} - -const char *fdt_string(const void *fdt, int stroffset) -{ - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -} - -static int _fdt_string_eq(const void *fdt, int stroffset, - const char *s, int len) -{ - const char *p = fdt_string(fdt, stroffset); - - return (strlen(p) == len) && (memcmp(p, s, len) == 0); -} - -int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) -{ - FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); - *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); - return 0; -} - -int fdt_num_mem_rsv(const void *fdt) -{ - int i = 0; - - while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) - i++; - return i; -} - -static int _nextprop(const void *fdt, int offset) -{ - uint32_t tag; - int nextoffset; - - do { - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_END: - if (nextoffset >= 0) - return -FDT_ERR_BADSTRUCTURE; - else - return nextoffset; - - case FDT_PROP: - return offset; - } - offset = nextoffset; - } while (tag == FDT_NOP); - - return -FDT_ERR_NOTFOUND; -} - -int fdt_subnode_offset_namelen(const void *fdt, int offset, - const char *name, int namelen) -{ - int depth; - - FDT_CHECK_HEADER(fdt); - - for (depth = 0; - (offset >= 0) && (depth >= 0); - offset = fdt_next_node(fdt, offset, &depth)) - if ((depth == 1) - && _fdt_nodename_eq(fdt, offset, name, namelen)) - return offset; - - if (depth < 0) - return -FDT_ERR_NOTFOUND; - return offset; /* error */ -} - -int fdt_subnode_offset(const void *fdt, int parentoffset, - const char *name) -{ - return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); -} - -int fdt_path_offset(const void *fdt, const char *path) -{ - const char *end = path + strlen(path); - const char *p = path; - int offset = 0; - - FDT_CHECK_HEADER(fdt); - - /* see if we have an alias */ - if (*path != '/') { - const char *q = strchr(path, '/'); - - if (!q) - q = end; - - p = fdt_get_alias_namelen(fdt, p, q - p); - if (!p) - return -FDT_ERR_BADPATH; - offset = fdt_path_offset(fdt, p); - - p = q; - } - - while (*p) { - const char *q; - - while (*p == '/') - p++; - if (! *p) - return offset; - q = strchr(p, '/'); - if (! q) - q = end; - - offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); - if (offset < 0) - return offset; - - p = q; - } - - return offset; -} - -const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) -{ - const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); - int err; - - if (((err = fdt_check_header(fdt)) != 0) - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) - goto fail; - - if (len) - *len = strlen(nh->name); - - return nh->name; - - fail: - if (len) - *len = err; - return NULL; -} - -int fdt_first_property_offset(const void *fdt, int nodeoffset) -{ - int offset; - - if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) - return offset; - - return _nextprop(fdt, offset); -} - -int fdt_next_property_offset(const void *fdt, int offset) -{ - if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) - return offset; - - return _nextprop(fdt, offset); -} - -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - int offset, - int *lenp) -{ - int err; - const struct fdt_property *prop; - - if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { - if (lenp) - *lenp = err; - return NULL; - } - - prop = _fdt_offset_ptr(fdt, offset); - - if (lenp) - *lenp = fdt32_to_cpu(prop->len); - - return prop; -} - -const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int offset, - const char *name, - int namelen, int *lenp) -{ - for (offset = fdt_first_property_offset(fdt, offset); - (offset >= 0); - (offset = fdt_next_property_offset(fdt, offset))) { - const struct fdt_property *prop; - - if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { - offset = -FDT_ERR_INTERNAL; - break; - } - if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), - name, namelen)) - return prop; - } - - if (lenp) - *lenp = offset; - return NULL; -} - -const struct fdt_property *fdt_get_property(const void *fdt, - int nodeoffset, - const char *name, int *lenp) -{ - return fdt_get_property_namelen(fdt, nodeoffset, name, - strlen(name), lenp); -} - -const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp) -{ - const struct fdt_property *prop; - - prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); - if (! prop) - return NULL; - - return prop->data; -} - -const void *fdt_getprop_by_offset(const void *fdt, int offset, - const char **namep, int *lenp) -{ - const struct fdt_property *prop; - - prop = fdt_get_property_by_offset(fdt, offset, lenp); - if (!prop) - return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - return prop->data; -} - -const void *fdt_getprop(const void *fdt, int nodeoffset, - const char *name, int *lenp) -{ - return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); -} - -uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) -{ - const uint32_t *php; - int len; - - /* FIXME: This is a bit sub-optimal, since we potentially scan - * over all the properties twice. */ - php = fdt_getprop(fdt, nodeoffset, "phandle", &len); - if (!php || (len != sizeof(*php))) { - php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); - if (!php || (len != sizeof(*php))) - return 0; - } - - return fdt32_to_cpu(*php); -} - -const char *fdt_get_alias_namelen(const void *fdt, - const char *name, int namelen) -{ - int aliasoffset; - - aliasoffset = fdt_path_offset(fdt, "/aliases"); - if (aliasoffset < 0) - return NULL; - - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); -} - -const char *fdt_get_alias(const void *fdt, const char *name) -{ - return fdt_get_alias_namelen(fdt, name, strlen(name)); -} - -int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) -{ - int pdepth = 0, p = 0; - int offset, depth, namelen; - const char *name; - - FDT_CHECK_HEADER(fdt); - - if (buflen < 2) - return -FDT_ERR_NOSPACE; - - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - while (pdepth > depth) { - do { - p--; - } while (buf[p-1] != '/'); - pdepth--; - } - - if (pdepth >= depth) { - name = fdt_get_name(fdt, offset, &namelen); - if (!name) - return namelen; - if ((p + namelen + 1) <= buflen) { - memcpy(buf + p, name, namelen); - p += namelen; - buf[p++] = '/'; - pdepth++; - } - } - - if (offset == nodeoffset) { - if (pdepth < (depth + 1)) - return -FDT_ERR_NOSPACE; - - if (p > 1) /* special case so that root path is "/", not "" */ - p--; - buf[p] = '\0'; - return 0; - } - } - - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; - - return offset; /* error from fdt_next_node() */ -} - -int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - int supernodedepth, int *nodedepth) -{ - int offset, depth; - int supernodeoffset = -FDT_ERR_INTERNAL; - - FDT_CHECK_HEADER(fdt); - - if (supernodedepth < 0) - return -FDT_ERR_NOTFOUND; - - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - if (depth == supernodedepth) - supernodeoffset = offset; - - if (offset == nodeoffset) { - if (nodedepth) - *nodedepth = depth; - - if (supernodedepth > depth) - return -FDT_ERR_NOTFOUND; - else - return supernodeoffset; - } - } - - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; - - return offset; /* error from fdt_next_node() */ -} - -int fdt_node_depth(const void *fdt, int nodeoffset) -{ - int nodedepth; - int err; - - err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); - if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; - return nodedepth; -} - -int fdt_parent_offset(const void *fdt, int nodeoffset) -{ - int nodedepth = fdt_node_depth(fdt, nodeoffset); - - if (nodedepth < 0) - return nodedepth; - return fdt_supernode_atdepth_offset(fdt, nodeoffset, - nodedepth - 1, NULL); -} - -int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, - const char *propname, - const void *propval, int proplen) -{ - int offset; - const void *val; - int len; - - FDT_CHECK_HEADER(fdt); - - /* FIXME: The algorithm here is pretty horrible: we scan each - * property of a node in fdt_getprop(), then if that didn't - * find what we want, we scan over them again making our way - * to the next node. Still it's the easiest to implement - * approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - val = fdt_getprop(fdt, offset, propname, &len); - if (val && (len == proplen) - && (memcmp(val, propval, len) == 0)) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} - -int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) -{ - int offset; - - if ((phandle == 0) || (phandle == -1)) - return -FDT_ERR_BADPHANDLE; - - FDT_CHECK_HEADER(fdt); - - /* FIXME: The algorithm here is pretty horrible: we - * potentially scan each property of a node in - * fdt_get_phandle(), then if that didn't find what - * we want, we scan over them again making our way to the next - * node. Still it's the easiest to implement approach; - * performance can come later. */ - for (offset = fdt_next_node(fdt, -1, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - if (fdt_get_phandle(fdt, offset) == phandle) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} - -static int _fdt_stringlist_contains(const char *strlist, int listlen, - const char *str) -{ - int len = strlen(str); - const char *p; - - while (listlen >= len) { - if (memcmp(str, strlist, len+1) == 0) - return 1; - p = memchr(strlist, '\0', listlen); - if (!p) - return 0; /* malformed strlist.. */ - listlen -= (p-strlist) + 1; - strlist = p + 1; - } - return 0; -} - -int fdt_node_check_compatible(const void *fdt, int nodeoffset, - const char *compatible) -{ - const void *prop; - int len; - - prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); - if (!prop) - return len; - if (_fdt_stringlist_contains(prop, len, compatible)) - return 0; - else - return 1; -} - -int fdt_node_offset_by_compatible(const void *fdt, int startoffset, - const char *compatible) -{ - int offset, err; - - FDT_CHECK_HEADER(fdt); - - /* FIXME: The algorithm here is pretty horrible: we scan each - * property of a node in fdt_node_check_compatible(), then if - * that didn't find what we want, we scan over them again - * making our way to the next node. Still it's the easiest to - * implement approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - err = fdt_node_check_compatible(fdt, offset, compatible); - if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) - return err; - else if (err == 0) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} diff --git a/recovery/fdt/fdt_rw.c b/recovery/fdt/fdt_rw.c deleted file mode 100644 index 24437df..0000000 --- a/recovery/fdt/fdt_rw.c +++ b/dev/null @@ -1,492 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -static int _fdt_blocks_misordered(const void *fdt, - int mem_rsv_size, int struct_size) -{ - return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) - || (fdt_off_dt_struct(fdt) < - (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) - || (fdt_off_dt_strings(fdt) < - (fdt_off_dt_struct(fdt) + struct_size)) - || (fdt_totalsize(fdt) < - (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); -} - -static int _fdt_rw_check_header(void *fdt) -{ - FDT_CHECK_HEADER(fdt); - - if (fdt_version(fdt) < 17) - return -FDT_ERR_BADVERSION; - if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), - fdt_size_dt_struct(fdt))) - return -FDT_ERR_BADLAYOUT; - if (fdt_version(fdt) > 17) - fdt_set_version(fdt, 17); - - return 0; -} - -#define FDT_RW_CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = _fdt_rw_check_header(fdt)) != 0) \ - return err; \ - } - -static inline int _fdt_data_size(void *fdt) -{ - return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); -} - -static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) -{ - char *p = splicepoint; - char *end = (char *)fdt + _fdt_data_size(fdt); - - if (((p + oldlen) < p) || ((p + oldlen) > end)) - return -FDT_ERR_BADOFFSET; - if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) - return -FDT_ERR_NOSPACE; - memmove(p + newlen, p + oldlen, end - p - oldlen); - return 0; -} - -static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, - int oldn, int newn) -{ - int delta = (newn - oldn) * sizeof(*p); - int err; - err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); - if (err) - return err; - fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); - fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); - return 0; -} - -static int _fdt_splice_struct(void *fdt, void *p, - int oldlen, int newlen) -{ - int delta = newlen - oldlen; - int err; - - if ((err = _fdt_splice(fdt, p, oldlen, newlen))) - return err; - - fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); - fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); - return 0; -} - -static int _fdt_splice_string(void *fdt, int newlen) -{ - void *p = (char *)fdt - + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); - int err; - - if ((err = _fdt_splice(fdt, p, 0, newlen))) - return err; - - fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); - return 0; -} - -static int _fdt_find_add_string(void *fdt, const char *s) -{ - char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); - const char *p; - char *new; - int len = strlen(s) + 1; - int err; - - p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); - if (p) - /* found it */ - return (p - strtab); - - new = strtab + fdt_size_dt_strings(fdt); - err = _fdt_splice_string(fdt, len); - if (err) - return err; - - memcpy(new, s, len); - return (new - strtab); -} - -int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) -{ - struct fdt_reserve_entry *re; - int err; - - FDT_RW_CHECK_HEADER(fdt); - - re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); - err = _fdt_splice_mem_rsv(fdt, re, 0, 1); - if (err) - return err; - - re->address = cpu_to_fdt64(address); - re->size = cpu_to_fdt64(size); - return 0; -} - -int fdt_del_mem_rsv(void *fdt, int n) -{ - struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); - int err; - - FDT_RW_CHECK_HEADER(fdt); - - if (n >= fdt_num_mem_rsv(fdt)) - return -FDT_ERR_NOTFOUND; - - err = _fdt_splice_mem_rsv(fdt, re, 1, 0); - if (err) - return err; - return 0; -} - -static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) -{ - int oldlen; - int err; - - *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); - if (! (*prop)) - return oldlen; - - if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), - FDT_TAGALIGN(len)))) - return err; - - (*prop)->len = cpu_to_fdt32(len); - return 0; -} - -static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) -{ - int proplen; - int nextoffset; - int namestroff; - int err; - - if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) - return nextoffset; - - namestroff = _fdt_find_add_string(fdt, name); - if (namestroff < 0) - return namestroff; - - *prop = _fdt_offset_ptr_w(fdt, nextoffset); - proplen = sizeof(**prop) + FDT_TAGALIGN(len); - - err = _fdt_splice_struct(fdt, *prop, 0, proplen); - if (err) - return err; - - (*prop)->tag = cpu_to_fdt32(FDT_PROP); - (*prop)->nameoff = cpu_to_fdt32(namestroff); - (*prop)->len = cpu_to_fdt32(len); - return 0; -} - -int fdt_set_name(void *fdt, int nodeoffset, const char *name) -{ - char *namep; - int oldlen, newlen; - int err; - - FDT_RW_CHECK_HEADER(fdt); - - namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); - if (!namep) - return oldlen; - - newlen = strlen(name); - - err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), - FDT_TAGALIGN(newlen+1)); - if (err) - return err; - - memcpy(namep, name, newlen+1); - return 0; -} - -int fdt_setprop(void *fdt, int nodeoffset, const char *name, - const void *val, int len) -{ - struct fdt_property *prop; - int err; - - FDT_RW_CHECK_HEADER(fdt); - - err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); - if (err == -FDT_ERR_NOTFOUND) - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); - if (err) - return err; - - memcpy(prop->data, val, len); - return 0; -} - -int fdt_appendprop(void *fdt, int nodeoffset, const char *name, - const void *val, int len) -{ - struct fdt_property *prop; - int err, oldlen, newlen; - - FDT_RW_CHECK_HEADER(fdt); - - prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); - if (prop) { - newlen = len + oldlen; - err = _fdt_splice_struct(fdt, prop->data, - FDT_TAGALIGN(oldlen), - FDT_TAGALIGN(newlen)); - if (err) - return err; - prop->len = cpu_to_fdt32(newlen); - memcpy(prop->data + oldlen, val, len); - } else { - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); - if (err) - return err; - memcpy(prop->data, val, len); - } - return 0; -} - -int fdt_delprop(void *fdt, int nodeoffset, const char *name) -{ - struct fdt_property *prop; - int len, proplen; - - FDT_RW_CHECK_HEADER(fdt); - - prop = fdt_get_property_w(fdt, nodeoffset, name, &len); - if (! prop) - return len; - - proplen = sizeof(*prop) + FDT_TAGALIGN(len); - return _fdt_splice_struct(fdt, prop, proplen, 0); -} - -int fdt_add_subnode_namelen(void *fdt, int parentoffset, - const char *name, int namelen) -{ - struct fdt_node_header *nh; - int offset, nextoffset; - int nodelen; - int err; - uint32_t tag; - uint32_t *endtag; - - FDT_RW_CHECK_HEADER(fdt); - - offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); - if (offset >= 0) - return -FDT_ERR_EXISTS; - else if (offset != -FDT_ERR_NOTFOUND) - return offset; - - /* Try to place the new node after the parent's properties */ - fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - } while ((tag == FDT_PROP) || (tag == FDT_NOP)); - - nh = _fdt_offset_ptr_w(fdt, offset); - nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; - - err = _fdt_splice_struct(fdt, nh, 0, nodelen); - if (err) - return err; - - nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); - memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); - memcpy(nh->name, name, namelen); - endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE); - *endtag = cpu_to_fdt32(FDT_END_NODE); - - return offset; -} - -int fdt_add_subnode(void *fdt, int parentoffset, const char *name) -{ - return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); -} - -int fdt_del_node(void *fdt, int nodeoffset) -{ - int endoffset; - - FDT_RW_CHECK_HEADER(fdt); - - endoffset = _fdt_node_end_offset(fdt, nodeoffset); - if (endoffset < 0) - return endoffset; - - return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), - endoffset - nodeoffset, 0); -} - -static void _fdt_packblocks(const char *old, char *new, - int mem_rsv_size, int struct_size) -{ - int mem_rsv_off, struct_off, strings_off; - - mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); - struct_off = mem_rsv_off + mem_rsv_size; - strings_off = struct_off + struct_size; - - memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); - fdt_set_off_mem_rsvmap(new, mem_rsv_off); - - memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); - fdt_set_off_dt_struct(new, struct_off); - fdt_set_size_dt_struct(new, struct_size); - - memmove(new + strings_off, old + fdt_off_dt_strings(old), - fdt_size_dt_strings(old)); - fdt_set_off_dt_strings(new, strings_off); - fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); -} - -int fdt_open_into(const void *fdt, void *buf, int bufsize) -{ - int err; - int mem_rsv_size, struct_size; - int newsize; - const char *fdtstart = fdt; - const char *fdtend = fdtstart + fdt_totalsize(fdt); - char *tmp; - - FDT_CHECK_HEADER(fdt); - - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) - * sizeof(struct fdt_reserve_entry); - - if (fdt_version(fdt) >= 17) { - struct_size = fdt_size_dt_struct(fdt); - } else { - struct_size = 0; - while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) - ; - if (struct_size < 0) - return struct_size; - } - - if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { - /* no further work necessary */ - err = fdt_move(fdt, buf, bufsize); - if (err) - return err; - fdt_set_version(buf, 17); - fdt_set_size_dt_struct(buf, struct_size); - fdt_set_totalsize(buf, bufsize); - return 0; - } - - /* Need to reorder */ - newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size - + struct_size + fdt_size_dt_strings(fdt); - - if (bufsize < newsize) - return -FDT_ERR_NOSPACE; - - /* First attempt to build converted tree at beginning of buffer */ - tmp = buf; - /* But if that overlaps with the old tree... */ - if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { - /* Try right after the old tree instead */ - tmp = (char *)(uintptr_t)fdtend; - if ((tmp + newsize) > ((char *)buf + bufsize)) - return -FDT_ERR_NOSPACE; - } - - _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); - memmove(buf, tmp, newsize); - - fdt_set_magic(buf, FDT_MAGIC); - fdt_set_totalsize(buf, bufsize); - fdt_set_version(buf, 17); - fdt_set_last_comp_version(buf, 16); - fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); - - return 0; -} - -int fdt_pack(void *fdt) -{ - int mem_rsv_size; - - FDT_RW_CHECK_HEADER(fdt); - - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) - * sizeof(struct fdt_reserve_entry); - _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); - fdt_set_totalsize(fdt, _fdt_data_size(fdt)); - - return 0; -} diff --git a/recovery/fdt/fdt_strerror.c b/recovery/fdt/fdt_strerror.c deleted file mode 100644 index e6c3cee..0000000 --- a/recovery/fdt/fdt_strerror.c +++ b/dev/null @@ -1,96 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -struct fdt_errtabent { - const char *str; -}; - -#define FDT_ERRTABENT(val) \ - [(val)] = { .str = #val, } - -static struct fdt_errtabent fdt_errtable[] = { - FDT_ERRTABENT(FDT_ERR_NOTFOUND), - FDT_ERRTABENT(FDT_ERR_EXISTS), - FDT_ERRTABENT(FDT_ERR_NOSPACE), - - FDT_ERRTABENT(FDT_ERR_BADOFFSET), - FDT_ERRTABENT(FDT_ERR_BADPATH), - FDT_ERRTABENT(FDT_ERR_BADSTATE), - - FDT_ERRTABENT(FDT_ERR_TRUNCATED), - FDT_ERRTABENT(FDT_ERR_BADMAGIC), - FDT_ERRTABENT(FDT_ERR_BADVERSION), - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), - FDT_ERRTABENT(FDT_ERR_BADLAYOUT), -}; -#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) - -const char *fdt_strerror(int errval) -{ - if (errval > 0) - return ""; - else if (errval == 0) - return ""; - else if (errval > -FDT_ERRTABSIZE) { - const char *s = fdt_errtable[-errval].str; - - if (s) - return s; - } - - return ""; -} diff --git a/recovery/fdt/fdt_sw.c b/recovery/fdt/fdt_sw.c deleted file mode 100644 index 55ebebf..0000000 --- a/recovery/fdt/fdt_sw.c +++ b/dev/null @@ -1,256 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -static int _fdt_sw_check_header(void *fdt) -{ - if (fdt_magic(fdt) != FDT_SW_MAGIC) - return -FDT_ERR_BADMAGIC; - /* FIXME: should check more details about the header state */ - return 0; -} - -#define FDT_SW_CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = _fdt_sw_check_header(fdt)) != 0) \ - return err; \ - } - -static void *_fdt_grab_space(void *fdt, size_t len) -{ - int offset = fdt_size_dt_struct(fdt); - int spaceleft; - - spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) - - fdt_size_dt_strings(fdt); - - if ((offset + len < offset) || (offset + len > spaceleft)) - return NULL; - - fdt_set_size_dt_struct(fdt, offset + len); - return _fdt_offset_ptr_w(fdt, offset); -} - -int fdt_create(void *buf, int bufsize) -{ - void *fdt = buf; - - if (bufsize < sizeof(struct fdt_header)) - return -FDT_ERR_NOSPACE; - - memset(buf, 0, bufsize); - - fdt_set_magic(fdt, FDT_SW_MAGIC); - fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); - fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); - fdt_set_totalsize(fdt, bufsize); - - fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), - sizeof(struct fdt_reserve_entry))); - fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); - fdt_set_off_dt_strings(fdt, bufsize); - - return 0; -} - -int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) -{ - struct fdt_reserve_entry *re; - int offset; - - FDT_SW_CHECK_HEADER(fdt); - - if (fdt_size_dt_struct(fdt)) - return -FDT_ERR_BADSTATE; - - offset = fdt_off_dt_struct(fdt); - if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) - return -FDT_ERR_NOSPACE; - - re = (struct fdt_reserve_entry *)((char *)fdt + offset); - re->address = cpu_to_fdt64(addr); - re->size = cpu_to_fdt64(size); - - fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); - - return 0; -} - -int fdt_finish_reservemap(void *fdt) -{ - return fdt_add_reservemap_entry(fdt, 0, 0); -} - -int fdt_begin_node(void *fdt, const char *name) -{ - struct fdt_node_header *nh; - int namelen = strlen(name) + 1; - - FDT_SW_CHECK_HEADER(fdt); - - nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); - if (! nh) - return -FDT_ERR_NOSPACE; - - nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); - memcpy(nh->name, name, namelen); - return 0; -} - -int fdt_end_node(void *fdt) -{ - uint32_t *en; - - FDT_SW_CHECK_HEADER(fdt); - - en = _fdt_grab_space(fdt, FDT_TAGSIZE); - if (! en) - return -FDT_ERR_NOSPACE; - - *en = cpu_to_fdt32(FDT_END_NODE); - return 0; -} - -static int _fdt_find_add_string(void *fdt, const char *s) -{ - char *strtab = (char *)fdt + fdt_totalsize(fdt); - const char *p; - int strtabsize = fdt_size_dt_strings(fdt); - int len = strlen(s) + 1; - int struct_top, offset; - - p = _fdt_find_string(strtab - strtabsize, strtabsize, s); - if (p) - return p - strtab; - - /* Add it */ - offset = -strtabsize - len; - struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); - if (fdt_totalsize(fdt) + offset < struct_top) - return 0; /* no more room :( */ - - memcpy(strtab + offset, s, len); - fdt_set_size_dt_strings(fdt, strtabsize + len); - return offset; -} - -int fdt_property(void *fdt, const char *name, const void *val, int len) -{ - struct fdt_property *prop; - int nameoff; - - FDT_SW_CHECK_HEADER(fdt); - - nameoff = _fdt_find_add_string(fdt, name); - if (nameoff == 0) - return -FDT_ERR_NOSPACE; - - prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); - if (! prop) - return -FDT_ERR_NOSPACE; - - prop->tag = cpu_to_fdt32(FDT_PROP); - prop->nameoff = cpu_to_fdt32(nameoff); - prop->len = cpu_to_fdt32(len); - memcpy(prop->data, val, len); - return 0; -} - -int fdt_finish(void *fdt) -{ - char *p = (char *)fdt; - uint32_t *end; - int oldstroffset, newstroffset; - uint32_t tag; - int offset, nextoffset; - - FDT_SW_CHECK_HEADER(fdt); - - /* Add terminator */ - end = _fdt_grab_space(fdt, sizeof(*end)); - if (! end) - return -FDT_ERR_NOSPACE; - *end = cpu_to_fdt32(FDT_END); - - /* Relocate the string table */ - oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); - newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); - memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); - fdt_set_off_dt_strings(fdt, newstroffset); - - /* Walk the structure, correcting string offsets */ - offset = 0; - while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { - if (tag == FDT_PROP) { - struct fdt_property *prop = - _fdt_offset_ptr_w(fdt, offset); - int nameoff; - - nameoff = fdt32_to_cpu(prop->nameoff); - nameoff += fdt_size_dt_strings(fdt); - prop->nameoff = cpu_to_fdt32(nameoff); - } - offset = nextoffset; - } - if (nextoffset < 0) - return nextoffset; - - /* Finally, adjust the header */ - fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); - fdt_set_magic(fdt, FDT_MAGIC); - return 0; -} diff --git a/recovery/fdt/fdt_wip.c b/recovery/fdt/fdt_wip.c deleted file mode 100644 index 6025fa1..0000000 --- a/recovery/fdt/fdt_wip.c +++ b/dev/null @@ -1,118 +0,0 @@ -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "libfdt_env.h" - -#include -#include - -#include "libfdt_internal.h" - -int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, - const void *val, int len) -{ - void *propval; - int proplen; - - propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); - if (! propval) - return proplen; - - if (proplen != len) - return -FDT_ERR_NOSPACE; - - memcpy(propval, val, len); - return 0; -} - -static void _fdt_nop_region(void *start, int len) -{ - uint32_t *p; - - for (p = start; (char *)p < ((char *)start + len); p++) - *p = cpu_to_fdt32(FDT_NOP); -} - -int fdt_nop_property(void *fdt, int nodeoffset, const char *name) -{ - struct fdt_property *prop; - int len; - - prop = fdt_get_property_w(fdt, nodeoffset, name, &len); - if (! prop) - return len; - - _fdt_nop_region(prop, len + sizeof(*prop)); - - return 0; -} - -int _fdt_node_end_offset(void *fdt, int offset) -{ - int depth = 0; - - while ((offset >= 0) && (depth >= 0)) - offset = fdt_next_node(fdt, offset, &depth); - - return offset; -} - -int fdt_nop_node(void *fdt, int nodeoffset) -{ - int endoffset; - - endoffset = _fdt_node_end_offset(fdt, nodeoffset); - if (endoffset < 0) - return endoffset; - - _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), - endoffset - nodeoffset); - return 0; -} diff --git a/recovery/fdt/libfdt.h b/recovery/fdt/libfdt.h deleted file mode 100644 index ea1ddcd..0000000 --- a/recovery/fdt/libfdt.h +++ b/dev/null @@ -1,1478 +0,0 @@ -#ifndef _LIBFDT_H -#define _LIBFDT_H -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "libfdt_env.h" -#include "fdt.h" - -#define FDT_FIRST_SUPPORTED_VERSION 0x10 -#define FDT_LAST_SUPPORTED_VERSION 0x11 - -/* Error codes: informative error codes */ -#define FDT_ERR_NOTFOUND 1 - /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ -#define FDT_ERR_EXISTS 2 - /* FDT_ERR_EXISTS: Attemped to create a node or property which - * already exists */ -#define FDT_ERR_NOSPACE 3 - /* FDT_ERR_NOSPACE: Operation needed to expand the device - * tree, but its buffer did not have sufficient space to - * contain the expanded tree. Use fdt_open_into() to move the - * device tree to a buffer with more space. */ - -/* Error codes: codes for bad parameters */ -#define FDT_ERR_BADOFFSET 4 - /* FDT_ERR_BADOFFSET: Function was passed a structure block - * offset which is out-of-bounds, or which points to an - * unsuitable part of the structure for the operation. */ -#define FDT_ERR_BADPATH 5 - /* FDT_ERR_BADPATH: Function was passed a badly formatted path - * (e.g. missing a leading / for a function which requires an - * absolute path) */ -#define FDT_ERR_BADPHANDLE 6 - /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle - * value. phandle values of 0 and -1 are not permitted. */ -#define FDT_ERR_BADSTATE 7 - /* FDT_ERR_BADSTATE: Function was passed an incomplete device - * tree created by the sequential-write functions, which is - * not sufficiently complete for the requested operation. */ - -/* Error codes: codes for bad device tree blobs */ -#define FDT_ERR_TRUNCATED 8 - /* FDT_ERR_TRUNCATED: Structure block of the given device tree - * ends without an FDT_END tag. */ -#define FDT_ERR_BADMAGIC 9 - /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a - * device tree at all - it is missing the flattened device - * tree magic number. */ -#define FDT_ERR_BADVERSION 10 - /* FDT_ERR_BADVERSION: Given device tree has a version which - * can't be handled by the requested operation. For - * read-write functions, this may mean that fdt_open_into() is - * required to convert the tree to the expected version. */ -#define FDT_ERR_BADSTRUCTURE 11 - /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt - * structure block or other serious error (e.g. misnested - * nodes, or subnodes preceding properties). */ -#define FDT_ERR_BADLAYOUT 12 - /* FDT_ERR_BADLAYOUT: For read-write functions, the given - * device tree has it's sub-blocks in an order that the - * function can't handle (memory reserve map, then structure, - * then strings). Use fdt_open_into() to reorganize the tree - * into a form suitable for the read-write operations. */ - -/* "Can't happen" error indicating a bug in libfdt */ -#define FDT_ERR_INTERNAL 13 - /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. - * Should never be returned, if it is, it indicates a bug in - * libfdt itself. */ - -#define FDT_ERR_MAX 13 - -/**********************************************************************/ -/* Low-level functions (you probably don't need these) */ -/**********************************************************************/ - -const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); -static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) -{ - return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); -} - -uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); - -/**********************************************************************/ -/* Traversal functions */ -/**********************************************************************/ - -int fdt_next_node(const void *fdt, int offset, int *depth); - -/**********************************************************************/ -/* General functions */ -/**********************************************************************/ - -#define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) -#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) -#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) -#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) -#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) -#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) -#define fdt_version(fdt) (fdt_get_header(fdt, version)) -#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) -#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) - -#define __fdt_set_hdr(name) \ - static inline void fdt_set_##name(void *fdt, uint32_t val) \ - { \ - struct fdt_header *fdth = (struct fdt_header*)fdt; \ - fdth->name = cpu_to_fdt32(val); \ - } -__fdt_set_hdr(magic); -__fdt_set_hdr(totalsize); -__fdt_set_hdr(off_dt_struct); -__fdt_set_hdr(off_dt_strings); -__fdt_set_hdr(off_mem_rsvmap); -__fdt_set_hdr(version); -__fdt_set_hdr(last_comp_version); -__fdt_set_hdr(boot_cpuid_phys); -__fdt_set_hdr(size_dt_strings); -__fdt_set_hdr(size_dt_struct); -#undef __fdt_set_hdr - -/** - * fdt_check_header - sanity check a device tree or possible device tree - * @fdt: pointer to data which might be a flattened device tree - * - * fdt_check_header() checks that the given buffer contains what - * appears to be a flattened device tree with sane information in its - * header. - * - * returns: - * 0, if the buffer appears to contain a valid device tree - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings, as above - */ -int fdt_check_header(const void *fdt); - -/** - * fdt_move - move a device tree around in memory - * @fdt: pointer to the device tree to move - * @buf: pointer to memory where the device is to be moved - * @bufsize: size of the memory space at buf - * - * fdt_move() relocates, if possible, the device tree blob located at - * fdt to the buffer at buf of size bufsize. The buffer may overlap - * with the existing device tree blob at fdt. Therefore, - * fdt_move(fdt, fdt, fdt_totalsize(fdt)) - * should always succeed. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings - */ -int fdt_move(const void *fdt, void *buf, int bufsize); - -/**********************************************************************/ -/* Read-only functions */ -/**********************************************************************/ - -/** - * fdt_string - retrieve a string from the strings block of a device tree - * @fdt: pointer to the device tree blob - * @stroffset: offset of the string within the strings block (native endian) - * - * fdt_string() retrieves a pointer to a single string from the - * strings block of the device tree blob at fdt. - * - * returns: - * a pointer to the string, on success - * NULL, if stroffset is out of bounds - */ -const char *fdt_string(const void *fdt, int stroffset); - -/** - * fdt_num_mem_rsv - retrieve the number of memory reserve map entries - * @fdt: pointer to the device tree blob - * - * Returns the number of entries in the device tree blob's memory - * reservation map. This does not include the terminating 0,0 entry - * or any other (0,0) entries reserved for expansion. - * - * returns: - * the number of entries - */ -int fdt_num_mem_rsv(const void *fdt); - -/** - * fdt_get_mem_rsv - retrieve one memory reserve map entry - * @fdt: pointer to the device tree blob - * @address, @size: pointers to 64-bit variables - * - * On success, *address and *size will contain the address and size of - * the n-th reserve map entry from the device tree blob, in - * native-endian format. - * - * returns: - * 0, on success - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings - */ -int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); - -/** - * fdt_subnode_offset_namelen - find a subnode based on substring - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * @namelen: number of characters of name to consider - * - * Identical to fdt_subnode_offset(), but only examine the first - * namelen characters of name for matching the subnode name. This is - * useful for finding subnodes based on a portion of a larger string, - * such as a full path. - */ -int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - const char *name, int namelen); -/** - * fdt_subnode_offset - find a subnode of a given node - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * - * fdt_subnode_offset() finds a subnode of the node at structure block - * offset parentoffset with the given name. name may include a unit - * address, in which case fdt_subnode_offset() will find the subnode - * with that unit address, or the unit address may be omitted, in - * which case fdt_subnode_offset() will find an arbitrary subnode - * whose name excluding unit address matches the given name. - * - * returns: - * structure block offset of the requested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist - * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ -int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); - -/** - * fdt_path_offset - find a tree node by its full path - * @fdt: pointer to the device tree blob - * @path: full path of the node to locate - * - * fdt_path_offset() finds a node of a given path in the device tree. - * Each path component may omit the unit address portion, but the - * results of this are undefined if any such path component is - * ambiguous (that is if there are multiple nodes at the relevant - * level matching the given component, differentiated only by unit - * address). - * - * returns: - * structure block offset of the node with the requested path (>=0), on success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid - * -FDT_ERR_NOTFOUND, if the requested node does not exist - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ -int fdt_path_offset(const void *fdt, const char *path); - -/** - * fdt_get_name - retrieve the name of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: structure block offset of the starting node - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_get_name() retrieves the name (including unit address) of the - * device tree node at structure block offset nodeoffset. If lenp is - * non-NULL, the length of this name is also returned, in the integer - * pointed to by lenp. - * - * returns: - * pointer to the node's name, on success - * If lenp is non-NULL, *lenp contains the length of that name (>=0) - * NULL, on error - * if lenp is non-NULL *lenp contains an error code (<0): - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings - */ -const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); - -/** - * fdt_first_property_offset - find the offset of a node's first property - * @fdt: pointer to the device tree blob - * @nodeoffset: structure block offset of a node - * - * fdt_first_property_offset() finds the first property of the node at - * the given structure block offset. - * - * returns: - * structure block offset of the property (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested node has no properties - * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ -int fdt_first_property_offset(const void *fdt, int nodeoffset); - -/** - * fdt_next_property_offset - step through a node's properties - * @fdt: pointer to the device tree blob - * @offset: structure block offset of a property - * - * fdt_next_property_offset() finds the property immediately after the - * one at the given structure block offset. This will be a property - * of the same node as the given property. - * - * returns: - * structure block offset of the next property (>=0), on success - * -FDT_ERR_NOTFOUND, if the given property is the last in its node - * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ -int fdt_next_property_offset(const void *fdt, int offset); - -/** - * fdt_get_property_by_offset - retrieve the property at a given offset - * @fdt: pointer to the device tree blob - * @offset: offset of the property to retrieve - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_get_property_by_offset() retrieves a pointer to the - * fdt_property structure within the device tree blob at the given - * offset. If lenp is non-NULL, the length of the property value is - * also returned, in the integer pointed to by lenp. - * - * returns: - * pointer to the structure representing the property - * if lenp is non-NULL, *lenp contains the length of the property - * value (>=0) - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - int offset, - int *lenp); - -/** - * fdt_get_property_namelen - find a property based on substring - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to find - * @name: name of the property to find - * @namelen: number of characters of name to consider - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * Identical to fdt_get_property_namelen(), but only examine the first - * namelen characters of name for matching the property name. - */ -const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int nodeoffset, - const char *name, - int namelen, int *lenp); - -/** - * fdt_get_property - find a given property in a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to find - * @name: name of the property to find - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_get_property() retrieves a pointer to the fdt_property - * structure within the device tree blob corresponding to the property - * named 'name' of the node at offset nodeoffset. If lenp is - * non-NULL, the length of the property value is also returned, in the - * integer pointed to by lenp. - * - * returns: - * pointer to the structure representing the property - * if lenp is non-NULL, *lenp contains the length of the property - * value (>=0) - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, - const char *name, int *lenp); -static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, - const char *name, - int *lenp) -{ - return (struct fdt_property *)(uintptr_t) - fdt_get_property(fdt, nodeoffset, name, lenp); -} - -/** - * fdt_getprop_by_offset - retrieve the value of a property at a given offset - * @fdt: pointer to the device tree blob - * @ffset: offset of the property to read - * @namep: pointer to a string variable (will be overwritten) or NULL - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_getprop_by_offset() retrieves a pointer to the value of the - * property at structure block offset 'offset' (this will be a pointer - * to within the device blob itself, not a copy of the value). If - * lenp is non-NULL, the length of the property value is also - * returned, in the integer pointed to by lenp. If namep is non-NULL, - * the property's namne will also be returned in the char * pointed to - * by namep (this will be a pointer to within the device tree's string - * block, not a new copy of the name). - * - * returns: - * pointer to the property's value - * if lenp is non-NULL, *lenp contains the length of the property - * value (>=0) - * if namep is non-NULL *namep contiains a pointer to the property - * name. - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -const void *fdt_getprop_by_offset(const void *fdt, int offset, - const char **namep, int *lenp); - -/** - * fdt_getprop_namelen - get property value based on substring - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to find - * @name: name of the property to find - * @namelen: number of characters of name to consider - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * Identical to fdt_getprop(), but only examine the first namelen - * characters of name for matching the property name. - */ -const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp); - -/** - * fdt_getprop - retrieve the value of a given property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to find - * @name: name of the property to find - * @lenp: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_getprop() retrieves a pointer to the value of the property - * named 'name' of the node at offset nodeoffset (this will be a - * pointer to within the device blob itself, not a copy of the value). - * If lenp is non-NULL, the length of the property value is also - * returned, in the integer pointed to by lenp. - * - * returns: - * pointer to the property's value - * if lenp is non-NULL, *lenp contains the length of the property - * value (>=0) - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -const void *fdt_getprop(const void *fdt, int nodeoffset, - const char *name, int *lenp); -static inline void *fdt_getprop_w(void *fdt, int nodeoffset, - const char *name, int *lenp) -{ - return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); -} - -/** - * fdt_get_phandle - retrieve the phandle of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: structure block offset of the node - * - * fdt_get_phandle() retrieves the phandle of the device tree node at - * structure block offset nodeoffset. - * - * returns: - * the phandle of the node at nodeoffset, on success (!= 0, != -1) - * 0, if the node has no phandle, or another error occurs - */ -uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); - -/** - * fdt_get_alias_namelen - get alias based on substring - * @fdt: pointer to the device tree blob - * @name: name of the alias th look up - * @namelen: number of characters of name to consider - * - * Identical to fdt_get_alias(), but only examine the first namelen - * characters of name for matching the alias name. - */ -const char *fdt_get_alias_namelen(const void *fdt, - const char *name, int namelen); - -/** - * fdt_get_alias - retreive the path referenced by a given alias - * @fdt: pointer to the device tree blob - * @name: name of the alias th look up - * - * fdt_get_alias() retrieves the value of a given alias. That is, the - * value of the property named 'name' in the node /aliases. - * - * returns: - * a pointer to the expansion of the alias named 'name', of it exists - * NULL, if the given alias or the /aliases node does not exist - */ -const char *fdt_get_alias(const void *fdt, const char *name); - -/** - * fdt_get_path - determine the full path of a node - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose path to find - * @buf: character buffer to contain the returned path (will be overwritten) - * @buflen: size of the character buffer at buf - * - * fdt_get_path() computes the full path of the node at offset - * nodeoffset, and records that path in the buffer at buf. - * - * NOTE: This function is expensive, as it must scan the device tree - * structure from the start to nodeoffset. - * - * returns: - * 0, on success - * buf contains the absolute path of the node at - * nodeoffset, as a NUL-terminated string. - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) - * characters and will not fit in the given buffer. - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); - -/** - * fdt_supernode_atdepth_offset - find a specific ancestor of a node - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose parent to find - * @supernodedepth: depth of the ancestor to find - * @nodedepth: pointer to an integer variable (will be overwritten) or NULL - * - * fdt_supernode_atdepth_offset() finds an ancestor of the given node - * at a specific depth from the root (where the root itself has depth - * 0, its immediate subnodes depth 1 and so forth). So - * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); - * will always return 0, the offset of the root node. If the node at - * nodeoffset has depth D, then: - * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); - * will return nodeoffset itself. - * - * NOTE: This function is expensive, as it must scan the device tree - * structure from the start to nodeoffset. - * - * returns: - - * structure block offset of the node at node offset's ancestor - * of depth supernodedepth (>=0), on success - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - int supernodedepth, int *nodedepth); - -/** - * fdt_node_depth - find the depth of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose parent to find - * - * fdt_node_depth() finds the depth of a given node. The root node - * has depth 0, its immediate subnodes depth 1 and so forth. - * - * NOTE: This function is expensive, as it must scan the device tree - * structure from the start to nodeoffset. - * - * returns: - * depth of the node at nodeoffset (>=0), on success - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_node_depth(const void *fdt, int nodeoffset); - -/** - * fdt_parent_offset - find the parent of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose parent to find - * - * fdt_parent_offset() locates the parent node of a given node (that - * is, it finds the offset of the node which contains the node at - * nodeoffset as a subnode). - * - * NOTE: This function is expensive, as it must scan the device tree - * structure from the start to nodeoffset, *twice*. - * - * returns: - * structure block offset of the parent of the node at nodeoffset - * (>=0), on success - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_parent_offset(const void *fdt, int nodeoffset); - -/** - * fdt_node_offset_by_prop_value - find nodes with a given property value - * @fdt: pointer to the device tree blob - * @startoffset: only find nodes after this offset - * @propname: property name to check - * @propval: property value to search for - * @proplen: length of the value in propval - * - * fdt_node_offset_by_prop_value() returns the offset of the first - * node after startoffset, which has a property named propname whose - * value is of length proplen and has value equal to propval; or if - * startoffset is -1, the very first such node in the tree. - * - * To iterate through all nodes matching the criterion, the following - * idiom can be used: - * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, - * propval, proplen); - * while (offset != -FDT_ERR_NOTFOUND) { - * // other code here - * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, - * propval, proplen); - * } - * - * Note the -1 in the first call to the function, if 0 is used here - * instead, the function will never locate the root node, even if it - * matches the criterion. - * - * returns: - * structure block offset of the located node (>= 0, >startoffset), - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, - const char *propname, - const void *propval, int proplen); - -/** - * fdt_node_offset_by_phandle - find the node with a given phandle - * @fdt: pointer to the device tree blob - * @phandle: phandle value - * - * fdt_node_offset_by_phandle() returns the offset of the node - * which has the given phandle value. If there is more than one node - * in the tree with the given phandle (an invalid tree), results are - * undefined. - * - * returns: - * structure block offset of the located node (>= 0), on success - * -FDT_ERR_NOTFOUND, no node with that phandle exists - * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); - -/** - * fdt_node_check_compatible: check a node's compatible property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of a tree node - * @compatible: string to match against - * - * - * fdt_node_check_compatible() returns 0 if the given node contains a - * 'compatible' property with the given string as one of its elements, - * it returns non-zero otherwise, or on error. - * - * returns: - * 0, if the node has a 'compatible' property listing the given string - * 1, if the node has a 'compatible' property, but it does not list - * the given string - * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property - * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_node_check_compatible(const void *fdt, int nodeoffset, - const char *compatible); - -/** - * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value - * @fdt: pointer to the device tree blob - * @startoffset: only find nodes after this offset - * @compatible: 'compatible' string to match against - * - * fdt_node_offset_by_compatible() returns the offset of the first - * node after startoffset, which has a 'compatible' property which - * lists the given compatible string; or if startoffset is -1, the - * very first such node in the tree. - * - * To iterate through all nodes matching the criterion, the following - * idiom can be used: - * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); - * while (offset != -FDT_ERR_NOTFOUND) { - * // other code here - * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); - * } - * - * Note the -1 in the first call to the function, if 0 is used here - * instead, the function will never locate the root node, even if it - * matches the criterion. - * - * returns: - * structure block offset of the located node (>= 0, >startoffset), - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset - * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, standard meanings - */ -int fdt_node_offset_by_compatible(const void *fdt, int startoffset, - const char *compatible); - -/**********************************************************************/ -/* Write-in-place functions */ -/**********************************************************************/ - -/** - * fdt_setprop_inplace - change a property's value, but not its size - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: pointer to data to replace the property value with - * @len: length of the property value - * - * fdt_setprop_inplace() replaces the value of a given property with - * the data in val, of length len. This function cannot change the - * size of a property, and so will only work if len is equal to the - * current length of the property. - * - * This function will alter only the bytes in the blob which contain - * the given property value, and will not alter or move any other part - * of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, if len is not equal to the property's current length - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, - const void *val, int len); - -/** - * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 32-bit integer value to replace the property with - * - * fdt_setprop_inplace_u32() replaces the value of a given property - * with the 32-bit integer value in val, converting val to big-endian - * if necessary. This function cannot change the size of a property, - * and so will only work if the property already exists and has length - * 4. - * - * This function will alter only the bytes in the blob which contain - * the given property value, and will not alter or move any other part - * of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, - const char *name, uint32_t val) -{ - val = cpu_to_fdt32(val); - return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 64-bit integer value to replace the property with - * - * fdt_setprop_inplace_u64() replaces the value of a given property - * with the 64-bit integer value in val, converting val to big-endian - * if necessary. This function cannot change the size of a property, - * and so will only work if the property already exists and has length - * 8. - * - * This function will alter only the bytes in the blob which contain - * the given property value, and will not alter or move any other part - * of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, - const char *name, uint64_t val) -{ - val = cpu_to_fdt64(val); - return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_setprop_inplace_cell - change the value of a single-cell property - * - * This is an alternative name for fdt_setprop_inplace_u32() - */ -static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, - const char *name, uint32_t val) -{ - return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); -} - -/** - * fdt_nop_property - replace a property with nop tags - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to nop - * @name: name of the property to nop - * - * fdt_nop_property() will replace a given property's representation - * in the blob with FDT_NOP tags, effectively removing it from the - * tree. - * - * This function will alter only the bytes in the blob which contain - * the property, and will not alter or move any other part of the - * tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_nop_property(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_nop_node - replace a node (subtree) with nop tags - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node to nop - * - * fdt_nop_node() will replace a given node's representation in the - * blob, including all its subnodes, if any, with FDT_NOP tags, - * effectively removing it from the tree. - * - * This function will alter only the bytes in the blob which contain - * the node and its properties and subnodes, and will not alter or - * move any other part of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_nop_node(void *fdt, int nodeoffset); - -/**********************************************************************/ -/* Sequential write functions */ -/**********************************************************************/ - -int fdt_create(void *buf, int bufsize); -int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); -int fdt_finish_reservemap(void *fdt); -int fdt_begin_node(void *fdt, const char *name); -int fdt_property(void *fdt, const char *name, const void *val, int len); -static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) -{ - val = cpu_to_fdt32(val); - return fdt_property(fdt, name, &val, sizeof(val)); -} -static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) -{ - val = cpu_to_fdt64(val); - return fdt_property(fdt, name, &val, sizeof(val)); -} -static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) -{ - return fdt_property_u32(fdt, name, val); -} -#define fdt_property_string(fdt, name, str) \ - fdt_property(fdt, name, str, strlen(str)+1) -int fdt_end_node(void *fdt); -int fdt_finish(void *fdt); - -/**********************************************************************/ -/* Read-write functions */ -/**********************************************************************/ - -int fdt_create_empty_tree(void *buf, int bufsize); -int fdt_open_into(const void *fdt, void *buf, int bufsize); -int fdt_pack(void *fdt); - -/** - * fdt_add_mem_rsv - add one memory reserve map entry - * @fdt: pointer to the device tree blob - * @address, @size: 64-bit values (native endian) - * - * Adds a reserve map entry to the given blob reserving a region at - * address address of length size. - * - * This function will insert data into the reserve map and will - * therefore change the indexes of some entries in the table. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new reservation entry - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); - -/** - * fdt_del_mem_rsv - remove a memory reserve map entry - * @fdt: pointer to the device tree blob - * @n: entry to remove - * - * fdt_del_mem_rsv() removes the n-th memory reserve map entry from - * the blob. - * - * This function will delete data from the reservation table and will - * therefore change the indexes of some entries in the table. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there - * are less than n+1 reserve map entries) - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_del_mem_rsv(void *fdt, int n); - -/** - * fdt_set_name - change the name of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: structure block offset of a node - * @name: name to give the node - * - * fdt_set_name() replaces the name (including unit address, if any) - * of the given node with the given string. NOTE: this function can't - * efficiently check if the new name is unique amongst the given - * node's siblings; results are undefined if this function is invoked - * with a name equal to one of the given node's siblings. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob - * to contain the new name - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings - */ -int fdt_set_name(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_setprop - create or change a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: pointer to data to set the property value to - * @len: length of the property value - * - * fdt_setprop() sets the value of the named property in the given - * node to the given value and length, creating the property if it - * does not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_setprop(void *fdt, int nodeoffset, const char *name, - const void *val, int len); - -/** - * fdt_setprop_u32 - set a property to a 32-bit integer - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 32-bit integer value for the property (native endian) - * - * fdt_setprop_u32() sets the value of the named property in the given - * node to the given 32-bit integer value (converting to big-endian if - * necessary), or creates a new property with that value if it does - * not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, - uint32_t val) -{ - val = cpu_to_fdt32(val); - return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_setprop_u64 - set a property to a 64-bit integer - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 64-bit integer value for the property (native endian) - * - * fdt_setprop_u64() sets the value of the named property in the given - * node to the given 64-bit integer value (converting to big-endian if - * necessary), or creates a new property with that value if it does - * not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, - uint64_t val) -{ - val = cpu_to_fdt64(val); - return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_setprop_cell - set a property to a single cell value - * - * This is an alternative name for fdt_setprop_u32() - */ -static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, - uint32_t val) -{ - return fdt_setprop_u32(fdt, nodeoffset, name, val); -} - -/** - * fdt_setprop_string - set a property to a string value - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @str: string value for the property - * - * fdt_setprop_string() sets the value of the named property in the - * given node to the given string value (using the length of the - * string to determine the new length of the property), or creates a - * new property with that value if it does not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -#define fdt_setprop_string(fdt, nodeoffset, name, str) \ - fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) - -/** - * fdt_appendprop - append to or create a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to append to - * @val: pointer to data to append to the property value - * @len: length of the data to append to the property value - * - * fdt_appendprop() appends the value to the named property in the - * given node, creating the property if it does not already exist. - * - * This function may insert data into the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_appendprop(void *fdt, int nodeoffset, const char *name, - const void *val, int len); - -/** - * fdt_appendprop_u32 - append a 32-bit integer value to a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 32-bit integer value to append to the property (native endian) - * - * fdt_appendprop_u32() appends the given 32-bit integer value - * (converting to big-endian if necessary) to the value of the named - * property in the given node, or creates a new property with that - * value if it does not already exist. - * - * This function may insert data into the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, - const char *name, uint32_t val) -{ - val = cpu_to_fdt32(val); - return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_appendprop_u64 - append a 64-bit integer value to a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 64-bit integer value to append to the property (native endian) - * - * fdt_appendprop_u64() appends the given 64-bit integer value - * (converting to big-endian if necessary) to the value of the named - * property in the given node, or creates a new property with that - * value if it does not already exist. - * - * This function may insert data into the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, - const char *name, uint64_t val) -{ - val = cpu_to_fdt64(val); - return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); -} - -/** - * fdt_appendprop_cell - append a single cell value to a property - * - * This is an alternative name for fdt_appendprop_u32() - */ -static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, - const char *name, uint32_t val) -{ - return fdt_appendprop_u32(fdt, nodeoffset, name, val); -} - -/** - * fdt_appendprop_string - append a string to a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @str: string value to append to the property - * - * fdt_appendprop_string() appends the given string to the value of - * the named property in the given node, or creates a new property - * with that value if it does not already exist. - * - * This function may insert data into the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ -#define fdt_appendprop_string(fdt, nodeoffset, name, str) \ - fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) - -/** - * fdt_delprop - delete a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to nop - * @name: name of the property to nop - * - * fdt_del_property() will delete the given property. - * - * This function will delete data from the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_delprop(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_add_subnode_namelen - creates a new node based on substring - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * @namelen: number of characters of name to consider - * - * Identical to fdt_add_subnode(), but use only the first namelen - * characters of name as the name of the new node. This is useful for - * creating subnodes based on a portion of a larger string, such as a - * full path. - */ -int fdt_add_subnode_namelen(void *fdt, int parentoffset, - const char *name, int namelen); - -/** - * fdt_add_subnode - creates a new node - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * - * fdt_add_subnode() creates a new node as a subnode of the node at - * structure block offset parentoffset, with the given name (which - * should include the unit address, if any). - * - * This function will insert data into the blob, and will therefore - * change the offsets of some existing nodes. - - * returns: - * structure block offset of the created nodeequested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist - * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of - * the given name - * -FDT_ERR_NOSPACE, if there is insufficient free space in the - * blob to contain the new node - * -FDT_ERR_NOSPACE - * -FDT_ERR_BADLAYOUT - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ -int fdt_add_subnode(void *fdt, int parentoffset, const char *name); - -/** - * fdt_del_node - delete a node (subtree) - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node to nop - * - * fdt_del_node() will remove the given node, including all its - * subnodes if any, from the blob. - * - * This function will delete data from the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ -int fdt_del_node(void *fdt, int nodeoffset); - -/**********************************************************************/ -/* Debugging / informational functions */ -/**********************************************************************/ - -const char *fdt_strerror(int errval); - -#endif /* _LIBFDT_H */ diff --git a/recovery/fdt/libfdt_env.h b/recovery/fdt/libfdt_env.h deleted file mode 100644 index 213d7fb..0000000 --- a/recovery/fdt/libfdt_env.h +++ b/dev/null @@ -1,29 +0,0 @@ -#ifndef _LIBFDT_ENV_H -#define _LIBFDT_ENV_H - -#include -#include -#include - -#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n]) -static inline uint16_t fdt16_to_cpu(uint16_t x) -{ - return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1); -} -#define cpu_to_fdt16(x) fdt16_to_cpu(x) - -static inline uint32_t fdt32_to_cpu(uint32_t x) -{ - return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3); -} -#define cpu_to_fdt32(x) fdt32_to_cpu(x) - -static inline uint64_t fdt64_to_cpu(uint64_t x) -{ - return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32) - | (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7); -} -#define cpu_to_fdt64(x) fdt64_to_cpu(x) -#undef EXTRACT_BYTE - -#endif /* _LIBFDT_ENV_H */ diff --git a/recovery/fdt/libfdt_internal.h b/recovery/fdt/libfdt_internal.h deleted file mode 100644 index 381133b..0000000 --- a/recovery/fdt/libfdt_internal.h +++ b/dev/null @@ -1,95 +0,0 @@ -#ifndef _LIBFDT_INTERNAL_H -#define _LIBFDT_INTERNAL_H -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include - -#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) - -#define FDT_CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = fdt_check_header(fdt)) != 0) \ - return err; \ - } - -int _fdt_check_node_offset(const void *fdt, int offset); -int _fdt_check_prop_offset(const void *fdt, int offset); -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); -int _fdt_node_end_offset(void *fdt, int nodeoffset); - -static inline const void *_fdt_offset_ptr(const void *fdt, int offset) -{ - return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; -} - -static inline void *_fdt_offset_ptr_w(void *fdt, int offset) -{ - return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); -} - -static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) -{ - const struct fdt_reserve_entry *rsv_table = - (const struct fdt_reserve_entry *) - ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); - - return rsv_table + n; -} -static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) -{ - return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); -} - -#define FDT_SW_MAGIC (~FDT_MAGIC) - -#endif /* _LIBFDT_INTERNAL_H */ diff --git a/recovery/recovery_extra/Android.mk b/recovery/recovery_extra/Android.mk deleted file mode 100644 index f94b6f4..0000000 --- a/recovery/recovery_extra/Android.mk +++ b/dev/null @@ -1,31 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := recovery_amlogic.cpp - -LOCAL_MODULE := librecovery_amlogic - -LOCAL_MODULE_TAGS := eng - -LOCAL_C_INCLUDES += bootable/recovery - -LOCAL_C_INCLUDES += \ - system/vold \ - system/core/adb - -LOCAL_C_INCLUDES += \ - system/core/base/include \ - system/core/libziparchive/include - -LOCAL_C_INCLUDES += bootable/recovery/bootloader_message/include - -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ - -LOCAL_FORCE_STATIC_EXECUTABLE := true - -LOCAL_STATIC_LIBRARIES += libfs_mgr libselinux - -LOCAL_CFLAGS += -Wall - -include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/recovery/recovery_extra/recovery_amlogic.cpp b/recovery/recovery_extra/recovery_amlogic.cpp deleted file mode 100644 index 249033f..0000000 --- a/recovery/recovery_extra/recovery_amlogic.cpp +++ b/dev/null @@ -1,392 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "install.h" -#include "ui.h" -#include -#include "bootloader_message/bootloader_message.h" -#include "recovery_amlogic.h" - -#include "ubootenv/set_display_mode.h" - -extern "C" { -#include "ubootenv/uboot_env.h" -} - -#define LOGE(...) ui_print("E:" __VA_ARGS__) -#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__) -#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__) - -static const int MAX_ARGS = 100; -static const int MAX_ARG_LENGTH = 4096; -#define NUM_OF_BLKDEVICE_TO_ENUM 3 -#define NUM_OF_PARTITION_TO_ENUM 6 - -static const char *UDISK_COMMAND_FILE = "/udisk/factory_update_param.aml"; -static const char *SDCARD_COMMAND_FILE = "/sdcard/factory_update_param.aml"; - -void setup_cache_mounts() { - int ret = 0; - ret = ensure_path_mounted("/cache"); - if (ret != 0) { - format_volume("/cache"); - } -} - - - -static int mount_fs_rdonly(char *device_name, Volume *vol, const char *fs_type) { - if (!mount(device_name, vol->mount_point, fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, 0)) { - LOGW("successful to mount %s on %s by read-only\n", - device_name, vol->mount_point); - return 0; - } else { - LOGE("failed to mount %s on %s by read-only (%s)\n", - device_name, vol->mount_point, strerror(errno)); - } - - return -1; -} - -int auto_mount_fs(char *device_name, Volume *vol) { - if (access(device_name, F_OK)) { - return -1; - } - - if (!strcmp(vol->fs_type, "auto")) { - if (!mount(device_name, vol->mount_point, "vfat", - MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { - goto auto_mounted; - } else { - if (strstr(vol->mount_point, "sdcard")) { - LOGW("failed to mount %s on %s (%s).try read-only ...\n", - device_name, vol->mount_point, strerror(errno)); - if (!mount_fs_rdonly(device_name, vol, "vfat")) { - goto auto_mounted; - } - } - } - - if (!mount(device_name, vol->mount_point, "ntfs", - MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { - goto auto_mounted; - } else { - if (strstr(vol->mount_point, "sdcard")) { - LOGW("failed to mount %s on %s (%s).try read-only ...\n", - device_name, vol->mount_point, strerror(errno)); - if (!mount_fs_rdonly(device_name, vol, "ntfs")) { - goto auto_mounted; - } - } - } - - if (!mount(device_name, vol->mount_point, "exfat", - MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { - goto auto_mounted; - } else { - if (strstr(vol->mount_point, "sdcard")) { - LOGW("failed to mount %s on %s (%s).try read-only ...\n", - device_name, vol->mount_point, strerror(errno)); - if (!mount_fs_rdonly(device_name, vol, "exfat")) { - goto auto_mounted; - } - } - } - } else { - if(!mount(device_name, vol->mount_point, vol->fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { - goto auto_mounted; - } else { - if (strstr(vol->mount_point, "sdcard")) { - LOGW("failed to mount %s on %s (%s).try read-only ...\n", - device_name, vol->mount_point, strerror(errno)); - if (!mount_fs_rdonly(device_name, vol, vol->fs_type)) { - goto auto_mounted; - } - } - } - } - - return -1; - -auto_mounted: - return 0; -} - -int customize_smart_device_mounted( - Volume *vol) { - int i = 0, j = 0; - int first_position = 0; - int second_position = 0; - char * tmp = NULL; - char *mounted_device = NULL; - char device_name[256] = {0}; - char device_boot[256] = {0}; - const char *usb_device = "/dev/block/sd"; - const char *sdcard_device = "/dev/block/mmcblk"; - - if (vol->blk_device != NULL) { - int num = 0; - const char *blk_device = vol->blk_device; - for (; *blk_device != '\0'; blk_device ++) { - if (*blk_device == '#') { - num ++; - } - } - - /* - * Contain two '#' for blk_device name in recovery.fstab - * such as /dev/block/sd## (udisk) - * such as /dev/block/mmcblk#p# (sdcard) - */ - if (num != 2) { - return 1; // Don't contain two '#' - } - - if (access(vol->mount_point, F_OK)) { - mkdir(vol->mount_point, 0755); - } - - // find '#' position - if (strchr(vol->blk_device, '#')) { - tmp = strchr(vol->blk_device, '#'); - first_position = tmp - vol->blk_device; - if (strlen(tmp+1) > 0 && strchr(tmp+1, '#')) { - tmp = strchr(tmp+1, '#'); - second_position = tmp - vol->blk_device; - } - } - - if (!first_position || !second_position) { - LOGW("decompose blk_device error(%s) in recovery.fstab\n", - vol->blk_device); - return -1; - } - - int copy_len = (strlen(vol->blk_device) < sizeof(device_name)) ? - strlen(vol->blk_device) : sizeof(device_name); - - for (i = 0; i < NUM_OF_BLKDEVICE_TO_ENUM; i ++) { - memset(device_name, '\0', sizeof(device_name)); - strncpy(device_name, vol->blk_device, copy_len); - - if (!strncmp(device_name, sdcard_device, strlen(sdcard_device))) { - // start from '0' for mmcblk0p# - device_name[first_position] = '0' + i; - } else if (!strncmp(device_name, usb_device, strlen(usb_device))) { - // start from 'a' for sda# - device_name[first_position] = 'a' + i; - } - - for (j = 1; j <= NUM_OF_PARTITION_TO_ENUM; j ++) { - device_name[second_position] = '0' + j; - if (!access(device_name, F_OK)) { - LOGW("try mount %s ...\n", device_name); - if (!auto_mount_fs(device_name, vol)) { - mounted_device = device_name; - LOGW("successful to mount %s\n", device_name); - goto mounted; - } - } - } - - if (!strncmp(device_name, sdcard_device, strlen(sdcard_device))) { - // mmcblk0p1->mmcblk0 - device_name[strlen(device_name) - 2] = '\0'; - sprintf(device_boot, "%s%s", device_name, "boot0"); - // TODO: Here,need to distinguish between cards and flash at best - } else if (!strncmp(device_name, usb_device, strlen(usb_device))) { - // sda1->sda - device_name[strlen(device_name) - 1] = '\0'; - } - - if (!access(device_name, F_OK)) { - if (strlen(device_boot) && (!access(device_boot, F_OK))) { - continue; - } - - LOGW("try mount %s ...\n", device_name); - if (!auto_mount_fs(device_name, vol)) { - mounted_device = device_name; - LOGW("successful to mount %s\n", device_name); - goto mounted; - } - } - } - } else { - LOGE("Can't get blk_device\n"); - } - - return -1; - -mounted: - return 0; -} - -int smart_device_mounted(Volume *vol) { - int i = 0, len = 0; - char * tmp = NULL; - char device_name[256] = {0}; - char *mounted_device = NULL; - - mkdir(vol->mount_point, 0755); - - if (vol->blk_device != NULL) { - int ret = customize_smart_device_mounted(vol); - if (ret <= 0) { - return ret; - } - } - - if (vol->blk_device != NULL) { - tmp = strchr(vol->blk_device, '#'); - len = tmp - vol->blk_device; - if (tmp && len < 255) { - strncpy(device_name, vol->blk_device, len); - for (i = 1; i <= NUM_OF_PARTITION_TO_ENUM; i++) { - device_name[len] = '0' + i; - device_name[len + 1] = '\0'; - LOGW("try mount %s ...\n", device_name); - if (!access(device_name, F_OK)) { - if (!auto_mount_fs(device_name, vol)) { - mounted_device = device_name; - LOGW("successful to mount %s\n", device_name); - goto mounted; - } - } - } - - const char *mmcblk = "/dev/block/mmcblk"; - if (!strncmp(device_name, mmcblk, strlen(mmcblk))) { - device_name[len - 1] = '\0'; - } else { - device_name[len] = '\0'; - } - - LOGW("try mount %s ...\n", device_name); - if (!access(device_name, F_OK)) { - if (!auto_mount_fs(device_name, vol)) { - mounted_device = device_name; - LOGW("successful to mount %s\n", device_name); - goto mounted; - } - } - } else { - LOGW("try mount %s ...\n", vol->blk_device); - strncpy(device_name, vol->blk_device, sizeof(device_name)); - if (!access(device_name, F_OK)) { - if (!auto_mount_fs(device_name, vol)) { - mounted_device = device_name; - LOGW("successful to mount %s\n", device_name); - goto mounted; - } - } - } - } - - return -1; - -mounted: - return 0; -} - - -//return value -// 0 mount OK -// -1 mount Faile -// 2 ignorel -int ensure_path_mounted_extra(Volume *v) { - Volume* vUsb = volume_for_path("/udisk"); - char tmp[128] = {0}; - - if (strcmp(v->fs_type, "ext4") == 0) { - if (strstr(v->mount_point, "system")) { - if (!mount(v->blk_device, v->mount_point, v->fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, "")) { - return 0; - } - } else { - if (!mount(v->blk_device, v->mount_point, v->fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME, "discard")) { - return 0; - } - } - LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno)); - return -1; - } else if (strcmp(v->fs_type, "vfat") == 0 || - strcmp(v->fs_type, "auto") == 0 ) { - if (strstr(v->mount_point, "sdcard") || strstr(v->mount_point, "udisk")) { - int time_out = 2000000; - while (time_out) { - if (!smart_device_mounted(v)) { - return 0; - } - usleep(100000); - time_out -= 100000; - } - } else { - if (!mount(v->blk_device, v->mount_point, v->fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, "")) { - return 0; - } - } - LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno)); - return -1; - } else { - return 2;//not deal - } -} - -void amlogic_init() { - set_display_mode("/etc/mesondisplay.cfg"); - sleep(1); -} - -void amlogic_get_args(std::vector& args) { - - if (args.size() == 1) { - std::string content; - if (ensure_path_mounted(UDISK_COMMAND_FILE) == 0 && - android::base::ReadFileToString(UDISK_COMMAND_FILE, &content)) { - - std::vector tokens = android::base::Split(content, "\n"); - for (auto it = tokens.begin(); it != tokens.end(); it++) { - // Skip empty and '\0'-filled tokens. - if (!it->empty() && (*it)[0] != '\0') { - args.push_back(std::move(*it)); - } - } - LOG(INFO) << "Got " << args.size() << " arguments from " << UDISK_COMMAND_FILE; - } - } - - if (args.size() == 1) { - std::string content; - if (ensure_path_mounted(SDCARD_COMMAND_FILE) == 0 && - android::base::ReadFileToString(SDCARD_COMMAND_FILE, &content)) { - - std::vector tokens = android::base::Split(content, "\n"); - for (auto it = tokens.begin(); it != tokens.end(); it++) { - // Skip empty and '\0'-filled tokens. - if (!it->empty() && (*it)[0] != '\0') { - args.push_back(std::move(*it)); - } - } - LOG(INFO) << "Got " << args.size() << " arguments from " << SDCARD_COMMAND_FILE; - } - } - - if (args.size() == 1) { - args.push_back(std::move("--show_text")); - } - -} diff --git a/recovery/recovery_extra/recovery_amlogic.h b/recovery/recovery_extra/recovery_amlogic.h deleted file mode 100644 index 7ab23cf..0000000 --- a/recovery/recovery_extra/recovery_amlogic.h +++ b/dev/null @@ -1,25 +0,0 @@ -#ifndef _RECOVERY_INSTALL_AMLOGIC_H_ -#define _RECOVERY_INSTALL_AMLOGIC_H_ - -#include "common.h" -#include "device.h" -#include "roots.h" - -#include -#include -#include -#include -#include -#include -#include - -void amlogic_init(); - -void amlogic_get_args(std::vector& args); - -void setup_cache_mounts(); - -int ensure_path_mounted_extra(Volume *v); - -#endif - diff --git a/recovery/ubootenv/Android.mk b/recovery/ubootenv/Android.mk deleted file mode 100644 index 8aedda6..0000000 --- a/recovery/ubootenv/Android.mk +++ b/dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := uboot_env.cpp set_display_mode.cpp - -LOCAL_MODULE := libenv - -LOCAL_MODULE_TAGS := eng - -LOCAL_C_INCLUDES += $(BOARD_AML_VENDOR_PATH)/frameworks/services/systemcontrol -LOCAL_C_INCLUDES += bootable/recovery - -LOCAL_FORCE_STATIC_EXECUTABLE := true - -LOCAL_STATIC_LIBRARIES += libsystemcontrol_static liblog libcutils libstdc++ libc libbz - -include $(BUILD_STATIC_LIBRARY) diff --git a/recovery/ubootenv/set_display_mode.cpp b/recovery/ubootenv/set_display_mode.cpp deleted file mode 100644 index eec9c29..0000000 --- a/recovery/ubootenv/set_display_mode.cpp +++ b/dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include - -#include "ubootenv/Ubootenv.h" -#include "SysWrite.h" -#include "DisplayMode.h" - -int set_display_mode(const char *path) -{ - Ubootenv *pUbootenv = new Ubootenv(); - SysWrite *pSysWrite = new SysWrite(); - - DisplayMode displayMode(path, pUbootenv); - //setBootEnv - //displayMode.setBootEnv("upgrade_step", "1"); - pUbootenv->updateValue("upgrade_step", "1"); - pSysWrite->setProperty(PROP_FS_MODE, "recovery"); - displayMode.init(); - - return 0; -} \ No newline at end of file diff --git a/recovery/ubootenv/set_display_mode.h b/recovery/ubootenv/set_display_mode.h deleted file mode 100644 index 41d0b33..0000000 --- a/recovery/ubootenv/set_display_mode.h +++ b/dev/null @@ -1,4 +0,0 @@ -#ifndef SET_DISPLAY_MODE_H_ -#define SET_DISPLAY_MODE_H_ -int set_display_mode(const char *path); -#endif \ No newline at end of file diff --git a/recovery/ubootenv/uboot_env.cpp b/recovery/ubootenv/uboot_env.cpp deleted file mode 100644 index 887387a..0000000 --- a/recovery/ubootenv/uboot_env.cpp +++ b/dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "ubootenv/Ubootenv.h" - - -// ------------------------------------ -// for uboot environment variable operation -// ------------------------------------ - - -int set_bootloader_env(const char* name, const char* value) -{ - Ubootenv *ubootenv = new Ubootenv(); - - char ubootenv_name[128] = {0}; - const char *ubootenv_var = "ubootenv.var."; - sprintf(ubootenv_name, "%s%s", ubootenv_var, name); - - if (ubootenv->updateValue(ubootenv_name, value)) { - fprintf(stderr,"could not set boot env\n"); - return -1; - } - - return 0; -} - -char *get_bootloader_env(const char * name) -{ - Ubootenv *ubootenv = new Ubootenv(); - char ubootenv_name[128] = {0}; - const char *ubootenv_var = "ubootenv.var."; - sprintf(ubootenv_name, "%s%s", ubootenv_var, name); - return (char *)ubootenv->getValue(ubootenv_name); -} - - -int set_env_optarg(char * optarg) -{ - int ret = -1; - char *buffer = NULL, *name = NULL, *value = NULL; - if ((optarg == NULL) || (strlen(optarg) == 0)) { - printf("param error!\n"); - return -1; - } - - buffer = strdup(optarg); - if (!buffer) { - printf("strdup for buffer failed\n"); - return -1; - } - - name = strtok(buffer, "="); - if (strlen(name) == strlen(optarg)) { - printf("strtok for '=' failed\n"); - goto END; - } - - value = optarg + strlen(name) + 1; - if (strlen(name) == 0) { - printf("name is NULL\n"); - goto END; - } - - if (strlen(value) == 0) { - printf("value is NULL\n"); - goto END; - } - - ret = set_bootloader_env(name, value); - if (ret < 0) { - printf("set env :%s=%s failed", name, value); - } - -END: - - if (buffer != NULL) { - free(buffer); - buffer = NULL; - } - return ret; -} - -int get_env_optarg(const char * optarg) -{ - int ret = -1; - - if (optarg == NULL) { - printf("param error!\n"); - return -1; - } - - char *env = get_bootloader_env(optarg); - if (env != NULL) - { - printf("get %s value:%s\n", optarg, env); - ret = 0; - } - - return ret; -} diff --git a/recovery/ubootenv/uboot_env.h b/recovery/ubootenv/uboot_env.h deleted file mode 100644 index effda27..0000000 --- a/recovery/ubootenv/uboot_env.h +++ b/dev/null @@ -1,24 +0,0 @@ -#ifndef BOOTLOADER_ENV_H_ -#define BOOTLOADER_ENV_H_ -/* -* set bootloader environment variable -* 0: success, <0: fail -*/ -extern int set_bootloader_env(const char* name, const char* value); - -/* -* get bootloader environment variable -* NULL: init failed or get env value is NULL -* NONE NULL: env value -*/ -extern char *get_bootloader_env(const char * name); - - - -extern int set_env_optarg(const char * optarg); - - - -extern int get_env_optarg(const char * optarg); - -#endif \ No newline at end of file diff --git a/recovery/ui/Android.mk b/recovery/ui/Android.mk deleted file mode 100644 index 80f0eaa..0000000 --- a/recovery/ui/Android.mk +++ b/dev/null @@ -1,32 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := amlogic_ui.cpp - -LOCAL_MODULE := libamlogic_ui - -LOCAL_C_INCLUDES += \ - bootable/recovery \ - system/vold \ - system/core/adb \ - device/amlogic/common/recovery - -LOCAL_C_INCLUDES += \ - system/core/base/include \ - system/core/libziparchive/include - -LOCAL_C_INCLUDES += bootable/recovery/bootloader_message/include - -LOCAL_STATIC_LIBRARIES := \ - librecovery_amlogic \ - libenv \ - libsystemcontrol_static - -LOCAL_MODULE_TAGS := eng - -#LOCAL_FORCE_STATIC_EXECUTABLE := true - -LOCAL_CFLAGS += -Wall - -include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/recovery/ui/amlogic_ui.cpp b/recovery/ui/amlogic_ui.cpp deleted file mode 100644 index acd82ef..0000000 --- a/recovery/ui/amlogic_ui.cpp +++ b/dev/null @@ -1,205 +0,0 @@ -#include -#include -#include -#include - -#include "amlogic_ui.h" - -#include "common.h" -#include "device.h" -#include "screen_ui.h" -#include "ui.h" -#include "recovery_extra/recovery_amlogic.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cutils/properties.h" - -#include -#include -#include -#include -#include -#include - -#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/ - - -class AmlogicDevice : public Device { - public: - AmlogicDevice(ScreenRecoveryUI* ui) : Device(ui) { } -}; - -Device* make_device() { - amlogic_init(); - load_key_map(); - fb_set(); - return new AmlogicDevice(new ScreenRecoveryUI); -} - - -int num_keys; -KeyMapItem_t* keys_map; - -KeyMapItem_t g_default_keymap[3] = { - { "select", KEY_ENTER, {KEY_ENTER, KEY_TAB, KEY_BACK, -1, -1, -1} }, - { "down", KEY_DOWN, {KEY_DOWN, KEY_VOLUMEDOWN, KEY_PAGEDOWN, -1, -1, -1} }, - { "up", KEY_UP, {KEY_UP, KEY_VOLUMEUP, KEY_PAGEUP, -1, -1, -1} }, -}; - -CtrlInfo_t g_ctrlinfo[3] = { - { "select", KEY_ENTER }, - { "down", KEY_DOWN }, - { "up", KEY_UP }, -}; - -static KeyMapItem_t g_presupposed_keymap[] = { - { "select", -4, {BTN_MOUSE, BTN_LEFT, -1, -1, -1, -1} } -}; - -#define NUM_PRESUPPOSED_KEY_MAP (sizeof(g_presupposed_keymap) / sizeof(g_presupposed_keymap[0])) - -void fb_set() { - fb_var_screeninfo vi2; - int fd = open("/dev/graphics/fb0", O_RDWR); - if (fd == -1) { - printf("cannot open fb0"); - } - - if (ioctl(fd, FBIOGET_VSCREENINFO, &vi2) < 0) { - printf("failed to get fb0 info"); - close(fd); - } - - vi2.nonstd=1; - vi2.transp.length=0; - vi2.activate = FB_ACTIVATE_FORCE; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi2) < 0) { - printf("active fb swap failed"); - } - - close(fd); -} - - -int getKey(char *key) { - - if (key == NULL) { - return -1; - } - - unsigned int i; - for (i = 0; i < NUM_CTRLINFO; i++) { - CtrlInfo_t *info = &g_ctrlinfo[i]; - if (strcmp(info->type, key) == 0) { - return info->value; - } - } - return -1; -} - -void load_key_map() { - FILE* fstab = fopen("/etc/recovery.kl", "r"); - if (fstab != NULL) { - printf("loaded /etc/recovery.kl\n"); - int alloc = 2; - keys_map = (KeyMapItem_t*)malloc(alloc * sizeof(KeyMapItem_t)); - - keys_map[0].type = "down"; - keys_map[0].value = KEY_DOWN; - keys_map[0].key[0] = -1; - keys_map[0].key[1] = -1; - keys_map[0].key[2] = -1; - keys_map[0].key[3] = -1; - keys_map[0].key[4] = -1; - keys_map[0].key[5] = -1; - num_keys = 0; - - char buffer[1024]; - int i; - int value = -1; - while (fgets(buffer, sizeof(buffer)-1, fstab)) { - for (i = 0; buffer[i] && isspace(buffer[i]); ++i); - - if (buffer[i] == '\0' || buffer[i] == '#') continue; - - char* original = strdup(buffer); - - char* type = strtok(original+i, " \t\n"); - char* key1 = strtok(NULL, " \t\n"); - char* key2 = strtok(NULL, " \t\n"); - char* key3 = strtok(NULL, " \t\n"); - char* key4 = strtok(NULL, " \t\n"); - char* key5 = strtok(NULL, " \t\n"); - char* key6 = strtok(NULL, " \t\n"); - - value = getKey(type); - if (type && key1 && (value > 0)) { - while (num_keys >= alloc) { - alloc *= 2; - keys_map = (KeyMapItem_t*)realloc(keys_map, alloc*sizeof(KeyMapItem_t)); - } - keys_map[num_keys].type = strdup(type); - keys_map[num_keys].value = value; - keys_map[num_keys].key[0] = key1?atoi(key1):-1; - keys_map[num_keys].key[1] = key2?atoi(key2):-1; - keys_map[num_keys].key[2] = key3?atoi(key3):-1; - keys_map[num_keys].key[3] = key4?atoi(key4):-1; - keys_map[num_keys].key[4] = key5?atoi(key5):-1; - keys_map[num_keys].key[5] = key6?atoi(key6):-1; - - ++num_keys; - } else { - printf("skipping malformed recovery.lk line: %s\n", original); - } - free(original); - } - - fclose(fstab); - } else { - printf("failed to open /etc/recovery.kl, use default map\n"); - num_keys = NUM_DEFAULT_KEY_MAP; - keys_map = g_default_keymap; - } - - printf("recovery key map table:\n"); - int i; - for (i = 0; i < num_keys; ++i) { - KeyMapItem_t* v = &keys_map[i]; - printf(" %d type:%s value:%d key:%d %d %d %d %d %d\n", i, v->type, v->value, - v->key[0], v->key[1], v->key[2], v->key[3], v->key[4], v->key[5]); - } - printf("\n"); -} - -int getMapKey(int key) { - int i,j; - printf("******getMapKey, key: %d 0x%x\n", key, key); - for (i = 0; i < num_keys; i++) { - KeyMapItem_t* v = &keys_map[i]; - for (j = 0; j < 6; j++) { - printf("******v->key[%d]=0x%x, value=0x%x\n", j, v->key[j], v->value); - if (v->key[j] == key) - return v->value; - } - } - - for (i = 0; i < (int)NUM_PRESUPPOSED_KEY_MAP; i++) { - for (j = 0; j < 6; j++) { - if (g_presupposed_keymap[i].key[j] == key) - return g_presupposed_keymap[i].value; - } - } - - return -1; -} - diff --git a/recovery/ui/amlogic_ui.h b/recovery/ui/amlogic_ui.h deleted file mode 100644 index 51be193..0000000 --- a/recovery/ui/amlogic_ui.h +++ b/dev/null @@ -1,25 +0,0 @@ -#ifndef AMLOGIC_UI_H -#define AMLOGIC_UI_H - -#include - -#define NUM_CTRLINFO 3 -#define NUM_DEFAULT_KEY_MAP 3 - -struct KeyMapItem_t { - const char* type; - int value; - int key[6]; -}; - -struct CtrlInfo_t { - const char *type; - int value; -}; - -void fb_set(); -int getKey(char *key); -void load_key_map(); -int getMapKey(int key); - -#endif // AMLOGIC_UI_H diff --git a/recovery/updater_extra/Android.mk b/recovery/updater_extra/Android.mk deleted file mode 100644 index 589ffe5..0000000 --- a/recovery/updater_extra/Android.mk +++ b/dev/null @@ -1,24 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := install_amlogic.cpp - -LOCAL_MODULE := libinstall_amlogic - -LOCAL_MODULE_TAGS := eng - -LOCAL_C_INCLUDES += bootable/recovery - -LOCAL_C_INCLUDES += \ - bootable/recovery/updater/include \ - system/core/libziparchive/include - -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ - -LOCAL_FORCE_STATIC_EXECUTABLE := true - -LOCAL_STATIC_LIBRARIES += libbootloader_message libfs_mgr libselinux -LOCAL_STATIC_LIBRARIES += libenv libsystemcontrol_static libsecurity libdtb - -include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/recovery/updater_extra/install_amlogic.cpp b/recovery/updater_extra/install_amlogic.cpp deleted file mode 100644 index f408d70..0000000 --- a/recovery/updater_extra/install_amlogic.cpp +++ b/dev/null @@ -1,751 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "bootloader.h" -#include "cutils/android_reboot.h" -#include "cutils/properties.h" -#include "edify/expr.h" -#include "error_code.h" -#include "updater/updater.h" -#include "check/dtbcheck.h" -#include "ubootenv/uboot_env.h" - -#include "roots.h" -#include -#include - - -#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0]) -#define EMMC_USER_PARTITION "bootloader" -#define EMMC_BLK0BOOT0_PARTITION "mmcblk0boot0" -#define EMMC_BLK0BOOT1_PARTITION "mmcblk0boot1" -#define EMMC_BLK1BOOT0_PARTITION "mmcblk1boot0" -#define EMMC_BLK1BOOT1_PARTITION "mmcblk1boot1" -#define COMMAND_FILE "/cache/recovery/command" -#define CACHE_ROOT "/cache" - - -enum emmcPartition { - USER = 0, - BLK0BOOT0, - BLK0BOOT1, - BLK1BOOT0, - BLK1BOOT1, -}; - -static int sEmmcPartionIndex = -1; -static const char *sEmmcPartionName[] = { - EMMC_USER_PARTITION, - EMMC_BLK0BOOT0_PARTITION, - EMMC_BLK0BOOT1_PARTITION, - EMMC_BLK1BOOT0_PARTITION, - EMMC_BLK1BOOT1_PARTITION, -}; - -int RecoverySecureCheck(const ZipArchiveHandle zipArchive); -int RecoveryDtbCheck(const ZipArchiveHandle zipArchive); -int GetEnvPartitionOffset(const ZipArchiveHandle za); -/* - * return value: 0 if no error; 1 if path not existed, -1 if access failed - * - */ -static int read_sysfs_val(const char* path, char* rBuf, const unsigned bufSz, int * readCnt) -{ - int ret = 0; - int fd = -1; - int count = 0; - - if (access(path, F_OK)) { - printf("path[%s] not existed\n", path); - return 1; - } - if (access(path, R_OK)) { - printf("path[%s] cannot read\n", path); - return -1; - } - - fd = open(path, O_RDONLY); - if (fd < 0) { - printf("fail in open[%s] in O_RDONLY\n", path); - goto _exit; - } - - count = read(fd, rBuf, bufSz); - if (count <= 0) { - printf("read %s failed (count:%d)\n", - path, count); - close(fd); - return -1; - } - *readCnt = count; - - ret = 0; -_exit: - if (fd >= 0) close(fd); - return ret; -} - -static int getBootloaderOffset(int* bootloaderOffset) -{ - const char* PathBlOff = "/sys/class/aml_store/bl_off_bytes" ; - int iret = 0; - int blOff = 0; - char buf[16] = { 0 }; - int readCnt = 0; - - iret = read_sysfs_val(PathBlOff, buf, 16, &readCnt); - if (iret < 0) { - printf("fail when read path[%s]\n", PathBlOff); - return __LINE__; - } - buf[readCnt] = 0; - *bootloaderOffset = atoi(buf); - printf("bootloaderOffset is %s\n", buf); - - return 0; -} - -static int _mmcblOffBytes = 0; - - -static int write_data(int fd, const char *data, ssize_t len) -{ - ssize_t size = len; - char *verify = NULL; - - off_t pos = lseek(fd, 0, SEEK_CUR); - fprintf(stderr, "data len = %d, pos = %ld\n", len, pos); - - - if (write(fd, data, len) != len) { - fprintf(stderr, " write error at 0x%08lx (%s)\n",pos, strerror(errno)); - return -1; - } - - verify = (char *)malloc(size); - if (verify == NULL) { - fprintf(stderr, "block: failed to malloc size=%u (%s)\n", size, strerror(errno)); - return -1; - } - - if ((lseek(fd, pos, SEEK_SET) != pos) ||(read(fd, verify, size) != size)) { - fprintf(stderr, "block: re-read error at 0x%08lx (%s)\n",pos, strerror(errno)); - if (verify) { - free(verify); - } - return -1; - } - - if (memcmp(data, verify, size) != 0) { - fprintf(stderr, "block: verification error at 0x%08lx (%s)\n",pos, strerror(errno)); - if (verify) { - free(verify); - } - return -1; - } - - fprintf(stderr, "successfully wrote data at %ld\n", pos); - if (verify) { - free(verify); - } - - return len; -} - - -//return value -// -1 : failed -// 0 : success -static int backup_partition_data(const char *name,const char *dir, long offset) { - int ret = 0; - int fd = 0; - FILE *fp = NULL; - int sor_fd = -1; - int dst_fd = -1; - ssize_t wrote = 0; - ssize_t readed = 0; - char devpath[128] = {0}; - char dstpath[128] = {0}; - const int BUFFER_MAX = 32*1024*1024; //Max support 32*M - printf("backup partition name:%s, to dir:%s\n", name, dir); - - if ((name == NULL) || (dir == NULL)) { - fprintf(stderr, "name(%s) or dir(%s) is NULL!\n", name, dir); - return -1; - } - - if (!strcmp(name, "dtb")) {//dtb is char device - sprintf(devpath, "/dev/%s", name); - } else { - sprintf(devpath, "/dev/block/%s", name); - } - - sprintf(dstpath, "%s%s.img", dir, name); - - sor_fd = open(devpath, O_RDONLY); - if (sor_fd < 0) { - fprintf(stderr, "open %s failed (%s)\n",devpath, strerror(errno)); - return -1; - } - - dst_fd = open(dstpath, O_WRONLY | O_CREAT, 00777); - if (dst_fd < 0) { - fprintf(stderr, "open %s failed (%s)\n",dstpath, strerror(errno)); - return -1; - } - - char* buffer = (char *)malloc(BUFFER_MAX); - if (buffer == NULL) { - fprintf(stderr, "can't malloc %d buffer!\n", BUFFER_MAX); - goto err_out; - } - - if (strcmp(name, "dtb")) { - lseek(sor_fd, offset, SEEK_SET); - } - - readed = read(sor_fd, buffer, BUFFER_MAX); - if (readed <= 0) { - fprintf(stderr, "read failed read:%d!\n", readed); - goto err_out; - } - - wrote = write(dst_fd, buffer, readed); - if (wrote != readed) { - fprintf(stderr, "write %s failed (%s)\n",dstpath, strerror(errno)); - goto err_out; - } - - close(dst_fd); - close(sor_fd); - free(buffer); - buffer == NULL; - - //umount /cache and do fsync for data save - ret = umount("/cache"); - if (ret != 0) { - fprintf(stderr, "umount cache failed (%s)\n",dstpath, strerror(errno)); - } - - fd = open("/dev/block/cache", O_RDWR); - if (fd < 0) { - fprintf(stderr, "open %s failed (%s)\n","/dev/block/cache", strerror(errno)); - return -1; - } - - fp = fdopen(fd, "r+"); - if (fp == NULL) { - printf("fdopen failed!\n"); - close(fd); - return -1; - } - - fflush(fp); - fsync(fd); - fclose(fp); - - ret = mount("/dev/block/cache", "/cache", "ext4",\ - MS_NOATIME | MS_NODEV | MS_NODIRATIME,"discard"); - if (ret < 0 ) { - fprintf(stderr, "mount cache failed (%s)\n","/dev/block/cache", strerror(errno)); - } - - return 0; - - -err_out: - if (sor_fd > 0) { - close(sor_fd); - } - - if (dst_fd > 0) { - close(dst_fd); - } - - if (buffer) { - free(buffer); - buffer == NULL; - } - - return -1; - -} - - -static ssize_t write_chrdev_data(const char *dev, const char *data, const ssize_t size) -{ - int fd = -1; - ssize_t wrote = 0; - ssize_t readed = 0; - char *verify = NULL; - - fd = open(dev, O_RDWR); - if (fd < 0) { - fprintf(stderr, "open %s failed (%s)\n", dev, strerror(errno)); - return -1; - } - - fprintf(stderr, "data len = %d\n", size); - if ((wrote = write(fd, data, size)) != size) { - fprintf(stderr, "wrote error, count %d (%s)\n",wrote, strerror(errno)); - goto err; - } - - fsync(fd); - close(fd); - sync(); - - fd = open(dev, O_RDWR); - if (fd < 0) { - fprintf(stderr, "open %s failed after wrote success (%s)\n", dev, strerror(errno)); - return -1; - } - - verify = (char *)malloc(256*1024); - if (verify == NULL) { - fprintf(stderr, "failed to malloc size=%d (%s)\n", size, strerror(errno)); - goto err; - } - - memset(verify, 0, 256*1024); - - if ((readed = read(fd, verify, size)) != size) { - fprintf(stderr, "readed error, count %d (%s)\n", readed, strerror(errno)); - if (verify != NULL) { - free(verify); - } - goto err; - } - - if (memcmp(data, verify, size) != 0) { - fprintf(stderr, "verification error, wrote != readed\n"); - if (verify != NULL) { - free(verify); - } - goto err; - } - - fprintf(stderr, " successfully wrote data\n"); - if (verify != NULL) { - free(verify); - } - - if (fd > 0) { - close(fd); - } - return wrote; - -err: - if (fd > 0) { - close(fd); - } - return -1; -} - -int block_write_data( const std::string& args, off_t offset) { - int fd = -1; - int result = 0; - bool success = false; - char * tmp_name = NULL; - char devname[64] = {0}; - - memset(devname, 0, sizeof(devname)); - sprintf(devname, "/dev/%s", "bootloader"); //nand partition - fd = open(devname, O_RDWR); - if (fd < 0) { - memset(devname, 0, sizeof(devname)); - // emmc user, boot0, boot1 partition - sprintf(devname, "/dev/block/%s", sEmmcPartionName[sEmmcPartionIndex]); - fd = open(devname, O_RDWR); - if (fd < 0) { - tmp_name = "mtdblock0"; - memset(devname, 0, sizeof(devname)); - sprintf(devname, "/dev/block/%s", tmp_name); //spi partition - fd = open(devname, O_RDWR); - if (fd < 0) { - printf("failed to open %s\n", devname); - goto done; - } - } - - printf("start to write bootloader to %s...\n", devname); - lseek(fd, offset, SEEK_SET);//seek to skip mmc area since gxl - ssize_t wrote = write_data(fd, args.c_str(), args.size()); - success = (wrote == args.size()); - - - if (!success) { - fprintf(stderr, "write_data to %s partition failed: %s\n", devname, strerror(errno)); - } else { - printf("write_data to %s partition successful\n", devname); - } - } else { - printf("start to write bootloader to %s...\n", devname); - success = true; - int size = args.size(); - lseek(fd, offset, SEEK_SET);//need seek one sector to skip MBR area since gxl - fprintf(stderr, "size = %d offset = %d\n", size, offset); - if (write(fd, args.c_str(), size) != size) { - fprintf(stderr, " write error at offset :%d (%s)\n",offset, strerror(errno)); - success = false; - } - - if (!success) { - fprintf(stderr, "write_data to %s partition failed: %s\n", devname, strerror(errno)); - } else { - printf("write_data to %s partition successful\n", devname); - } - } - - result = success ? 0 : -1; - return result; - -done: - if (fd > 0) { - close(fd); - fd = -1; - } - return -1; -} - - -Value* WriteBootloaderImageFn(const char* name, State* state, const std::vector>& argv) { - char* result = NULL; - int iRet = 0; - - if (argv.size() != 1) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name); - } - - std::vector> args; - if (!ReadValueArgs(state, argv, &args)) { - return nullptr; - } - - if ((args[0]->type == VAL_STRING || (args[0]->data.size())) == 0) { - ErrorAbort(state, kArgsParsingFailure, "file argument to %s can't be empty", name); - return nullptr; - } - - iRet = getBootloaderOffset(&_mmcblOffBytes); - if (iRet) { - printf("Fail in getBootloaderOffset, ret=%d\n", iRet); - return StringValue("bootloader err"); - } - - unsigned int i; - char emmcPartitionPath[128]; - for (i = BLK0BOOT0; i < ARRAY_SIZE(sEmmcPartionName); i ++) { - memset(emmcPartitionPath, 0, sizeof(emmcPartitionPath)); - sprintf(emmcPartitionPath, "/dev/block/%s", sEmmcPartionName[i]); - if (!access(emmcPartitionPath, F_OK)) { - sEmmcPartionIndex = i; - iRet = block_write_data(args[0]->data, _mmcblOffBytes); - if (iRet == 0) { - printf("Write Uboot Image to %s successful!\n\n", sEmmcPartionName[sEmmcPartionIndex]); - } else { - printf("Write Uboot Image to %s failed!\n\n", sEmmcPartionName[sEmmcPartionIndex]); - printf("iRet= %d, exit !!!\n", iRet); - return ErrorAbort(state, kFwriteFailure, "%s() update bootloader", name); - } - } - } - - sEmmcPartionIndex = USER; - iRet = block_write_data(args[0]->data, _mmcblOffBytes); - if (iRet == 0) { - printf("Write Uboot Image successful!\n\n"); - } else { - printf("Write Uboot Image failed!\n\n"); - printf("iRet= %d, exit !!!\n", iRet); - return ErrorAbort(state, kFwriteFailure, "%s() update bootloader", name); - } - - return StringValue("bootloader"); -} - -Value* WriteDtbImageFn(const char* name, State* state, const std::vector>& argv) { - bool success = false; - const char *DTB_DEV= "/dev/dtb"; - const int DTB_DATA_MAX = 256*1024;// write 256K dtb datas to dtb device maximum,kernel limit - - if (argv.size() != 1) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name); - } - - std::vector> args; - - if (!ReadValueArgs(state, argv, &args)) { - return nullptr; - } - - if (args[0]->type == VAL_INVALID) { - return StringValue(""); - } - - fprintf(stderr, "\nstart to write dtb.img to %s...\n", DTB_DEV); - if (args[0]->type == VAL_BLOB) { - fprintf(stderr, "contents type: VAL_BLOB\ncontents size: %d\n", args[0]->data.size()); - if (!args[0]->data.c_str() || -1 == args[0]->data.size()) { - fprintf(stderr, "#ERR:BLOb Data extracted FAILED for dtb\n"); - success = false; - } else { - if (args[0]->data.size() > DTB_DATA_MAX) { - fprintf(stderr, "data size(%d) out of range size(max:%d)\n", args[0]->data.size(), DTB_DATA_MAX); - return StringValue(""); - } - ssize_t wrote = write_chrdev_data(DTB_DEV, args[0]->data.c_str(), args[0]->data.size()); - success = (wrote == args[0]->data.size()); - } - } - - if (!success) { - return ErrorAbort(state, kFwriteFailure, "%s() update dtb failed", name); - } else { - return StringValue("dtb"); - } -} - -Value* SetBootloaderEnvFn(const char* name, State* state, const std::vector>& argv) { - int ret = 0; - if (argv.size() != 2) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,argv.size()); - } - - std::vector args; - if (!ReadArgs(state, argv, &args)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); - } - - const std::string& env_name = args[0]; - const std::string& env_val = args[1]; - - if ((env_name.size() == 0) || (env_val.size() == 0)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed, one of the argument(s) is null ", name); - } - - //rm backup dtb.img and recovery.img - if ((!strcmp(env_val.c_str(), "1")) || (!strcmp(env_val.c_str(), "2"))) { - struct stat st; - if (stat("/cache/recovery/dtb.img", &st) == 0) { - unlink("/cache/recovery/dtb.img"); - } - - if (stat("/cache/recovery/recovery.img", &st) == 0) { - unlink("/cache/recovery/recovery.img"); - } - } - - ret = set_bootloader_env(env_name.c_str(), env_val.c_str()); - printf("setenv %s %s %s.(%d)\n", env_name.c_str(), env_val.c_str(), (ret < 0) ? "failed" : "successful", ret); - if (!ret) { - return StringValue("success"); - } else { - return StringValue(""); - } -} - - -Value* OtaZipCheck(const char* name, State* state, - const std::vector>&argv) { - int check = 0; - ZipArchiveHandle za = static_cast(state->cookie)->package_zip; - - printf("\n-- Secure Check...\n"); - - check = RecoverySecureCheck(za); - if (check <= 0) { - return ErrorAbort(state, "Secure check failed. %s\n\n", !check ? "(Not match)" : ""); - } else if (check == 1) { - printf("Secure check complete.\n\n"); - } - -#ifndef RECOVERY_DISABLE_DTB_CHECK - printf("\n-- Dtb Check...\n"); - - check = RecoveryDtbCheck(za); - if (check != 0) { - if (check > 1) { - printf("dtb check not match, but can upgrade by two step.\n\n"); - return StringValue(strdup("1")); - } - return ErrorAbort(state, "Dtb check failed. %s\n\n", !check ? "(Not match)" : ""); - } else { - printf("dtb check complete.\n\n"); - } -#endif - return StringValue(strdup("0")); -} - -Value* BackupDataCache(const char* name, State* state, const std::vector>& argv) { - int ret = 0; - if (argv.size() != 2) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name, argv.size()); - } - - std::vector args; - if (!ReadArgs(state, argv, &args)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); - } - - const std::string& partition = args[0]; - const std::string& destination = args[1]; - - ret = backup_partition_data(partition.c_str(), destination.c_str(), 0); - if (ret != 0) { - printf("backup %s to %s , failed!\n", partition.c_str(), destination.c_str()); - } else { - printf("backup %s to %s , success!\n", partition.c_str(), destination.c_str()); - } - - return StringValue("backup"); -} - -Value* RebootRecovery(const char* name, State* state, const std::vector>& argv) { - struct bootloader_message boot {}; - std::string err; - - read_bootloader_message(&boot, &err); - - if (strstr(boot.recovery, "--update_package=")) { - strlcat(boot.recovery, "--wipe_data\n", sizeof(boot.recovery)); - } - - printf("write_bootloader_message \n"); - if (!write_bootloader_message(boot, &err)) { - printf("%s\n", err.c_str()); - return ErrorAbort(state, "write_bootloader_message failed!\n"); - } - - property_set(ANDROID_RB_PROPERTY, "reboot,recovery"); - sleep(5); - - return ErrorAbort(state, "reboot to recovery failed!\n"); -} - -Value* SetUpdateStage(const char* name, State* state, const std::vector>& argv) { - int ret = 0; - if (argv.size() != 1) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 args, got %zu", name, argv.size()); - } - - std::vector args; - if (!ReadArgs(state, argv, &args)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); - } - - const std::string& stage_step = args[0]; - - FILE *pf = fopen("/cache/recovery/stage", "w+"); - if (pf == NULL) { - return ErrorAbort(state, "fopen stage failed!\n"); - } - - int len = fwrite(stage_step.c_str(), 1, strlen(stage_step.c_str()), pf); - printf("stage write len:%d, %s\n", len, stage_step.c_str()); - fflush(pf); - fclose(pf); - - return StringValue("done"); -} - -Value* GetUpdateStage(const char* name, State* state, const std::vector>& argv) { - char buff[128] = {0}; - - FILE *pf = fopen("/cache/recovery/stage", "r"); - if (pf == NULL) { - return StringValue("0"); - } - - int len = fread(buff, 1, 128, pf); - printf("stage fread len:%d, %s\n", len, buff); - fclose(pf); - - return StringValue(buff); -} - -Value* BackupEnvPartition(const char* name, State* state, - const std::vector>&argv) { - int offset = 0; - char tmpbuf[32] = {0}; - ZipArchiveHandle za = static_cast(state->cookie)->package_zip; - - offset = GetEnvPartitionOffset(za); - if (offset <= 0) { - return ErrorAbort(state, "get env partition offset failed!\n"); - } - - offset = offset/(1024*1024); - - sprintf(tmpbuf, "%s%d", "seek=", offset); - char *args2[7] = {"/sbin/busybox", "dd", "if=/dev/block/env", "of=/dev/block/mmcblk0", "bs=1M"}; - args2[5] = &tmpbuf[0]; - args2[6] = nullptr; - pid_t child = fork(); - if (child == 0) { - execv("/sbin/busybox", args2); - printf("execv failed\n"); - _exit(EXIT_FAILURE); - } - - int status; - waitpid(child, &status, 0); - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) { - ErrorAbort(state,"child exited with status:%d\n", WEXITSTATUS(status)); - } - } else if (WIFSIGNALED(status)) { - ErrorAbort(state,"child terminated by signal :%d\n", WTERMSIG(status)); - } - - return StringValue(strdup("0")); -} - -void Register_libinstall_amlogic() { - RegisterFunction("write_dtb_image", WriteDtbImageFn); - RegisterFunction("write_bootloader_image", WriteBootloaderImageFn); - RegisterFunction("reboot_recovery", RebootRecovery); - RegisterFunction("backup_data_cache", BackupDataCache); - RegisterFunction("set_bootloader_env", SetBootloaderEnvFn); - RegisterFunction("ota_zip_check", OtaZipCheck); - RegisterFunction("get_update_stage", GetUpdateStage); - RegisterFunction("set_update_stage", SetUpdateStage); - RegisterFunction("backup_env_partition", BackupEnvPartition); -} diff --git a/recovery/updater_extra/install_amlogic.h b/recovery/updater_extra/install_amlogic.h deleted file mode 100644 index 9981f76..0000000 --- a/recovery/updater_extra/install_amlogic.h +++ b/dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _UPDATER_INSTALL_AMLOGIC_H_ -#define _UPDATER_INSTALL_AMLOGIC_H_ - -#endif -- cgit