summaryrefslogtreecommitdiff
authorXindong Xu <xindong.xu@amlogic.com>2018-01-12 08:30:31 (GMT)
committer Xindong Xu <xindong.xu@amlogic.com>2018-01-12 08:30:31 (GMT)
commite01226016beccd02aeabd8f5e0c95804ac5b300d (patch)
tree0f8073766f528fa1f1a6aaeced2bd6b50087295f
parent143af7bf8724c568fbf4b0b1da57aff1932b80a6 (diff)
downloadcommon-e01226016beccd02aeabd8f5e0c95804ac5b300d.zip
common-e01226016beccd02aeabd8f5e0c95804ac5b300d.tar.gz
common-e01226016beccd02aeabd8f5e0c95804ac5b300d.tar.bz2
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
Diffstat
-rw-r--r--audio.mk15
-rw-r--r--hdcp_rx22/arm_tools/aictool4831
-rw-r--r--hdcp_rx22/arm_tools/hdcprxkeys3909
-rw-r--r--hdcp_rx22/firmware/esm_config.i2
-rw-r--r--hdcp_rx22/firmware/firmware.le862
-rw-r--r--hdcp_rx22/hdcp_rx22208
-rw-r--r--hdcp_tx22/hdcp_tx22.contenttype1165
-rw-r--r--patch/frameworks#base#0001.patch41
-rw-r--r--products/tv/init.amlogic.rc7
-rw-r--r--products/tv/product_tv.mk99
-rw-r--r--recovery/Android.mk8
-rw-r--r--recovery/check/Android.mk27
-rw-r--r--recovery/check/dtbcheck.cpp860
-rw-r--r--recovery/check/dtbcheck.h15
-rw-r--r--recovery/check/security.cpp578
-rw-r--r--recovery/check/security.h158
-rw-r--r--recovery/fdt/Android.mk18
-rw-r--r--recovery/fdt/Makefile.libfdt10
-rw-r--r--recovery/fdt/fdt.c222
-rw-r--r--recovery/fdt/fdt.h60
-rw-r--r--recovery/fdt/fdt_empty_tree.c84
-rw-r--r--recovery/fdt/fdt_ro.c574
-rw-r--r--recovery/fdt/fdt_rw.c492
-rw-r--r--recovery/fdt/fdt_strerror.c96
-rw-r--r--recovery/fdt/fdt_sw.c256
-rw-r--r--recovery/fdt/fdt_wip.c118
-rw-r--r--recovery/fdt/libfdt.h1478
-rw-r--r--recovery/fdt/libfdt_env.h29
-rw-r--r--recovery/fdt/libfdt_internal.h95
-rw-r--r--recovery/recovery_extra/Android.mk31
-rw-r--r--recovery/recovery_extra/recovery_amlogic.cpp392
-rw-r--r--recovery/recovery_extra/recovery_amlogic.h25
-rw-r--r--recovery/ubootenv/Android.mk17
-rw-r--r--recovery/ubootenv/set_display_mode.cpp24
-rw-r--r--recovery/ubootenv/set_display_mode.h4
-rw-r--r--recovery/ubootenv/uboot_env.cpp107
-rw-r--r--recovery/ubootenv/uboot_env.h24
-rw-r--r--recovery/ui/Android.mk32
-rw-r--r--recovery/ui/amlogic_ui.cpp205
-rw-r--r--recovery/ui/amlogic_ui.h25
-rw-r--r--recovery/updater_extra/Android.mk24
-rw-r--r--recovery/updater_extra/install_amlogic.cpp751
-rw-r--r--recovery/updater_extra/install_amlogic.h20
43 files changed, 4922 insertions, 12076 deletions
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 <T<o+f+Gpp
- h
- hi64FV\
-x
-F c
-XF9h
-gpT354B
-"`,!BFKFE
-Q1
-u#o0SFSYhhh BP
-S[i+ H@
-Sh;O
-Sh
->F,F4Fgh8FQF ``a^a`(a ,OPShOhdh
-F<&Fci
+(
+ 
+Cy DXXH0  H$HT ,* KFCF*SFT9)*FF 8F)FFFXFTFT <T<o+f+H8
+ hq
+ h64FV\
+x
+F
+XF9h)
+gpT354B
+"`,!BFKFnE
+Q1
+#o0SFSYhhh B0P
+S[i+ HP
+Sh;O
+Sh
+>F,F4Fgh8FQF ``a^a`(a ,OPShOhdh
+F<ci
CE8CF
-740B<
-D
-j0k@
-ZT3 +Sh+ +
-ѩ!FOr
-0@p!)D2FPF "
-0
+740B<
+D
+j0k@
+ѩ!FOrp襨!F"l h+
+0@p!)D2FPF "
+0
O
-HX,F i
-
-SiB3
+Hlh,F i7
+
+SiQBO0/
F
-*FxU4瘱
-F 8 F8-O
-;WB+*yY#BPF}iBFF4BF*'"F
- !hY@pG8F FH08(FE"F8-O] U5Ot# S3`& ^
-OG IFZFI
-tPG
- P 0 Q1h
- BUDAeB
-: ^ 
-Q
- BX"`
-X,
- -X<"Z`X<X,bXl6
-
-zX,
-F0 P0 X<
-0h
-D0h
-F0 P0 X<
-0hl
-D0h`
-`
-<"*
+*FxU4瘱
+F 8 F8-OHcD4`O"+
+
+F:FF ,4BF 
+
+4#x
+ !h@pG8F FH0T8(FE"F8-O] R2`& S` ^
+OG IFZFI
+4PM
+ P 0 Q1h
+!B%UDQ-k+mB#
+: ^ 
+R
+@BX"`
+X,
+ -X<"Z`X<X,bXl6
+
+zX,
+F0 P0 X<
+0h
+D0h
+F0 P0 X<
+0ht
+D0hh
+`
+p"*
-
-@,SDATEO8hyhh?;M=F ^ 
-8F@i y`a0I
-GB-B
-C=X@l
-G@=\0;"+l#
-+
-D` 0  R!l D<
-+
-D`!,|0Zh`0#pX@\03\03 0Op
-+
-D`Op
-+
-D`o)j(h1 `ohPoH<(Op
-+
-D`Op
-+
-D` #b@
-+
-D`Op
-+
-D`#,0EF 0  R!l D<
-+
-D`o)j(h1 `ohPoH<?Op
-+
-D`#bo(h!m `ohSoH<Op
-+
-D`oI !Op
-+
-D`@
-+
-D`Op
-+
-D`|0Zh`00$l
-+
-D`ohZ`oIl!Op
-+
-D`oh:`Z`noI!xOp
-+
-D`F
+
+A,SDATEO8hyhh?;M=F ^ 
+F$P0+p,0  R! iDP0T `.FF;#0 @
++
+D` 0
++
+|0hZ`|0h
+D`", |0Zh`0
++
+D`OpEF 0
++
+|0hZ`|0h
+D`o)j(h1 `ohPoH<1Op
++
+D`Op
++
+|0hZ`|0h
+D` #b@
++
+D`Op
++
+|0hZ`|0h
+D`#,0EF 0
++
+|0hZ`|0h
+D`o)j(h1 `ohPoH<>Op
++
+|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`<FTF
-+
-D`noI1xOpEF 0  R!l D<
-+
-D`I(0
-@d5
-B*&B @
-
-(`-F
-U6
-0ItQiIO0j `
-0IaiO0Xj2hB
-0I,aiO0XF1
-F(FIDa"FO00F$!FOPROhIlahO4
-O  ],P D@ BVaI #k`#+bE@L+ #k`@B
-O4O4O4O4@F K F
-Ii Ihch+r`h8GO
- h?IX"jI`
-I,sI4sI<si7xP/sxK+Eѳxf+Bx
-0Fp FQ1
-Fi F)F0#
-0
-0
-T`!aba
-U+`)aja
-WN̸aa:b{b
-@0C Pe-&F,F
+10`#h"+@ @oI!nO3?Op
++
+|0hZ`|0h
+D`o(h)j `ohPoH<Op
++
+|0hZ`|0h
+D`IPCh$0 &0+j+ nQxX)2f;+bo+j3sY(h1I `ohSoH<Op
+b4D q+j
++
+|0hZ`|0h
+D`|0i2`|0ha|0nF,F 0
++
+|0hZ`|0h
+D`|0i2`|0ha|08NFF,F03p{$0lpZ zx $0 0
++
+|0hZ`|0h
+D`|0i2`|0ha|0 0
++
+|0hZ`|0h
+D`
++
+|0hZ`|0h
+D`#boiD`ohao`S`@F,F 0
++
+|0hZ`|0h
+D`
++
+D`F,F
++
+|0hZ`|0h
+D`noI1xkOpEF 0
++
+|0hZ`|0h
+D`I80
+
+(@-pF
+T 
+0IQiO0j `
+0IaihO0Xj2hB
+0I<aiYO0XF1
+O  ],P D@ BVaI #k`#+bE@L+ #k`@B
+O4O4O4O4@F K F
+Ii Ihch+r`h8GO
+ h?IX"jI`
+I<s
+ FFi F)F0#
+ 0
+WSxhi88`S"`F
+0
+T aaaa
+U+(aiaa
+WNa9bzbb
+@0C Pe-&F,F
J{?xEeONxGgyzJjN nxJ
zC{NJ*bG kN.G'PkkE%kv
_@E@F{_O`_ϲ Y
@@ -164,33 +179,33 @@ _@E@F{_O`_ϲ Y
[,`T[! 3
S
-S\ 
+S\ 
+W>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 UF4F<iT  "*@
-
-`@FhAFD
-0FIF
-p_0dFeB"_Z
-BV#
+d Yh i1D
+
+PFyhFRF+F P$/#p
+мi@
+}j
+Db UF4F<iT  "*@
+
+`@FhAFD
+0FIF
+p_0dFeB"_Z
+BV#

-SE<lD=k,(
+SE<lD=k,(
^yE.
-^yA.
-F-O#
-!8
-!
-*
+^yA.
+F-O#
+!8
+!
+*
SкE 
d IF
-+hxʱ:*13F+:*F:BFK:,
-
-
-F
-@&3"@#۲@0
++hxʱ:*13F+:*F:BFK:,
+
+i
+F
+F
+@&3"@#۲@0
- 1 F"
- 0
-`4```x""F_+
- F@
-' z@p4FFFoWF
+ 1 F"
+ 0
+`4```x""F_+
+ F@
+' z@4FFFoWF
ByOj
E

-
-ZFd 9F"RFGD8FZ
+
+ZF 9F"RFGD8F
DEFk .
К
!;`\@FA
06)

-
+
P`D6( D$aB\a"Da  

-#300:0Ҳ *FB;0:0 _ Os$j
-7P&F;
-"
-
-B@!
-OQ
-
+#300:0Ҳ *FB;0:0 _ Os$j
+7P&F;
+"
+
+B@!
+O
+

-
-*\Б
-"Bsk$30[k$07;۲B چE<#pELx
-"F$1 RkR$ @*E
-*VЖ
-"B{k$30[k$07;۲B ڰB<#ӆBLx61
+
+*\Б
+"Bsk$30[k$07;۲B چE<#pELx
+"F$1 RkR$ @*E
+*VЖ
+"B{k$30[k$07;۲B ڰB<#ӆBLx61
F(DAFEтBћjx8(
-"F$6 RkR$ @*
+"F$6 RkR$ @*

-F7+иEM]D
-@ĹXFGF0?zO0 FAF<GF
- @|cDX S"0@|fOqq9aCGKE %` "O0{DhI qK"O0{DhI h0L9s@0?$h
+F7+иEM]D
+@ĹXFGF0?zO0 FAF<GF
+ @cDX S"0@fOqq9aCGKE %` "O0{DhI qK"O0{DhI h0Ls@0O$Ȋ
_oo
# B0 3o 3
-
-(FKK"{DhI F`4#PS
-_yjѹͱ F !*FC?ǭOssE
-$F
+
+_yjѹͱ F !*FC?ǭOssE
+$F
ciiBY'"aap3{5Y@=ciiBZY+"aap3{5 ciiBY-"aap51i0)
-"
-0OssE
-
-[DGDm@<P
+"
+0OssE
+
+[DGDm@<P
_
-# D0x ۲Z+@PK-P5
-|KK"{DhI PX00tK{DhY0hjjP0+x;۲+P+xP
-0x$*? ۲Z+?X00KK"{DhI |
-"
+# D0x ۲Z+@PK-P5
+|KK"{DhI PX00tK{DhY0hjjP0+x;۲+P+xP
+0x$*? ۲Z+?X00KK"{DhI 
+"
-؂DѹKK"{DhI KK"{DhI F ?0~kX>o
-
-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<k
- F2F0GBO5#hո
+%H%F
+~
+ F+!`0h9n
+O<k
+ F2F0GBO5#hո

-#(hhY`B#
-#hF:> 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`
Л
- 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 F<cbN&
- h
-c
-F
+ݻoO S C+BgŻ &
+EKX+B9llkk
+`:`
+ 8DIB|x F<cbN&
+ h
+c
!
-#ooxo0yoo+#
-hB) o2FRoC&
-ORDKFO KFoo`RDBoo
-C;Q#0 8PB&
+#ooxo0yoo+#
+hB) o2FboC&
+ORDKF_ KFoo`RDRoo
+C;Q#0 8PB&
B>Scap𱁸

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"<iG(D,
-%hF+h)ԪlphhCEc!_R
-"Aap)+htHo
-!0F+hFԫlZh:Z`ҹF`h_S
-8F
-"KF
+B8F!Fn%)' C^OpF
+F@s+j*Kp/!
+F@8s0 F9F FhF#h0F#S# C%`UBOј
+F
+00F9F"<iG(D,
++%hF+h)ԪlphhCEc!_R
+"Aap)+htHo
+!0F+hFԫlZh:Z`ҹF`h_S
+"[F
3F1FRF(4pPIFBF Bp<,O?
->F-O<S[`@HP
+>F-O<S[`@`P
O
_O
-
+
X
  Rh
-\E
+\E

-BC
-#'` 0#hF(FC&`#h JpzDhX *
-p0FAF"<iG(D,
-*F
-XD*F 1j
-F`ba`!`0F`BlCh B #j
-
+BC
+#'` $0#hF(FC&`#h JpzDhX *
+p0FAF"<iG(D,
+*F
+XD*F Aj
+F`ba`!`0F`BlCh B #j
+
R `A#h##`0O1iG
,SM
-,ЙBD0pG08pG
-ED(FFPFZF \F
-
-"F0+FXF
--(Fn
+,ЙBD0pG08pG
+ED(FFPFZF \F
+
+"F0+FXF
+-(Fn
\0ihBRHF-
)S
)ИEO
-
-@
-#hk(F0O1hGJC ` !p?O0zDhPF [v+hFԫlZh:Z`ҹF`h_S
-h
-0F!F O2O3#2;F@F1FH#3l0?
-J@<c@PؿT
-F F F' F<F$
+
+@
+#hk(F0O1hGJC ` !p?O0zDhPF kv+hFԫlZh:Z`ҹF`h_S
+h
+0F!F O2O3#2;F@F1FH#3l0?
+J@Tc@PؿT
+F F κF' F<F$
*;2B
-=ГBF3O
+=ГBF3O
F O0kpFJIh@@
F Fgm
-F F
+F F
O
-PF
-/+
-2k;#0?
-HF!
-#O3
+PF
+/+
+2k;#0?
+HF!
+#O3
- i
F`
-B`b`
-"FHFpjhDsbb3kHD
-"Fhpj3kD,
-H!"
-F`h_P
-%h
-
-YBF# F
-#%baO0O1pG
+B`b`4
+"FHFpjhDsbb3kHD
+"Fhpj3kD,
+H!"
+F`h_P
+%h
+
+iBF# F
+3%baO0O1pG
+1
%x
--ЋBF3DppG0p8pG
-
+-ЋBF3DppG0p8pG
+
F FjG O3fdk

- cZh2Z`iC jii#`bff!flal
-
-ZF
-Vj@s
+ sZh2Z`iC jii#`bff!flal
+
+jF
+fjA
bhLhh`#k+`%c8F#h
-DZ`ppGh ԜhAvhj]j`b`Xb`h
-%Bch:`F0`Zh_Q
+DZ`ppGh ԜhAvhj]j`b`Xb`h
+5Bch:`F0`Zh_Q
OJ
-E@0PFGF
-
-# ciKD `HD"jID```caaZbapcih(FB8`O0
+E@0PFGF
+
+# ciKD `HD"jID```caaZbapcih(FB8`O0
JD Y3iTEipi3jrhID
-
+
-
-CWLYB9O\TCx|S`E.DBxd|dFF8FA@A4B`
+
++CWLYB9O\TCx|S`E.DBxd|dFF8FAXALBx
0O0

-ED
- P D
-ܽ F!"
-,
-2B@h*DB@FB0@f`@ihh DXh(@2(FF Fhch#D6)
+ED
+ P D
+ܽ F!"
+,
+2B@h*DB@FB0@f`@ihh DXh(@2(FF Fhch#D6)
$O\S
-
-
+
+
.
ch@O\W083 [7n3
w7|3 ByO
@@ -778,7 +791,7 @@ JD Y3iTEipi3jrhID
vH
(-O@[00sErFa?aZh
(9O@n0bkB BF
-FR~
+FR~
/@
+@D/O~R
/ /
@@ -787,49 +800,50 @@ FR~
. 
)XhdF 
UE
- hhB@𨄏hB@𤄰
+ hhB@𨄏hB@𤄰
+  F
-F .|O~kZhB@
+F .|O~kZhB@
Fh
-hB@hhB@dXh``
+hB@hhB@dXh``
D*
UE0O  "VE
-
+
+PFF
FO
-O0r`
-CQ``tJFGH4GFO
-a?A A4B
-O\XA1F,A A4B
-A
-A !QFJ
-aJAA4B
-K B
+O0r`
+CQ``tJFGH4GFO
+a?A ALB
+O\XA AF,A$ ALB
+A
+A !QFJ
+aJAALB
+K B
-
9O\QBH
- Jk`KhCK`IFV<C8FCF,"E!F0F
-h`F FR真
-WE=
-O\P!
-[ "_( O T
+ Jk`KhCK`IFV<C8FCF,"E!F0F+
+h`F FR
+WE=
+O\P!
+[ "_( O T
ʿ
-F
+F
O
-KdOM3 O\THh_T
-a(F*bj
-DSh
-y
-"#Fo
-"F
-"Fo
-"FO0c5
-"Fo
-"Fo
-"Fo
-"Fo
+KdOM3 O\THh_T
+a(F*bj
+DSh
+y
+"!Fo
+"F
+"Fo
+"FO0c5
+"Fo
+"Fo
+"Fo
+"Fo
 n O< wٶ .|6~&B
` {
-U+2`*`hJ `E+@/FܫkB
+U+2`*`hJ `E+@/FܫkB
8
O\*
[
@@ -840,23 +854,22 @@ DSh
w
OL |
O~
-VE6H4+3#0B8r
-kO\P!
+VE6H4+3#0B(r
 n
-5O
-L F!"
+5O
+L F!"
P4x
- _U
-Ba|$0h3hk
-Cc g(F!"
-
-FF
-"B:FF(*F0FAF
-"FBF:F0FAF(*F
+ _U
+Ba|$0h3hk
+Cc g(F!"
+
+FF
+"B:FF(*F0FAF
+"VBF:F0FAF(*F
FB
BppG

-
+
#,EFZF#F  KEpBD
B
FBFXFYD
@@ -875,7 +888,7 @@ FB
Ec

- (x\s\1B903E?Ӯ
+ (x\s\1B903E?Ӯ

W
('t&|d%lT$\D#LU `
@@ -883,7 +896,7 @@ W
('x&xh%hX$XH#HU `
01\#  R
('|&tl%d\$TL#DU `
-01\# c
+01\# c

@@ -922,134 +935,137 @@ W
 ++KK  ++K  ++ [ [" " $$&+&+([* * ,,.+.+
 ++{{  ++{` +
-
-F]HD T 
+
+F]HD T 
-" \BxB
-+
+" \BxB
++
E ܻ
sFhhBCKSE^DBȿB $ED P

-<oa9bchb{b@#h
-"qap0F0OPUE+h
-!:{j
-
-'
-KABp/O0{DhPKABp/O4{DhP
- @!
-B##FEC
-1
-S# +`8FP FJFoc$<K{Dh[P8F=oc $$$2K{Dh[P
-E#
+<oa9bchb{b@#h
+"qap0F0OPUE+h
+!:{j
+
+'
+KABp/O0{DhPKABp/O4{DhP
+ @!
+B##FEC
+1
+S# +`8F@ FJFoc$<K{Dh[P8F-oc $$$2K{Dh[P
+E#
{hKhf
-s"{c``B"s`L`ppGhK`Ch``D`
+s"{c``B"s`L`ppGhK`Ch``D`
 qh0K
P4

F
-^
+^
{o
s o
{o
s o
!hF FBFPC3`(hBy؄B F
-Bx!FBFHFF*hPF3hO KD+`
-!D,`
+Bx!FBFHFF*hPF3hO KD+`
+!D,`
!XF0O
-
-KdBp/
-"XF;iFE
-"XF{`i{hE=ГF:KABp/{DhPB`}aa
- B@a"x00; +4
- 1FRF
-"P0Bx
-i@XD]KpGp?c2Z?(O3B4
-+8 FO3 2h_CR
-"+F%
-Btg 
+
+KdBp/
+"XF)iFE
+"XF{`i{hE=ГF:KABp/{DhPB`}aa
+_`
+ BXa"x00; +4
+ 1FRF
+">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 5JFGH<GDHDHH|BT YF
O "f'O OO
--OC`#h`
+-OCP#h`
 
-C& h
+C& h
(h
-F h
+F h
`+` `
-P<P,#O2P<P<
- F
-)@C@s`Fid2C
-:2Cl
+P<P,#O2P<P<
+ F
+)@C@s`Fid2C
+:2C
Vyq߉R
{)R
hIDBhBПh9DBihEREFX23VE``
-D D0@
-x0:Ӳ +"KxM0 , 1 FB;0:0 ,.+B
-
- FE\
-oFi
+D D0@
+x0:Ӳ +"KxM0 , 1 FB;0:0 ,.+B
+@0/!Cx
+
+ FE\
+oFi
{DhEKp_{DhU
-  YLTh&i
+  YLTh&i
`hX`
-F+,*
+F+,*
aK.F`]$shc`sh&Fuh&F+F-OF0LdЛF+h;
-
-V$ (V<$68Fz@FIFC
+
+V$ (sV<$68Fj@FIFC

-;n
+;n
!F
K,<#K4<
HF
-
-,h
-0 @F0
- FF:a{`
-"{`i{hBE (F!yaZF"za^FMF
+
+,h
+0 @F0
+ FF:a{`
+"{`i{hBE (F!yaZF"za^FMF
F:)
-:+
-:+ x F1
-(=a[hia3#i hFCsFi`@\1(`hF`n
-"3F :$#!XF
+:+
+:+ x F1
+(=a[hia3#i hFCsFi`@t1(`hF`^
+"3F :$#!XF
PSD

-a
-F
-+ 
+a
+F
++ 
KBF4$(F
B@
-bBF3#(F
+bBF3#(F
*ܚEO
-C`FC@ C,!Cdc
+C`FCX CD!C|c
F H
k
G(\ B@À
-BF3#(Ft4F;F
+BF3#(Ft4F;F
*YܚEO
C`
-G&h-C@ C,!CDc
+G&h-CX CD!C\c

- B@
+ B@
*ܚEO
-C`FC@ C,!C c
+C`FCX CD!C8c
HO
kP3O$h
C`@y*
G(m B@
-BF3#(F
+BF3#(F
*[ܚEO
C`
-G :h
+G :h
k
FGF
-*h
+*h
 k6m3O$h^@
:F3F B𹀕B@h)lSp1 FBѓF
 G( [E@#h
@@ -1057,12 +1073,12 @@ C`
O
 O
1
-
-C`
- G7h C C,!C\S
+
+C`
+ G7h C( CD!CtS
-F2B q  _?
-`|C$0C!C@S
+F2B q  _?
+`|C<0C!CXS
$ 
mk3O$hZ@

@@ -1071,16 +1087,16 @@ CpF
1BDBـB>S <
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<F)!0DBA)`R
-
- G*Oa"Oa"_C C,!CC
+ )!)@!PB"FO 4 
+     ٝ@0+ A
+ФF<F)!0DBA)`R
+
+ G*Oa"Oa"_C( CD!CC
k

@
@@ -1102,103 +1118,103 @@ BF=F #E%FFx+o2+`B*`
`=$
##DBB
--;F/D\3Bq   C C,!CC
+-;F/D\3Bq   C( CD!CC
@X`x2q hB0h!
-C`{2h
+C`{2h
 mk3O$hY@
 G(KB@5
`P _3F?I
-h8!F FC C,!ClC
-C`("F
- G/hEC C,!ClC
-`1C$0C!CPC
+h8!F FC( CD!CC
+C`("F
+ G/hEC( CD!CC
+`1C<0C!ChC

@
F
'G" W
##DBB
--;F/D\3Bq  } C C,!C(C
+-;F/D\3Bq  } C( CD!C@C
@X`x2q hB0h!
-C`2h
+C`2h
 mk3O$hY@
 G(EB@
Sp71:F FEgF\FF*-(F
-Sp23cE@& 
+Sp23cE@& 
C`8
- G/hmC C,!C3
-` BF2h
+ G/hmC( CD!C3
+` BF2h
@36
D R S" sFP"
-BuK @{DhX
+BuK @{DhX
gF @Q ["0F S
F
-`;`!F!h32:` `-
-8FXi8j)hJFWF
-F
-
-+@F\D
-F
+`;`!F!h32:` `-
+8FXi8j)hJFWF
+F
+
++@F\D
+F
}H ibh3C

-
-Z@"aX@`a#h"
+
+Z@"aX@`a#h"

-,S
-pFα@ah FO@@1 FG
+pFα@ah F?@@(1 F7
B
-lhAD-O=0
+lhADO=0

-  - ,S `
-PExe
-0FTF
+  - ,S `
+PExe
+0FTF
ii*F
-
-
+
+
O  

 X
0TQ
3]ID
Z0G@0V
-PFBziB@P Ѡm;iB @cB9ieC#h2`yGKp/!
+PFBziB@P Ѡm;iB @cB9ieC#h2`yGKp/!
O

- B{iHF"F;iD
-
-h"Oc B@&DwhU$0B
-`33#  F;D!"4CqCs
-rDn FO
-
-fhB
-SFFFFziFKFFDFFEDD @Fah
-O
-O93h4`.F#`65  . +D0FZh\n
-
+ B{iHF"F;iD
+
+h"Oc B@&DwhU$0B
+`33#  F;D!"4D
+rD FO
+
+
+fhB
+SFFFFziFKFFDFFEDD @Fah
+O
+O93h4`.F#`65  . +D0FZh\n
CQB
C ppG
-0
-F#
+*
+F#
OJ 9
-JE
+JE
h
-OIFkBAEӿ
+OIFkBAEӿ
FJ < n 8
?gFW`
O1J  N
X3O 7 D
- D F9F9FF F
-+DSO@@AB ى
+ D F9F9FF F
++DSO@@AB ى
0{ҌB
-u 9FHFz9FFHFCCE ٛ1ҙE<
+u 9FHF~9FFHFCCE ٛ1ҙE<
B)D=BA,
- O ?5 D F)Fv FF)FCF
+ O ?5 D F)Fz FF)FGF
CBٛ2/ҘB<*
-)FPF[PFF)F(
+)FPF_PFF)F,
ٻi;R 0A
@DD(
@@ -1213,7 +1229,7 @@ F;F2R1B ;
V>`
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# E<xcjjC#
+C@~iBgo.Bc.0# E<xcjjC#
-#xT
-
-+~8l
-
+#xT
++~8l
XSBSA*F
-+ ?0F)F*FF`i
-.
++ ?0F)F*FEF`i
+.
*~;l
0F)F
-&*F`2F
-.4.#. RFFFFFeF Foz`>k 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`<`<i
-B@X
-( @FJF!;hE
-  h
+Ya`xB РhchB F`Ahsjj2kCE RDQ`<`<i
+B@X
+( @FJF!;hE
+  h
FY
-
-
- Kp/!O0{DhPpGKABp/O0{DhPX
-F
-(F#Dl/)FB
- h)ca
-
-F
-G+hmh\a
-G+hZi_TQ
-KABp/O0{DhPKp/!O0{DhPpG
-@  h`(FO|_p@pG1F(FO|_F0F] F
-KABp/O0{DhPKABp/O4{DhP
-@  hp(FB
-KABp/O0{DhPKABp/O4{DhP
-KABp/O4{DhPt
+
+
+ Kp/!O0{DhPpGKABp/O0{DhP
+F
+(F#Dl/)FB
+ h)ca
+
+F
+G+hmh\a
+G+hZi_TQ
+KABp/O0{DhPKp/!O0{DhPpG
+@  h`(FO|_p@pG1F(FO|_F0F] F
+KABp/O0{DhPKABp/O4{DhP
+@  hp(FB
+KABp/O0{DhPKABp/O4{DhP
+KABp/O4{DhP
FFpGx/)
-F
-8b
+F
+8b
-aP*NRVC*tFC
+aP*NRVCtFBqO"F@#
Q3&dFtI(b zd;dcKE
-
+
PD:hADd

FT ,D:mB0la ٸlS,B dT,F9l
@8"hF
`
-
+
F ( sxkYF"FB@X1\$Oaq
-)@C@s`0F
+)@C@s`0F
D 2BH
-D(F~I"
-HF"
-hh
+D(F~I"
+HF"
+hh
-
-xOp Cd,FFDF F  O
-FDD
-FDlZ:
- F/!
- F/!
-KO О3Fb
+
+xOp CT,FFDF F  O
+FD\
+FDr:
+ F/!
+ F/!
+KO О3Fb
(F
*i2

WF(Fe,5F8
-_lQ
-
-IF"
-"hx C;CP*CqO8P
-C"
-+ +  
-FDD i
- hD+hD<3F cD$1zdD"0L  O
+_lQ
+
+IF"
+"hx C;C@*CqO8P
+Ct"
++ +  
+FD\ i
+ hD+hDT3F cD<1zdD"0L  O
4L0c9ddTLED
-D!#0  @FTEDX2
-< O 4cc9cEDZD@QD@R D\A#0  HFFE
-BO<O
-#, aL1p[hhxh^hUB!|QhA!1pk۱[hS+x!1!pGD0D8!D,C
+D!#0  @FTEDp2
+< O 4cc9cEDZDXQDXR DtA#0  HFFE
+BO<O
+#, aL1p[hhxh^hUB!|QhA!1pk۱[hS+x!1!pGD@DP!DDC
'Fh
- F
-J
-F:fp Rh*
+ F
+J
+F:fp Rh*
O,0 D ~e
F$
-)
+)
O-4 D
d
F$
)
-D"|i
-De=lff}g"F#FB_ Gp|cdF<F
+D"|i
+De=lff}g"F#FB_ H
d
F$
-)
+)
F$
-)
-RhhDD
-DP0҉
-DPF;`;h<
+)
+RhhDD
+DP0҉
+DPF;`;h<
H
Ha

-  ;cZ c8<
+  ;cZ c8<


- E:
+ E:
+
-6
- Z ѾlF;dk
+6
+ Z ѾlF;dk
 #HB
C 


P`1dEE
-l%C;d5;m/$hhS=mm
-F
+l%C;d5;m/$hhS=mm
+F
-
+
+;Sx2F%+
-+ЈF
++ЈF
#
- 0O0*+qD
+ 0O0*+qDDD$
##0h`2Fh
-МEF1F8 FE A5
-O
+МEF1F8 FE A5
+O
YF
-
-
+
+
&a
$O
@
-Bch
+Bch
L9iBNҹiBLhZj_D^
FA 
 _DT
-BiBiJI$ \j  _&DQ
-
-
-#{;hF3RV,4B KBЦ
-Q2 ?F
+BiBiJI$ \j  _&DQ
+
+#{;hF3BV,4B KBЦ
+Q2 ?F
!F# FbKi1]\B)  h
-) h
+) h
F `1jOIЈFO
a# 3  ;b`F

-<j O
-hFFBIh
+<j O
+hFFBIh
0 
zbF<08}d8l
0

-E
-%@.P
-8 dDx`D(aEh
+E
+%@.P
+8 dD`D@aE
DlB 8lhB`O
?安E KEّFdO
02O
 lF8lO
-d`DppD(aEh
-x0 ,ٓB0x1
+d`DpD@aE
+x0 ,ٓB0x1

vvt
F'FF
umOE QiB1DHF
-8EݽE
+8EݽE
@CC #
U<BBD
-
-/(-
-O
+
+/-
+O

ƱnHFbk200BYx20

ԁFEC%

-E@ՇBѼg&
+E@ՇBѼg&
F0

Nk6
-:xzh%=S-πws3xTK@P{DhP<o&O5=g
-F1
+:xzh%=S-πws3xTK@P{DhP<o&O5=g
+F1

ck30

-Ԑ}o@˅P?%P}o3_n
+Ԑ}o@˅P?%P}o3_n


Ԑ#0?
 #
-,
+,
0"K@P{DhP=o&

-?_XF&E?
+?_XF&qE?

P

@@ -1537,92 +1546,89 @@ ck30
@

P
-%PD@|gXF9az``?F9izhhl
+%PD@|gXF9az``?F9izhhl
F<I0sxyD h^
:?\0BK0
+2<n
-F0Fc
+F0Fc

 0cX,F
-F0oB(%F? <_XFz`zho9LEF4FXFz`BzhoF3DD
-n@
+F0oB(%F? <_XFz`zho9LEF4FXFz`BzhoF3DD
+n@
#0@
- %j|ot @!F
+ %j|ot @!F

ck30=|oLV<m`n0 

2 <eLXF_
-:z
-m(h=m!Bm(`=o
+:j
+m(h=m!Bm(`=o

-:
+:

Kk308XF_
-:|
+:l
O4@P9m`vE:m2
-D
+D
h 0@@xoB
-
-Y
-B*zo4Fl`Rf
-m:mh!B#m`8o
+
+B*zo4Fl`Rf
+m:mh!Bm`8o


-<B@kx
+<B@kx

<BApc05

kS"0n+B
-@,P&@B@
-kS"0f+BP
-:n-n}m{mC3!
-:BBcx5
+@,P&@B@
+kS"0f+BP
+:n-n}m{mC3!
+:BBcx5
*J;nF m3~lEe|d,Fc{bF

<HE#F,F5FF
-:9ME ҠFXFE+3DD
+:9ME ҠFXFE+3DD
*(QѺmTF;j2BekUF|lt|

-0E030i2F%FFEv
- BȇQ
-?FjHSFFF0xD
-}o4Fme&+hPB=o:C"@5=gDO5F=g>O4<g9XF?F}`KP{DhX0X|n°OuP;KT"P&{DhPp$&eT
-K@{DhX0#PO4
-:<
+0E030i2F%FFEv
+ BȇQ
+}o4Fme&+hPB=o:C"@5=gDO5F=g>O4<g9XF|?F}`KP{DhX0X|n°OuP;KT"P&{DhPp$&eT
+K@{DhX0#PO4
+z;
+4

-k. D"F|d
-,
-:8l(F>b9lB,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<i
ZFxlPPAFV
B

-(`m<&@O5
+(`m<&@O5
xn8Oz
-# kFE
-zh8,FFQ,FFMFO5F0`=gOXF?F|K@{DhX0{mp&7n,n|m{mC3!h2FFFk@,n,n|m{mC3!h|nO5=g@&F
- <_XFo
-4BFF6XFEo3DD
-F
-xKxS FPF
-p yD hX0hwi
+# kFE
+ <_XFo
+4BFF6XFEo3DD
+F
+xKxS FPF
+p yD hX0hwi
OyF #
8FlOO
-   O{
-F!C(2!
+   O{
+F!C2!
 ,   @msu:D
@@ -1630,7 +1636,7 @@ F!C(2!
  OsDES
C{

-O
+O
E
gO@mFBr#7:(% 
@@ -1648,43 +1654,43 @@ E
#
FH
#GfB8OFuBO B
-#
-X:e`CtL `ja|c\1"4O
-FTj\EF?OZ1
+#
+X:e`CtL `ja|c\1"4O
+FTj\EF?OZ1
 FD&<SsEfFh
-1`1X
-S/`1 SE ;D 
-#<b{cdF@{kxl; DDD2\`,;lE+ (Fi^, F99BQ/
-
-Fh
-PFF
+1`1X
+S/`1 SE ;D 
+#<b{cdF@{kxl; DDD2\`,;lE+ (Fi^, F99BQ/
+
+Fh
+PFF
Ҳ*JZ{{ bRhpa2 Qh
-+AC\#hbQFE$@EDAEhC
++ACL#hbQFE<@E\AEC
_Owђ b
1
-++C\#hQO3HF)F`|(F)FO3`O "_{!hUh
-+ DB(ShGFE$@EDAETC
+++CL#hQO3HF)F`|(F)FO3`O "_{!hUh
++ DBShGFE<@E\AElC
-=
+=
R
0jD2\i! B 23нiEhS,3F88BP
-
-Z=G<kmZh+hDG1  E31ii=Laad$7FhF
-h`UL<`
-#=` ESx`<F`x40)F  (FBTB$PhXFXIDf
-
+
+Z=G<kmZh+hDG1  E31ii=Laad$7FhF
+h`UL<`
+#=` ESx`<F`x40)F  (FvBTpB$PhXFXIDV
+
%F`1

-E\1@FOS*i
-0SD
-#=bEDcxb b(!60)F  (F/FEVEe ah xcO8RCshh
+E\1@FOS*i
+0SD
+#=bE\cxb b(!60)F  (FFEVE4e ah xcO8RCshh


+(

-*БO
+*БO
!`
"
@@ -1692,15 +1698,15 @@ Z=G<kmZh+hDG1  E31ii=Laad$7FhF
F,`E4@!

"fE
-3
-FrBD0FҲ *,ZE#qFoBBOF7
+3
+FrBD0FҲ *,ZE#qFoBBOF7
"F


+(

-*sБO
+*sБO
!`
"
@@ -1710,20 +1716,20 @@ Z=G<kmZh+hDG1  E31ii=Laad$7FhF
"E
3
FrBD0FҲ *,ZE"qF
-
-"F$5 R< R$ @*
+
+"F$5 R< R$ @*
o}O3Bu
{DhP6
,u
{DhP

-.
-F"4F@FAFE
+
+F"4F@FAFE
R1B;O 
F
-
-U#0
-R1B;#
+
+U#0
+R1B;#
[h
08Q$Ӳ +_;#aڲ*+@ˀ
@@ -1731,7 +1737,7 @@ F
 0_ +@FB<0+
SF;,0*FFB
-0۲ +@gk$0i+
+0۲ +@ gk$0i+
(
A3xB@$FFCE@?

@@ -1743,32 +1749,32 @@ A3xB@$FFCE@?
FFE8F#
:gBqF F'$O
O
-8A|kBq"F KABs  
+8AkBq"F KABs  
F$FMVFFU lHFU<>
-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<B  F
Q\
)DD8QMF
@@ -1777,22 +1783,22 @@ A3xB@$FFCE@?
RF0F
-`f A|FF
+`f AFF
RFMF$ F8UlPF
:DP[FFFPOD'
-[F
+[F
1@S<J
-
-3Y҈B<QDT 1F(F(FF1FF
+
+3Y҈B<QDT 1F(F(FF1FF
1AҘB:SD<BA
2 C36F
-FBA
+FBA
O

-O
+O

-"
-Ѻ!FO ~ FQPF F!C $
+"
+Ѻ!FO ~ FQPF F!C $
{DhPz '
1 F1x0:Ҳ *
@@ -1800,37 +1806,37 @@ O

z
-FaF# d BpFF 0F$Fl3
+FaF# d BpFF80F<F3
4F
0`

-"
- OFFF$Fl3
+"
+ OFF0F<F3
z '
4FF d Kp/"!{DhP
-
+
{DhP.z '
Z
-VF F$Fl3
+VF F<F3
9{  #H|H=%BF5:и
F
-h%Dh
+h%Dh
R1B;O 
F
-
-U#0
-R1B;#
+
+U#0
+R1B;#
[h
0Q$p_ +-_;#a۲+/x3xB@U_FFCE@M?
 ?70FҲ *,#
 0_ +@PFB<0+
SF;,0*FFBׂ
- `
+ `
(

0&$ [ p*
@@ -1844,97 +1850,98 @@ F
OsO
ipEq 0
rF
-FFKABs A|#FO O
+FFKABs A#FO O
FFE
<
F0F$4<0; +
-:
+:
c csPC
K
-
+
< BF
->`
-
-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<GAE
+ 3E
+ OCCAB  3𦀌B AD@ )FF
+
2ҋB<AD
@"
,
 
-IF{
- 0EҊB AD? IF`F
- "; CAB
-  2ҎB 
-@FGAE 3E>@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****뻻<<<<SSSSaaaa++++~~~~wwww&&&&iiiiccccUUUU!!!! }}}}
+XXXXEEEE,,,,????kkkk::::AAAAOOOOggggꗗ𴴴sssstttt""""筭55557777uuuunnnnGGGGqqqq))))ʼnoooobbbbVVVV>>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<<SSSSaaaa++++~~~~wwww&&&&iiiiccccUUUU!!!! }}}}
|LuQnZgk>X`3Q}$Jv)Cb4o= x&u/3V8[%L.A aהlކ{ňv̢UXO᰽B =0'*z<Gt7Nf*Uh!\BcLj^qP x
dory2H+<C".^9 U0
-&;0YҒRۀODɤu~ch g
@@ -2086,7 +2093,7 @@ dory+2H"<C9.^0 U
-IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNNllllVVVVeeeezzzzxxxx%%%%....ttttKKKKpppp>>>>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<gHIKDJON
LLMFGETDA@B\CTU"WdVSR*PlQZ[2YtX]\:^|_
LЦTء\"d*l2t:|__ehdr_start.e_phentsize == sizeof *_dl_phdr
@@ -2100,15 +2107,20 @@ LLMFGETDA@B\CTU"WdVSR*PlQZ[2YtX]\:^|_


  
-
+
p=
^B{ I$ B|uPq
-
-
+
+
+
+
+
+
+
-
+
-
+
<sizes>
@@ -2136,7 +2148,7 @@ LLMFGETDA@B\CTU"WdVSR*PlQZ[2YtX]\:^|_
<aspace type="total" size="%zu"/>
<aspace type="mprotect" size="%zu"/>
</malloc>
-
+
@@ -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߸<bBQuɶluYD?e1Væ5RğIJ@A[
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u
@@ -2476,7 +2407,7 @@ calling fini: %s [%lu]
file=%s [%lu]; destroying link map
-
+
@@ -2491,274 +2422,288 @@ calling preinit: %s
p=
ףp=
؉؉ %^B{ $I$I$ =B!B|PuPuPqq
-
-_
-Z\
-ll
-
+
+_
+Z\
+ll

-b`
-T`
-Z`
-?
-? 
-
+b`
+
+
+T`
+
+
+Z`
+@
+
A 
- "
-v
+ "
+v
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-%
-Z
-
-
-
-v
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%
+Z
+
+
+v
+
+
+
+
+
+
+
+
+
+(
+)Z
+*Z
++
+.E
+.E
+0
+1L
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<
+
+'Q<
+
+
+
+<'Py
+
+
+
+'Q<
+'Q<
+
-
-
-
-
-
-
-
-
-"~
-*
-+Z
-,Z
--
-0E
-0E
-2
-3L
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<
-'Q$
-
-
-
-<'Py
-
-
-
-'Q$
-'Q$
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
-
-
+
+


-\
+w

-
-q
-0
-
->
+]
+
+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<u==.
+
+.1<u==.
//g=Zg%)!u@><~t2Z=ggL=.
-.!>>l!u< ./K1nty f?@gZ\=[
-mtI-eR-#
- /
-.*C'K
+.!0>l!u< ./K1nty f?@gZ\=[
<
-J[s0 tL$Y0 0$
-.vJ#./ =>!
-h<HZ=~f0?Z3/
+J[t0 tL$Y0 0$
+JCgh"YK==3-3Y_A
+.vJ#./ =>!
+h<HZ=~f0MZ3/
<2214121 .!!K<~<"!K2L. /!!!!"!!"!!!'!  %!K
- /!!!!"!!"!!!'!a *.2Z
+ /!!!!"!!"!!!'!a *.2Z
<B
-<}J$K!u?YOY!u=1K!uK=1!#1
-f!;#ugg/k.<Xo<"g>yfe
-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
-
- 0</00
-v
-
-X
-
-
-
-
-pP
- 0@""
-0
-@
-
-@-
-`
-
-pk
- 
-@
-
-/
-p`
-1
-`
-
-
-/:
-p`
+
+ B0
+p
+
+<0@, @
+
+
+$0@`Lp
+90
+$
+ >0@, @
+
+ 0</
+`
+
+
+
+
+
+?0@,(`8 @
+ 4
+
+
+"
+
+0(
+ 0@ P
+0! 4  0/
+0
+@
+
+@-
+`
+
+p}
+ 
+@
+( 
+p`
+
+
+1
+`
+
+( 9
+p`
+
+
-
+
@-
-
-
-
-0
-p
-< 0@
- 0
-
-
-0
-
-
-/
-
-
-0
-
-w
-s
- =
+
+
+
+0
+
+p
+?0@
+
+
+
+
+
+
+<
+
+0
+
+
+
+
+0
+
+^
+Z
+ =
-
-p
+
+p
-
-
+
+
0c?o20
-0c?o2 0J?o20J?o2 0J?o20J?o2d
+0c?o2 0J?o20J?o2 0J?o20J?o2
P
-`”
+`”
-
-p
-
-
-
-
-P ` 
-p
-
-
-
-
-d1-0@ @
-
-
-0
-800H?o20H?o20H?o2:0
-
-•
-10@-
-
+
+p
+
+
+
+
+P ` 
+
+
+
+
+0
+800H?o2
+
+•
+30@!
  r
-
-
-
-
-
-
-
-
-
-
-,
- c\F
-
-刲@(&΅ @
- 00
-
-(4
-0
-0
-
-
-
-
-Dz@
-
- 0cS
-
-
-@
-
-
-QP
-
- 0cS
-l3(0@ @
-P
-
-
-QaP
-
-@
-
-x SӁِ
- 0
-
-
-!
-5(0@ @
-
-
-!
-0 •0 </
-
- 
-
-
- @
-p 0
-
-`Pp
-`
-
-
-& 
-`0-
-
-p8f/`0@`
+
+
+
+
+
+
+90
+$ 0B 
+"
+
+ 
+ @
+ 
+O
+
+ P
+`Pp
+`
+
+
+
+->&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@</
+p <0@</
-
+

2

 
-
-
-
- 0
--:
-
-
-
-
+
+ 0
+:
+
+
+
+
010##(#4  0

"
-&.
+&.
M
- Č Ď Ă
+ Č Ď Ă

"
-&.B
+&.B
p
-ݍ<0@4 
-0
+ݍ?0@4 
+0
0
-ݍ 
+ݍ
+
0P 
p
0
a
-
+
0
P`
@@ -374,14 +328,14 @@ a
P
-
-
+
+
-
-
+
+
03/p
p 0
@@ -390,20 +344,20 @@ a

3/0
-=L-0@ @
+:<*0@ @
3/
- >L-0@ @
-4 0@-
+;<*0@ @
+$0@-

-
+
ЍD  d
0</
-
+
0
-$ЍD@
+$ЍD@
HЍxp
0
@@ -414,14 +368,14 @@ X

- 
+ 

X
X
 0A
-
+

 P|0
@@ -432,28 +386,28 @@ S
S
S
-
+

-
-
-P:kw0EoO0O
-7+?O 
+
+
+P:kw0EoO0O
+7+?O 
 [
J
]
-
+"
-
+


@0k

-
+
0
@@ -464,7 +418,8 @@ S
-
+
+
v

0
@@ -492,7 +447,7 @@ S
@
 
p@-`
-/
+0


@@ -505,78 +460,71 @@ p@-`
0
!0 0" 0 #0 0$ 0 %0 0& '00|
`0G| P
-
-
-P
-
-@-@@
+
+P
+
!s
- B0p@-
-r`@
+ B0p@-r`@
!s@
- B0p@-
-r`@
-!s@
+ B0p@-r`@
+!s@
P
-
-@D
-
+
+@D
+

-
-,
-X[
+
+
+ 
+[

-
-
-@-@ 
-04 0
-8
- 0@
+
+
+0$ 0
+( 0@
p
-80
-
-@
+(=
-
-
-
-0$0
-0$0
+
+
+
+0$0
+0$0
T0
-p
-`P@
-
+p

-
+
+
$
-
-@p`
-p
+
+p
+A$  
+
-p@0a0P4@8
+p@0a0P4@8
`.,@# !+(sP| {
-0h+dH)nD$ )P%k) l(i\%a(`%4@b |*<$|z`0 1qa
+0h+dH)nD$ )P%k) l(i\%a(`%$@b |*<$|z`0 1qa
"\"Ġ"H

-jO-<Mp404x 8 P
+jO-<Mp$04x 8 P
Pa0 4@ 

PpP`&Q
-
+
&
-5
-4/ @0
+5
+$, @0
`
-
-0
+
+0
,00/
-$0
+$0
$
1
@@ -585,22 +533,22 @@ $
/o"
-0C
+0C
1
` A
-
+

+

$!

-e
-
+e
+
A- g~
rc:UB-
-rrhY M FgKnCqEkI_A:%
-00?
+rrhY M FgKnCqEkI_A:%
+00?
00 00 01 00#4000#0020 0#40 00'0020$0#40$00+0020(0#40(00/0020,0#40,004`O-
䨠y'e+4*&u'ॱ+$*D`` `x
``)8y'H@堑)
@@ -682,26 +630,26 @@ p
,)v'K

`
-
+
0
-
-
+
+
 6 " 0
-
+
-
+
-
-
+
+
-
-
+
+
-
+
D03/
P`
@@ -709,112 +657,94 @@ P`
@0

-lN
+TK
03/
-
+
03/

-l^P@@03/
+T[ P@@03/
0
-0
+0
K


-@-W
+@-W


-
-0@1
+


-
-0@
+



-P
-0@1P
+P



-
-0@
+


-
-0@1
+


-
-0@
+


-
-0@
+


-
-0@
+


-
-0@
+


-
-0@
+


-
-0@
+


-
-0@
+


-
-0@
+
O


-
-0@
+


-
-0@
+
@-V


-
-0@
-P
+
+P

-
-0@Q
+


-P
+P

-
-p@a0
-
+
+


@@ -829,12 +759,10 @@ w


-
- @1
-
+
+
B
-
-0@Q
+


@@ -869,14 +797,14 @@ w
∠ 娐p
xP
-
+

p 
-
+
x00
@@ -888,9 +816,9 @@ xP
0 
Ѝp

-
-
-⪠቟$@?
+
+
+⪠቟$@?
!C!


@@ -898,11 +826,11 @@ xP

- 
+ 


@
- 0
+ 0
(
A0 L
@@ -910,18 +838,18 @@ xP
( 0O-`0
-@T@
+@T@
\
-
+


00(,
- 0
+ 0
1J1
-
+
<
@@ -950,78 +878,73 @@ P0
o0
bP@

-UpS 
+UpS 
+
- 0
+ 0
0
-
+
0!
-
-
-
-
-
-
-
- 
-
-
-
-
- 0
-
+
+
+
+
+
+
+ 
+
+
+ 0
+
4

- 
+ 
0 p
-
+
00
-40
+40
`0
-\0
+\0
T0
d
-\ 
+\ 
d(0
#

-
-
+
+
X
H
-0A
+0A
X 0
`#
-
-
-
+
+
+
H0
-10C
+10C
0
-
-H0`@
-
- 
-0@ 
+
+
+ 0@ 
0Ϡ  
-0
+0
!C!
l
   0
p
-!L!
+!L!


@@ -1030,17 +953,17 @@ p
p0 ` p (

-
+
O-p0M
0

`p p
0
- 0
+ 0
Ѝ
-
+
P `-

@@ -1052,55 +975,55 @@ P `-


-
+
B



`
-`
+`
p@-M




-
+
D
-@P D
-
+@P D
+
-
-
+
+
-
-
+
+
0 N
0 
(A 
  " 0
0
-
+
P
@}  " 0
-
+
H
-@
+@
-
-
-
-
+
+
+
+
-
-
+
+
0PD L
0
-  " T
-0t
-
-
+  " T
+0t
+
+

@@ -1108,7 +1031,7 @@ H

@D
((((4
- 
+ 
p: BAB  3ҍB AD
HFQGAE 3E=
: BAE  3E AD@)FF
@@ -1133,64 +1056,64 @@ H
@#E  !
FOCCAB  39ҍB 3MAF(FuF(F
AFKAB 3ҍB> 
-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 UF4F<iT  "*@
-
-`@FhAFD
-0FIF
-p_0dFeB"_Z
+
+`@FhAFD
+0FIF
+p_0dFeB"_Z
BV#

-SE<lD=k,(
+SE<lD=k,(
^yE.
-^yA.
-F-O#
-!8
+^yA.
+F-O#
+!8
!
-*
+*
SкE 
-d IF
-+hxʱ:*13F+:*F:BFK:,
+d IF
++hxʱ:*13F+:*F:BFK:,
-
+
F
@&3"@#۲@0
 1 F"O
- 0
+ 0
`4```x""F_+
F@
-' zJdFFFoWF
+' zH4FFFoWF
ByOj
E

-ZF 9F"RFGD8F
+ZF 9F"RFGD8F
DEFk .
К
!;`\@FA
@@ -1200,46 +1123,47 @@ ZF 9F"RFGD8F
P`D6( D$aB\a"Da  

-#300:0Ҳ *FB;0:0 _ Os$j
-7P&F;
+#300:0Ҳ *FB;0:0 _ Os$j
+7P&F;
"
-
-Mx@!
-O
-
-
-*\Б
+
+K`!
+O
+
+
+*\Б
"Bsk$30[k$07;۲B چE<#pELx
-"F$1 RkR$ @*E
-*VЖ
+"F$1 RkR$ @*E
+*VЖ
"B{k$30[k$07;۲B ڰB<#ӆBLx61
F(DAFEтBћjx8(
-"F$6 RkR$ @*
+"F$6 RkR$ @*

F7+иEM]D
-𾿝K-Op-]F{DhnY0F 0
-@ĹXFGF0?zO0 FAF<GF
- JDX S"0JOqq9aCGKE %` "O0{DhI qK"O0{DhI h0K@0y$X;
+𾿝K-Op-]F{DhnY0F 0
+@ĹXFGF0?zO0 FAF<GF
+ HcDX S"0HfOqq9aCGKE %` "O0{DhI qK"O0{DhI h0IC@0y$H4
+2
_oo
# B0 3o 3
-
-
-_yjѹͱ F !*FsC?ǭOssE
-$Fy
+
+
+_yjѹͱ F !*FsC?ǭOssE
+$Fy
ciiBY'"aap3{5Y@=ciiBZY+"aap3{5 ciiBY-"aap51i0)
-"
+"
"0OssE
-
-[DGDm@<P
+
+[DGDm@<P
_
-# D0x ۲Z+@PK-P5
-|KK"{DhI PX00tK{DhY0hjjP0+x;۲+P+xP
-0x$*? ۲Z+?X00KK"{DhI t
+# D0x ۲Z+@PK-P5
+|KK"{DhI PX00tK{DhY0hjjP0+x;۲+P+xP
+0x$*? ۲Z+?X00KK"{DhI X
"
-؂DѹKK"{DhI KK"{DhI F 0~kX>o
-
-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<k
- F2F0GBO5#hո
+%H%F
+~
+ F+!`.0h9n
+O<k
+ F2F0GBO5#hո
#(hhY`B#
-#hF:> FT&P!FD&
+#hF:> FT&P!FD&
1q
`8mF
- mZ
+ mZ
v
`o+! FAHBHA
-O
+O
` F !
-ݸo
-cdFV \Vxo
+ݸo
+cdFV \Vxo
"ze`
Л
- 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 F<cbN&
h
-c
+c
!
#ooxoU0yoo+#
hB) o2FoC&
@@ -1325,143 +1248,143 @@ ORDKF KFoo`RDoo
a
i/ F-!)CXBXA
Qi
-Nǹ)
+Nǹ)

%Fz`
fzhF
F0!0

-F:k0FF8ksf)оk:k
-O#`
+F:k0FF8ksf)оk:k
+Ls`
:@
-`7
+`7
FFF^
-`{+!0FAHBHA
+`{+!0FAHBHA
B
;C #
)@Կ
`W0F !
-"9F F
+"9F F


-C
+C

-8`
-л08FI 
-л08FI 
-Fo#sOxhO1!c`
+8`
+л08FI 
+л08FI 
+Fo#sLxcxhO1!c`
F#`?%C `USx0; +@&b*F6%C``
F#{PC#soSxh+#{c{
F2CC#scs]#{
FC#sV#{C#sSxl+
FK"{DOrbPDO
-Ѓ%!`a a(Fj
+Ѓ%!`a a(Fj
ACa;hB8F;`2ixS!0
0
-3# iF+x3 ?2D?B@Fzh!F 7FCpG@F)FI
-# 
-F
-F9F@F"F۹khDDl`
-
+3# iF+x3 ?2D?B@Fzh!F 7FCpG@F)FGc
+# 
+F
+F9F@F"F۹khDDl`
+
-00F9F"<iG(D,
+00F9F"<iG(D,
%hF+h)ԪlphhCEc!_R
"Aap)+htHo
-!0F+hFԫlZh:Z`ҹF`h_S
+!0F+hFԫlZh:Z`ҹF`h_S
O
_O
-
+
X
  Rh
\E

-MC
-#'` l0#hF(FC&`#h JpzDhX *
-p0FAF"<iG(D,
+Kp
+#'` l0#hF(FC&`#h JpzDhX *
+p0FAF"<iG(D,
*F
XD*F j
F`ba`!`0F`BlCh B #j
R `A#h##`0O1iG
,SM
-,ЙBD0pG08pG
+,ЙBD0pG08pG
ED(FFPFZF
\F
-
-"F0+FXF
--(Fn
+
+"F0+FXF
+-(Fn
\0ihBRHF-
)S
)ИEO
-*
-@
-#hk(F0O1hGJC ` !p?O0zDhPF)v+hFԫlZh:Z`ҹF`h_S
-h
-0F!F OO2O3#2;F@F1FH#3l0?
-JK<@PؿT
-F F F' F<F$
+*
+@
+#hk(F0O1hGJC ` !p?O0zDhPF)v+hFԫlZh:Z`ҹF`h_S
+h
+0F!F OO2O3#2;F@F1FH#3l0?
+JH,c@PؿT
+F F F' F<F$
*;2B
-=ГBF3O
+=ГBF3O
F O0kpFJIh@@
F Fgm
-F F
+F F
O
-PF
-/+
-2k;#0?
+PF
+/+
+2k;#0?
xHF!
-s#O3
+s#O3
- i
F`
-B`b`
-"FHFppjhDsbb3kHD
-"F\hpj3kD,
-H!"
-F`h_P
+B`b`܋
+"FHFppjhDsbb3kHD
+"F\hpj3kD,
+H!"
+F`h_P
%h
BF# F
g%baO0O1pG
+1
%x
--ЋBF3DppG0p8pG
-
+-ЋBF3DppG0p8pG
+
F FjG O3fdk

- Zh2Z`iC jii#`bff!flal
-
+ Zh2Z`iC jii#`bff!flal
+
bhLhh`#k+`%c8F#h
-DZ`ppGh ԜhAvhj]j`b`Xb`h
+DZ`ppGh ԜhAvhj]j`b`Xb`h
OJ
-E@0PFGF
+E@0PFGF

-# ciKD `HD"jID```caaZbapcih(FB8`O0
+# ciKD `HD"jID```caaZbapcih(FB8`O0
JD Y3iTEipi3jrhID
-
-_CWLYB9ICx|S`E.DBxd|dFF8FK@@K4AL`3
+
+_CWLYB9GdCx|S`E.DBxd|dFF8FI0I$JP
0O0

-ED
- P D
-ܽ F!"
-,
+ED
+ P D
+ܽ F!"
+,
2B@h*DB@FB0@f`@ihh DXh(@2(FF Fhch#D6)
-$I
-
-
+$Gc
+
+
.
-ch@I083 [7n3
+ch@Gg083 [7n3
w7|3 ByO
("DA
@@ -1469,59 +1392,59 @@ JD Y3iTEipi3jrhID
vH
(-O@[00sErFa?aZh
(9O@n0bkB BF
-FR~
+FR~
/@
-+@D/O~R
++@D/O~R
/ /
hث w:8T n
0 k
. 
)XhdF 
UE
- hhB@𨄏hB@𤄰
+ hhB@𨄏hB@𤄰
+  F
-F .|O~kZhB@
+F .|O~kZhB@
Fh
-hB@hhB@dXh``
- K@K4AL3
+hB@hhB@dXh``
+ II$J|
D*
UE0O  "VE

FO
-O0r`
-CQ``tJFGH4GFO
-a?KPK4AL3
-IKaF,K PK4AL3
-K1
-A !QFJ
-aJK@K4AL3
-K B
+O0r`
+CQ``tJFGH4GFO
+a?I I$Jp
+GhI1F,II$Jp
+I
+A !QFJ
+aJII$J|
+K B
-
-9IBH
- Jk`KhCK`IFV<C8FCF,"E!F0F
-h`F FRP
-WE=
-I!
-[ "_( O T
-ʿ
-F
+9GaBH
+ Jk`KhCK`IFV<C8FCF,"E!F0F
+h`F FRI
+WE=
+G`!
+[ "_( O T
+ʿ
+F
O
-KdOM3 IHh_T
-a(F*bj
-DSh
-y
-"Fo
+KdOM3 GdHh_T
+a(F*bj
+DSh
+y
+"Fo
"F
"Fo
-"FO0c5
-"jFo
+"FO0c5
+"jFo
"DFo
"9Fo
-".Fo
+".Fo
 n O< wٶ .|6~&B
` {
-U+2`*`hJ `E+@/FܫkB
+U+2`*`hJ `E+@/FܫkB
8
O\*
[
@@ -1532,15 +1455,15 @@ DSh
w
OL |
O~
-VE6H4+3#0Mb
+VE6H4+3#0K2
 n
-5O
-L F!"
-P4x
- _U
-Cc g(F!"
-
-"2B:FF(*F0FAFuBF70-"pB !FB(:F5D
+5O
+L F!"
+P4x
+ _U
+Cc g(F!"
+
+"2B:FF(*F0FAFuBF70-"pB !FB(:F5D
"BF:F0FAF(*F5
FB
BppG
@@ -1564,7 +1487,7 @@ FB
Ec

- (x\s\1B903E?Ӯ
+ (x\s\1B903E?Ӯ

W
('t&|d%lT$\D#LU `
@@ -1572,7 +1495,7 @@ W
('x&xh%hX$XH#HU `
01\#  R
('|&tl%d\$TL#DU `
-01\# c
+01\# c

@@ -1611,33 +1534,33 @@ W
 ++KK  ++K  ++ [ [" " $$&+&+([* * ,,.+.+
 ++{{  ++{` +
-
-F=HD T 
+
+F=HD T 
" \BxB
-+
++
E ܻ
sFhhBCKSE^DBȿB $ED P

-<oa9bchb{b@#h
-"qap0FA0I@!+h
-!::{j
-
-'
-KABp/O0{DhPKABp/O4{DhP
- @!
-B##FEC
+<oa9bchb{b@#h
+"qap0FA0GeMq+h
+!::{j
+
+'
+KABp/O0{DhPKABp/O4{DhP
+ @!
+B##FEC
1
S# +`8F FJFoc$<K{Dh[P8Foc $$$2K{Dh[P
-E#
+E#
{hKhf
-s"{c``B"s`L`ppGhK`Ch``D`
+s"{c``B"s`L`ppGhK`Ch``D`
 qh0K
P4

F
-^
+^
{o
s o
{o
@@ -1646,141 +1569,141 @@ s o
Bx!FBFHFV*hPF3hO KD+`
!D,`
!XF@O
-
-KdBp/
+
+KdBp/
"XFiFE
-"XF{`Gi{hE=ГF:KABp/{DhPM
- M0"vx00; +4
- 1FRF
-Fp
-"0Bx
+"XF{`Gi{hE=ГF:KABp/{DhPJP}aa
+ J a"vx00; +4
+ 1FRF
+Fp
+"0Bx
i@XD]KpGp?c2Z?(O3B4
-+8 FO3 2h_CR
-"+F
-Md 
++8 FO3 2h_CR
+"+F
+JTg 
O "' T
(;(CH|'ND|"
"1FT JH|'
O "f'O OO
--OOh`
-O h
+-OLch`
+Lf h
(h
-F h
+F h
`+` `
-P<P,#O2P<P<
- F
-)@C@s`Fid2M@
-:2M\0Ml1MS
+P<P,#O2P<P<
+ F
+)@C@s`Fid2K
+:2KL
Vyq߉R
{)R
hIDBhBПh9DBihEREFX23VE``
-D D0@9s+J
-x0:Ӳ +"KxM0 , 1 FB;0:0 ,.+B
+D D0N93+GP
+x0:Ӳ +"KxM0 , 1 FB;0:0 ,.+B
- FE\
-oFi
+ FE\
+oFi
{DhEKp_{DhU
-  YLTh&i
+  YLTh&i
`hX`
-F+,*
-aK.F`]$shc`sh&Fuh&F+F-OF0LdЛF+h;
-
-V$ (gV<$68F^@FIFC
-;n
+F+,*
+aK.F`]$shc`sh&Fuh&F+F-OF0LdЛF+h;
+
+V$ (gV<$68F^@FIFC
+;n
!F
K,<#K4<
HF
-
-,h
-0 @F0
- FF:a{`
-"{`Mi{hBE (F!yaZF"za^FMF
+
+,h
+0 @F0
+ FF:a{`
+"{`Mi{hBE (F!yaZF"za^FMF
F:)
-:+
-:+ x F1
-(=a[hia3#i hFM#Fi`Ja(`hF`
+:+
+:+ x F1
+(=a[hia3#i hFKpsFi`H1(`hF`
"3F:$#!XFx
PSD

-a
-F
-+ 
+a
+F
++ 
KBF4$(F
B@
-bBF3#(F
+bBF3#(F
*ܚEO
-C`FM0PMQNT
+C`FK K !KDc
F H
-k
+k
G(\ B@À
-BF3#(Ft4F;F
+BF3#(Ft4F;F
*YܚEO
C`
-G&h-M0PMQN4
+G&h-K K !K$c

- B@
+ B@
*ܚEO
-C`FM0PMQN
+C`FK K !K
HO
-kP3I#h
+kP3Fsh
C`@y*
G(m B@
-BF3#(F
+BF3#(F
*[ܚEO
C`
-G :h
-k
+G :h
+k
FGF
-*h
- k6m3I#h^@
+*h
+ k6m3Fsh^@
:F3F B𹀕B@h)lSp1 FBѓF
 G( [E@#h

O
 O
1
-
-C`
- G7h M
+
+C`
+ G7h KK !K<S
-F2B q  _?
-`|M`MQN0
+F2B q  _?
+`|K0K!K S
$ 
-mk3I#hZ@
+mk3FshZ@

CpF

1BDBـB>S <
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
-ФF<F)!0DBA)`R
-
- G*Oa"Oa"_M
-k
+ )!)@!PB"FO 4 
+     ٝ@0+ A
+ФF<F)!0DBA)`R
+
+ G*Oa"Oa"_KK !KC
+k

@
F
@@ -1788,87 +1711,85 @@ BF=F #E%FFx+o2+`B*`
`=$
##DBB
--;F/D\3Bq   M
+-;F/D\3Bq   KK !KC
@X`x2q hB0h!
-C`{2h
- mk3I#hY@
+C`{2h
+ mk3FshY@
 G(KB@5
`P _3F?I
-h8!F FM
-C`("F
- G/hEM
-`1M`MQM@s
+h8!F FKK !KLC
+C`("F
+ G/hEKK !KLC
+`1K0K!K0C

@
F
'G" W
##DBB
--;F/D\3Bq  } M
+-;F/D\3Bq  } KK !KC
@X`x2q hB0h!
-C`2h
- mk3I#hY@
+C`2h
+ mk3FshY@
 G(EB@
Sp71:F FEgF\FF*-(F
-Sp23cE@& 
+Sp23cE@& 
C`8
- G/hmM
-` BF2h
+ G/hmKK !K3
+` BF2h
@36
D R S" sFP"
BuK @{DhX
gF @Q ["0F S
F
-`;`!F!h32:` `-
-8FXi8j)hJFF
+`;`!F!h32:` `-
+8FXi8j)hJFF
F
.F1FXF F 0O 
-+@F\D
-F
++@F\D
+F
}H ibh3C

-
-Z@"aX@`a#h"
+
+Z@"aX@`a#h"

-,S
-pFαJh F7@Jxa F/
+pFαHQh F7@Hh1 F/
B
lhADO=0

-  - ,S `
-
+  - ,S `
PExe
-0FTF
+0FTF
ii*F
-
-DD
-
+
+
O  

 X
0TQ
3]ID
Z0G@0V
-PFBziB@P Ѡm;iB JB9ieOh2`yGKp/!
+PFBziB@P Ѡm;iB HSB9ieLlch2`yGKp/!
O

- B{iHF"F;iD+
-
-h"Oc B@&NEwhU$0B
-`33#  FsNQ"lN!N#
-rD FO
-fhB
-SFFFFziFKFFDFFEDD @Fah
-O
+ B{iHF"F;iD+
+
+h"Oc B@&LwhU$0B
+`33#  FsL!"lKqKs
+rD FO
+fhB
+SFFFFziFKFFDFFEDD @Fah
+O
gi
-O93h4`.F#`65  . +D0FZh\n
+O93h4`.F#`65  . +D0FZh\n
CQB
C ppG
-~
-F#
+l
+F#
OJ 9
JE
@@ -1910,11 +1831,11 @@ A`$!
EخFFpE1FsF/Fx B pFٮB
#Fxx B!FBFG
-#Fxx B FIFBFG
-
-NP!
-" lF*F1F F=%yih
-*F0*"*8 F9Fs\ FEF9F9F
+#Fxx B FIFBFG
+
+L !
+" lF*F1F F=%yih
+*F0*"*8 F9Fs\ FEF9F9F
)
)

@@ -1941,7 +1862,7 @@ b
B
F)FK
-BKD(F 0
+BKD(F 0
J
@@ -1963,17 +1884,19 @@ J

F d

-XFl-OpO
+XFl-OpO

ƱnHFbk200BYx20

ԁFEC%

-E@ՇBѼg&
+E@ՇBѼg&
F0

Nk6
-:xzh%=S-πws3xTK@P{DhP<o&O5=g
+:xzh%=S-πws3xTK@P{DhP<o&O5=g
+
+
F1

ck30
@@ -2000,13 +1923,13 @@ ck30
F<I0sxyD h^
:?\0BK0
+2<n
-F0FJ 
+F0F:

 0cX,F
F0oB(%F? <_XFz`zho9LEF4FXFz`BzhoF3DD
n@
#0@
- %j|ot @!F
+ %j|ot @!F

ck30=|oLV<m`n0 

@@ -2021,45 +1944,45 @@ Kk308XF_
O4@P9m`vE:m2
D
h 0@@xoB
-
+
B*zo4Fl`Rf
-m:mh!BMm`8o
+m:mh!BMm`8o


-<B@kx
+<B@kx

<BApc05

kS"0n+B
-@,P&@B@
-kS"0f+BP
-:n-n}m{mC3!
-:BBcx5
+@,P&@B@
+kS"0f+BP
+:n-n}m{mC3!
+:BBcx5
*J;nF m3~lEe|d,Fc{bF

<HE#F,F5FF
:9ME ҠFXF E+3DD
*(QѺmTF;j2BekUF|lt|

-0E030i2F%FFEv
+0E030i2F%FFEv
 BȇQ
-}o4Fme&+hPB=o:C"@5=gDO5F=g>O4<g9XF?F}`KP{DhX0X|n°OuP;KT"P&{DhPp$&eT
+}o4Fme&+hPB=o:C"@5=gDO5F=g>O4<g9XF?F}`KP{DhX0X|n°OuP;KT"P&{DhPp$&eT
K@{DhX0#PO4
-
+

k. "F|d
,
-:8l(F>b9lB,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`e<i
FxlPPAFV
@@ -2067,242 +1990,245 @@ yn8Oz

(`m<&@O5
xn8Oz
-# kFE
+# kFE
<_XF9o
-4BFF6XF(Eo3DD
+4BFF6XF(Eo3DD
#~o
-D3l ):;m
-&`P4!`a
+D3l ):;m
+&`P4!`a
!z`P FV!0
-!,+`@zhF
+!,+`@zhF
!z`lP FV!0
!,+`@2zhF
&g~m4#
`
C@~iBgo.Bc.0# E<xcjjC#
-#x
-+~8l
+#x
++~8l
XSBSA*F
-+ ?0F)F*FF`i
++ ?0F)F*FF`i
.
*~;l
0F)F
-&*F`0F
+&*F`0F
.4.#. RFFFFFeF Foz`>k 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`<`<i
-B@X
-( @FJF!;hE
-  h
- FY
-
-
- Kp/!O0{DhPpGKABp/O0{DhPT
+Ya`xB РhchB F`KAhsjj2kCE RDQ`<`<i
+B@X
+( @FJF!;hE
+  h
+ FY
+
+
+ Kp/!O0{DhPpGKABp/O0{DhPM
F
-(F#Dl!)FB
- h)ca
-
-F
-l F
-G+hmh\a
-G+hZi_TQ
-KABp/O0{DhPKp/!O0{DhPpG
+(F#Dl!)FB
+ h)ca
+
+F
+l F
+G+hmh\a
+G+hZi_TQ
+KABp/O0{DhPKp/!O0{DhPpG
@  h`(FO|p_p@pGYF(FO|Z_F0F F
-KABp/O0{DhPKABp/O4{DhP
+KABp/O0{DhPKABp/O4{DhP
@  hp(FB
-KABp/O0{DhPKABp/O4{DhP
-KABp/O4{DhP$K
+KABp/O0{DhPKABp/O4{DhP
+KABp/O4{DhPD
FFpGx/)
-F
-8b
+F
+
+
+8b
-aP*NRVOptFNlqIbF@#
-Q3&dFtI(b zd;dcKE
-
+aP*NRVLXjtFLTAGx2F@#
+Q3&dFtI(b zd;dcKE
+
PD:hADd

FT ,D:mB0la ٸlS,B dT,F9l
@8"hF
`
-
+
F ( 3xkYF"FB@X1\$Oaq
-)@C@s`0F
+)@C@s`0F
D 2BH
-D(F~I"2
-HF"
-hh
-6
+D(F~I"2
+HF"
+hh
-
-xI+OFFDF F  O
-FN
-FN(C
- F/!
- F/!
-KO О3Fb
+
+xF{LlFFDF F  O
+FL
+FL
+
+ F/!
+ F/!
+KO О3Fb
(F
*i2

WF(Fe,5F8
-_lQ
-
-IF"
-"hx C;ONd1J
-O
-+ +  
-FN
- hN@khNcF cNazdNHb0L  O
+_lQ
+
+IF"
+
+"hx C;LjLTG`
+Lb
++ +  
+FL i
+ hL0;hL3F cL1zdL820L  O
4L0c9ddTSLED
-N@a#0  @FTENr
-< O 4cc9cEDZJO
-BO<O
-#, aL1p[hhxh^hUB!|QhA!1pk۱[hS+x!1!pGNpNQNs
-'Fh
- F
-J
-
-F:fp Rh*
+L01#0  @FTELB
+< O 4cc9cEDZJLQLR LQ#0  HFtFE
+BO<O
+#, aL1p[hhxh^hUB!|QhA!1pk۱[hS+x!1!pGL@L!LC
+'Fh
+ F
+J
+
+F:fp Rh*
O,0 D ~e
F$
-)
+)
O-4 D
d
F$
)
-D"|i
-De=lff}g"F#FB_ L0|cdF<F
+D"|i
+De=lff}g"F#FB_ Jp|cdF<F
d
F$
-)
+)
F$
-)
-RhhDD
-DP0҉
-DPF;`;h<
+)
+RhhDD
+DP0҉
+DPF;`;h<
H
Ha

-  ;cZ c8<
+  ;cZ c8<


- E:
+ E:
+
-6
- Z ѾlF;dk
+6
+ Z ѾlF;dk
 #HB
C 


P`1dEE
-l%C;d5;m/$hhs=mm
-F
+l%C;d5;m/$hhs=mm
+F
-
+
+;Sx2F%+
+ЈF
#
- 0O0*+qN@NANC
+ 0O0*+qLLL
##0h`2Fh
-МEF1F8 FE A5
-O
+МEF1F8 FE A5
+O
YF
-
-
-##`p/i+O!AFHFO FOpFr
+
+
+##`p/i+O!AFHFO FOpFb
&a
$O
@
-Nch
+L3h
L9iBNҹiBLhZj_D^
FA 
 _DT
-BiBiJI$ \j  _&DQ
+BiBiJI$ \j  _&DQ
-02
-#{;hF3V,4B KBЦ
-Q2 ?F
+02
+#{;hF3V,4B KBЦ
+Q2 ?F
!F# FbKi1]\B)  h
-) h
+) h
F`1jOIЈFO
a# 3  ;b`F

-\j O
-hFFBIh
+\j O
+hFFBIh
0 
zbF<08}d8l
0

-E
-%@.P
-8 dO8 OO(C
+E
+%@.P
+8 dL(pLaM
DlB 8lhB`O
?安E KEّFdO
02O
 lF8lO
-d`O00OO(C
-x0 ,ٓB0x1
+d`M
+x0 ,ٓB0x1

vvt
F'FF
umOE QiB1DHF
-8EݽOP@)
-
+8EݽM@)
+
@CC #
U<BBD
-
-/
-O
+
+/
+O


+(

-*БO
+*БO
!`
"
@@ -2310,7 +2236,7 @@ x0 ,ٓB0x1
F,`E4@!

"fE
-3
+3
FrBD0FҲ *,ZE#qFoBBOF7
"F

@@ -2318,7 +2244,7 @@ x0 ,ٓB0x1
+(

-*sБO
+*sБO
!`
"
@@ -2328,20 +2254,20 @@ x0 ,ٓB0x1
"E
3
FrBD0FҲ *,ZE"qF
-
-"F$5 R< R$ @*
+
+"F$5 R< R$ @*
o}O3Bu
{DhP6
,u
{DhP


-F"4F@FAFE
+F"4F@FAFE
R1B;O 
F
-
-U#0
-R1B;#
+
+U#0
+R1B;#
[h
08Q$Ӳ +_;#aڲ*+@ˀ
@@ -2349,7 +2275,7 @@ F
 0_ +@FB<0+
SF;,0*FFB
-0۲ +Jk$0i+
+0۲ +HWk$0i+
(
A3xB@$FFCE@?

@@ -2361,9 +2287,9 @@ A3xB@$FFCE@?
FFE8F#
:gBqF F'$O
O
-8KLkBq"F KABs  
+8IkBq"F KABs  
F$FMVFFU lHFU<>
-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<J
3Y҈B<QDT 1F(F(FF1FF
1AҘB:SD<BA
2 C36F
-FBA
+FBA
O

-O
+O

-"
-Ѻ!FOb ~ FQPF F!C $
+"
+Ѻ!FOb ~ FQPF F!C $
{DhPz '
1 F1x0:Ҳ *
@@ -2418,37 +2344,37 @@ O

z
-FaF# d BpF@POTa@
+FaF# d BpFM@`MD1Mc
4F
0`

-"
- OFOHpOTa@
+"
+ OFM8@MD1Mc
z '
4FF d Kp/"!{DhP
-
+
{DhP.z '
Z
-V@
+VMPMD1Mc
9{  #H|H=%BF5:и
F
-kh%Dh
+kh%Dh
R1B;O 
F
-
-U#0
-R1B;#
+
+U#0
+R1B;#
[h
0Q$p_ +-_;#a۲+/x3xB@U_FFCE@M?
 ?70FҲ *,#
 0_ +@PFB<0+
SF;,0*FFBׂ
- `
+ `
(

0&$ [ p*
@@ -2462,21 +2388,21 @@ F
OsO
ipEq 0
rF
-FFKABs KA#FO O
+FFKABs I#FO O
FFE
<
F0F$4<0; +
-:
+:
c csPC
K
< BF
->`
-
-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&<SsEfFh
-1`1X
-S/`1 SE ;D 
-#<b{cdF@{kxl; DDD2\`,;lE+ (Fi^, F99BQ/
-
-Fh
-PF-F
+1`1X
+S/`1 SE ;D 
+#<b{cdF@{kxl; DDD2\`,;lE+ (Fi^, F99BQ/
+
+Fh
+PF-F
Ҳ*JZ{{ bRhpa2 Qh
-+AOhbQF@pP@Q@S
++ALchbQFN` N!N#
_Owђ b
1
-++OhQO3HF)F`(F)FO3`O "_{!hUh
-+ DNChGF@pP@Q@S
+++LchQO3HF)F`(F)FO3`O "_{!hUh
++ DLhGFN` N!N#
-=
+=
R
0jD2\i! B 23нiEhS,3F88BP
-
-Z=G<kmZh+hDG1  E31ii=Laad$7FhF
-h`UL<`
-#=`@sx`<F`40)F  (FBTB$PhXFXID
-
+
+Z=G<kmZh+hDG1  E31ii=Laad$7FhF
+h`UL<`
+#=`NCx`<F`40)F  (FBTB$PhXFXID
+
%F`1

-E\1@FOS*
-0SD
-#=b@sxb b(a60)F  (FFEV@hu ah xcJNd3hh
+E\1@FOS*
+0SD
+#=bNCxb b(a60)F  (FFEVNXE ah xcGbLThh
FB?
-*D<F,7FJHhB7+F
-(
- O 
+*D<F,7FG8chB7+F
+(
+ O 
F
h{D 
DGE
 X
-
+
D FB
@+P+0+F@{+ о6

-Bج
-@
- {DhXh@
-,Fh hh F
+Bج
+0FAK K!K#
+@
+ {DhXh@
+,Fh hh F
%s
Usage: %s [-qh?] --in ... --out ... --type ...
or
@@ -2634,14 +2561,13 @@ or
-
-
+
-
+


@@ -2660,8 +2586,8 @@ IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNN
-XXXXEEEE,,,,????kkkk::::AAAAOOOOggggꗗ𴴴sssstttt""""筭55557777uuuunnnnGGGGqqqq))))ʼnoooobbbbVVVV>>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<<SSSSaaaa++++~~~~wwww&&&&iiiiccccUUUU!!!! }}}}
- 
+XXXXEEEE,,,,????kkkk::::AAAAOOOOggggꗗ𴴴sssstttt""""筭55557777uuuunnnnGGGGqqqq))))ʼnoooobbbbVVVV>>>>KKKKyyyy xxxxZZZZݨ33331111YYYY''''____````QQQQJJJJ ----zzzzɜ;;;;MMMM****뻻<<<<SSSSaaaa++++~~~~wwww&&&&iiiiccccUUUU!!!! }}}}
+ 
%n
@@ -2672,27 +2598,15 @@ IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNN


  
-
+
p=
^B{ I$ B|uPq
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
<sizes>
@@ -2720,7 +2634,7 @@ IIII$$$$\\\\Ӭbbbbyyyy7777mmmmNNNN
<aspace type="total" size="%zu"/>
<aspace type="mprotect" size="%zu"/>
</malloc>
-
+
@@ -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߸<bBQuɶluYD?e1Væ5RğIJ@A[
-
-
-
-
-
-
-
+
+
entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u
@@ -2979,7 +2888,7 @@ calling fini: %s [%lu]
file=%s [%lu]; destroying link map
-
+
p=
ףp=
؉؉ %^B{ $I$I$ =B!B|PuPuPqq
@@ -2994,1190 +2903,1162 @@ calling preinit: %s
-
-_
-\d
-rt
-Z\
-ll
-T`
-b`
-Z`
-Ԏ
-
-
+
+_
+\d
+rt
+Z\
+ll
+T`
+b`
+Z`
+
+
+
A 
- "
-$B
+ "
+$B
$B a
$B _
-$B
+$B

-
-
+
+
B R
-B B,
+B B,
A u
-A B
-
-
-
- B
+A B
+ B
A C
-A
-B
-$B
+A
+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
-
+
$A B I
$A B
-
-
-$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
-
- 
- B A
+,BP$K
+
+ 
+ B A
B M
-B
-$A B A
-
-B
-B
+B
+$A B A
+
+B
+B
$B d
-$B 
+$B 
A G
-A
-A
-A
-B
-A
+A
+A
+A
+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
+$B B
+B
+C
+C
+C
+B A
+B A
$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 
-A
-
-B
+$A B
+
+A 
+A
+
+B
$B 
-$B
+$B
$B 
-$B
+$B
$A B !
-$A B
-
-,A BP$B
-
-B
+$A B
+
+,A BP$B
+B
B M
-B
-A
-$B
-
-B
+B
+A
+$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 C
B L
-B
+B
$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
-C
-B
- A W
-
-$B
+ B
+BA
+BA
+C
+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 
+
$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 O
-A
+A
A w
A e
-A
-
-A
+A
+
+A


-
-A
-B B
-
-
+
+A
+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
-A
-A
-$A B
+$A B 
+A
+B B
+A
+A
+$A 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-D
-
-
-F
-
-
-
-
-
-
-
-
-
-
-W
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-l
-
-
-
-
-
-
-
-
-
-
-
-
-
-x
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+F
+
+
+
+
+
+N
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+v
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hdcp_rx22/firmware/esm_config.i b/hdcp_rx22/firmware/esm_config.i
index 466cc5b..fcfe773 100644
--- a/hdcp_rx22/firmware/esm_config.i
+++ b/hdcp_rx22/firmware/esm_config.i
@@ -1 +1 @@
-CWɮ 
+CWɮ
diff --git a/hdcp_rx22/firmware/firmware.le b/hdcp_rx22/firmware/firmware.le
index cd007ef..6875f5a 100644
--- a/hdcp_rx22/firmware/firmware.le
+++ b/hdcp_rx22/firmware/firmware.le
@@ -1,17 +1,21 @@
-ND QXLnX |?[Ic99k:oׅ[Pb^
-ZHٓ?-]vBtS##P5: Zo<EH;"QZi%<eLOF8rwDu$ίjr.U_Q ϱu>
-.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<EH;"QZi%<eLOF8rwDu$ίjr.U_Q ϱu>
+.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Ħ4<C)G5[s$.m=CQfk ` lbE!JNUL4Oe!8exJ`Cs᪋(b)ubWH&0dLߺ52ƯIS!ߔ|+̯|MwvPjG)"ugW. 4|eԞ]1e̡ =;{9TtN`~DhPt/҆z3#}t4KFWkcko`
-$ȿ f?G.|Z40
-̀n'WFZ,f:`W)`68zj&2{q
- h>OƦ_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Ħ4<C)G5[s$.m=CQfk ` lbE!JNUL4Oe!8exJ`Cs᪋(b)ubWH52ƯIS!ߔ|+̯|!!k.~*ypgW. 4|eԞ]1e̡ =;{9TtN`~DhPt/҆z3#}t4KFWkcio`
+B(%$ȿ f?G.|Z40
+̀n'WFZ-f:`WEg68zI̮yc@
+ h>OƦ_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-}<PZ&e`
+ nY#_0l
44Y*+}sș]Z[? 44Jd\tEq K?k 4|\/܇F,:V$f).jp`u^NdKE_a#i3bR@˩N'*i׶yF ?Cҝ0P"-կ& ~3
BD9DS!9 4Cvjv;?eGuڨ}{ɠ?8޾㈮tdFqGο/J (D\FK@} RHأ_?B/[#K9'oy;"c@?C?YB0
~݊>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_<aE'r; XüpX#9 @Ա9bZ8( f`%Rc?fh<Ei;]7O\Y7Zh1YICvy`:?l]m^9VW'
+\ڥ8rŽ4;mGa]$;Fpμ{h̑!-Hm?0T< "_Un/Uvd0e?Ө$|fgUnșT{£IfG\U07
+W6>dJzɗWxN|? |3`nd >TԷOua]Ҟ<KA)C!UUv~: }`eB2\JN%)V?m>`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|WFw<? FetN4+.~(Zӗo{I9Ս1?Y44.*7!>M!/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):\p<RAxgq˫wgm^iLks;zI E3Sk:р3pb4eL `kOڰΧgVy=f[,#mT 73nv Vá=^V;mV) yWqr;' 2eL"I7doބ3Ԛdwmh*qt?'Nb oVD3 th>X`e8Kwok8qD,+޳Φ.MaXN6qL /%A4$~& IG0O}Ns U?O΍ŎO\dv.z˵։3XIXa<Q8oGM#&%؇ʙ5p
lB\O,=3<UNgw |/Zሀ0D)rI"(DߟlJ0yu)x88UW͞9 يӈb6_[ܘ$4:*HDf0J/ jEs'\OpȜҥcqڎ=J:;=r7RzIʝ,0sNaaW[_Id
N{ z9p79 /_MYzyõncRh&<f uD,o D %Zwܵq瞀n1d*2%9KYocI6$թ fx7n;Wbh16;b9Z0쪀~@#q}*_~g`b uݘרI ĝSJt}xn}-ab s!Ǧ,'2rś@"̰sӒW ðO_䙙}{h9;%H:ſrdIgH"=ۄxحRLq#X@.M +_g8}_6z{-yԎ
@@ -66,399 +85,426 @@ eVu@AoOt7z5"\ԙDȱyL+ C{YR& !.)4y
=/SU䈌 EV{z:XvkVҊI
p
Q&v" A B)䶊g̅:G=p&D,I@.!G9Tr8c]-ƿQ,Y\'ZBOݭf}
-M-BI.Nc d!*F*x
-nb^QM4G:̏
-=|U8pkCC -JѨ@#ڒ4%ǓI` +:Xl9Q-O.]aUbF?<=Flb 7,lZmm=QU@[;!BV
-=DXC8 OJ`eۋW~ '\{+9mg1jvCEZn
-;mHFQJbIΆep{@S"PPW;y/ m'+r)Q;kSX5)Dن*5?ZPLR1i]ZmE󮄆>kCa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<Rވ*!dFp% pC40j;'P>}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
-<Q O{^wU $L莏O jQ9o1.ɽ+ 9q+fLj8 )S
-\hJEȳ|*JO(}4 Z&E1$Oo:NVITsX
-oA7A<iNS[+ưfm"L5>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|.ɶ: iL<MyOȌ} ;<&F:Er!T Sc;X"( u-T8ڣp<ZƟn!\yÎ61N"~FSRHY$)l]csiwB.mKbn@+Ku+uw82FʊRJuk/UۿUtҵHEx̴ cX/g${0D{NIv'8M-$tN?O8>tbh>*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 ~{5<bsb ocFڼVtuCP64=bȻX4^S>c.[}
-!y^[P&5vG^G섔yݾm+ k<C|{9 \#P#bC:u~M]+-\(VhO[,*R)5e
-HM/bZתHҭyF>~݅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(yB<jI@ i$>Suh
-_@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
-ȡs<r=SEcKU/v
-SOcڗ.;IU.
-XaHJȚ+bتD<Zl$gn t<oLTxÂWçN}u/?)J!<P|gPՂ;N_l0k^M;C˸"wbn-r[>i :)'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[s<P"6٬VćDҬ&>Pabj*&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<U๬ NpUe -Pk]Eha֐ӌzJ .>|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<\u<r~Pa[9l Pyf7'-.ό+3ғ`/{)J>4><ِS 'u<n-ud y}?f3{J.:|;zZ9$4
-& T? C@A̍6ca~4uBTw' `Vv_JC$">
-:o`ٴ7+y4/y϶1rUXE/n{]̹_gXR7<^)סE,Yh#0&OvAwy2<>p 8D
-6*lh1]L-5.<at)f=)dZJb!KM0c!}hM|R|ȳ󰥵n ~ *3
-DHkRj%fB: W8gE}?Srnjt/ ;gą3nM,K~eƹCp"3숛͹@$D[eA:I#ú[>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+
-/FqQ<uGҒ{C;
-!'`lAarz|]D9hi|)B R3#}AL4ˏ* 2'x3呖ܴ,۵}I5
-2.Efjpt
-aeK<f)\.m4GK\":U1\Ne7dKK\%j]k TAdsZbbj KaF .*<j~RaM0hP7 = `OlhR;tYEXB8ȇlC:KOF= 0d \1+UvIQhh6HzVҺ`X9@u^aG|g(Gưa;Tdh&;ӻ{)P[#
-
-gWW5)$T?ʢwC ked%݉ۗWPѸȰCStK
-K7igѱ6EGRX1K0/JXXҚOY-`m}_K*GR|&ԡ38^AـjR'۽yyBiW`[&h,p?<yW"zILa),{;̢]ou孱!TS
-Ъ
-(rjzH Wau mmܗX'D6xג\ڹo%2bN~ +f*js00.5*$]</uH9EV [$qmZnm;vCt\x駒JC
-;U4.]PXj+'FWήa%<!ӒATmiR\5@K}aM`:{شGrҦvhK^rt
-ߺ%`ڞG: x.~)&-5+`qKRLք ;z[&67G>lyE;-ڈ~Z|(x'zi" N,ErZw{+l6@>J<I> [)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=<HEiDڡgaq MwLW=URV^.
-%Xs*SuRv!D%|@`74m:&9h(kJ^c%xqˁJK5=ԺJ mv۱y,[f^^t&射S9¨H^ \U.rxxx_ bZJA; [dsC
-E
-Ci~dfQ3zznB:9YթCdڈR+Z
-H!򇚗ilvL{-$ӊ`(TwHP (U}[MS᥾.Z8 HLCZ$I 0N2ح~'.u?TK.ਪ]l13خ$CW" M_ʕ߻3FQ驐M!Zw&4$WlWxy _>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ϟ}]//><F7<$
-?5?'\x; ѡX-J{zʺGL[?eY+rz EuR$j
--C>%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Ђ<ie t֝C"JO~Pt?秹^Ni;lAϫS*rY
-ywn"t}Aٖ1^x\b0 vVc^nB;X"(rh gZǦfEfR"Im' m,R,`y7dI6;fw(?:OBF琊IR> 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<DТ_ØgXߎ|͡:{ʊ;&*893TJ*ԓzor綇.İK~sY%Y/\1uE5XuOXk7@0GBˍxCZ9O/
-:?8r!o#dlɄ7C5xFs C:!2rx-hN`{J[8ţ<jZwVrW'3mfbMN:!.}Skǝ iШt_,OT+0mKd
-2<!@%O=UR3 m̅< K|J `󇹎PUNh&\ $.*~/uӱC#7jLֺ,"{tuTent~_ZW=ۭ|A=/IoebNKii4m1#c lJ0CvwSFlm_)_T$u.Tġ
-|Ȼ4;+RJ"g"m0!Q#(6Mq=.:X1g&,)`y3ʥ񻏣w#eq܉b$R]jnj[S~⻲AvpNky< ZE$y=:K-(8P':6KL%8_?B_e顰ypT#,1=~OԭĔacqF1ڞGyO>@0?"
-!1Eq)B}(H~\JǷ){(~D*+^Z`gZxLCV R-K\bԌ}DO/pO[kGĞL. <4
-WM|<GpF_i<s4)I{^ 4"]d2}֞@`IV%/3\IM^4_xOnR?&Hzf\uoCe 4Zo
-K=GVwY{[@}6zgdHқ H^ՙ͆vK/t`)FQ {Z$ϗQaF{k
-CaL
-g>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/@}<U s
-^#^|hbc#T[##mB+Î-Sk/|J( 0l&pu^1,`ONkU'v7:SVwБ7x@sBa!`P:8.B[<@IT(ԥ餥;ڮ*^M5`n ]ćK㏳2͋:w: GA
-u+4P|^qϤ(?K W|r5rRC4Y9q;=pc6i|֯SQvʬxl&YF9`
-Id)8SȺ]jhܾ !;#󱫵->:]ol\cuHWkE'b%]RG$HN;F4
-xv8irf%i~=7*{-RٝL'B<J:?lan]F%! :EKK5ninLFKt aN:F{`]}wfU_G 3X0 Ƣ*+-U^1:ٟ}FPd pL*6AjrP]"œ"LY+@{?IYa?YHI9 ]}(,4|znWǓa֌3!IkcMi82Q+kNg\L~TpC>:
-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&<?P7 kq $$[Fо55XmӁ q%=c:uӽ,=Pgmqry?+RP%DO |G=Ğ-}K_3Þa.C2EE^
-l%g[Ih?8˵]CbL0FcgT`Xp1;pgă@vy4%@0N|-/*:TOé=os&A6+"h
-BPga]R';uJ֙o
-0t"\/ʴ.[dWe{Ȁ&|5"yx_mI﷘N
-
-q:@ح;sjFlF bZp7MC* agn%{P6=5j1
-_k"æV W!8ANmӤDW =]]oTzt{FIG_/24r13/<j殜#-_3vm&V`"7CTTx&OԨ,?"*~cr4b'B[xa|JR 98 jG!lx;$M,7]}롵m`vC?XmזN\VT
-~ա%|05C:1գc>Ѥ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
-<m
-{p_\jyRvώ H>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%<B!B}آm1Ɩ|Aa=P<U=ԂƔgۜ -W"^mi67SȁO i;7w>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 <xj< [9=:Nb
-o7nzcRe ΣLqz}X z )C6ͦM.!3pGI׋
-Dnp%6j1 CےM-X 
-8?\GB(*J|x-m);4rze1QTg = ':=(ў55!S"{[〨(f} 'b=&lO",Źŋk*h^#/hS+~>=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`8<t
-QqOhXtk
-K "ՊbR?lMa/ϤyWIӬT7P7Ɲd{l׍˞
-8c,xu#Sq]~.`{i.#YR7xgTԇN=P"Q(u̍(fį04E͵v~YLO|=]2ag'זYOty6𔋡F)lv=ù Vͷk0IAa]FZBZNgL }db4$OH$#Q"h"? ?R+*2/Y"F4jt<Řިݐ['oR_kҿO Ÿ?rýQo޼ZT$a1UOkZ:UO
-:øEcCg5qMkl ǟH>N1/Wׄo*|Xը _A2<n} X^ !yum 3INĮ9> 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{&#4L}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 <r!ʺ/'kLpvw=Rqaw N&=c"kB|BzC0=[c`209\l8 y$#=<W򳴎vӓۛޚ ӧ?. KM5ptC_WKb1yV]Åz+)`/w~-
-Avt/Ui1G`kIg~L!QϸMréb6=uidk<s[6io-6DAFsHzڳ3򄧨SǜQ
-C6slńФM*i2V793EYOӕ3^vR~QCF-SYB$k۠u%=3p`Vds ( BT>Oė|`|m_=?
-UeB;8CbHuK'Җ>g35-W^q^)dl1q0bERGnp>|C~]eeƦ.~#<bmi\
-^,HKfBv|sg e2,)g8ÞU_{
-$JCN(v[)K{`
-[;B
-%Z$ʔo~"Y"h$\C
-\˜jb<KM nm2_S~E:Tډ]B
-m1È/Ni HT(w ^|Ke&.R1D@rR?Ƒ@6-XF>{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^Ů<pBܛ@MޥՂ88eLp%T|}=HF抂0.E{nX
-jf};kVJ5ó@QqƎv{{]]!iwaz&0DABc LZ_˗=
-e= fs_L@ClƺIP` E5йt{ 
-E »]1faXS)7^Ṣ%Qs "6b;CUހjb00Rȗ{3w61fn܄d[̄QVS,wb&,RRhx$ɬn?rfkjk=)6){zb9LXS5Hy5/H!]l3ǶJ޿>p\~B`
-<<k[eZYE?x{u AC\ϙɅwa@HAǃV^nS.oP3L9wH&sDe͍0Bޜ^y媮*.EV_3a%TL"UDuQk[.6C";B^7%*èƩly73 BӴ..cvtI^>̾)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
-uS2<D} B`SU)sYX,/Z\=2]xIU:8L[g*j;?n !>k5os0|I$ܱ;9Pׯq jIspH͐[74!Oj(h__l^!URZ'<N6
-(FD®?+16 HC# %mQ}x<h"Ո
-eUeϮ=|bi׷Y\i_ n؛v0ij+B\;TsG'saƵ}B7_%wЬ}1<w
-q)˝?WURژg"K*$ t%["T#nXӏ+q50(Y5dž=hN*44p|PZM=XOuLcq&ܡVnD<,D+_!2*5 \̄ιԃ8Vu\*wѫ<\[dUPZ3+tr <%6R7FYR }׫tVF4OXo9Tl4L@B"&\/[?_UZ&8@ sE&Sgzؠ$9Bc+)B=\Z^_
-f
-C}aqaL;?nQkHٰ8GM,cڋğ=C Ғ7ʯXCSf[i>k;D(^3e+3$MF?2<%6g^_7[tHM{|™<Nl7̂RF 1d#/s%a9-Cѡ}
-h.q e?Qw,e>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? <jg4N@oyI 9Y^z'GR>y.RLf:f!St(̍] <KVX
-j1~ǻ^3$5"PsӇ!Ã*o* yk+6 ' v}d#
-NY$tQqţ//' !â%CQep_0~3Y\;/WR& "Fm/U/im73:,7; Eeד*Am{NM-JCŸ
-vZ[ⱕ ie}1\1Yi-xu-S㡝J~i}#M'{#cuO; M4J\Hߥ>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<LBfRir=1p0+ Jl7GC|PյgSQMޅrAoǃbW@y{:ެ 4im:ںԝ-u+O <W#GYn54%_ HS\"94IzF޴tZI+ 캈g]<BƁ}̯rC8hE)$c;/xreNf1N"<YU?Ej,'J0aq` ʊZ9:xG a%;TUk _M(D<#_·Y}2|]{ѹOj&M\7!DQ䈌5]>;޸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\%<EM.T>=;ԁ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@\pOP<t4ʚ"<厯XC.][} jn\{0,\*ܿ0pFRB@KvI6[Gߚ05v^wL'iSVN-_L~׽/G˳MҾfk >C `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[<C?d( mf%
-:t d;-uO{Uz4uވ_eVTlҭd^c06PA>+>? *
-=|cv\h.G곬,'a$fLaiD2 u<J^§犜o#k7dv:UW#h'+Lb^βw@ҼNΘY@cw('N'XBĒf)hA`( iBwj* fg\V+UisdUM
-:O;ɧUwQL x4vY}-+ PIwѷ<<.sz|sl:rZ
- s B
- ymB{>(~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:<OV*Yh$֑ݏem0%{.<6|u?qTF1ߗ[@
-b%w*15_w²
-(ӵOo,:
-U`O7W0 L c_e 7FxxjkUZ˜>Zr;2#<DvLGp>Ӵ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~<DG$SPu/gTYh)|DoĮcY}1f*a3:BF[yv!?i٥8fMnsQ,;I჎ | gRx0ۿ0L8fHYPW>-<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η. <r])zJ=^B\iBi3ͯu A쿿Mj5pvG%k90 `IM}lԥ p"><d"L10V u1lo
- #)e)x~F+3|!&?;(=0&h>T4t>'
-|dTD$Jp׾Ah?ȶ0RBЖ̀<F 0f\U$[a7q# E"0+Y|}FQǏ!mq9b&!LŖxB6ũs6s9xvjKqg^,z&:Q/:%ؠQ,r&H!e.k;w&\Ht?`2B
-B3?^`tLSc]n2ǰ VB?,؁]_
-壮g48dk#[0"Ve
--l}^B'0e~ys>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<lC!_HҔ L5u5!/G<>=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 &'` \<e=qRɇi&DžMr]j@V8Pi#`u_y^A8roxq.ig!Y+R N6oધy+j^
-9FSb+`xǽ
-0PS^U'
-?L㑍Sڑ`M/ HW# OT15vf7r臣E:(bw K?92ȸRY=}tjo$DMFS/P/
-x5$ doP afC
-Ё,eK.{oƳ*9./̧nVbr(uc
- c8hXR&ecꮮ\!a5mk.Hz? Q"P!?#BZb?{2m&Qk- 2[3 Rb Y_%U:تtu1c߄˼feopEtE&U ^w" YDK&ʚ75I-Ws%U
-CeU4 *k3h{eZ;MC)6"L?I :P," ~.F: W)>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.gosH<JR6Ö*fik=O`Y^һ1ssÑi+
-9Qk6C-9 R}bVq仙"=2/^shwǎEc?Ĥ""5"tJ[WɸWq M=Q)F;e ixge·򪺔cA+>ISF^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?<JeK"zh ́YQ_DrϬ6~ʟj]Ywr j(rJ'++L |u3Vn9trv̲‡֢I+
-B S[b-W}f^AhewXsY=\/`]bƪ2dsC'$I#=)ft _w[嵝j/@]L#"Zui-*&SЎѐ9׋*pNn6skZ7жAlC1bSXHMm=pHtulU h}',ڛ yճPju\q1)t",|uUN jZpt Jgr˝J噅@V'wx,S"ϟ=2%vjN-NHf /?BlLԚ0p^@>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֣,ʍr<rDVbS<x}ۤ)Ǫqh'NLN@8]#!e[}
-0H>K-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"<pF$g [^t?Sc ^tOa݋<́,.Dǵ[ QUiMXH~n^Ky˾,WJܬ7Dm_Fe(f@-vxbW?>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}d<X\).h$c3Fc2΅Ņv+U2a
-0R-H}4UjB]]+^VR-;fQ v
-h91,e$q1,~xo\SLo
-[\cq\ڡzubDGp
-GOEa9s֤uwm=Elx7t<ZoސfٽXJ=иn唽5o˝XrJAm6uW!紲x<(>f<C@\q;"V,l6LMujir|?cYBG-}'~X)/ **]J9kqhg%68R/m|.$oK
-*$r%ֺ?ls"
-n )G|8jn߫xv
- }k`'^A .Wځ)l9`2GmQ2}j_Ȏ>5vb[4ۄZWڠ*!T4'`R-y6-EucX(r0hf <[_ wkktj.!&5wZ
-jsk7I[xҔ{* f6.[Iu+\.q4^*<j˛4]EU 4P'Iu/+*%qy񊓤_JvmBr-hgPԾR1jնQܗt"龜5kƷ`YHUﷂE{!>_[+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{<I =8h<q^X%/~Ґ$f2#浻X]4zɇq/ѓ{G-jalL>\-ӊҊ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{Mh<OOhntY=ku)8 7綬&j ^H3O3 g}O\J:.VӝiME -b "ғ]ˏFCr,L!#XF@+۫c&Ae_U.0BSW]J8x{ѲIw'Gi
-vn3޼.{T-mlG&8A?H I?`נtmq{k8)N"<pjcc(Q`] Jk2{oyp[hQN$^+2R=](#G
-h`|[RFPFo!sd#'"<V17 a#j79I ]RI
-ˬ4a97xOӒV$eB9{esrvԎ[&
-ΝHL A\dT%*O(L}Gh[ mTP5g2öL*(9.͎g2=(s@wKgr5ylqwb4'MNQEq4 ʴL@.]u[٘q<wʨZc)GR!l)j;(&
-:
-% KݴJ`&t!*
- ק??e3^)
-Az
-Y9`?O[ɩ2g=̚#~c$Q?{'lkLSN?CIE +,#q%1zv.z80 Τ6` ̲\Y6*= P zX/sԋ);MRt`0A~RӲhm6') _R}?ty&fP7pFաۃ,2XUX 7":곷Bj|i1ʐ0,'-
-Gx)ߩ=L3bҲW: tVg$/RIW 7o!ʋ/?2 čMn`tOG^x.zcϣ ̃ :_md|Է=k}ߙG M6l^pCGb'{KOIa%V檐~Va+ 1JQ+ԵoRE}%LcѼAm~s7{k$)Az,B'KC
-Q$~<ui/(
-pM3:tؙԢ2h-MUԈ 5me1O7 RRsv筟踊ʆjuب#'tĀ<N<e5k ̙fknL
--
-_uUM. h).W
-:
-<
-]hyeo<F+\"-#njġhV*
-tj^ҭa6 &;V\зw*Ȋss慁ѝRjU@!GX %r3H&zA5nJ\a=CRV
-̓]Ɛbg" HV ʈ(Gl<4Ϛ,=`(̣֨M-Iev4y]67F|Đ0AiQבVe{^XĚ!۳iPo4ês+[\+ z -j`ʀ#>b[XX.Iol]dJOfj%u~gON+in4¿t2]ǢmTXgB-o68
- ȇl-atgSl *wannŋ6Pf4cU8k3 R
-wJDL>Sʟ-KBH3LkJ(NBjyj$C?
-zY1BV]r/* 2MPqAF<RhAᩎ{%A*!7ůmy>VN5V5{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><X."B|Fv2s7Ԅ<^(ӐL̼p%J
-gOUc8s2}TݑOh|+ӘiQ>W9CU%U4%¡xOs5TUe\hoI޻߱Ky5SV-4ΰn`!1X<I<Lj1++r=
-m0m5bELq ƇiW!s0`V 8Ԥ}78W%4',ڢ#2uz;rɗ dr~K-Յ_;ǯU?i~JGKa&)H&=H76|cbSY|AWpHָWnB񵹇GDpG|;!+2/Q$sm[pr\q}m(@e7&<yy'
-_7,H{<pia}.=ހ3XC&`R>3kϼO.c~$`<ϋ8ώZPvU\
-esQJ>EUB.[XPn|/@ <?l Qү2 8L7:;S\@O9P_Z$X!PzE> 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 <f¥(v Ԑ~I6Xk' 㩕&?e=Xz7حYJ::'t[[܋Y'eѧر ]8HVO_T9 qqA*U&4eseʨ;}*` !O~%~geFȷBg f)%H^L<:&r(3H?0W cu벭@
-*/o/3cxMdYIܲ^-bO~ӑ_,$tQ.
+M-BI.Nc d!*F*x
+BNvg/5-Щ/>ОΣ 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};Q<O[lg '/Rzq>X < }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\<J,73N;YVq!2Й
+yĚ?tJ\Ato7[
+6J{n]z`KW-ĆVߨLQUF$"ṯ
+8pCM2c& jŤ1Nf9I ;X02i/ԏr bOfwq,
+׬ i7WuH,^GkPPX@FMVKEL,z|xn@4oٓ2]&^q$G˟)k{mS%.:l2hyHI v
+We7(M@Cނ&k7jBR- u6RYP\~-!M` D8;-4g}^ԟT.e(*9i- ;{=2;!x+L̶_]CM6j`/pvFQ}̉0 7W|=*0DjѸy5 @D3xE@DS"J}X^@C#Ta~w/
+<,}`ZߔY};:!8 -_H8[h~rgb v25DpV
+LuC5+|< /oa>;3
+!|kzot[*?C<wnJ:,^(R:۷qغ"k7F׺kS"2SLN*˰IO'jdM&/"XOa֚(Jaqq8:LAvlF-F)TE BU 'ySs^n-j!Ɇ "-kUBMi|G`2OklLXr2¼m _JD)8۝hx2j!6Y`?{+3Q(G :Y4s`@;"s` M^:@2^f ƺ_8YjL"&2x ʮ 2@?J/l+K9>qr|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&/ <CN
+C&1? x[wD]+.yT&_ouT6bZ
+kuʭzf;l_F5 ?gxBa{: ALִwRQ`k@pC1e$~{&@ -
+F^*C]Gh<,!hb r1 .F^DVí (Yxi:m<ǮVViZ_`(7s{ c0]yR.j<FQR ~"7ؗ]J}+"+\pJB DIƴ-B\o0=2?Nbsj7(BwP*!S"YW#>ya7r:er9ŏ5b`R sa>`Oazt
+y@rLtPdQGKNOQ(:1L*r֎Qů,
+Ԙq+0-y3sEI=fLk>'C,.7YI
+ )~+# 12 ŴB/vh`Ψf6IƉ T1[X)I8rN,A<t&_Fl hm1E4 9(.H$dtpZoOV?9wqE+Ԃp kQN~';"ԍY;G^݅xcMѠ°]1c\oijON oljftnhL?:2{[`KXbj[Lt$~Ԇ:g̈́curJOt}V< [1 ^@ j4E/ e**&Tt#/2A`ӲI]:5ETvjSUHMmK qgl(*`WV_2w#I#xq%Aqa74|xTVI+{I$}ҜP) (1W $hu+OrUh.yiX|s`=_!.q&I_!O@⒧e_JJ4Tc돚
+W:jՙw,({Z=6Ϧ'Ƚl;Pm@_>D"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" =76<uO1KJƀ53z67rpMYP~c0r2EҗQAQ9 R|J;n #.{&%t%{-*W=oKS(n<غ}r mk
+/r<|^ X^^NMs o9oTך$ tltPrpV,~YÜ@xgK^~t /I;GDYzHd) Ŷ@eVaHaىulnFg&}=*o*s\b$;a+͏mJA}{UBoDe?.=!7E
+[Y V
+$IT``f 1Q<J m_삤p6$t/䞈^|2a4S1Xgۋۂ
+fl0AB/pJIdlY7*#~76U"AlGj4L]fl_ 'pV]WTkH< O'XPg5SEƮP0c,Cu8Ȣ4
+Sjшr
+;D&܌[_p{8 80EĒH.Fm\4 <{M7vm~Bcjt"λ"E*9rw(+g&8A{'+}wc1mDhwS,.uᓂ|G CGYf0܌ˊ%ciU1w99\@QGVA"ww0ol?R'd죊 i{J0M~y8BBTㇰsG^T:!@wg A5K4fB8S#ƈ|YXTn3٨
+\wh~OX8 vF3 6`=s5[ީRnzq:2FUs}\0y-yF?V9%~.}=??Q*.Ď6Oyuj
+v{o\cRU>Ww 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]<rÄ?iݗ|m8ꮕ3fu.eᒍnLX]nr'*pi&XDOs?ǣ;n*<jq>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<r\V2@@үҶ!)AZ}1&<{v rp?u :H@zYªq˫iae>'~Eo-r<zl?05;:h'ϸSt?Ruk~JH
+[OVg۸Yvĵ2 }FP TtWg
++7\sYâ&HGNNHK|Lvz/y˖ x.=/\P'7^="l +] TIE -8`a]qgnR>ت 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+`iWyIl<qlFH" -F{>3 j!0MŊ^~1Z:Fi/79\z'7-7\&& 1'cԭG >܃Q` }V
+;}5YIvnZ{8w<p")ױmBb+NjN <Jȑⴗ3$4 N1`N1n<+ ;h]$XnPsHV ;T}Bʮȷ6EdtVt.˧( !"DZ
+&GOjN'&пGqco 8^*'$@Y\VEBM.YUsO{5zoΛP ?4PkKV7)LY2 gob}{AldC?z7R9 !jSk%w+ .?8(5<
+.8]Ewճ϶NߛۆVVw$x^)" *d= 3 El`6xmLe9s!zypރ2yK0>[>^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#}<M;)}څHamv@-7o^^˓ H(4z>k^W诺JtT)\;92Mm<zG7B@`(rDw ucb [<#H֟o-CZO
+'s'RM:49Hm@ޛr{sF&r먉?_xko=X?QE%P6
+v7c9:8kܜJJ5
+as&9;/VgՅ:0.5Ӥ5#Y(߸\ ywD\vz9%|yuRla ̅ qnWU;~0B~p+RBw>_/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]<<Y(zW8V P%) a%-zW;T2<Up[(,rk8Kq<}k yUgz }Tec)}0R<jRb1TG྘
+2< e쇕Ч"`i(V>X'-V`bnU[;I"
+>P dx ,z[((GQi (k7̡s ا<lx
+{z>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 Zhp3N<Hw7
+OGmX*awkZR
+ r85FD,Lg V4XL[%)Ii1[oK ]̀_3=F&kANlE y0 q2ͭg5+) ;z&
+bݝTbX'L4"4L[~pi̻كfK M''.B+\lL t>Ff: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[<fyJ8"3$B.>0n褉R6H@)n:E a*
+ݩ%8WܿhTAu|| .!=)#+MKwĊ4"W@N?˙K8v
+tH0(X9@:S˫f:#Z<J_,TW{[48QILD4- )'>K6#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=~~<v4FU3 ةh[ؚfC%J;HpO ^,hWð>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_pB<gX¨у<4ڝ>kU7BYw__.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ӑ[<XuLw ˃y&:(q?c=u:W{d#1i St`:buԱ]h܀>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`erUW<?CIۗlW qyJVEIԂpŦS<n
+KMFd%D>UeIz&HM6#~*" `
+<F ( @) F&iv:sB`*C,2)Ү4Qlz,W1 _${XO
+F^ҝ&9e"̖#-Tql fH5740bi8Hs+mjYcPl/KKDFʒzf^.5ٝ́# { gJHAwh'X_3 bHXS2B5B6Ǻgi.@%sthpV0Rs~}tޔOfeGPUyݜ͚UW/tѺO㈊IXUךpOp0ׁd+v,e&EhCN  %8n+#ZOwﲊ(zi|&,lSQ P I )E#Fb~2`@1·.5ZTl=Ԥ>Q쑚6!eZ4;Jvrm9Xuьc v\,p.j ۦWeERibq 3{zY"팗7g]K;(kjp6ٛ&w .#u'DdP"BZ`,P;CLGI9~<S/v |
+QѸvS
+֊Wf-#x$Pho0~T}K. * x־V4XI #ue#rEs Y'oTJ2R?vߗ=Ƿ{pK󃀄Κr_E?Zcx~WdoGL0$$.G R2|cOVv8sn8eϗ<66))|pܠC!*JQHyU`U'ϦIfB
+1Ɗ'فuv)
+@tzX5FڼGba|-djvr72Az7 IJt^4S)Rk JCUnL|]/ կoxcMB0k]
+%?kR9Ņw
+x)9Kdfw։Ob2*G)=~- 8za| = *Ξr/lS_"s.b󰮹Xd34AǣgFfI"X
+~G>$[K%/HI\Ȟ΀ӡòd=%א5;O̿jpi6
+%K8^dam=&%ޔ`n"չIK;g#2)[ݟ'xs'713C0}i6p4<K=(esږ/0dSH'$ *䉇K,Bo,z|t-ѶV C X'yg0^yy@+<J!!q*x^:7T6_Y#{G|*r3D$Ffx(*n,dR
+PЅ\L%`Ă~p(%rS}xiS2rwx\ Н>8@V ΰ"Eכ " bnnu}_Jl
+}N\*{Au5&NN ;5θ峒/yҪ>~ڲ)޹_93<P2֍oY#;:
+`wjO{bz) -V-rMR/:8ʫ\*yn%H+=N=L}f*o !cZu|\tLi1%`3#D)RgFoVßt E+9%;Y7BZ~C^d=wF!.:t@6igl޳mܨC0]C98f1r;nPCvm4`ar [1"Nf:_m&v܆eS|6LA 왑 iM>K̉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<kD<W~JQc !
+rM8cao
+r&-kb.bnOp|W~ţ
+ĸ6m.Gd@(H̺8?j:Dzw8NKv%j`/ݡԙy
+BIUQϬwڦ.'}dxȯYHAν,@͇lF>&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^<WD![u^ۃmV:*,k>'; 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;w<X,-QWpNfnلps_/"/%\,Q3DKzfOy4%FE^*0-KμM])2q*!2~j3HP6)K&i+px/YIeHK:tUP蝇4aYzCO^h<//Aнv U?AW&B29Ya<?!
+ݩ$rxW
+xF 5RSZ6Td`;wv1*Fw6NKTV(󞸌MI5*/
+\ WFK$FͰ_Ӝ d[E0Rf3Mx29߈}/uJqUE!Ӛ{3Vz~Ec[9&Ux^VqK |2LLV0a$oP>O`_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Ś<am@ҿ5@ODV%[Gwv vrWߌ
+ב薻Ud4[v\ݽ g==xRn.^ t%i&P𓧻\u -S'~ PI7 1
+`"7p@mA ~.oZ?֫BU5hI?0n7y )F.q9~xX`-,ψp%?0WW{DxzJyU򶸺ua~dH>b6P,!oy(
+鶀lAcJUf;>= $ #k5m۽i90oVAdE
+t>l
+tJكڏCW?Q7/̟tT.{25o5 %*+[-M/ke <Q t[ꑓn
+T$E;v6FDEbzXxǕH~X,V?cEIX`i*7յklCGU+" L&y$ z"2c rWImIjN̢]QMy+,*v;J֐1c8Ē?Uĺi{F4hvvpzh'c,_PrhnILSjoϏM4'N_jddg
+2f浂Z1D7q7ꡰMX~d8Kǔ=[J/ѯPUh6LjX}\ U~D1><N>&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<tRjqFqBnwlO_ _4a09M5YDI*<pW%'6hKB`}4fSsOL̕!apOcFY&uΥ]RoO3`ͱVZǻgD_ވdu2=k?ECOQ Ҙmt C8ԻHs3Ë6JiPUl'pGm5MI~
+s"F'<4.
+br
+/0LT*Sf$ p.#;X"DP 肉MG [GbaU#vYܲ'1XJ] p#''?'U}./hmooMk5d/0s7xg@ڤRk>!$6aFد„xgA)_7{9'|[8-C9a[$lIlʣ~f5GdE0Fe<?U-Q^a,)nCO5AY/p|:R!'<:>l!A<%qbYvMEad8DՀd<FjXxǟy-[0k ޑ\.?U׻uO bgׂ:Ln1mﰭ:NA9tƉu%wKO}? ew:)I2KIe*s})XW\^i`)xR7
+>tu/;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 / <n綵EKB.;z~&($ȈU&5B91B~me!jL`>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 <tjPb:ɺ(3j3mj,TyW=0i JNdOF(};V,Gk}#q.-ϼ{csa %i
+GaL 5аݚK7E74v?ߑn!0ΑuڧJ뒉R(
+G9pxoKoЭ"O'*Wor4y}%&Kq(AO9vŘJZ(%x:JTB4(٠?ݴM::eQT"xr@փagkkN; IR
+_p4~2ۣ# Ga^cL8=\6'SM~cQB&
+'\nUd9fA-{>SƄiiWg`U F&NDfw&kҬZTwbg_6⮲Y5ta{Al#\k?%Do"M$DIHn ^AΝ4ZYTSBVr b.I1B "S!:<m]tE;}uNaVz6}tABU {-VyM;-H0ups>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<s?85%5ăaî_ؑ πt =92]L9TA0=[%,Mq*ƄE0A{bټϤ=s\ wJNSLE$cλWzh;78LuΎ&λ͎PE~>\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>?԰ĆN<mw4
+
+}wCN]G>IAO
+ڰą`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@9<uڈ֤_,YJiV-3h34}6xTQ!]~3l4
+wE8I P\w.,yNn&P*}":hi(Y@EWC
+%GĨ?߭J+T:\~*BFlwpeL ApT̫/.rC/y $ͥFU=F,R{XGF% 3@;:ke%KuRbuX~¼cbm\ `'?`4mG*[O!c% R+֑D5m)@3}{,amJ`Â'FP!6uUz3$HJ œn<ڷsP=;%"? ѕgmZ܃I2p$U2-E"+0c̽vc"]`璝vi>ZT s70`M3z;#w:~g ꩛pz1+ܳ,=:0/
+/x=vqx0JAI~
+<Fo_[Mx['@N#踝VF ﷎k(I1__NI‹ќ'нK6D7ly X$*kJ=a2)\ @|t{COO=
+4;ҞE@èjm 6 .(,j;tA('"]P ĹfK5.Ώlr|'T~ W ` 54y~_DP0[&
+(c6`;C9GQr^ص M
+T) _bvejh*qtG;& [>{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<yzyU+/%c}kTиX'u%;
+,fI#xIjICF2)\ٌBz(1_?8DRzJ$PwދDK,YTx',J6Έ'lpW.ͮ5zi1oΙ
+.mhzS`&yP ƺu2rو JWQڻmٽ69E,L?< ]/d1ǙMULZ]Pԛz[!aumjbO}̏}D??I]RmWG}^
+g-?aLzQttK|E&/MGԫ</t zgIeS{7?_ `LluZrKh(;;D*T
+1M#nϓ)Y;>'[^` }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<G{9-:R:?i~BoUEXjPm Lwx+Ȃ`1 C|!YF|!)_WW'{:k͙B~_$kv"~NXXӆ$bnFHqA5=B˵ p_HUϙ_$d!n Jz7Q39$9rYfح;Yﹱit(a ϗw!Wm$#A 5n\r K2h6c\*ֆp3یk & 2ѧMǮF% 3| tɳ p̤KAvuENy&'+0c-;vϿp`)A+0Zg*ʺ/{S-gnO]: 7¤҂=xu.cv'PJQ26_q;`NkԔ0]F.{_ 6`gtԯ)[?`6Ws)~sZ U2|A%
+7cK2a wkh  ?\jF _"-/$8Ht|P^\@FÄb@3w2a9D6_.=o[<u${yV|̰an},U>!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ڐ<vK&?)Ji@GWXq.ƙd
+[k\iJ,ԧ5=CGnCS+oϷP=v-?!/#;pg0x\]CcC02"<Qf|hv0sB#z7'~U>?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 ż8OSZ4062<Kӟ
+{2E`qȰtv6S6ׯ>PWS 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 f<n KY_*4/ݬٔwM"]t;&tO36c6Mwkwj
+Ϧ>p*'
+ѧP;:i<=Slg+(H<-OQ8޶'J=f14u:15J:=\F@4kLsV[.(| &V*&~n"*xY]3 t⊤.wl\xo}#]'ۏj <U(fGa1ьj~$ӓX@x^Q`7 ͠
+A^(fs팊N?EW Gt0@{J=9 ^"ىkxCze5Q-;eѡS-Ig6sՕg%v4uy 2?m0%iǫ7e0kdyOdrԎ}M%شlXFV4BHWuD.;rJ_yKYCP2٩J<
+$[:LhVD]/Y?W7 ٮ2iEKbآaR^VO)@;׏B6^щ97 2BeNV3yL~a4n=[|ŕRo t:%V> 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<x Ot1I#$0#z9V{b?:f5)%N]CX~dBڅW>ފ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<zl2v˵Ng*4{nثG):ۉqW?snRiNaQ0'^ʨƹY/e%Vn86[z[DYk+ZE
+g
+Pdӑ90$ {<B @\
+D]BcvUߵ=\Piii3x^EкϾNAk
+JJ#M-MQBȱA4J&:#[oSK3?$>{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<kPxQ'9gy޽W#L2n>(-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Ԩs<meU-!9‡^LvKgc`f<4ϻ!ؠr K)Y|[y<Ki6}^[ K CoOF"bloGE]8LT 1
+#8[,m2]{NDςp +b*@¬=Q o4ӜbH fR?vz{uRe
+Y
+HR,B㜇_oIo!pζH;aZ- ͤ8rQ2[kMf[ڐm\E g
+|*骎+kn ȉVN2䌍X͍CeՔDXS¿
+$o8( 
+9>nGґ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@a<wob(6հ e܀,6<a.
+XM} t %TVSԙFa`gb7,!h͖;J8y6;KƘX3<btZxK!u8ޗJ&ŖIQ̞-ą=&Kv_qZ <st'guQ#s:!E<^S
+Z
+O/ne|{&ꓑDOmmhp
+s;//k[N)FR>NxoVҲ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 "<m^౰iw">{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 Ѽ*,iNg<QQA8hn=) \Յ[&
+<fڊ+S_qPE
+Ι5ȃl:JJ[FD2 d9.j0]1pX]׻t&p&Nѿjp;~~qs<,SOB2q) e5DZˆ`m <DpP %vVmЬDۺCPHdexa>O6(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<Fz`i jb p>ǟ/;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:&<?e*k( no^[Ot\KA,uH?Yy% b얈48^˼f9~?;%dޞ4 4![0]-~|
+7jԂ3);um27dc{Ji%jpohص e>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ļ<y\T%jsg%BQ4 NI'p!mn{UqM%{z繻+n,0 tKc҈ijZ E2) ?=|/
+8nE+зM6.y2^ws6˅.rmm¬a:uy!h;|finڐk婢bkOHfשt'B45fKhYEI@lQ(CoAq(h5:PUcNSKu:ǸߘΟa95C K
+
+xnF'Ef^ J'`H 4te,Vo 7?k +dz+('-wg=) M=Ӛ> ݦK Vqu<T$E?|ylQ#]ys@ZE Ҫ$lKyW z }AG7tN4BE'YYMF *phni8frՒBؓ<h'"ω/$ e$T)a[,ܙz>SA6J7&^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<av}t
+kixeX*W hv#`/njip'**?mKHԝT4>(E<j_)*pt*'7AD/?qnu񀬅k(j:/uu1TQ7Q/`1>vwmܨ\,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^$<e:b
+ldK x
+\,RrFj
+d
+A+SqC\_Qs(|xptp7J΃R4 z[ֻz=^M.. +9hH4wFV  ̎$(&u
+iɾyP;cT?%5Mq*ڊkx7 Psou|=ë?r<_'[j څR[?n"5v U2΃]I:[hZ#4Bh̸/skl'_/Zeq+`3&h{KƇv<默}+b0m`3|ڒYcԉ8og:噙bx~ LX!_'u '8N^a.
+:pf
+36TGUV@ 5? Rt3q˜x"A <4Ab~ғ* FZXi@Z#H%R#DJn.hs=1<gOz0Xd_&JW-vL(0~8tR~GqS-У:\Hس‘BRUj bnz;JDۓ/vޱtƶ :l]2,
+a735J ٧!<uo2iFF.ìm`0y枆- L?vݳ1H@F`x/,ny'
+b韁O&2Ú#I/jsBƒHRpUp?MOb
+lߖ"I]:adMɽē$]ن琍Qu2܇3Jh!DxFGLEAz2p1ݣ,Zdv+`H+
+S%pwmsRzHr`Xc2ɒ$ !gfGXl[Ce~UgXފ\3ï.sfj<b'Su,1'y -q} c囌EGҘpy;&-!⡕䑆 /,􋜾 '!SVIMqc
+NIIELw)sD/^#h7zOR+U~H] @"e6IiF`@}>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)<vDZE&D}؝<H1 it[
+Df{&=M"nMW(wvMx5 <_Z
+twbИP!g@4m Id$f
+%5yʖė[a@D˜D.:3QA
+B;Vӳ6Mpy嫺=FT<whK[,첞 %Y{$_6c8\:׹OzQ=?T}1TwmElv& {Xc&7Jg:
+4b@2yUxR%e<@}?UHMmop+Rn ȕD!}ͿN_NK%- ktG!O;;"9!{8{:뾏5J`Ȗ+WhvC||
+DR4e!޸,|duP"=dXCN0ݢw
+D
+q#a.yۭNX,Q?>NPI<u]|XQ.ydNJGX$`E#?ݰ/kV(V&CDd F/A>7lR+(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/)_s<bwv&qH%bnŃN!VGwКdVP 2Xu숮$rbOjԜ+Ewnl٫{MWPf=ìDR* Xێ20BM6QA4@%oldEEe9&HGHp3c
+s,M/6V+XpQM {"0<m\֗Y8n¡UC[ hYam
+qV6`R Dmg`
+@ˁ֖;qNvZJu0 mٔbb '=;B9QpNogQ٫%斔IJ5(/ Ar"?g1i(~E| dG6FF']Ml{g>b"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 <chaomin.zheng@amlogic.com>
-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<IAudioRoutesObserver>();
-
- // 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 <errno.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <ziparchive/zip_archive.h>
-#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; z<aml_each_id_length; z++) {
- /*fix string with \0*/
- if (0x20 == (uint)dt_info[x][z]) {
- dt_info[x][z] = '\0';
- }
- }
- }
-
- if (dt_tool_version == 1)
- printf(" dtb %d soc: %.4s plat: %.4s vari: %.4s\n", i, (char *)(dt_info[0]), (char *)(dt_info[1]), (char *)(dt_info[2]));
- else if(dt_tool_version == 2)
- printf(" dtb %d soc: %.16s plat: %.16s vari: %.16s\n", i, (char *)(dt_info[0]), (char *)(dt_info[1]), (char *)(dt_info[2]));
- uint match_str_counter = 0;
-
- for (z=0; z<AML_DT_ID_VARI_TOTAL; z++) {
- /*must match 3 strings*/
- if (!strncmp(tokens[z], (char *)(dt_info[z]), strlen(tokens[z])) && \
- (strlen(tokens[z]) == strlen(dt_info[z])))
- match_str_counter++;
- }
-
- if (match_str_counter == AML_DT_ID_VARI_TOTAL) {
- //printf("Find match dtb\n");
- dtb_match_num = i;
- }
-
- for (z=0; z<AML_DT_ID_VARI_TOTAL; z++) {
- /*clear data for next loop*/
- memset(dt_info[z], 0, sizeof(aml_each_id_length));
- }
- }
-
- /*clean malloc memory*/
- for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++) {
- if (dt_info[i])
- free(dt_info[i]);
- }
-
- if (dt_info)
- free(dt_info);
-
- /*if find match dtb, return address, or else return main entrance address*/
- if (0xffff != dtb_match_num) {
- printf(" Find match dtb: %d\n", dtb_match_num);
- /*this offset is based on dtb image package, so should add on base address*/
- *plen = STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \
- dtb_match_num * aml_dtb_header_size + aml_dtb_offset_offset+4);
- return fdt_addr + STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \
- dtb_match_num * aml_dtb_header_size + aml_dtb_offset_offset);
- } else {
- printf(" Not match any dtb.\n");
- return NULL;
- }
- } else {
- printf(" Cannot find legal dtb!\n");
- return NULL;
- }
-
- return NULL;
-}
-
-
-/**
- * --- 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_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_zip;i++) {
- printf("%s:0x%08x\n", dtb_zip[i].partition_name, dtb_zip[i].partition_size);
- if (!strcmp("cache", dtb_zip[i].partition_name)) {
- offset += dtb_zip[i].partition_size;
- find = 1;
- }
- }
-
- if (find == 0) {
- printf("get cache partition size from dtb.img failed!\n");
- ret = -1;
- goto END;
- }
- printf("env partition offset:0x%08x\n", offset);
-
- ret = offset;
-
-END:
- if (s_pDtbBuffer != NULL)
- {
- free(s_pDtbBuffer);
- s_pDtbBuffer = NULL;
- }
-
- return ret;
-}
-
-int
-RecoveryDtbCheck(const ZipArchiveHandle za){
- int i = 0, ret = -1, err = -1;
- int fd = -1;
- int partition_num_zip = 0;
- int partition_num_dev = 0;
- int imageSize = 0;
- int recovery_dev = 0, recovery_zip = 0;
- int data_dev = 0, data_zip = 0;
- int recovery_offset_dev = 0, recovery_offset_zip = 0;
- int data_offset_dev = 0, data_offset_zip = 0;
- int device_type = 0;
- int partition_num;
- int cache_offset_dev = 0, cache_offset_zip = 0;
- int recovery_size_dev = 0, recovery_size_zip = 0;
- int cache_size_dev = 0, cache_size_zip = 0;
-
- isEncrypted = IsPlatformEncrypted();
- if (isEncrypted == 2) {
- printf("kernel doesn't support!\n");
- return 0;
- } else if (isEncrypted < 0) {
- return -1;
- }
-
- 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;
- }
-
- ret = GetDevDtbImage();
- if (ret != 0) {
- printf("read dtb from /dev/dtb failed!\n");
- ret = -1;
- goto END;
- }
-
- working_fdt = (struct fdt_header *)s_pDtbBuffer;
- ret = GetPartitionFromDtb("/partitions", MAX_LEVEL, &partition_num_dev, 1);
- if (ret != 0) {
- printf("get partition map from /dev/dtb failed!\n");
- ret = -1;
- goto END;
- }
-
- partition_num = partition_num_dev;
- device_type = GetDeviceType();
- printf("device_type = %d \n",device_type);
-
- if (partition_num_zip != partition_num_dev) {
- printf("partition num don't match zip:%d, dev:%d\n",partition_num_zip, partition_num_dev);
- if (device_type == DEVICE_NAND) {
- printf("the partitions changed & device is nand! can not upgrade!\n ");
- ret = -1;
- goto END;
- }
- #ifdef SUPPORT_PARTNUM_CHANGE
- ret = 2;
- partition_num = partition_num_zip > 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<partition_num;i++) {
- printf("%s:0x%08x\n", dtb_zip[i].partition_name, dtb_zip[i].partition_size);
- printf("%s:0x%08x\n", dtb_dev[i].partition_name, dtb_dev[i].partition_size);
-
- if (!strcmp("recovery", dtb_dev[i].partition_name)) {
- recovery_size1 = dtb_zip[i].partition_size;
- recovery_dev = i;
- recovery_size_dev = dtb_dev[i].partition_size;
- }
- if (!strcmp("recovery", dtb_zip[i].partition_name)) {
- recovery_zip = i;
- recovery_size_zip = dtb_zip[i].partition_size;
- }
-
- if (!strcmp("data", dtb_dev[i].partition_name)) {
- data_dev = i;
- }
- if (!strcmp("data", dtb_zip[i].partition_name)) {
- data_zip = i;
- }
-
- if (!strcmp("cache", dtb_dev[i].partition_name)) {
- cache_size_dev = dtb_dev[i].partition_size;
- }
- if (!strcmp("cache", dtb_zip[i].partition_name)) {
- cache_size_zip = dtb_zip[i].partition_size;
- }
-
- if ((strcmp(dtb_zip[i].partition_name, dtb_dev[i].partition_name) != 0)||
- (dtb_zip[i].partition_size != dtb_dev[i].partition_size)) {
- ret = 2;
- /*just emmc support partition changes*/
- if (device_type == DEVICE_NAND) {
- printf("the partitions changed & device is nand! can not upgrade!\n ");
- ret = -1;
- goto END;
- }
- }
- }
-
- /*the offset of recovery/data cannot be changed*/
- for (i=0;i<recovery_dev;i++) {
- recovery_offset_dev += dtb_dev[i].partition_size;
- }
- for (i=0;i<recovery_zip;i++) {
- recovery_offset_zip += dtb_zip[i].partition_size;
- }
- for (i=0;i<data_dev;i++) {
- data_offset_dev += dtb_dev[i].partition_size;
- }
- for (i=0;i<data_zip;i++) {
- data_offset_zip += dtb_zip[i].partition_size;
- }
-
- for (i=0;i<2;i++) {
- cache_offset_dev += dtb_dev[i].partition_size;
- cache_offset_zip += dtb_zip[i].partition_size;
- }
-
- printf("recovery_dev: %d recovery_offset_dev :0x%08x\n", recovery_dev, recovery_offset_dev);
- printf("recovery_zip: %d recovery_offset_zip :0x%08x\n", recovery_zip, recovery_offset_zip);
- printf("data_dev: %d data_offset_dev :0x%08x\n", data_dev, data_offset_dev);
- printf("data_zip: %d data_offset_zip :0x%08x\n", data_zip, data_offset_zip);
- printf("cache_offset_dev :0x%08x, cache_size_dev: %d\n", cache_offset_dev, cache_size_dev);
- printf("cache_offset_zip :0x%08x, cache_size_zip: %d\n", cache_offset_zip, cache_size_zip);
-
- if (data_offset_dev != data_offset_zip) {
- printf("data changed, need wipe_data\n ");
- ret = 3;
- }
-
- if ((recovery_offset_dev != recovery_offset_zip) || (recovery_size_dev != recovery_size_zip)) {
- printf("recovery part changed! can not upgrade!\n ");
- ret = -1;
- goto END;
- }
-
- if ((cache_offset_dev != cache_offset_zip) || (cache_size_dev != cache_size_zip)) {
- printf("cache part changed! can not upgrade!\n ");
- ret = -1;
- goto END;
- }
-
-END:
- if (s_pDtbBuffer != NULL)
- {
- free(s_pDtbBuffer);
- s_pDtbBuffer = NULL;
- }
-
- return ret;
-}
diff --git a/recovery/check/dtbcheck.h b/recovery/check/dtbcheck.h
deleted file mode 100644
index eb9691d..0000000
--- a/recovery/check/dtbcheck.h
+++ b/dev/null
@@ -1,15 +0,0 @@
-#ifndef _SECURITY_H_
-#define _SECURITY_H_
-
-#define DTB_IMG "dtb.img"
-
-extern unsigned int recovery_size1;
-
-typedef struct Dtb_Partition_s
-{
- char partition_name[16];
- unsigned int partition_size;
-}Dtb_Partition_S;
-
-
-#endif \ No newline at end of file
diff --git a/recovery/check/security.cpp b/recovery/check/security.cpp
deleted file mode 100644
index 8c48cdf..0000000
--- a/recovery/check/security.cpp
+++ b/dev/null
@@ -1,578 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <string.h>
-
-#include <ziparchive/zip_archive.h>
-#include <android-base/logging.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
-
- if (s)
- return s;
- }
-
- return "<unknown error>";
-}
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 <fdt.h>
-#include <libfdt.h>
-
-#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 <fdt.h>
-#include <libfdt.h>
-
-#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 <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#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 <fdt.h>
-
-#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 <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <fs_mgr.h>
-#include "install.h"
-#include "ui.h"
-#include <dirent.h>
-#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<std::string>& 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<std::string> 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<std::string> 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 <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-
-void amlogic_init();
-
-void amlogic_get_args(std::vector<std::string>& 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 <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#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<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#include<ctype.h>
-
-#include "amlogic_ui.h"
-
-#include "common.h"
-#include "device.h"
-#include "screen_ui.h"
-#include "ui.h"
-#include "recovery_extra/recovery_amlogic.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <string.h>
-#include <ziparchive/zip_archive.h>
-#include <android-base/logging.h>
-#include "cutils/properties.h"
-
-#include <fcntl.h>
-#include <linux/fb.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#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 <linux/input.h>
-
-#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 <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <selinux/selinux.h>
-#include <ftw.h>
-#include <sys/capability.h>
-#include <sys/xattr.h>
-#include <linux/xattr.h>
-#include <inttypes.h>
-#include <ziparchive/zip_archive.h>
-
-#include <memory>
-#include <vector>
-
-#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 <bootloader_message/bootloader_message.h>
-#include <fs_mgr.h>
-
-
-#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<std::unique_ptr<Expr>>& argv) {
- char* result = NULL;
- int iRet = 0;
-
- if (argv.size() != 1) {
- return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name);
- }
-
- std::vector<std::unique_ptr<Value>> 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<std::unique_ptr<Expr>>& 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<std::unique_ptr<Value>> 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<std::unique_ptr<Expr>>& argv) {
- int ret = 0;
- if (argv.size() != 2) {
- return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,argv.size());
- }
-
- std::vector<std::string> 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<std::unique_ptr<Expr>>&argv) {
- int check = 0;
- ZipArchiveHandle za = static_cast<UpdaterInfo*>(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<std::unique_ptr<Expr>>& argv) {
- int ret = 0;
- if (argv.size() != 2) {
- return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name, argv.size());
- }
-
- std::vector<std::string> 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<std::unique_ptr<Expr>>& 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<std::unique_ptr<Expr>>& argv) {
- int ret = 0;
- if (argv.size() != 1) {
- return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 args, got %zu", name, argv.size());
- }
-
- std::vector<std::string> 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<std::unique_ptr<Expr>>& 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<std::unique_ptr<Expr>>&argv) {
- int offset = 0;
- char tmpbuf[32] = {0};
- ZipArchiveHandle za = static_cast<UpdaterInfo*>(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